//===- ASTMatchers.h - Structural query framework ---------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  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,
//  call `.bind("name")` on 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"), has(recordDecl().bind("child")))
//  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 `.bind()` 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/ASTTypeTraits.h"
#include "clang/AST/Attr.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/LambdaCapture.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/OpenMPClause.h"
#include "clang/AST/OperationKinds.h"
#include "clang/AST/ParentMapContext.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
#include "clang/AST/StmtOpenMP.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/ASTMatchers/ASTMatchersInternal.h"
#include "clang/ASTMatchers/ASTMatchersMacros.h"
#include "clang/Basic/AttrKinds.h"
#include "clang/Basic/ExceptionSpecificationType.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TypeTraits.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Regex.h"
#include <cassert>
#include <cstddef>
#include <iterator>
#include <limits>
#include <string>
#include <utility>
#include <vector>

namespace clang {
namespace ast_matchers {

/// 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:
  /// 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);
  }

  /// 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::DynTypedNode
  using IDToNodeMap = internal::BoundNodesMap::IDToNodeMap;

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

private:
  friend class internal::BoundNodesTreeBuilder;

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

  internal::BoundNodesMap MyBoundNodes;
};

/// Types of matchers for the top-level classes in the AST class
/// hierarchy.
/// @{
using DeclarationMatcher = internal::Matcher<Decl>;
using StatementMatcher = internal::Matcher<Stmt>;
using TypeMatcher = internal::Matcher<QualType>;
using TypeLocMatcher = internal::Matcher<TypeLoc>;
using NestedNameSpecifierMatcher = internal::Matcher<NestedNameSpecifier>;
using NestedNameSpecifierLocMatcher = internal::Matcher<NestedNameSpecifierLoc>;
using CXXBaseSpecifierMatcher = internal::Matcher<CXXBaseSpecifier>;
using CXXCtorInitializerMatcher = internal::Matcher<CXXCtorInitializer>;
using TemplateArgumentMatcher = internal::Matcher<TemplateArgument>;
using TemplateArgumentLocMatcher = internal::Matcher<TemplateArgumentLoc>;
using LambdaCaptureMatcher = internal::Matcher<LambdaCapture>;
using AttrMatcher = internal::Matcher<Attr>;
/// @}

/// 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(); }

/// 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".
extern const internal::VariadicDynCastAllOfMatcher<Decl, TranslationUnitDecl>
    translationUnitDecl;

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

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

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

/// Matches type alias template declarations.
///
/// typeAliasTemplateDecl() matches
/// \code
///   template <typename T>
///   using Y = X<T>;
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasTemplateDecl>
    typeAliasTemplateDecl;

/// 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.getBeginLoc()));
}

/// 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.getBeginLoc());
  if (ExpansionLoc.isInvalid()) {
    return false;
  }
  return SourceManager.isInSystemHeader(ExpansionLoc);
}

/// 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_REGEX(isExpansionInFileMatching,
                              AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt,
                                                              TypeLoc),
                              RegExp) {
  auto &SourceManager = Finder->getASTContext().getSourceManager();
  auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getBeginLoc());
  if (ExpansionLoc.isInvalid()) {
    return false;
  }
  auto FileEntry =
      SourceManager.getFileEntryForID(SourceManager.getFileID(ExpansionLoc));
  if (!FileEntry) {
    return false;
  }

  auto Filename = FileEntry->getName();
  return RegExp->match(Filename);
}

/// Matches statements that are (transitively) expanded from the named macro.
/// Does not match if only part of the statement is expanded from that macro or
/// if different parts of the statement are expanded from different
/// appearances of the macro.
AST_POLYMORPHIC_MATCHER_P(isExpandedFromMacro,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc),
                          std::string, MacroName) {
  // Verifies that the statement' beginning and ending are both expanded from
  // the same instance of the given macro.
  auto& Context = Finder->getASTContext();
  llvm::Optional<SourceLocation> B =
      internal::getExpansionLocOfMacro(MacroName, Node.getBeginLoc(), Context);
  if (!B) return false;
  llvm::Optional<SourceLocation> E =
      internal::getExpansionLocOfMacro(MacroName, Node.getEndLoc(), Context);
  if (!E) return false;
  return *B == *E;
}

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

/// Matches decomposition-declarations.
///
/// Examples matches the declaration node with \c foo and \c bar, but not
/// \c number.
/// (matcher = declStmt(has(decompositionDecl())))
///
/// \code
///   int number = 42;
///   auto [foo, bar] = std::make_pair{42, 42};
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Decl, DecompositionDecl>
    decompositionDecl;

/// Matches binding declarations
/// Example matches \c foo and \c bar
/// (matcher = bindingDecl()
///
/// \code
///   auto [foo, bar] = std::make_pair{42, 42};
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Decl, BindingDecl>
    bindingDecl;

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

/// 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
extern const internal::VariadicDynCastAllOfMatcher<Decl, NamedDecl> namedDecl;

/// Matches a declaration of label.
///
/// Given
/// \code
///   goto FOO;
///   FOO: bar();
/// \endcode
/// labelDecl()
///   matches 'FOO:'
extern const internal::VariadicDynCastAllOfMatcher<Decl, LabelDecl> labelDecl;

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

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

/// 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
extern const internal::VariadicDynCastAllOfMatcher<Decl, RecordDecl> recordDecl;

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

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

/// 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>
extern const internal::VariadicDynCastAllOfMatcher<
    Decl, ClassTemplateSpecializationDecl>
    classTemplateSpecializationDecl;

/// Matches C++ class template partial specializations.
///
/// Given
/// \code
///   template<class T1, class T2, int I>
///   class A {};
///
///   template<class T, int I>
///   class A<T, T*, I> {};
///
///   template<>
///   class A<int, int, 1> {};
/// \endcode
/// classTemplatePartialSpecializationDecl()
///   matches the specialization \c A<T,T*,I> but not \c A<int,int,1>
extern const internal::VariadicDynCastAllOfMatcher<
    Decl, ClassTemplatePartialSpecializationDecl>
    classTemplatePartialSpecializationDecl;

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

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

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

/// Matches class bases.
///
/// Examples matches \c public virtual B.
/// \code
///   class B {};
///   class C : public virtual B {};
/// \endcode
extern const internal::VariadicAllOfMatcher<CXXBaseSpecifier> cxxBaseSpecifier;

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

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

/// Matches template arguments (with location info).
///
/// Given
/// \code
///   template <typename T> struct C {};
///   C<int> c;
/// \endcode
/// templateArgumentLoc()
///   matches 'int' in C<int>.
extern const internal::VariadicAllOfMatcher<TemplateArgumentLoc>
    templateArgumentLoc;

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

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

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

/// Matches template template parameter declarations.
///
/// Given
/// \code
///   template <template <typename> class Z, int N> struct C {};
/// \endcode
/// templateTypeParmDecl()
///   matches 'Z', but not 'N'.
extern const internal::VariadicDynCastAllOfMatcher<Decl,
                                                   TemplateTemplateParmDecl>
    templateTemplateParmDecl;

/// Matches public C++ declarations and C++ base specifers that specify public
/// inheritance.
///
/// Examples:
/// \code
///   class C {
///   public:    int a; // fieldDecl(isPublic()) matches 'a'
///   protected: int b;
///   private:   int c;
///   };
/// \endcode
///
/// \code
///   class Base {};
///   class Derived1 : public Base {}; // matches 'Base'
///   struct Derived2 : Base {}; // matches 'Base'
/// \endcode
AST_POLYMORPHIC_MATCHER(isPublic,
                        AST_POLYMORPHIC_SUPPORTED_TYPES(Decl,
                                                        CXXBaseSpecifier)) {
  return getAccessSpecifier(Node) == AS_public;
}

/// Matches protected C++ declarations and C++ base specifers that specify
/// protected inheritance.
///
/// Examples:
/// \code
///   class C {
///   public:    int a;
///   protected: int b; // fieldDecl(isProtected()) matches 'b'
///   private:   int c;
///   };
/// \endcode
///
/// \code
///   class Base {};
///   class Derived : protected Base {}; // matches 'Base'
/// \endcode
AST_POLYMORPHIC_MATCHER(isProtected,
                        AST_POLYMORPHIC_SUPPORTED_TYPES(Decl,
                                                        CXXBaseSpecifier)) {
  return getAccessSpecifier(Node) == AS_protected;
}

/// Matches private C++ declarations and C++ base specifers that specify private
/// inheritance.
///
/// Examples:
/// \code
///   class C {
///   public:    int a;
///   protected: int b;
///   private:   int c; // fieldDecl(isPrivate()) matches 'c'
///   };
/// \endcode
///
/// \code
///   struct Base {};
///   struct Derived1 : private Base {}; // matches 'Base'
///   class Derived2 : Base {}; // matches 'Base'
/// \endcode
AST_POLYMORPHIC_MATCHER(isPrivate,
                        AST_POLYMORPHIC_SUPPORTED_TYPES(Decl,
                                                        CXXBaseSpecifier)) {
  return getAccessSpecifier(Node) == AS_private;
}

/// 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();
}

/// Matches non-static data members that are bit-fields of the specified
/// bit width.
///
/// Given
/// \code
///   class C {
///     int a : 2;
///     int b : 4;
///     int c : 2;
///   };
/// \endcode
/// fieldDecl(hasBitWidth(2))
///   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;
}

/// Matches non-static data members that have an in-class initializer.
///
/// Given
/// \code
///   class C {
///     int a = 2;
///     int b = 3;
///     int c;
///   };
/// \endcode
/// fieldDecl(hasInClassInitializer(integerLiteral(equals(2))))
///   matches 'int a;' but not 'int b;'.
/// fieldDecl(hasInClassInitializer(anything()))
///   matches 'int a;' and 'int b;' but not 'int c;'.
AST_MATCHER_P(FieldDecl, hasInClassInitializer, internal::Matcher<Expr>,
              InnerMatcher) {
  const Expr *Initializer = Node.getInClassInitializer();
  return (Initializer != nullptr &&
          InnerMatcher.matches(*Initializer, Finder, Builder));
}

/// Determines whether the function is "main", which is the entry point
/// into an executable program.
AST_MATCHER(FunctionDecl, isMain) {
  return Node.isMain();
}

/// Matches the specialized template of a specialization declaration.
///
/// Given
/// \code
///   template<typename T> class A {}; #1
///   template<> class A<int> {}; #2
/// \endcode
/// classTemplateSpecializationDecl(hasSpecializedTemplate(classTemplateDecl()))
///   matches '#2' with classTemplateDecl() matching the class template
///   declaration of 'A' at #1.
AST_MATCHER_P(ClassTemplateSpecializationDecl, hasSpecializedTemplate,
              internal::Matcher<ClassTemplateDecl>, InnerMatcher) {
  const ClassTemplateDecl* Decl = Node.getSpecializedTemplate();
  return (Decl != nullptr &&
          InnerMatcher.matches(*Decl, Finder, Builder));
}

/// Matches an entity that has been implicitly added by the compiler (e.g.
/// implicit default/copy constructors).
AST_POLYMORPHIC_MATCHER(isImplicit,
                        AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Attr,
                                                        LambdaCapture)) {
  return Node.isImplicit();
}

/// 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) != List.end();
}

/// Causes all nested matchers to be matched with the specified traversal kind.
///
/// Given
/// \code
///   void foo()
///   {
///       int i = 3.0;
///   }
/// \endcode
/// The matcher
/// \code
///   traverse(TK_IgnoreUnlessSpelledInSource,
///     varDecl(hasInitializer(floatLiteral().bind("init")))
///   )
/// \endcode
/// matches the variable declaration with "init" bound to the "3.0".
template <typename T>
internal::Matcher<T> traverse(TraversalKind TK,
                              const internal::Matcher<T> &InnerMatcher) {
  return internal::DynTypedMatcher::constructRestrictedWrapper(
             new internal::TraversalMatcher<T>(TK, InnerMatcher),
             InnerMatcher.getID().first)
      .template unconditionalConvertTo<T>();
}

template <typename T>
internal::BindableMatcher<T>
traverse(TraversalKind TK, const internal::BindableMatcher<T> &InnerMatcher) {
  return internal::BindableMatcher<T>(
      internal::DynTypedMatcher::constructRestrictedWrapper(
          new internal::TraversalMatcher<T>(TK, InnerMatcher),
          InnerMatcher.getID().first)
          .template unconditionalConvertTo<T>());
}

template <typename... T>
internal::TraversalWrapper<internal::VariadicOperatorMatcher<T...>>
traverse(TraversalKind TK,
         const internal::VariadicOperatorMatcher<T...> &InnerMatcher) {
  return internal::TraversalWrapper<internal::VariadicOperatorMatcher<T...>>(
      TK, InnerMatcher);
}

template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
          typename T, typename ToTypes>
internal::TraversalWrapper<
    internal::ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>>
traverse(TraversalKind TK, const internal::ArgumentAdaptingMatcherFuncAdaptor<
                               ArgumentAdapterT, T, ToTypes> &InnerMatcher) {
  return internal::TraversalWrapper<
      internal::ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T,
                                                   ToTypes>>(TK, InnerMatcher);
}

template <template <typename T, typename... P> class MatcherT, typename... P,
          typename ReturnTypesF>
internal::TraversalWrapper<
    internal::PolymorphicMatcher<MatcherT, ReturnTypesF, P...>>
traverse(TraversalKind TK,
         const internal::PolymorphicMatcher<MatcherT, ReturnTypesF, P...>
             &InnerMatcher) {
  return internal::TraversalWrapper<
      internal::PolymorphicMatcher<MatcherT, ReturnTypesF, P...>>(TK,
                                                                  InnerMatcher);
}

template <typename... T>
internal::Matcher<typename internal::GetClade<T...>::Type>
traverse(TraversalKind TK, const internal::MapAnyOfHelper<T...> &InnerMatcher) {
  return traverse(TK, InnerMatcher.with());
}

/// 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, internal::Matcher<Expr>,
              InnerMatcher) {
  return InnerMatcher.matches(*Node.IgnoreImplicit(), Finder, Builder);
}

/// 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 a.
AST_MATCHER_P(Expr, ignoringImpCasts,
              internal::Matcher<Expr>, InnerMatcher) {
  return InnerMatcher.matches(*Node.IgnoreImpCasts(), Finder, Builder);
}

/// 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);
}

/// 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);
}

/// 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_OVERLOAD(QualType, ignoringParens, internal::Matcher<QualType>,
                       InnerMatcher, 0) {
  return InnerMatcher.matches(Node.IgnoreParens(), Finder, Builder);
}

/// Overload \c ignoringParens for \c Expr.
///
/// Given
/// \code
///   const char* str = ("my-string");
/// \endcode
/// The matcher
/// \code
///   implicitCastExpr(hasSourceExpression(ignoringParens(stringLiteral())))
/// \endcode
/// would match the implicit cast resulting from the assignment.
AST_MATCHER_P_OVERLOAD(Expr, ignoringParens, internal::Matcher<Expr>,
                       InnerMatcher, 1) {
  const Expr *E = Node.IgnoreParens();
  return InnerMatcher.matches(*E, Finder, Builder);
}

/// Matches expressions that are instantiation-dependent even if it is
/// neither type- nor value-dependent.
///
/// In the following example, the expression sizeof(sizeof(T() + T()))
/// is instantiation-dependent (since it involves a template parameter T),
/// but is neither type- nor value-dependent, since the type of the inner
/// sizeof is known (std::size_t) and therefore the size of the outer
/// sizeof is known.
/// \code
///   template<typename T>
///   void f(T x, T y) { sizeof(sizeof(T() + T()); }
/// \endcode
/// expr(isInstantiationDependent()) matches sizeof(sizeof(T() + T())
AST_MATCHER(Expr, isInstantiationDependent) {
  return Node.isInstantiationDependent();
}

/// Matches expressions that are type-dependent because the template type
/// is not yet instantiated.
///
/// For example, the expressions "x" and "x + y" are type-dependent in
/// the following code, but "y" is not type-dependent:
/// \code
///   template<typename T>
///   void add(T x, int y) {
///     x + y;
///   }
/// \endcode
/// expr(isTypeDependent()) matches x + y
AST_MATCHER(Expr, isTypeDependent) { return Node.isTypeDependent(); }

/// Matches expression that are value-dependent because they contain a
/// non-type template parameter.
///
/// For example, the array bound of "Chars" in the following example is
/// value-dependent.
/// \code
///   template<int Size> int f() { return Size; }
/// \endcode
/// expr(isValueDependent()) matches return Size
AST_MATCHER(Expr, isValueDependent) { return Node.isValueDependent(); }

/// 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> void 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);
}

/// 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;
}

/// 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);
}

/// 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);
}

/// Matches a canonical TemplateArgument that refers to a certain
/// declaration.
///
/// Given
/// \code
///   struct B { int next; };
///   template<int(B::*next_ptr)> struct A {};
///   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;
}

/// Matches a sugar TemplateArgument that refers to a certain expression.
///
/// Given
/// \code
///   struct B { int next; };
///   template<int(B::*next_ptr)> struct A {};
///   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;
}

/// Matches a TemplateArgument that is an integral value.
///
/// Given
/// \code
///   template<int T> struct C {};
///   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;
}

/// Matches a TemplateArgument that refers to an integral type.
///
/// Given
/// \code
///   template<int T> struct C {};
///   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);
}

/// 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 C {};
///   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 toString(Node.getAsIntegral(), 10) == Value;
}

/// Matches an Objective-C autorelease pool statement.
///
/// Given
/// \code
///   @autoreleasepool {
///     int x = 0;
///   }
/// \endcode
/// autoreleasePoolStmt(stmt()) matches the declaration of "x"
/// inside the autorelease pool.
extern const internal::VariadicDynCastAllOfMatcher<Stmt,
       ObjCAutoreleasePoolStmt> autoreleasePoolStmt;

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

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

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

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

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

/// Matches tag declarations.
///
/// Example matches X, Z, U, S, E
/// \code
///   class X;
///   template<class T> class Z {};
///   struct S {};
///   union U {};
///   enum E {
///     A, B, C
///   };
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Decl, TagDecl> tagDecl;

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

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

/// Matches user-defined and implicitly generated deduction guide.
///
/// Example matches the deduction guide.
/// \code
///   template<typename T>
///   class X { X(int) };
///   X(int) -> X<int>;
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXDeductionGuideDecl>
    cxxDeductionGuideDecl;

/// 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
extern const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> varDecl;

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

/// Matches indirect field declarations.
///
/// Given
/// \code
///   struct X { struct { int a; }; };
/// \endcode
/// indirectFieldDecl()
///   matches 'a'.
extern const internal::VariadicDynCastAllOfMatcher<Decl, IndirectFieldDecl>
    indirectFieldDecl;

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

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

/// Matches friend declarations.
///
/// Given
/// \code
///   class X { friend void foo(); };
/// \endcode
/// friendDecl()
///   matches 'friend void foo()'.
extern const internal::VariadicDynCastAllOfMatcher<Decl, FriendDecl> friendDecl;

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

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

/// 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
extern const internal::VariadicDynCastAllOfMatcher<Stmt, MemberExpr> memberExpr;

/// Matches unresolved member expressions.
///
/// Given
/// \code
///   struct X {
///     template <class T> void f();
///     void g();
///   };
///   template <class T> void h() { X x; x.f<T>(); x.g(); }
/// \endcode
/// unresolvedMemberExpr()
///   matches x.f<T>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, UnresolvedMemberExpr>
    unresolvedMemberExpr;

/// Matches member expressions where the actual member referenced could not be
/// resolved because the base expression or the member name was dependent.
///
/// Given
/// \code
///   template <class T> void f() { T t; t.g(); }
/// \endcode
/// cxxDependentScopeMemberExpr()
///   matches t.g
extern const internal::VariadicDynCastAllOfMatcher<Stmt,
                                                   CXXDependentScopeMemberExpr>
    cxxDependentScopeMemberExpr;

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

/// Matches call expressions which were resolved using ADL.
///
/// Example matches y(x) but not y(42) or NS::y(x).
/// \code
///   namespace NS {
///     struct X {};
///     void y(X);
///   }
///
///   void y(...);
///
///   void test() {
///     NS::X x;
///     y(x); // Matches
///     NS::y(x); // Doesn't match
///     y(42); // Doesn't match
///     using NS::y;
///     y(x); // Found by both unqualified lookup and ADL, doesn't match
//    }
/// \endcode
AST_MATCHER(CallExpr, usesADL) { return Node.usesADL(); }

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

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

/// 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
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCMessageExpr>
    objcMessageExpr;

/// Matches ObjectiveC String literal expressions.
///
/// Example matches @"abcd"
/// \code
///   NSString *s = @"abcd";
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCStringLiteral>
    objcStringLiteral;

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

/// Matches Objective-C implementation declarations.
///
/// Example matches Foo
/// \code
///   @implementation Foo
///   @end
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCImplementationDecl>
    objcImplementationDecl;

/// Matches Objective-C protocol declarations.
///
/// Example matches FooDelegate
/// \code
///   @protocol FooDelegate
///   @end
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCProtocolDecl>
    objcProtocolDecl;

/// Matches Objective-C category declarations.
///
/// Example matches Foo (Additions)
/// \code
///   @interface Foo (Additions)
///   @end
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryDecl>
    objcCategoryDecl;

/// Matches Objective-C category definitions.
///
/// Example matches Foo (Additions)
/// \code
///   @implementation Foo (Additions)
///   @end
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryImplDecl>
    objcCategoryImplDecl;

/// Matches Objective-C method declarations.
///
/// Example matches both declaration and definition of -[Foo method]
/// \code
///   @interface Foo
///   - (void)method;
///   @end
///
///   @implementation Foo
///   - (void)method {}
///   @end
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCMethodDecl>
    objcMethodDecl;

/// Matches block declarations.
///
/// Example matches the declaration of the nameless block printing an input
/// integer.
///
/// \code
///   myFunc(^(int p) {
///     printf("%d", p);
///   })
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Decl, BlockDecl>
    blockDecl;

/// Matches Objective-C instance variable declarations.
///
/// Example matches _enabled
/// \code
///   @implementation Foo {
///     BOOL _enabled;
///   }
///   @end
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCIvarDecl>
    objcIvarDecl;

/// Matches Objective-C property declarations.
///
/// Example matches enabled
/// \code
///   @interface Foo
///   @property BOOL enabled;
///   @end
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCPropertyDecl>
    objcPropertyDecl;

/// Matches Objective-C \@throw statements.
///
/// Example matches \@throw
/// \code
///   @throw obj;
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtThrowStmt>
    objcThrowStmt;

/// Matches Objective-C @try statements.
///
/// Example matches @try
/// \code
///   @try {}
///   @catch (...) {}
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtTryStmt>
    objcTryStmt;

/// Matches Objective-C @catch statements.
///
/// Example matches @catch
/// \code
///   @try {}
///   @catch (...) {}
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtCatchStmt>
    objcCatchStmt;

/// Matches Objective-C @finally statements.
///
/// Example matches @finally
/// \code
///   @try {}
///   @finally {}
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtFinallyStmt>
    objcFinallyStmt;

/// 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
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ExprWithCleanups>
    exprWithCleanups;

/// 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 }"
extern const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr>
    initListExpr;

/// 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));
}

/// Matches C++ initializer list expressions.
///
/// Given
/// \code
///   std::vector<int> a({ 1, 2, 3 });
///   std::vector<int> b = { 4, 5 };
///   int c[] = { 6, 7 };
///   std::pair<int, int> d = { 8, 9 };
/// \endcode
/// cxxStdInitializerListExpr()
///   matches "{ 1, 2, 3 }" and "{ 4, 5 }"
extern const internal::VariadicDynCastAllOfMatcher<Stmt,
                                                   CXXStdInitializerListExpr>
    cxxStdInitializerListExpr;

/// 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)
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitValueInitExpr>
    implicitValueInitExpr;

/// 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.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ParenListExpr>
    parenListExpr;

/// 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;"
extern const internal::VariadicDynCastAllOfMatcher<Stmt,
                                                   SubstNonTypeTemplateParmExpr>
    substNonTypeTemplateParmExpr;

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

/// Matches using-enum declarations.
///
/// Given
/// \code
///   namespace X { enum x {...}; }
///   using enum X::x;
/// \endcode
/// usingEnumDecl()
///   matches \code using enum X::x \endcode
extern const internal::VariadicDynCastAllOfMatcher<Decl, UsingEnumDecl>
    usingEnumDecl;

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

/// 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
extern const internal::VariadicDynCastAllOfMatcher<Stmt, UnresolvedLookupExpr>
    unresolvedLookupExpr;

/// 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
extern const internal::VariadicDynCastAllOfMatcher<Decl,
                                                   UnresolvedUsingValueDecl>
    unresolvedUsingValueDecl;

/// 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
extern const internal::VariadicDynCastAllOfMatcher<Decl,
                                                   UnresolvedUsingTypenameDecl>
    unresolvedUsingTypenameDecl;

/// Matches a constant expression wrapper.
///
/// Example matches the constant in the case statement:
///     (matcher = constantExpr())
/// \code
///   switch (a) {
///   case 37: break;
///   }
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ConstantExpr>
    constantExpr;

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

/// 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
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstructExpr>
    cxxConstructExpr;

/// 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
extern const internal::VariadicDynCastAllOfMatcher<Stmt,
                                                   CXXUnresolvedConstructExpr>
    cxxUnresolvedConstructExpr;

/// 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
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThisExpr>
    cxxThisExpr;

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

/// 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());
///   f().func();
/// \endcode
/// but does not match
/// \code
///   f();
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Stmt,
                                                   MaterializeTemporaryExpr>
    materializeTemporaryExpr;

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

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

/// Matches noexcept expressions.
///
/// Given
/// \code
///   bool a() noexcept;
///   bool b() noexcept(true);
///   bool c() noexcept(false);
///   bool d() noexcept(noexcept(a()));
///   bool e = noexcept(b()) || noexcept(c());
/// \endcode
/// cxxNoexceptExpr()
///   matches `noexcept(a())`, `noexcept(b())` and `noexcept(c())`.
///   doesn't match the noexcept specifier in the declarations a, b, c or d.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNoexceptExpr>
    cxxNoexceptExpr;

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

/// 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
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDefaultArgExpr>
    cxxDefaultArgExpr;

/// 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
/// See also the binaryOperation() matcher for more-general matching of binary
/// uses of this AST node.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXOperatorCallExpr>
    cxxOperatorCallExpr;

/// Matches rewritten binary operators
///
/// Example matches use of "<":
/// \code
///   #include <compare>
///   struct HasSpaceshipMem {
///     int a;
///     constexpr auto operator<=>(const HasSpaceshipMem&) const = default;
///   };
///   void compare() {
///     HasSpaceshipMem hs1, hs2;
///     if (hs1 < hs2)
///         return;
///   }
/// \endcode
/// See also the binaryOperation() matcher for more-general matching
/// of this AST node.
extern const internal::VariadicDynCastAllOfMatcher<Stmt,
                                                   CXXRewrittenBinaryOperator>
    cxxRewrittenBinaryOperator;

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

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

/// Matches a reference to an ObjCIvar.
///
/// Example: matches "a" in "init" method:
/// \code
/// @implementation A {
///   NSString *a;
/// }
/// - (void) init {
///   a = @"hello";
/// }
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCIvarRefExpr>
    objcIvarRefExpr;

/// Matches a reference to a block.
///
/// Example: matches "^{}":
/// \code
///   void f() { ^{}(); }
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Stmt, BlockExpr> blockExpr;

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

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

/// 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));
}

/// 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));
}

/// 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
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXForRangeStmt>
    cxxForRangeStmt;

/// 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));
}

/// 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));
}

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

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

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

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

/// Matches co_return statements.
///
/// Given
/// \code
///   while (true) { co_return; }
/// \endcode
/// coreturnStmt()
///   matches 'co_return'
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CoreturnStmt>
    coreturnStmt;

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

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

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

/// Matches address of label statements (GNU extension).
///
/// Given
/// \code
///   FOO: bar();
///   void *ptr = &&FOO;
///   goto *bar;
/// \endcode
/// addrLabelExpr()
///   matches '&&FOO'
extern const internal::VariadicDynCastAllOfMatcher<Stmt, AddrLabelExpr>
    addrLabelExpr;

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

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

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

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

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

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

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

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

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

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

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

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

/// 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
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CharacterLiteral>
    characterLiteral;

/// Matches integer literals of all sizes / encodings, e.g.
/// 1, 1L, 0x1 and 1U.
///
/// Does not match character-encoded integers such as L'a'.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, IntegerLiteral>
    integerLiteral;

/// 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
extern const internal::VariadicDynCastAllOfMatcher<Stmt, FloatingLiteral>
    floatLiteral;

/// Matches imaginary literals, which are based on integer and floating
/// point literals e.g.: 1i, 1.0i
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ImaginaryLiteral>
    imaginaryLiteral;

/// Matches fixed point literals
extern const internal::VariadicDynCastAllOfMatcher<Stmt, FixedPointLiteral>
    fixedPointLiteral;

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

/// 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
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundLiteralExpr>
    compoundLiteralExpr;

/// Matches co_await expressions.
///
/// Given
/// \code
///   co_await 1;
/// \endcode
/// coawaitExpr()
///   matches 'co_await 1'
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CoawaitExpr>
    coawaitExpr;
/// Matches co_await expressions where the type of the promise is dependent
extern const internal::VariadicDynCastAllOfMatcher<Stmt, DependentCoawaitExpr>
    dependentCoawaitExpr;
/// Matches co_yield expressions.
///
/// Given
/// \code
///   co_yield 1;
/// \endcode
/// coyieldExpr()
///   matches 'co_yield 1'
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CoyieldExpr>
    coyieldExpr;

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

/// Matches GNU __builtin_choose_expr.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ChooseExpr>
    chooseExpr;

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

/// Matches C11 _Generic expression.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, GenericSelectionExpr>
    genericSelectionExpr;

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

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

/// Matches binary operator expressions.
///
/// Example matches a || b
/// \code
///   !(a || b)
/// \endcode
/// See also the binaryOperation() matcher for more-general matching.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, BinaryOperator>
    binaryOperator;

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

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

/// Matches binary conditional operator expressions (GNU extension).
///
/// Example matches a ?: b
/// \code
///   (a ?: b) + 42;
/// \endcode
extern const internal::VariadicDynCastAllOfMatcher<Stmt,
                                                   BinaryConditionalOperator>
    binaryConditionalOperator;

/// 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
extern const internal::VariadicDynCastAllOfMatcher<Stmt, OpaqueValueExpr>
    opaqueValueExpr;

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

/// 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
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXReinterpretCastExpr>
    cxxReinterpretCastExpr;

/// 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
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXStaticCastExpr>
    cxxStaticCastExpr;

/// 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
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDynamicCastExpr>
    cxxDynamicCastExpr;

/// 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
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstCastExpr>
    cxxConstCastExpr;

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

/// 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
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ExplicitCastExpr>
    explicitCastExpr;

/// 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.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitCastExpr>
    implicitCastExpr;

/// 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
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CastExpr> castExpr;

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

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

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

/// 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
extern const internal::VariadicDynCastAllOfMatcher<Stmt, DesignatedInitExpr>
    designatedInitExpr;

/// 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;
}

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

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

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

/// 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
extern const internal::VariadicOperatorMatcherFunc<
    2, std::numeric_limits<unsigned>::max()>
    eachOf;

/// Matches if any of the given matchers matches.
///
/// Usable as: Any Matcher
extern const internal::VariadicOperatorMatcherFunc<
    2, std::numeric_limits<unsigned>::max()>
    anyOf;

/// Matches if all given matchers match.
///
/// Usable as: Any Matcher
extern const internal::VariadicOperatorMatcherFunc<
    2, std::numeric_limits<unsigned>::max()>
    allOf;

/// Matches any node regardless of the submatcher.
///
/// However, \c optionally will retain any bindings generated by the submatcher.
/// Useful when additional information which may or may not present about a main
/// matching node is desired.
///
/// For example, in:
/// \code
///   class Foo {
///     int bar;
///   }
/// \endcode
/// The matcher:
/// \code
///   cxxRecordDecl(
///     optionally(has(
///       fieldDecl(hasName("bar")).bind("var")
///   ))).bind("record")
/// \endcode
/// will produce a result binding for both "record" and "var".
/// The matcher will produce a "record" binding for even if there is no data
/// member named "bar" in that class.
///
/// Usable as: Any Matcher
extern const internal::VariadicOperatorMatcherFunc<1, 1> optionally;

/// 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)
extern const internal::VariadicDynCastAllOfMatcher<Stmt,
                                                   UnaryExprOrTypeTraitExpr>
    unaryExprOrTypeTraitExpr;

/// Matches any of the \p NodeMatchers with InnerMatchers nested within
///
/// Given
/// \code
///   if (true);
///   for (; true; );
/// \endcode
/// with the matcher
/// \code
///   mapAnyOf(ifStmt, forStmt).with(
///     hasCondition(cxxBoolLiteralExpr(equals(true)))
///     ).bind("trueCond")
/// \endcode
/// matches the \c if and the \c for. It is equivalent to:
/// \code
///   auto trueCond = hasCondition(cxxBoolLiteralExpr(equals(true)));
///   anyOf(
///     ifStmt(trueCond).bind("trueCond"),
///     forStmt(trueCond).bind("trueCond")
///     );
/// \endcode
///
/// The with() chain-call accepts zero or more matchers which are combined
/// as-if with allOf() in each of the node matchers.
/// Usable as: Any Matcher
template <typename T, typename... U>
auto mapAnyOf(internal::VariadicDynCastAllOfMatcher<T, U> const &...) {
  return internal::MapAnyOfHelper<U...>();
}

/// Matches nodes which can be used with binary operators.
///
/// The code
/// \code
///   var1 != var2;
/// \endcode
/// might be represented in the clang AST as a binaryOperator, a
/// cxxOperatorCallExpr or a cxxRewrittenBinaryOperator, depending on
///
/// * whether the types of var1 and var2 are fundamental (binaryOperator) or at
///   least one is a class type (cxxOperatorCallExpr)
/// * whether the code appears in a template declaration, if at least one of the
///   vars is a dependent-type (binaryOperator)
/// * whether the code relies on a rewritten binary operator, such as a
/// spaceship operator or an inverted equality operator
/// (cxxRewrittenBinaryOperator)
///
/// This matcher elides details in places where the matchers for the nodes are
/// compatible.
///
/// Given
/// \code
///   binaryOperation(
///     hasOperatorName("!="),
///     hasLHS(expr().bind("lhs")),
///     hasRHS(expr().bind("rhs"))
///   )
/// \endcode
/// matches each use of "!=" in:
/// \code
///   struct S{
///       bool operator!=(const S&) const;
///   };
///
///   void foo()
///   {
///      1 != 2;
///      S() != S();
///   }
///
///   template<typename T>
///   void templ()
///   {
///      1 != 2;
///      T() != S();
///   }
///   struct HasOpEq
///   {
///       bool operator==(const HasOpEq &) const;
///   };
///
///   void inverse()
///   {
///       HasOpEq s1;
///       HasOpEq s2;
///       if (s1 != s2)
///           return;
///   }
///
///   struct HasSpaceship
///   {
///       bool operator<=>(const HasOpEq &) const;
///   };
///
///   void use_spaceship()
///   {
///       HasSpaceship s1;
///       HasSpaceship s2;
///       if (s1 != s2)
///           return;
///   }
/// \endcode
extern const internal::MapAnyOfMatcher<BinaryOperator, CXXOperatorCallExpr,
                                       CXXRewrittenBinaryOperator>
    binaryOperation;

/// Matches function calls and constructor calls
///
/// Because CallExpr and CXXConstructExpr do not share a common
/// base class with API accessing arguments etc, AST Matchers for code
/// which should match both are typically duplicated. This matcher
/// removes the need for duplication.
///
/// Given code
/// \code
/// struct ConstructorTakesInt
/// {
///   ConstructorTakesInt(int i) {}
/// };
///
/// void callTakesInt(int i)
/// {
/// }
///
/// void doCall()
/// {
///   callTakesInt(42);
/// }
///
/// void doConstruct()
/// {
///   ConstructorTakesInt cti(42);
/// }
/// \endcode
///
/// The matcher
/// \code
/// invocation(hasArgument(0, integerLiteral(equals(42))))
/// \endcode
/// matches the expression in both doCall and doConstruct
extern const internal::MapAnyOfMatcher<CallExpr, CXXConstructExpr> invocation;

/// 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);
}

/// 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)
///
/// If the matcher is use from clang-query, UnaryExprOrTypeTrait parameter
/// should be passed as a quoted string. e.g., ofKind("UETT_SizeOf").
AST_MATCHER_P(UnaryExprOrTypeTraitExpr, ofKind, UnaryExprOrTypeTrait, Kind) {
  return Node.getKind() == Kind;
}

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

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

/// 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(StringRef Name) {
  return internal::Matcher<NamedDecl>(
      new internal::HasNameMatcher({std::string(Name)}));
}

/// 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
extern const internal::VariadicFunction<internal::Matcher<NamedDecl>, StringRef,
                                        internal::hasAnyNameFunc>
    hasAnyName;

/// 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_REGEX(NamedDecl, matchesName, RegExp) {
  std::string FullNameString = "::" + Node.getQualifiedNameAsString();
  return RegExp->match(FullNameString);
}

/// 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::PolymorphicMatcher<
    internal::HasOverloadedOperatorNameMatcher,
    AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl),
    std::vector<std::string>>
hasOverloadedOperatorName(StringRef Name) {
  return internal::PolymorphicMatcher<
      internal::HasOverloadedOperatorNameMatcher,
      AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl),
      std::vector<std::string>>({std::string(Name)});
}

/// Matches overloaded operator names.
///
/// Matches overloaded operator names specified in strings without the
/// "operator" prefix: e.g. "<<".
///
///   hasAnyOverloadedOperatorName("+", "-")
/// Is equivalent to
///   anyOf(hasOverloadedOperatorName("+"), hasOverloadedOperatorName("-"))
extern const internal::VariadicFunction<
    internal::PolymorphicMatcher<internal::HasOverloadedOperatorNameMatcher,
                                 AST_POLYMORPHIC_SUPPORTED_TYPES(
                                     CXXOperatorCallExpr, FunctionDecl),
                                 std::vector<std::string>>,
    StringRef, internal::hasAnyOverloadedOperatorNameFunc>
    hasAnyOverloadedOperatorName;

/// Matches template-dependent, but known, member names.
///
/// In template declarations, dependent members are not resolved and so can
/// not be matched to particular named declarations.
///
/// This matcher allows to match on the known name of members.
///
/// Given
/// \code
///   template <typename T>
///   struct S {
///       void mem();
///   };
///   template <typename T>
///   void x() {
///       S<T> s;
///       s.mem();
///   }
/// \endcode
/// \c cxxDependentScopeMemberExpr(hasMemberName("mem")) matches `s.mem()`
AST_MATCHER_P(CXXDependentScopeMemberExpr, hasMemberName, std::string, N) {
  return Node.getMember().getAsString() == N;
}

/// Matches template-dependent, but known, member names against an already-bound
/// node
///
/// In template declarations, dependent members are not resolved and so can
/// not be matched to particular named declarations.
///
/// This matcher allows to match on the name of already-bound VarDecl, FieldDecl
/// and CXXMethodDecl nodes.
///
/// Given
/// \code
///   template <typename T>
///   struct S {
///       void mem();
///   };
///   template <typename T>
///   void x() {
///       S<T> s;
///       s.mem();
///   }
/// \endcode
/// The matcher
/// @code
/// \c cxxDependentScopeMemberExpr(
///   hasObjectExpression(declRefExpr(hasType(templateSpecializationType(
///       hasDeclaration(classTemplateDecl(has(cxxRecordDecl(has(
///           cxxMethodDecl(hasName("mem")).bind("templMem")
///           )))))
///       )))),
///   memberHasSameNameAsBoundNode("templMem")
///   )
/// @endcode
/// first matches and binds the @c mem member of the @c S template, then
/// compares its name to the usage in @c s.mem() in the @c x function template
AST_MATCHER_P(CXXDependentScopeMemberExpr, memberHasSameNameAsBoundNode,
              std::string, BindingID) {
  auto MemberName = Node.getMember().getAsString();

  return Builder->removeBindings(
      [this, MemberName](const BoundNodesMap &Nodes) {
        const auto &BN = Nodes.getNode(this->BindingID);
        if (const auto *ND = BN.get<NamedDecl>()) {
          if (!isa<FieldDecl, CXXMethodDecl, VarDecl>(ND))
            return true;
          return ND->getName() != MemberName;
        }
        return true;
      });
}

/// Matches C++ classes that are directly or indirectly derived from a class
/// matching \c Base, or Objective-C classes that directly or indirectly
/// subclass 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
///
/// In the following example, Bar matches isDerivedFrom(hasName("NSObject"))
/// \code
///   @interface NSObject @end
///   @interface Bar : NSObject @end
/// \endcode
///
/// Usable as: Matcher<CXXRecordDecl>, Matcher<ObjCInterfaceDecl>
AST_POLYMORPHIC_MATCHER_P(
    isDerivedFrom,
    AST_POLYMORPHIC_SUPPORTED_TYPES(CXXRecordDecl, ObjCInterfaceDecl),
    internal::Matcher<NamedDecl>, Base) {
  // Check if the node is a C++ struct/union/class.
  if (const auto *RD = dyn_cast<CXXRecordDecl>(&Node))
    return Finder->classIsDerivedFrom(RD, Base, Builder, /*Directly=*/false);

  // The node must be an Objective-C class.
  const auto *InterfaceDecl = cast<ObjCInterfaceDecl>(&Node);
  return Finder->objcClassIsDerivedFrom(InterfaceDecl, Base, Builder,
                                        /*Directly=*/false);
}

/// Overloaded method as shortcut for \c isDerivedFrom(hasName(...)).
AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
    isDerivedFrom,
    AST_POLYMORPHIC_SUPPORTED_TYPES(CXXRecordDecl, ObjCInterfaceDecl),
    std::string, BaseName, 1) {
  if (BaseName.empty())
    return false;

  const auto M = isDerivedFrom(hasName(BaseName));

  if (const auto *RD = dyn_cast<CXXRecordDecl>(&Node))
    return Matcher<CXXRecordDecl>(M).matches(*RD, Finder, Builder);

  const auto *InterfaceDecl = cast<ObjCInterfaceDecl>(&Node);
  return Matcher<ObjCInterfaceDecl>(M).matches(*InterfaceDecl, Finder, Builder);
}

/// Matches C++ classes that have a direct or indirect base matching \p
/// BaseSpecMatcher.
///
/// Example:
/// matcher hasAnyBase(hasType(cxxRecordDecl(hasName("SpecialBase"))))
/// \code
///   class Foo;
///   class Bar : Foo {};
///   class Baz : Bar {};
///   class SpecialBase;
///   class Proxy : SpecialBase {};  // matches Proxy
///   class IndirectlyDerived : Proxy {};  //matches IndirectlyDerived
/// \endcode
///
// FIXME: Refactor this and isDerivedFrom to reuse implementation.
AST_MATCHER_P(CXXRecordDecl, hasAnyBase, internal::Matcher<CXXBaseSpecifier>,
              BaseSpecMatcher) {
  return internal::matchesAnyBase(Node, BaseSpecMatcher, Finder, Builder);
}

/// Matches C++ classes that have a direct base matching \p BaseSpecMatcher.
///
/// Example:
/// matcher hasDirectBase(hasType(cxxRecordDecl(hasName("SpecialBase"))))
/// \code
///   class Foo;
///   class Bar : Foo {};
///   class Baz : Bar {};
///   class SpecialBase;
///   class Proxy : SpecialBase {};  // matches Proxy
///   class IndirectlyDerived : Proxy {};  // doesn't match
/// \endcode
AST_MATCHER_P(CXXRecordDecl, hasDirectBase, internal::Matcher<CXXBaseSpecifier>,
              BaseSpecMatcher) {
  return Node.hasDefinition() &&
         llvm::any_of(Node.bases(), [&](const CXXBaseSpecifier &Base) {
           return BaseSpecMatcher.matches(Base, Finder, Builder);
         });
}

/// Similar to \c isDerivedFrom(), but also matches classes that directly
/// match \c Base.
AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
    isSameOrDerivedFrom,
    AST_POLYMORPHIC_SUPPORTED_TYPES(CXXRecordDecl, ObjCInterfaceDecl),
    internal::Matcher<NamedDecl>, Base, 0) {
  const auto M = anyOf(Base, isDerivedFrom(Base));

  if (const auto *RD = dyn_cast<CXXRecordDecl>(&Node))
    return Matcher<CXXRecordDecl>(M).matches(*RD, Finder, Builder);

  const auto *InterfaceDecl = cast<ObjCInterfaceDecl>(&Node);
  return Matcher<ObjCInterfaceDecl>(M).matches(*InterfaceDecl, Finder, Builder);
}

/// Overloaded method as shortcut for
/// \c isSameOrDerivedFrom(hasName(...)).
AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
    isSameOrDerivedFrom,
    AST_POLYMORPHIC_SUPPORTED_TYPES(CXXRecordDecl, ObjCInterfaceDecl),
    std::string, BaseName, 1) {
  if (BaseName.empty())
    return false;

  const auto M = isSameOrDerivedFrom(hasName(BaseName));

  if (const auto *RD = dyn_cast<CXXRecordDecl>(&Node))
    return Matcher<CXXRecordDecl>(M).matches(*RD, Finder, Builder);

  const auto *InterfaceDecl = cast<ObjCInterfaceDecl>(&Node);
  return Matcher<ObjCInterfaceDecl>(M).matches(*InterfaceDecl, Finder, Builder);
}

/// Matches C++ or Objective-C classes that are directly derived from a class
/// matching \c Base.
///
/// Note that a class is not considered to be derived from itself.
///
/// Example matches Y, 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_POLYMORPHIC_MATCHER_P_OVERLOAD(
    isDirectlyDerivedFrom,
    AST_POLYMORPHIC_SUPPORTED_TYPES(CXXRecordDecl, ObjCInterfaceDecl),
    internal::Matcher<NamedDecl>, Base, 0) {
  // Check if the node is a C++ struct/union/class.
  if (const auto *RD = dyn_cast<CXXRecordDecl>(&Node))
    return Finder->classIsDerivedFrom(RD, Base, Builder, /*Directly=*/true);

  // The node must be an Objective-C class.
  const auto *InterfaceDecl = cast<ObjCInterfaceDecl>(&Node);
  return Finder->objcClassIsDerivedFrom(InterfaceDecl, Base, Builder,
                                        /*Directly=*/true);
}

/// Overloaded method as shortcut for \c isDirectlyDerivedFrom(hasName(...)).
AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
    isDirectlyDerivedFrom,
    AST_POLYMORPHIC_SUPPORTED_TYPES(CXXRecordDecl, ObjCInterfaceDecl),
    std::string, BaseName, 1) {
  if (BaseName.empty())
    return false;
  const auto M = isDirectlyDerivedFrom(hasName(BaseName));

  if (const auto *RD = dyn_cast<CXXRecordDecl>(&Node))
    return Matcher<CXXRecordDecl>(M).matches(*RD, Finder, Builder);

  const auto *InterfaceDecl = cast<ObjCInterfaceDecl>(&Node);
  return Matcher<ObjCInterfaceDecl>(M).matches(*InterfaceDecl, Finder, Builder);
}
/// 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) {
  BoundNodesTreeBuilder Result(*Builder);
  auto MatchIt = matchesFirstInPointerRange(InnerMatcher, Node.method_begin(),
                                            Node.method_end(), Finder, &Result);
  if (MatchIt == Node.method_end())
    return false;

  if (Finder->isTraversalIgnoringImplicitNodes() && (*MatchIt)->isImplicit())
    return false;
  *Builder = std::move(Result);
  return true;
}

/// 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();
}

/// 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())).
extern const internal::ArgumentAdaptingMatcherFunc<internal::HasMatcher> has;

/// 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
extern const internal::ArgumentAdaptingMatcherFunc<
    internal::HasDescendantMatcher>
    hasDescendant;

/// Matches AST nodes that have child AST nodes that match the
/// provided matcher.
///
/// Example matches X, Y, Y::X, Z::Y, Z::Y::X
///   (matcher = cxxRecordDecl(forEach(cxxRecordDecl(hasName("X")))
/// \code
///   class X {};
///   class Y { class X {}; };  // Matches Y, because Y::X is a class of name X
///                             // inside Y.
///   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
extern const internal::ArgumentAdaptingMatcherFunc<internal::ForEachMatcher>
    forEach;

/// Matches AST nodes that have descendant AST nodes that match the
/// provided matcher.
///
/// Example matches X, A, A::X, B, B::C, B::C::X
///   (matcher = cxxRecordDecl(forEachDescendant(cxxRecordDecl(hasName("X")))))
/// \code
///   class X {};
///   class A { class X {}; };  // Matches A, because A::X is a class of name
///                             // X inside A.
///   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
extern const internal::ArgumentAdaptingMatcherFunc<
    internal::ForEachDescendantMatcher>
    forEachDescendant;

/// 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));
}

/// 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
extern const internal::ArgumentAdaptingMatcherFunc<
    internal::HasParentMatcher,
    internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>,
    internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>>
    hasParent;

/// 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
extern const internal::ArgumentAdaptingMatcherFunc<
    internal::HasAncestorMatcher,
    internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>,
    internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>>
    hasAncestor;

/// 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
extern const internal::VariadicOperatorMatcherFunc<1, 1> unless;

/// 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
/// - for CXXNewExpr, the declaration of the operator new
/// - for ObjCIvarExpr, the declaration of the ivar
///
/// For type nodes, hasDeclaration will generally match the declaration of the
/// sugared type. Given
/// \code
///   class X {};
///   typedef X Y;
///   Y y;
/// \endcode
/// in varDecl(hasType(hasDeclaration(decl()))) the decl will match the
/// typedefDecl. A common use case is to match the underlying, desugared type.
/// This can be achieved by using the hasUnqualifiedDesugaredType matcher:
/// \code
///   varDecl(hasType(hasUnqualifiedDesugaredType(
///       recordType(hasDeclaration(decl())))))
/// \endcode
/// In this matcher, the decl will match the CXXRecordDecl of class X.
///
/// Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>,
///   Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>,
///   Matcher<EnumType>, Matcher<InjectedClassNameType>, Matcher<LabelStmt>,
///   Matcher<MemberExpr>, Matcher<QualType>, Matcher<RecordType>,
///   Matcher<TagType>, Matcher<TemplateSpecializationType>,
///   Matcher<TemplateTypeParmType>, Matcher<TypedefType>,
///   Matcher<UnresolvedUsingType>
inline internal::PolymorphicMatcher<
    internal::HasDeclarationMatcher,
    void(internal::HasDeclarationSupportedTypes), internal::Matcher<Decl>>
hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) {
  return internal::PolymorphicMatcher<
      internal::HasDeclarationMatcher,
      void(internal::HasDeclarationSupportedTypes), internal::Matcher<Decl>>(
      InnerMatcher);
}

/// 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);
}

/// Matches on the implicit object argument of a member call expression, after
/// stripping off any parentheses or implicit casts.
///
/// Given
/// \code
///   class Y { public: void m(); };
///   Y g();
///   class X : public Y {};
///   void z(Y y, X x) { y.m(); (g()).m(); x.m(); }
/// \endcode
/// cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y")))))
///   matches `y.m()` and `(g()).m()`.
/// cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("X")))))
///   matches `x.m()`.
/// cxxMemberCallExpr(on(callExpr()))
///   matches `(g()).m()`.
///
/// 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));
}


/// Matches on the receiver of an ObjectiveC Message expression.
///
/// Example
/// matcher = objCMessageExpr(hasReceiverType(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);
}

/// Returns true when the Objective-C method declaration is a class method.
///
/// Example
/// matcher = objcMethodDecl(isClassMethod())
/// matches
/// \code
/// @interface I + (void)foo; @end
/// \endcode
/// but not
/// \code
/// @interface I - (void)bar; @end
/// \endcode
AST_MATCHER(ObjCMethodDecl, isClassMethod) {
  return Node.isClassMethod();
}

/// Returns true when the Objective-C method declaration is an instance method.
///
/// Example
/// matcher = objcMethodDecl(isInstanceMethod())
/// matches
/// \code
/// @interface I - (void)bar; @end
/// \endcode
/// but not
/// \code
/// @interface I + (void)foo; @end
/// \endcode
AST_MATCHER(ObjCMethodDecl, isInstanceMethod) {
  return Node.isInstanceMethod();
}

/// Returns true when the Objective-C message is sent to a class.
///
/// Example
/// matcher = objcMessageExpr(isClassMessage())
/// matches
/// \code
///   [NSString stringWithFormat:@"format"];
/// \endcode
/// but not
/// \code
///   NSString *x = @"hello";
///   [x containsString:@"h"];
/// \endcode
AST_MATCHER(ObjCMessageExpr, isClassMessage) {
  return Node.isClassMessage();
}

/// Returns true when the Objective-C message is sent to an instance.
///
/// Example
/// matcher = objcMessageExpr(isInstanceMessage())
/// matches
/// \code
///   NSString *x = @"hello";
///   [x containsString:@"h"];
/// \endcode
/// but not
/// \code
///   [NSString stringWithFormat:@"format"];
/// \endcode
AST_MATCHER(ObjCMessageExpr, isInstanceMessage) {
  return Node.isInstanceMessage();
}

/// Matches if the Objective-C message is sent to an instance,
/// and the inner matcher matches on that instance.
///
/// For example the method call in
/// \code
///   NSString *x = @"hello";
///   [x containsString:@"h"];
/// \endcode
/// is matched by
/// objcMessageExpr(hasReceiver(declRefExpr(to(varDecl(hasName("x"))))))
AST_MATCHER_P(ObjCMessageExpr, hasReceiver, internal::Matcher<Expr>,
              InnerMatcher) {
  const Expr *ReceiverNode = Node.getInstanceReceiver();
  return (ReceiverNode != nullptr &&
          InnerMatcher.matches(*ReceiverNode->IgnoreParenImpCasts(), Finder,
                               Builder));
}

/// 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 == Sel.getAsString();
}

/// Matches when at least one of the supplied string equals to the
/// Selector.getAsString()
///
///  matcher = objCMessageExpr(hasSelector("methodA:", "methodB:"));
///  matches both of the expressions below:
/// \code
///     [myObj methodA:argA];
///     [myObj methodB:argB];
/// \endcode
extern const internal::VariadicFunction<internal::Matcher<ObjCMessageExpr>,
                                        StringRef,
                                        internal::hasAnySelectorFunc>
                                        hasAnySelector;

/// 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_REGEX(ObjCMessageExpr, matchesSelector, RegExp) {
  std::string SelectorString = Node.getSelector().getAsString();
  return RegExp->match(SelectorString);
}

/// 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();
}

/// 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();
}

/// 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();
}

/// 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;
}

/// 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));
}

/// Matches 1) if the call expression's callee's declaration matches the
/// given matcher; or 2) if the Obj-C message expression's callee's method
/// 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
///
/// Example 2. Matches [I foo] with
/// objcMessageExpr(callee(objcMethodDecl(hasName("foo"))))
///
/// \code
///   @interface I: NSObject
///   +(void)foo;
///   @end
///   ...
///   [I foo]
/// \endcode
AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
    callee, AST_POLYMORPHIC_SUPPORTED_TYPES(ObjCMessageExpr, CallExpr),
    internal::Matcher<Decl>, InnerMatcher, 1) {
  if (const auto *CallNode = dyn_cast<CallExpr>(&Node))
    return callExpr(hasDeclaration(InnerMatcher))
        .matches(Node, Finder, Builder);
  else {
    // The dynamic cast below is guaranteed to succeed as there are only 2
    // supported return types.
    const auto *MsgNode = cast<ObjCMessageExpr>(&Node);
    const Decl *DeclNode = MsgNode->getMethodDecl();
    return (DeclNode != nullptr &&
            InnerMatcher.matches(*DeclNode, Finder, Builder));
  }
}

/// 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")))
///             and friend class X (matcher = friendDecl(hasType("X"))
///             and public virtual X (matcher = cxxBaseSpecifier(hasType(
///                                               asString("class X")))
/// \code
///  class X {};
///  void y(X &x) { x; X z; }
///  typedef int U;
///  class Y { friend class X; };
///  class Z : public virtual X {};
/// \endcode
AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
    hasType,
    AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, FriendDecl, TypedefNameDecl,
                                    ValueDecl, CXXBaseSpecifier),
    internal::Matcher<QualType>, InnerMatcher, 0) {
  QualType QT = internal::getUnderlyingType(Node);
  if (!QT.isNull())
    return InnerMatcher.matches(QT, Finder, Builder);
  return false;
}

/// 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")))))
///             and friend class X (matcher = friendDecl(hasType("X"))
///             and public virtual X (matcher = cxxBaseSpecifier(hasType(
///                                               cxxRecordDecl(hasName("X"))))
/// \code
///  class X {};
///  void y(X &x) { x; X z; }
///  class Y { friend class X; };
///  class Z : public virtual X {};
/// \endcode
///
/// Example matches class Derived
/// (matcher = cxxRecordDecl(hasAnyBase(hasType(cxxRecordDecl(hasName("Base"))))))
/// \code
/// class Base {};
/// class Derived : Base {};
/// \endcode
///
/// Usable as: Matcher<Expr>, Matcher<FriendDecl>, Matcher<ValueDecl>,
/// Matcher<CXXBaseSpecifier>
AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
    hasType,
    AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, FriendDecl, ValueDecl,
                                    CXXBaseSpecifier),
    internal::Matcher<Decl>, InnerMatcher, 1) {
  QualType QT = internal::getUnderlyingType(Node);
  if (!QT.isNull())
    return qualType(hasDeclaration(InnerMatcher)).matches(QT, Finder, Builder);
  return false;
}

/// Matches if the type location of a node matches the inner matcher.
///
/// Examples:
/// \code
///   int x;
/// \endcode
/// declaratorDecl(hasTypeLoc(loc(asString("int"))))
///   matches int x
///
/// \code
/// auto x = int(3);
/// \code
/// cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int"))))
///   matches int(3)
///
/// \code
/// struct Foo { Foo(int, int); };
/// auto x = Foo(1, 2);
/// \code
/// cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo"))))
///   matches Foo(1, 2)
///
/// Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>,
///   Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>,
///   Matcher<CXXNewExpr>, Matcher<CXXTemporaryObjectExpr>,
///   Matcher<CXXUnresolvedConstructExpr>,
///   Matcher<ClassTemplateSpecializationDecl>, Matcher<CompoundLiteralExpr>,
///   Matcher<DeclaratorDecl>, Matcher<ExplicitCastExpr>,
///   Matcher<ObjCPropertyDecl>, Matcher<TemplateArgumentLoc>,
///   Matcher<TypedefNameDecl>
AST_POLYMORPHIC_MATCHER_P(
    hasTypeLoc,
    AST_POLYMORPHIC_SUPPORTED_TYPES(
        BlockDecl, CXXBaseSpecifier, CXXCtorInitializer, CXXFunctionalCastExpr,
        CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr,
        ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl,
        ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc,
        TypedefNameDecl),
    internal::Matcher<TypeLoc>, Inner) {
  TypeSourceInfo *source = internal::GetTypeSourceInfo(Node);
  if (source == nullptr) {
    // This happens for example for implicit destructors.
    return false;
  }
  return Inner.matches(source->getTypeLoc(), Finder, Builder);
}

/// 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();
}

/// 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));
}

/// 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);
}

/// Matches if the matched type matches the unqualified desugared
/// type of the matched node.
///
/// For example, in:
/// \code
///   class A {};
///   using B = A;
/// \endcode
/// The matcher type(hasUnqualifiedDesugaredType(recordType())) matches
/// both B and A.
AST_MATCHER_P(Type, hasUnqualifiedDesugaredType, internal::Matcher<Type>,
              InnerMatcher) {
  return InnerMatcher.matches(*Node.getUnqualifiedDesugaredType(), Finder,
                              Builder);
}

/// 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));
}

/// 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);
}

/// 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);
}

/// Matches on the implicit object argument of a member call expression. Unlike
/// `on`, matches the argument directly without stripping away anything.
///
/// Given
/// \code
///   class Y { public: void m(); };
///   Y g();
///   class X : public Y { void g(); };
///   void z(Y y, X x) { y.m(); x.m(); x.g(); (g()).m(); }
/// \endcode
/// cxxMemberCallExpr(onImplicitObjectArgument(hasType(
///     cxxRecordDecl(hasName("Y")))))
///   matches `y.m()`, `x.m()` and (g()).m(), but not `x.g()`.
/// cxxMemberCallExpr(on(callExpr()))
///   does not match `(g()).m()`, because the parens are not ignored.
///
/// FIXME: Overload to allow directly matching types?
AST_MATCHER_P(CXXMemberCallExpr, onImplicitObjectArgument,
              internal::Matcher<Expr>, InnerMatcher) {
  const Expr *ExprNode = Node.getImplicitObjectArgument();
  return (ExprNode != nullptr &&
          InnerMatcher.matches(*ExprNode, Finder, Builder));
}

/// Matches if the type of the expression's implicit object argument either
/// matches the InnerMatcher, or is a pointer to a type that matches the
/// InnerMatcher.
///
/// Given
/// \code
///   class Y { public: void m(); };
///   class X : public Y { void g(); };
///   void z() { Y y; y.m(); Y *p; p->m(); X x; x.m(); x.g(); }
/// \endcode
/// cxxMemberCallExpr(thisPointerType(hasDeclaration(
///     cxxRecordDecl(hasName("Y")))))
///   matches `y.m()`, `p->m()` and `x.m()`.
/// cxxMemberCallExpr(thisPointerType(hasDeclaration(
///     cxxRecordDecl(hasName("X")))))
///   matches `x.g()`.
AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType,
                       internal::Matcher<QualType>, InnerMatcher, 0) {
  return onImplicitObjectArgument(
      anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher))))
      .matches(Node, Finder, Builder);
}

/// 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);
}

/// 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));
}

/// Matches if a node refers to a declaration through a specific
/// using shadow declaration.
///
/// Examples:
/// \code
///   namespace a { int f(); }
///   using a::f;
///   int x = f();
/// \endcode
/// declRefExpr(throughUsingDecl(anything()))
///   matches \c f
///
/// \code
///   namespace a { class X{}; }
///   using a::X;
///   X x;
/// \code
/// typeLoc(loc(usingType(throughUsingDecl(anything()))))
///   matches \c X
///
/// Usable as: Matcher<DeclRefExpr>, Matcher<UsingType>
AST_POLYMORPHIC_MATCHER_P(throughUsingDecl,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(DeclRefExpr,
                                                          UsingType),
                          internal::Matcher<UsingShadowDecl>, Inner) {
  const NamedDecl *FoundDecl = Node.getFoundDecl();
  if (const UsingShadowDecl *UsingDecl = dyn_cast<UsingShadowDecl>(FoundDecl))
    return Inner.matches(*UsingDecl, Finder, Builder);
  return false;
}

/// 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) != Node.decls_end();
}

/// 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;
}

/// 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));
}

/// Matches a variable serving as the implicit variable for a lambda init-
/// capture.
///
/// Example matches x (matcher = varDecl(isInitCapture()))
/// \code
/// auto f = [x=3]() { return x; };
/// \endcode
AST_MATCHER(VarDecl, isInitCapture) { return Node.isInitCapture(); }

/// Matches each lambda capture in a lambda expression.
///
/// Given
/// \code
///   int main() {
///     int x, y;
///     float z;
///     auto f = [=]() { return x + y + z; };
///   }
/// \endcode
/// lambdaExpr(forEachLambdaCapture(
///     lambdaCapture(capturesVar(varDecl(hasType(isInteger()))))))
/// will trigger two matches, binding for 'x' and 'y' respectively.
AST_MATCHER_P(LambdaExpr, forEachLambdaCapture,
              internal::Matcher<LambdaCapture>, InnerMatcher) {
  BoundNodesTreeBuilder Result;
  bool Matched = false;
  for (const auto &Capture : Node.captures()) {
    if (Finder->isTraversalIgnoringImplicitNodes() && Capture.isImplicit())
      continue;
    BoundNodesTreeBuilder CaptureBuilder(*Builder);
    if (InnerMatcher.matches(Capture, Finder, &CaptureBuilder)) {
      Matched = true;
      Result.addMatch(CaptureBuilder);
    }
  }
  *Builder = std::move(Result);
  return Matched;
}

/// \brief Matches a static variable with local scope.
///
/// Example matches y (matcher = varDecl(isStaticLocal()))
/// \code
/// void f() {
///   int x;
///   static int y;
/// }
/// static int z;
/// \endcode
AST_MATCHER(VarDecl, isStaticLocal) {
  return Node.isStaticLocal();
}

/// 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();
}

/// 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();
}

/// 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;
}

/// Matches a variable declaration that has static storage duration.
/// It includes the variable declared at namespace scope and those declared
/// with "static" and "extern" storage class specifiers.
///
/// \code
/// void f() {
///   int x;
///   static int y;
///   thread_local int z;
/// }
/// int a;
/// static int b;
/// extern int c;
/// varDecl(hasStaticStorageDuration())
///   matches the function declaration y, a, b and c.
/// \endcode
AST_MATCHER(VarDecl, hasStaticStorageDuration) {
  return Node.getStorageDuration() == SD_Static;
}

/// 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;
}

/// 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();
}

/// 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,
                              CXXUnresolvedConstructExpr, ObjCMessageExpr),
                          unsigned, N) {
  unsigned NumArgs = Node.getNumArgs();
  if (!Finder->isTraversalIgnoringImplicitNodes())
    return NumArgs == N;
  while (NumArgs) {
    if (!isa<CXXDefaultArgExpr>(Node.getArg(NumArgs - 1)))
      break;
    --NumArgs;
  }
  return NumArgs == N;
}

/// 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,
                               CXXUnresolvedConstructExpr, ObjCMessageExpr),
                           unsigned, N, internal::Matcher<Expr>, InnerMatcher) {
  if (N >= Node.getNumArgs())
    return false;
  const Expr *Arg = Node.getArg(N);
  if (Finder->isTraversalIgnoringImplicitNodes() && isa<CXXDefaultArgExpr>(Arg))
    return false;
  return InnerMatcher.matches(*Arg->IgnoreParenImpCasts(), Finder, Builder);
}

/// Matches the n'th item of an initializer list expression.
///
/// Example matches y.
///     (matcher = initListExpr(hasInit(0, expr())))
/// \code
///   int x{y}.
/// \endcode
AST_MATCHER_P2(InitListExpr, hasInit, unsigned, N,
               ast_matchers::internal::Matcher<Expr>, InnerMatcher) {
  return N < Node.getNumInits() &&
          InnerMatcher.matches(*Node.getInit(N), Finder, Builder);
}

/// 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;
}

/// 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);
}

/// 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;
}

/// 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) {
  auto MatchIt = matchesFirstInPointerRange(InnerMatcher, Node.init_begin(),
                                            Node.init_end(), Finder, Builder);
  if (MatchIt == Node.init_end())
    return false;
  return (*MatchIt)->isWritten() || !Finder->isTraversalIgnoringImplicitNodes();
}

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

/// 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));
}

/// 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();
}

/// 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();
}

/// 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();
}

/// Matches any argument of a call expression or a constructor call
/// expression, or an ObjC-message-send 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
///
/// For ObjectiveC, given
/// \code
///   @interface I - (void) f:(int) y; @end
///   void foo(I *i) { [i f:12]; }
/// \endcode
/// objcMessageExpr(hasAnyArgument(integerLiteral(equals(12))))
///   matches [i f:12]
AST_POLYMORPHIC_MATCHER_P(hasAnyArgument,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(
                              CallExpr, CXXConstructExpr,
                              CXXUnresolvedConstructExpr, ObjCMessageExpr),
                          internal::Matcher<Expr>, InnerMatcher) {
  for (const Expr *Arg : Node.arguments()) {
    if (Finder->isTraversalIgnoringImplicitNodes() &&
        isa<CXXDefaultArgExpr>(Arg))
      break;
    BoundNodesTreeBuilder Result(*Builder);
    if (InnerMatcher.matches(*Arg, Finder, &Result)) {
      *Builder = std::move(Result);
      return true;
    }
  }
  return false;
}

/// Matches lambda captures.
///
/// Given
/// \code
///   int main() {
///     int x;
///     auto f = [x](){};
///     auto g = [x = 1](){};
///   }
/// \endcode
/// In the matcher `lambdaExpr(hasAnyCapture(lambdaCapture()))`,
/// `lambdaCapture()` matches `x` and `x=1`.
extern const internal::VariadicAllOfMatcher<LambdaCapture> lambdaCapture;

/// Matches any capture in a lambda expression.
///
/// Given
/// \code
///   void foo() {
///     int t = 5;
///     auto f = [=](){ return t; };
///   }
/// \endcode
/// lambdaExpr(hasAnyCapture(lambdaCapture())) and
/// lambdaExpr(hasAnyCapture(lambdaCapture(refersToVarDecl(hasName("t")))))
///   both match `[=](){ return t; }`.
AST_MATCHER_P(LambdaExpr, hasAnyCapture, internal::Matcher<LambdaCapture>,
              InnerMatcher) {
  for (const LambdaCapture &Capture : Node.captures()) {
    clang::ast_matchers::internal::BoundNodesTreeBuilder Result(*Builder);
    if (InnerMatcher.matches(Capture, Finder, &Result)) {
      *Builder = std::move(Result);
      return true;
    }
  }
  return false;
}

/// Matches a `LambdaCapture` that refers to the specified `VarDecl`. The
/// `VarDecl` can be a separate variable that is captured by value or
/// reference, or a synthesized variable if the capture has an initializer.
///
/// Given
/// \code
///   void foo() {
///     int x;
///     auto f = [x](){};
///     auto g = [x = 1](){};
///   }
/// \endcode
/// In the matcher
/// lambdaExpr(hasAnyCapture(lambdaCapture(capturesVar(hasName("x")))),
/// capturesVar(hasName("x")) matches `x` and `x = 1`.
AST_MATCHER_P(LambdaCapture, capturesVar, internal::Matcher<ValueDecl>,
              InnerMatcher) {
  auto *capturedVar = Node.getCapturedVar();
  return capturedVar && InnerMatcher.matches(*capturedVar, Finder, Builder);
}

/// Matches a `LambdaCapture` that refers to 'this'.
///
/// Given
/// \code
/// class C {
///   int cc;
///   int f() {
///     auto l = [this]() { return cc; };
///     return l();
///   }
/// };
/// \endcode
/// lambdaExpr(hasAnyCapture(lambdaCapture(capturesThis())))
///   matches `[this]() { return cc; }`.
AST_MATCHER(LambdaCapture, capturesThis) { return Node.capturesThis(); }

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

/// 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();
}

/// Matches the n'th parameter of a function or an ObjC method
/// declaration or a block.
///
/// Given
/// \code
///   class X { void f(int x) {} };
/// \endcode
/// cxxMethodDecl(hasParameter(0, hasType(varDecl())))
///   matches f(int x) {}
/// with hasParameter(...)
///   matching int x
///
/// For ObjectiveC, given
/// \code
///   @interface I - (void) f:(int) y; @end
/// \endcode
//
/// the matcher objcMethodDecl(hasParameter(0, hasName("y")))
/// matches the declaration of method f with hasParameter
/// matching y.
AST_POLYMORPHIC_MATCHER_P2(hasParameter,
                           AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
                                                           ObjCMethodDecl,
                                                           BlockDecl),
                           unsigned, N, internal::Matcher<ParmVarDecl>,
                           InnerMatcher) {
  return (N < Node.parameters().size()
          && InnerMatcher.matches(*Node.parameters()[N], Finder, Builder));
}

/// 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;
}

/// Matches all arguments and their respective types for a \c CallExpr or
/// \c CXXConstructExpr. It is very similar to \c forEachArgumentWithParam but
/// it works on calls through function pointers as well.
///
/// The difference is, that function pointers do not provide access to a
/// \c ParmVarDecl, but only the \c QualType for each argument.
///
/// Given
/// \code
///   void f(int i);
///   int y;
///   f(y);
///   void (*f_ptr)(int) = f;
///   f_ptr(y);
/// \endcode
/// callExpr(
///   forEachArgumentWithParamType(
///     declRefExpr(to(varDecl(hasName("y")))),
///     qualType(isInteger()).bind("type)
/// ))
///   matches f(y) and f_ptr(y)
/// with declRefExpr(...)
///   matching int y
/// and qualType(...)
///   matching int
AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParamType,
                           AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
                                                           CXXConstructExpr),
                           internal::Matcher<Expr>, ArgMatcher,
                           internal::Matcher<QualType>, 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;

  const FunctionProtoType *FProto = nullptr;

  if (const auto *Call = dyn_cast<CallExpr>(&Node)) {
    if (const auto *Value =
            dyn_cast_or_null<ValueDecl>(Call->getCalleeDecl())) {
      QualType QT = Value->getType().getCanonicalType();

      // This does not necessarily lead to a `FunctionProtoType`,
      // e.g. K&R functions do not have a function prototype.
      if (QT->isFunctionPointerType())
        FProto = QT->getPointeeType()->getAs<FunctionProtoType>();

      if (QT->isMemberFunctionPointerType()) {
        const auto *MP = QT->getAs<MemberPointerType>();
        assert(MP && "Must be member-pointer if its a memberfunctionpointer");
        FProto = MP->getPointeeType()->getAs<FunctionProtoType>();
        assert(FProto &&
               "The call must have happened through a member function "
               "pointer");
      }
    }
  }

  unsigned ParamIndex = 0;
  bool Matched = false;
  unsigned NumArgs = Node.getNumArgs();
  if (FProto && FProto->isVariadic())
    NumArgs = std::min(NumArgs, FProto->getNumParams());

  for (; ArgIndex < NumArgs; ++ArgIndex, ++ParamIndex) {
    BoundNodesTreeBuilder ArgMatches(*Builder);
    if (ArgMatcher.matches(*(Node.getArg(ArgIndex)->IgnoreParenCasts()), Finder,
                           &ArgMatches)) {
      BoundNodesTreeBuilder ParamMatches(ArgMatches);

      // This test is cheaper compared to the big matcher in the next if.
      // Therefore, please keep this order.
      if (FProto && FProto->getNumParams() > ParamIndex) {
        QualType ParamType = FProto->getParamType(ParamIndex);
        if (ParamMatcher.matches(ParamType, Finder, &ParamMatches)) {
          Result.addMatch(ParamMatches);
          Matched = true;
          continue;
        }
      }
      if (expr(anyOf(cxxConstructExpr(hasDeclaration(cxxConstructorDecl(
                         hasParameter(ParamIndex, hasType(ParamMatcher))))),
                     callExpr(callee(functionDecl(
                         hasParameter(ParamIndex, hasType(ParamMatcher)))))))
              .matches(Node, Finder, &ParamMatches)) {
        Result.addMatch(ParamMatches);
        Matched = true;
        continue;
      }
    }
  }
  *Builder = std::move(Result);
  return Matched;
}

/// Matches the ParmVarDecl nodes that are at the N'th position in the parameter
/// list. The parameter list could be that of either a block, function, or
/// objc-method.
///
///
/// Given
///
/// \code
/// void f(int a, int b, int c) {
/// }
/// \endcode
///
/// ``parmVarDecl(isAtPosition(0))`` matches ``int a``.
///
/// ``parmVarDecl(isAtPosition(1))`` matches ``int b``.
AST_MATCHER_P(ParmVarDecl, isAtPosition, unsigned, N) {
  const clang::DeclContext *Context = Node.getParentFunctionOrMethod();

  if (const auto *Decl = dyn_cast_or_null<FunctionDecl>(Context))
    return N < Decl->param_size() && Decl->getParamDecl(N) == &Node;
  if (const auto *Decl = dyn_cast_or_null<BlockDecl>(Context))
    return N < Decl->param_size() && Decl->getParamDecl(N) == &Node;
  if (const auto *Decl = dyn_cast_or_null<ObjCMethodDecl>(Context))
    return N < Decl->param_size() && Decl->getParamDecl(N) == &Node;

  return false;
}

/// Matches any parameter of a function or an ObjC method declaration or a
/// block.
///
/// 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
///
/// For ObjectiveC, given
/// \code
///   @interface I - (void) f:(int) y; @end
/// \endcode
//
/// the matcher objcMethodDecl(hasAnyParameter(hasName("y")))
/// matches the declaration of method f with hasParameter
/// matching y.
///
/// For blocks, given
/// \code
///   b = ^(int y) { printf("%d", y) };
/// \endcode
///
/// the matcher blockDecl(hasAnyParameter(hasName("y")))
/// matches the declaration of the block b with hasParameter
/// matching y.
AST_POLYMORPHIC_MATCHER_P(hasAnyParameter,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
                                                          ObjCMethodDecl,
                                                          BlockDecl),
                          internal::Matcher<ParmVarDecl>,
                          InnerMatcher) {
  return matchesFirstInPointerRange(InnerMatcher, Node.param_begin(),
                                    Node.param_end(), Finder,
                                    Builder) != Node.param_end();
}

/// 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 \c g and \c h
/// functionProtoType(parameterCountIs(2))
///   matches \c g and \c h
/// functionProtoType(parameterCountIs(3))
///   matches \c k
AST_POLYMORPHIC_MATCHER_P(parameterCountIs,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
                                                          FunctionProtoType),
                          unsigned, N) {
  return Node.getNumParams() == N;
}

/// Matches classTemplateSpecialization, templateSpecializationType and
/// functionDecl nodes where the template argument matches the inner matcher.
/// This matcher may produce multiple matches.
///
/// Given
/// \code
///   template <typename T, unsigned N, unsigned M>
///   struct Matrix {};
///
///   constexpr unsigned R = 2;
///   Matrix<int, R * 2, R * 4> M;
///
///   template <typename T, typename U>
///   void f(T&& t, U&& u) {}
///
///   bool B = false;
///   f(R, B);
/// \endcode
/// templateSpecializationType(forEachTemplateArgument(isExpr(expr())))
///   matches twice, with expr() matching 'R * 2' and 'R * 4'
/// functionDecl(forEachTemplateArgument(refersToType(builtinType())))
///   matches the specialization f<unsigned, bool> twice, for 'unsigned'
///   and 'bool'
AST_POLYMORPHIC_MATCHER_P(
    forEachTemplateArgument,
    AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
                                    TemplateSpecializationType, FunctionDecl),
    clang::ast_matchers::internal::Matcher<TemplateArgument>, InnerMatcher) {
  ArrayRef<TemplateArgument> TemplateArgs =
      clang::ast_matchers::internal::getTemplateSpecializationArgs(Node);
  clang::ast_matchers::internal::BoundNodesTreeBuilder Result;
  bool Matched = false;
  for (const auto &Arg : TemplateArgs) {
    clang::ast_matchers::internal::BoundNodesTreeBuilder ArgBuilder(*Builder);
    if (InnerMatcher.matches(Arg, Finder, &ArgBuilder)) {
      Matched = true;
      Result.addMatch(ArgBuilder);
    }
  }
  *Builder = std::move(Result);
  return Matched;
}

/// Matches \c FunctionDecls that have a noreturn attribute.
///
/// Given
/// \code
///   void nope();
///   [[noreturn]] void a();
///   __attribute__((noreturn)) void b();
///   struct c { [[noreturn]] c(); };
/// \endcode
/// functionDecl(isNoReturn())
///   matches all of those except
/// \code
///   void nope();
/// \endcode
AST_MATCHER(FunctionDecl, isNoReturn) { return Node.isNoReturn(); }

/// 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);
}

/// Matches extern "C" function or variable declarations.
///
/// Given:
/// \code
///   extern "C" void f() {}
///   extern "C" { void g() {} }
///   void h() {}
///   extern "C" int x = 1;
///   extern "C" int y = 2;
///   int z = 3;
/// \endcode
/// functionDecl(isExternC())
///   matches the declaration of f and g, but not the declaration of h.
/// varDecl(isExternC())
///   matches the declaration of x and y, but not the declaration of z.
AST_POLYMORPHIC_MATCHER(isExternC, AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
                                                                   VarDecl)) {
  return Node.isExternC();
}

/// Matches variable/function declarations that have "static" storage
/// class specifier ("static" keyword) written in the source.
///
/// Given:
/// \code
///   static void f() {}
///   static int i = 0;
///   extern int j;
///   int k;
/// \endcode
/// functionDecl(isStaticStorageClass())
///   matches the function declaration f.
/// varDecl(isStaticStorageClass())
///   matches the variable declaration i.
AST_POLYMORPHIC_MATCHER(isStaticStorageClass,
                        AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
                                                        VarDecl)) {
  return Node.getStorageClass() == SC_Static;
}

/// 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();
}

/// 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();
}

/// Matches weak function declarations.
///
/// Given:
/// \code
///   void foo() __attribute__((__weakref__("__foo")));
///   void bar();
/// \endcode
/// functionDecl(isWeak())
///   matches the weak declaration "foo", but not "bar".
AST_MATCHER(FunctionDecl, isWeak) { return Node.isWeak(); }

/// 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;
}

/// 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();
}

/// Matches consteval function declarations and if consteval/if ! consteval
/// statements.
///
/// Given:
/// \code
///   consteval int a();
///   void b() { if consteval {} }
///   void c() { if ! consteval {} }
///   void d() { if ! consteval {} else {} }
/// \endcode
/// functionDecl(isConsteval())
///   matches the declaration of "int a()".
/// ifStmt(isConsteval())
///   matches the if statement in "void b()", "void c()", "void d()".
AST_POLYMORPHIC_MATCHER(isConsteval,
                        AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, IfStmt)) {
  return Node.isConsteval();
}

/// Matches constexpr variable and function declarations,
///        and if constexpr.
///
/// Given:
/// \code
///   constexpr int foo = 42;
///   constexpr int bar();
///   void baz() { if constexpr(1 > 0) {} }
/// \endcode
/// varDecl(isConstexpr())
///   matches the declaration of foo.
/// functionDecl(isConstexpr())
///   matches the declaration of bar.
/// ifStmt(isConstexpr())
///   matches the if statement in baz.
AST_POLYMORPHIC_MATCHER(isConstexpr,
                        AST_POLYMORPHIC_SUPPORTED_TYPES(VarDecl,
                                                        FunctionDecl,
                                                        IfStmt)) {
  return Node.isConstexpr();
}

/// Matches constinit variable declarations.
///
/// Given:
/// \code
///   constinit int foo = 42;
///   constinit const char* bar = "bar";
///   int baz = 42;
///   [[clang::require_constant_initialization]] int xyz = 42;
/// \endcode
/// varDecl(isConstinit())
///   matches the declaration of `foo` and `bar`, but not `baz` and `xyz`.
AST_MATCHER(VarDecl, isConstinit) {
  if (const auto *CIA = Node.getAttr<ConstInitAttr>())
    return CIA->isConstinit();
  return false;
}

/// Matches selection statements with initializer.
///
/// Given:
/// \code
///  void foo() {
///    if (int i = foobar(); i > 0) {}
///    switch (int i = foobar(); i) {}
///    for (auto& a = get_range(); auto& x : a) {}
///  }
///  void bar() {
///    if (foobar() > 0) {}
///    switch (foobar()) {}
///    for (auto& x : get_range()) {}
///  }
/// \endcode
/// ifStmt(hasInitStatement(anything()))
///   matches the if statement in foo but not in bar.
/// switchStmt(hasInitStatement(anything()))
///   matches the switch statement in foo but not in bar.
/// cxxForRangeStmt(hasInitStatement(anything()))
///   matches the range for statement in foo but not in bar.
AST_POLYMORPHIC_MATCHER_P(hasInitStatement,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(IfStmt, SwitchStmt,
                                                          CXXForRangeStmt),
                          internal::Matcher<Stmt>, InnerMatcher) {
  const Stmt *Init = Node.getInit();
  return Init != nullptr && InnerMatcher.matches(*Init, Finder, Builder);
}

/// 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));
}

/// 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));
}

/// 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));
}

/// 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 = DynTypedNode::create(Node);
  return Builder->removeBindings(Predicate);
}

/// 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);
}

/// 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;
}

/// 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;
}

/// Matches a 'for', 'while', 'do while' statement or a function
/// definition that has a given body. Note that in case of functions
/// this matcher only matches the definition itself and not the other
/// declarations of the same function.
///
/// Given
/// \code
///   for (;;) {}
/// \endcode
/// hasBody(compoundStmt())
///   matches 'for (;;) {}'
/// with compoundStmt()
///   matching '{}'
///
/// Given
/// \code
///   void f();
///   void f() {}
/// \endcode
/// hasBody(functionDecl())
///   matches 'void f() {}'
/// with compoundStmt()
///   matching '{}'
///   but does not match 'void f();'

AST_POLYMORPHIC_MATCHER_P(hasBody,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(DoStmt, ForStmt,
                                                          WhileStmt,
                                                          CXXForRangeStmt,
                                                          FunctionDecl),
                          internal::Matcher<Stmt>, InnerMatcher) {
  if (Finder->isTraversalIgnoringImplicitNodes() && isDefaultedHelper(&Node))
    return false;
  const Stmt *const Statement = internal::GetBodyMatcher<NodeType>::get(Node);
  return (Statement != nullptr &&
          InnerMatcher.matches(*Statement, Finder, Builder));
}

/// Matches a function declaration that has a given body present in the AST.
/// Note that this matcher matches all the declarations of a function whose
/// body is present in the AST.
///
/// Given
/// \code
///   void f();
///   void f() {}
///   void g();
/// \endcode
/// functionDecl(hasAnyBody(compoundStmt()))
///   matches both 'void f();'
///   and 'void f() {}'
/// with compoundStmt()
///   matching '{}'
///   but does not match 'void g();'
AST_MATCHER_P(FunctionDecl, hasAnyBody,
              internal::Matcher<Stmt>, InnerMatcher) {
  const Stmt *const Statement = Node.getBody();
  return (Statement != nullptr &&
          InnerMatcher.matches(*Statement, Finder, Builder));
}


/// 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) != CS->body_end();
}

/// 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;
}

/// Matches literals that are equal to the given value of type ValueT.
///
/// Given
/// \code
///   f('\0', false, 3.14, 42);
/// \endcode
/// characterLiteral(equals(0))
///   matches '\0'
/// cxxBoolLiteral(equals(false)) and cxxBoolLiteral(equals(0))
///   match false
/// floatLiteral(equals(3.14)) and floatLiteral(equals(314e-2))
///   match 3.14
/// integerLiteral(equals(42))
///   matches 42
///
/// Note that you cannot directly match a negative numeric literal because the
/// minus sign is not part of the literal: It is a unary operator whose operand
/// is the positive numeric literal. Instead, you must use a unaryOperator()
/// matcher to match the minus sign:
///
/// unaryOperator(hasOperatorName("-"),
///               hasUnaryOperand(integerLiteral(equals(13))))
///
/// Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteralExpr>,
///            Matcher<FloatingLiteral>, Matcher<IntegerLiteral>
template <typename ValueT>
internal::PolymorphicMatcher<internal::ValueEqualsMatcher,
                             void(internal::AllNodeBaseTypes), ValueT>
equals(const ValueT &Value) {
  return internal::PolymorphicMatcher<internal::ValueEqualsMatcher,
                                      void(internal::AllNodeBaseTypes), ValueT>(
      Value);
}

AST_POLYMORPHIC_MATCHER_P_OVERLOAD(equals,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(CharacterLiteral,
                                                          CXXBoolLiteralExpr,
                                                          IntegerLiteral),
                          bool, Value, 0) {
  return internal::ValueEqualsMatcher<NodeType, ParamT>(Value)
    .matchesNode(Node);
}

AST_POLYMORPHIC_MATCHER_P_OVERLOAD(equals,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(CharacterLiteral,
                                                          CXXBoolLiteralExpr,
                                                          IntegerLiteral),
                          unsigned, Value, 1) {
  return internal::ValueEqualsMatcher<NodeType, ParamT>(Value)
    .matchesNode(Node);
}

AST_POLYMORPHIC_MATCHER_P_OVERLOAD(equals,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(CharacterLiteral,
                                                          CXXBoolLiteralExpr,
                                                          FloatingLiteral,
                                                          IntegerLiteral),
                          double, Value, 2) {
  return internal::ValueEqualsMatcher<NodeType, ParamT>(Value)
    .matchesNode(Node);
}

/// 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, CXXOperatorCallExpr,
                                    CXXRewrittenBinaryOperator, UnaryOperator),
    std::string, Name) {
  if (Optional<StringRef> OpName = internal::getOpName(Node))
    return *OpName == Name;
  return false;
}

/// Matches operator expressions (binary or unary) that have any of the
/// specified names.
///
///    hasAnyOperatorName("+", "-")
///  Is equivalent to
///    anyOf(hasOperatorName("+"), hasOperatorName("-"))
extern const internal::VariadicFunction<
    internal::PolymorphicMatcher<internal::HasAnyOperatorNameMatcher,
                                 AST_POLYMORPHIC_SUPPORTED_TYPES(
                                     BinaryOperator, CXXOperatorCallExpr,
                                     CXXRewrittenBinaryOperator, UnaryOperator),
                                 std::vector<std::string>>,
    StringRef, internal::hasAnyOperatorNameFunc>
    hasAnyOperatorName;

/// Matches all kinds of assignment operators.
///
/// Example 1: matches a += b (matcher = binaryOperator(isAssignmentOperator()))
/// \code
///   if (a == b)
///     a += b;
/// \endcode
///
/// Example 2: matches s1 = s2
///            (matcher = cxxOperatorCallExpr(isAssignmentOperator()))
/// \code
///   struct S { S& operator=(const S&); };
///   void x() { S s1, s2; s1 = s2; }
/// \endcode
AST_POLYMORPHIC_MATCHER(
    isAssignmentOperator,
    AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,
                                    CXXRewrittenBinaryOperator)) {
  return Node.isAssignmentOp();
}

/// Matches comparison operators.
///
/// Example 1: matches a == b (matcher = binaryOperator(isComparisonOperator()))
/// \code
///   if (a == b)
///     a += b;
/// \endcode
///
/// Example 2: matches s1 < s2
///            (matcher = cxxOperatorCallExpr(isComparisonOperator()))
/// \code
///   struct S { bool operator<(const S& other); };
///   void x(S s1, S s2) { bool b1 = s1 < s2; }
/// \endcode
AST_POLYMORPHIC_MATCHER(
    isComparisonOperator,
    AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,
                                    CXXRewrittenBinaryOperator)) {
  return Node.isComparisonOp();
}

/// 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, CXXOperatorCallExpr,
                              CXXRewrittenBinaryOperator, ArraySubscriptExpr),
                          internal::Matcher<Expr>, InnerMatcher) {
  const Expr *LeftHandSide = internal::getLHS(Node);
  return (LeftHandSide != nullptr &&
          InnerMatcher.matches(*LeftHandSide, Finder, Builder));
}

/// 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, CXXOperatorCallExpr,
                              CXXRewrittenBinaryOperator, ArraySubscriptExpr),
                          internal::Matcher<Expr>, InnerMatcher) {
  const Expr *RightHandSide = internal::getRHS(Node);
  return (RightHandSide != nullptr &&
          InnerMatcher.matches(*RightHandSide, Finder, Builder));
}

/// Matches if either the left hand side or the right hand side of a
/// binary operator matches.
AST_POLYMORPHIC_MATCHER_P(
    hasEitherOperand,
    AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,
                                    CXXRewrittenBinaryOperator),
    internal::Matcher<Expr>, InnerMatcher) {
  return internal::VariadicDynCastAllOfMatcher<Stmt, NodeType>()(
             anyOf(hasLHS(InnerMatcher), hasRHS(InnerMatcher)))
      .matches(Node, Finder, Builder);
}

/// Matches if both matchers match with opposite sides of the binary operator.
///
/// Example matcher = binaryOperator(hasOperands(integerLiteral(equals(1),
///                                              integerLiteral(equals(2)))
/// \code
///   1 + 2 // Match
///   2 + 1 // Match
///   1 + 1 // No match
///   2 + 2 // No match
/// \endcode
AST_POLYMORPHIC_MATCHER_P2(
    hasOperands,
    AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,
                                    CXXRewrittenBinaryOperator),
    internal::Matcher<Expr>, Matcher1, internal::Matcher<Expr>, Matcher2) {
  return internal::VariadicDynCastAllOfMatcher<Stmt, NodeType>()(
             anyOf(allOf(hasLHS(Matcher1), hasRHS(Matcher2)),
                   allOf(hasLHS(Matcher2), hasRHS(Matcher1))))
      .matches(Node, Finder, Builder);
}

/// Matches if the operand of a unary operator matches.
///
/// Example matches true (matcher = hasUnaryOperand(
///                                   cxxBoolLiteral(equals(true))))
/// \code
///   !true
/// \endcode
AST_POLYMORPHIC_MATCHER_P(hasUnaryOperand,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(UnaryOperator,
                                                          CXXOperatorCallExpr),
                          internal::Matcher<Expr>, InnerMatcher) {
  const Expr *const Operand = internal::getSubExpr(Node);
  return (Operand != nullptr &&
          InnerMatcher.matches(*Operand, Finder, Builder));
}

/// 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));
}

/// 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
///
/// If the matcher is use from clang-query, CastKind parameter
/// should be passed as a quoted string. e.g., hasCastKind("CK_NullToPointer").
AST_MATCHER_P(CastExpr, hasCastKind, CastKind, Kind) {
  return Node.getCastKind() == Kind;
}

/// 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);
}

/// 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);
}

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

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

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

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

/// 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));
}

/// 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));
}

/// 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.
///   @interface X
///   - (void)ma; // Doesn't match, interface is declaration.
///   @end
///   @implementation X
///   - (void)ma {}
///   @end
/// \endcode
///
/// Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>,
///   Matcher<ObjCMethodDecl>
AST_POLYMORPHIC_MATCHER(isDefinition,
                        AST_POLYMORPHIC_SUPPORTED_TYPES(TagDecl, VarDecl,
                                                        ObjCMethodDecl,
                                                        FunctionDecl)) {
  return Node.isThisDeclarationADefinition();
}

/// 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();
}

/// 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) {

  ASTChildrenNotSpelledInSourceScope RAII(Finder, false);

  const CXXRecordDecl *Parent = Node.getParent();
  return (Parent != nullptr &&
          InnerMatcher.matches(*Parent, Finder, Builder));
}

/// Matches each method overridden 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;
}

/// Matches declarations of virtual methods and C++ base specifers that specify
/// virtual inheritance.
///
/// Example:
/// \code
///   class A {
///    public:
///     virtual void x(); // matches x
///   };
/// \endcode
///
/// Example:
/// \code
///   class Base {};
///   class DirectlyDerived : virtual Base {}; // matches Base
///   class IndirectlyDerived : DirectlyDerived, Base {}; // matches Base
/// \endcode
///
/// Usable as: Matcher<CXXMethodDecl>, Matcher<CXXBaseSpecifier>
AST_POLYMORPHIC_MATCHER(isVirtual,
                        AST_POLYMORPHIC_SUPPORTED_TYPES(CXXMethodDecl,
                                                        CXXBaseSpecifier)) {
  return Node.isVirtual();
}

/// 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();
}

AST_MATCHER(CXXConstructorDecl, isInheritingConstructor) {
  return Node.isInheritingConstructor();
}

/// 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>();
}

/// 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();
}

/// 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();
}

/// 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();
}

/// 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();
}

/// 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>();
}

/// 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();
}

/// 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; }
///     template <class T> void f() { this->f<T>(); f<T>(); }
///     int a;
///     static int b;
///   };
///   template <class T>
///   class Z {
///     void x() { this->m; }
///   };
/// \endcode
/// memberExpr(isArrow())
///   matches this->x, x, y.x, a, this->b
/// cxxDependentScopeMemberExpr(isArrow())
///   matches this->m
/// unresolvedMemberExpr(isArrow())
///   matches this->f<T>, f<T>
AST_POLYMORPHIC_MATCHER(
    isArrow, AST_POLYMORPHIC_SUPPORTED_TYPES(MemberExpr, UnresolvedMemberExpr,
                                             CXXDependentScopeMemberExpr)) {
  return Node.isArrow();
}

/// 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();
}

/// 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();
}

/// 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();
}

/// 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();
}

/// 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();
}

/// 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();
}

/// 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();
}

/// 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();
}

/// 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);
}

/// Matches a member expression where the object expression is matched by a
/// given matcher. Implicit object expressions are included; that is, it matches
/// use of implicit `this`.
///
/// Given
/// \code
///   struct X {
///     int m;
///     int f(X x) { x.m; return m; }
///   };
/// \endcode
/// memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))))
///   matches `x.m`, but not `m`; however,
/// memberExpr(hasObjectExpression(hasType(pointsTo(
//      cxxRecordDecl(hasName("X"))))))
///   matches `m` (aka. `this->m`), but not `x.m`.
AST_POLYMORPHIC_MATCHER_P(
    hasObjectExpression,
    AST_POLYMORPHIC_SUPPORTED_TYPES(MemberExpr, UnresolvedMemberExpr,
                                    CXXDependentScopeMemberExpr),
    internal::Matcher<Expr>, InnerMatcher) {
  if (const auto *E = dyn_cast<UnresolvedMemberExpr>(&Node))
    if (E->isImplicitAccess())
      return false;
  if (const auto *E = dyn_cast<CXXDependentScopeMemberExpr>(&Node))
    if (E->isImplicitAccess())
      return false;
  return InnerMatcher.matches(*Node.getBase(), Finder, Builder);
}

/// 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(BaseUsingDecl, hasAnyUsingShadowDecl,
              internal::Matcher<UsingShadowDecl>, InnerMatcher) {
  return matchesFirstInPointerRange(InnerMatcher, Node.shadow_begin(),
                                    Node.shadow_end(), Finder,
                                    Builder) != Node.shadow_end();
}

/// 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);
}

/// 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
/// or
/// \code
///   template <typename T> class X {}; class A {}; extern 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 ||
          Node.getTemplateSpecializationKind() ==
              TSK_ExplicitInstantiationDeclaration);
}

/// 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)));
}

/// 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())))));
}

/// 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);
}

/// 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));
}

/// Matches `QualifiedTypeLoc`s in the clang AST.
///
/// Given
/// \code
///   const int x = 0;
/// \endcode
/// qualifiedTypeLoc()
///   matches `const int`.
extern const internal::VariadicDynCastAllOfMatcher<TypeLoc, QualifiedTypeLoc>
    qualifiedTypeLoc;

/// Matches `QualifiedTypeLoc`s that have an unqualified `TypeLoc` matching
/// `InnerMatcher`.
///
/// Given
/// \code
///   int* const x;
///   const int y;
/// \endcode
/// qualifiedTypeLoc(hasUnqualifiedLoc(pointerTypeLoc()))
///   matches the `TypeLoc` of the variable declaration of `x`, but not `y`.
AST_MATCHER_P(QualifiedTypeLoc, hasUnqualifiedLoc, internal::Matcher<TypeLoc>,
              InnerMatcher) {
  return InnerMatcher.matches(Node.getUnqualifiedLoc(), Finder, Builder);
}

/// Matches a function declared with the specified return `TypeLoc`.
///
/// Given
/// \code
///   int f() { return 5; }
///   void g() {}
/// \endcode
/// functionDecl(hasReturnTypeLoc(loc(asString("int"))))
///   matches the declaration of `f`, but not `g`.
AST_MATCHER_P(FunctionDecl, hasReturnTypeLoc, internal::Matcher<TypeLoc>,
              ReturnMatcher) {
  auto Loc = Node.getFunctionTypeLoc();
  return Loc && ReturnMatcher.matches(Loc.getReturnLoc(), Finder, Builder);
}

/// Matches pointer `TypeLoc`s.
///
/// Given
/// \code
///   int* x;
/// \endcode
/// pointerTypeLoc()
///   matches `int*`.
extern const internal::VariadicDynCastAllOfMatcher<TypeLoc, PointerTypeLoc>
    pointerTypeLoc;

/// Matches pointer `TypeLoc`s that have a pointee `TypeLoc` matching
/// `PointeeMatcher`.
///
/// Given
/// \code
///   int* x;
/// \endcode
/// pointerTypeLoc(hasPointeeLoc(loc(asString("int"))))
///   matches `int*`.
AST_MATCHER_P(PointerTypeLoc, hasPointeeLoc, internal::Matcher<TypeLoc>,
              PointeeMatcher) {
  return PointeeMatcher.matches(Node.getPointeeLoc(), Finder, Builder);
}

/// Matches reference `TypeLoc`s.
///
/// Given
/// \code
///   int x = 3;
///   int& l = x;
///   int&& r = 3;
/// \endcode
/// referenceTypeLoc()
///   matches `int&` and `int&&`.
extern const internal::VariadicDynCastAllOfMatcher<TypeLoc, ReferenceTypeLoc>
    referenceTypeLoc;

/// Matches reference `TypeLoc`s that have a referent `TypeLoc` matching
/// `ReferentMatcher`.
///
/// Given
/// \code
///   int x = 3;
///   int& xx = x;
/// \endcode
/// referenceTypeLoc(hasReferentLoc(loc(asString("int"))))
///   matches `int&`.
AST_MATCHER_P(ReferenceTypeLoc, hasReferentLoc, internal::Matcher<TypeLoc>,
              ReferentMatcher) {
  return ReferentMatcher.matches(Node.getPointeeLoc(), Finder, Builder);
}

/// Matches template specialization `TypeLoc`s.
///
/// Given
/// \code
///   template <typename T> class C {};
///   C<char> var;
/// \endcode
/// varDecl(hasTypeLoc(templateSpecializationTypeLoc(typeLoc())))
///   matches `C<char> var`.
extern const internal::VariadicDynCastAllOfMatcher<
    TypeLoc, TemplateSpecializationTypeLoc>
    templateSpecializationTypeLoc;

/// Matches template specialization `TypeLoc`s that have at least one
/// `TemplateArgumentLoc` matching the given `InnerMatcher`.
///
/// Given
/// \code
///   template<typename T> class A {};
///   A<int> a;
/// \endcode
/// varDecl(hasTypeLoc(templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
///   hasTypeLoc(loc(asString("int")))))))
///   matches `A<int> a`.
AST_MATCHER_P(TemplateSpecializationTypeLoc, hasAnyTemplateArgumentLoc,
              internal::Matcher<TemplateArgumentLoc>, InnerMatcher) {
  for (unsigned Index = 0, N = Node.getNumArgs(); Index < N; ++Index) {
    clang::ast_matchers::internal::BoundNodesTreeBuilder Result(*Builder);
    if (InnerMatcher.matches(Node.getArgLoc(Index), Finder, &Result)) {
      *Builder = std::move(Result);
      return true;
    }
  }
  return false;
}

/// Matches template specialization `TypeLoc`s where the n'th
/// `TemplateArgumentLoc` matches the given `InnerMatcher`.
///
/// Given
/// \code
///   template<typename T, typename U> class A {};
///   A<double, int> b;
///   A<int, double> c;
/// \endcode
/// varDecl(hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(0,
///   hasTypeLoc(loc(asString("double")))))))
///   matches `A<double, int> b`, but not `A<int, double> c`.
AST_POLYMORPHIC_MATCHER_P2(
    hasTemplateArgumentLoc,
    AST_POLYMORPHIC_SUPPORTED_TYPES(DeclRefExpr, TemplateSpecializationTypeLoc),
    unsigned, Index, internal::Matcher<TemplateArgumentLoc>, InnerMatcher) {
  return internal::MatchTemplateArgLocAt(Node, Index, InnerMatcher, Finder,
                                         Builder);
}

/// Matches C or C++ elaborated `TypeLoc`s.
///
/// Given
/// \code
///   struct s {};
///   struct s ss;
/// \endcode
/// elaboratedTypeLoc()
///   matches the `TypeLoc` of the variable declaration of `ss`.
extern const internal::VariadicDynCastAllOfMatcher<TypeLoc, ElaboratedTypeLoc>
    elaboratedTypeLoc;

/// Matches elaborated `TypeLoc`s that have a named `TypeLoc` matching
/// `InnerMatcher`.
///
/// Given
/// \code
///   template <typename T>
///   class C {};
///   class C<int> c;
///
///   class D {};
///   class D d;
/// \endcode
/// elaboratedTypeLoc(hasNamedTypeLoc(templateSpecializationTypeLoc()));
///   matches the `TypeLoc` of the variable declaration of `c`, but not `d`.
AST_MATCHER_P(ElaboratedTypeLoc, hasNamedTypeLoc, internal::Matcher<TypeLoc>,
              InnerMatcher) {
  return InnerMatcher.matches(Node.getNamedTypeLoc(), Finder, Builder);
}

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

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

template <typename NodeType>
using AstTypeMatcher = internal::VariadicDynCastAllOfMatcher<Type, NodeType>;

/// 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"
extern const AstTypeMatcher<BuiltinType> builtinType;

/// 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]]";
extern const AstTypeMatcher<ArrayType> arrayType;

/// Matches C99 complex types.
///
/// Given
/// \code
///   _Complex float f;
/// \endcode
/// complexType()
///   matches "_Complex float f"
extern const AstTypeMatcher<ComplexType> complexType;

/// 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();
}

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

/// 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]"
extern const AstTypeMatcher<ConstantArrayType> constantArrayType;

/// 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);
}

/// 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]"
extern const AstTypeMatcher<DependentSizedArrayType> dependentSizedArrayType;

/// 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[]"
extern const AstTypeMatcher<IncompleteArrayType> incompleteArrayType;

/// 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]]"
extern const AstTypeMatcher<VariableArrayType> variableArrayType;

/// 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);
}

/// Matches atomic types.
///
/// Given
/// \code
///   _Atomic(int) i;
/// \endcode
/// atomicType()
///   matches "_Atomic(int) i"
extern const AstTypeMatcher<AtomicType> atomicType;

/// 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_DECL(hasValueType, getValue,
                                  AST_POLYMORPHIC_SUPPORTED_TYPES(AtomicType));

/// 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"
extern const AstTypeMatcher<AutoType> autoType;

/// Matches types nodes representing C++11 decltype(<expr>) types.
///
/// Given:
/// \code
///   short i = 1;
///   int j = 42;
///   decltype(i + j) result = i + j;
/// \endcode
/// decltypeType()
///   matches "decltype(i + j)"
extern const AstTypeMatcher<DecltypeType> decltypeType;

/// 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));

/// Matches \c DecltypeType or \c UsingType nodes to find the underlying type.
///
/// Given
/// \code
///   decltype(1) a = 1;
///   decltype(2.0) b = 2.0;
/// \endcode
/// decltypeType(hasUnderlyingType(isInteger()))
///   matches the type of "a"
///
/// Usable as: Matcher<DecltypeType>, Matcher<UsingType>
AST_TYPE_TRAVERSE_MATCHER(hasUnderlyingType, getUnderlyingType,
                          AST_POLYMORPHIC_SUPPORTED_TYPES(DecltypeType,
                                                          UsingType));

/// Matches \c FunctionType nodes.
///
/// Given
/// \code
///   int (*f)(int);
///   void g();
/// \endcode
/// functionType()
///   matches "int (*f)(int)" and the type of "g".
extern const AstTypeMatcher<FunctionType> functionType;

/// 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.
extern const AstTypeMatcher<FunctionProtoType> functionProtoType;

/// 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.
extern const AstTypeMatcher<ParenType> parenType;

/// 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));

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

/// Matches member pointer types.
/// Given
/// \code
///   struct A { int i; }
///   A::* ptr = A::i;
/// \endcode
/// memberPointerType()
///   matches "A::* ptr"
extern const AstTypeMatcher<MemberPointerType> memberPointerType;

/// 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".
extern const AstTypeMatcher<PointerType> pointerType;

/// 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".
extern const AstTypeMatcher<ObjCObjectPointerType> objcObjectPointerType;

/// 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.
extern const AstTypeMatcher<ReferenceType> referenceType;

/// 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.
extern const AstTypeMatcher<LValueReferenceType> lValueReferenceType;

/// 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.
extern const AstTypeMatcher<RValueReferenceType> rValueReferenceType;

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

/// Matches typedef types.
///
/// Given
/// \code
///   typedef int X;
/// \endcode
/// typedefType()
///   matches "typedef int X"
extern const AstTypeMatcher<TypedefType> typedefType;

/// 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.
extern const AstTypeMatcher<EnumType> enumType;

/// 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.
extern const AstTypeMatcher<TemplateSpecializationType>
    templateSpecializationType;

/// Matches C++17 deduced template specialization types, e.g. deduced class
/// template types.
///
/// Given
/// \code
///   template <typename T>
///   class C { public: C(T); };
///
///   C c(123);
/// \endcode
/// \c deducedTemplateSpecializationType() matches the type in the declaration
/// of the variable \c c.
extern const AstTypeMatcher<DeducedTemplateSpecializationType>
    deducedTemplateSpecializationType;

/// Matches types nodes representing unary type transformations.
///
/// Given:
/// \code
///   typedef __underlying_type(T) type;
/// \endcode
/// unaryTransformType()
///   matches "__underlying_type(T)"
extern const AstTypeMatcher<UnaryTransformType> unaryTransformType;

/// 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.
extern const AstTypeMatcher<RecordType> recordType;

/// Matches tag types (record and enum types).
///
/// Given
/// \code
///   enum E {};
///   class C {};
///
///   E e;
///   C c;
/// \endcode
///
/// \c tagType() matches the type of the variable declarations of both \c e
/// and \c c.
extern const AstTypeMatcher<TagType> tagType;

/// 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.
extern const AstTypeMatcher<ElaboratedType> elaboratedType;

/// 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;
}

/// 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);
}

/// Matches types specified through a using declaration.
///
/// Given
/// \code
///   namespace a { struct S {}; }
///   using a::S;
///   S s;
/// \endcode
///
/// \c usingType() matches the type of the variable declaration of \c s.
extern const AstTypeMatcher<UsingType> usingType;

/// 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'
extern const AstTypeMatcher<SubstTemplateTypeParmType>
    substTemplateTypeParmType;

/// Matches template type parameter substitutions that have a replacement
/// type that matches the provided matcher.
///
/// Given
/// \code
///   template <typename T>
///   double F(T t);
///   int i;
///   double j = F(i);
/// \endcode
///
/// \c substTemplateTypeParmType(hasReplacementType(type())) matches int
AST_TYPE_TRAVERSE_MATCHER(
    hasReplacementType, getReplacementType,
    AST_POLYMORPHIC_SUPPORTED_TYPES(SubstTemplateTypeParmType));

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

/// 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
extern const AstTypeMatcher<InjectedClassNameType> injectedClassNameType;

/// 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
extern const AstTypeMatcher<DecayedType> decayedType;

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

/// 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);
}

/// 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::"
extern const internal::VariadicAllOfMatcher<NestedNameSpecifier>
    nestedNameSpecifier;

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

/// 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));
}

/// 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);
}

/// 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 && Node.getNestedNameSpecifier()->getAsType() &&
         InnerMatcher.matches(Node.getTypeLoc(), Finder, Builder);
}

/// 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);
}

/// 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);
}

/// 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);
}

/// Matches attributes.
/// Attributes may be attached with a variety of different syntaxes (including
/// keywords, C++11 attributes, GNU ``__attribute``` and MSVC `__declspec``,
/// and ``#pragma``s). They may also be implicit.
///
/// Given
/// \code
///   struct [[nodiscard]] Foo{};
///   void bar(int * __attribute__((nonnull)) );
///   __declspec(noinline) void baz();
///
///   #pragma omp declare simd
///   int min();
/// \endcode
/// attr()
///   matches "nodiscard", "nonnull", "noinline", and the whole "#pragma" line.
extern const internal::VariadicAllOfMatcher<Attr> attr;

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

/// 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;
}
/// 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;
}
/// 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;
}

/// @}

/// 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;
}

/// 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()) {
    if (Finder->isTraversalIgnoringImplicitNodes() && !I->isWritten())
      continue;
    BoundNodesTreeBuilder InitBuilder(*Builder);
    if (InnerMatcher.matches(*I, Finder, &InitBuilder)) {
      Matched = true;
      Result.addMatch(InitBuilder);
    }
  }
  *Builder = std::move(Result);
  return Matched;
}

/// 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();
}

/// 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();
}

/// 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();
}

/// 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();
}

/// Matches constructor, conversion function, and deduction guide declarations
/// that have an explicit specifier if this explicit specifier is resolved to
/// true.
///
/// Given
/// \code
///   template<bool b>
///   struct S {
///     S(int); // #1
///     explicit S(double); // #2
///     operator int(); // #3
///     explicit operator bool(); // #4
///     explicit(false) S(bool) // # 7
///     explicit(true) S(char) // # 8
///     explicit(b) S(S) // # 9
///   };
///   S(int) -> S<true> // #5
///   explicit S(double) -> S<false> // #6
/// \endcode
/// cxxConstructorDecl(isExplicit()) will match #2 and #8, but not #1, #7 or #9.
/// cxxConversionDecl(isExplicit()) will match #4, but not #3.
/// cxxDeductionGuideDecl(isExplicit()) will match #6, but not #5.
AST_POLYMORPHIC_MATCHER(isExplicit, AST_POLYMORPHIC_SUPPORTED_TYPES(
                                        CXXConstructorDecl, CXXConversionDecl,
                                        CXXDeductionGuideDecl)) {
  return Node.isExplicit();
}

/// Matches the expression in an explicit specifier if present in the given
/// declaration.
///
/// Given
/// \code
///   template<bool b>
///   struct S {
///     S(int); // #1
///     explicit S(double); // #2
///     operator int(); // #3
///     explicit operator bool(); // #4
///     explicit(false) S(bool) // # 7
///     explicit(true) S(char) // # 8
///     explicit(b) S(S) // # 9
///   };
///   S(int) -> S<true> // #5
///   explicit S(double) -> S<false> // #6
/// \endcode
/// cxxConstructorDecl(hasExplicitSpecifier(constantExpr())) will match #7, #8 and #9, but not #1 or #2.
/// cxxConversionDecl(hasExplicitSpecifier(constantExpr())) will not match #3 or #4.
/// cxxDeductionGuideDecl(hasExplicitSpecifier(constantExpr())) will not match #5 or #6.
AST_MATCHER_P(FunctionDecl, hasExplicitSpecifier, internal::Matcher<Expr>,
              InnerMatcher) {
  ExplicitSpecifier ES = ExplicitSpecifier::getFromDecl(&Node);
  if (!ES.getExpr())
    return false;

  ASTChildrenNotSpelledInSourceScope RAII(Finder, false);

  return InnerMatcher.matches(*ES.getExpr(), Finder, Builder);
}

/// Matches functions, variables and namespace declarations that are marked with
/// the inline keyword.
///
/// Given
/// \code
///   inline void f();
///   void g();
///   namespace n {
///   inline namespace m {}
///   }
///   inline int Foo = 5;
/// \endcode
/// functionDecl(isInline()) will match ::f().
/// namespaceDecl(isInline()) will match n::m.
/// varDecl(isInline()) will match Foo;
AST_POLYMORPHIC_MATCHER(isInline, AST_POLYMORPHIC_SUPPORTED_TYPES(NamespaceDecl,
                                                                  FunctionDecl,
                                                                  VarDecl)) {
  // 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();
  if (const auto *NSD = dyn_cast<NamespaceDecl>(&Node))
    return NSD->isInline();
  if (const auto *VD = dyn_cast<VarDecl>(&Node))
    return VD->isInline();
  llvm_unreachable("Not a valid polymorphic type");
}

/// 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();
}

/// Matches declarations in the namespace `std`, but not in nested namespaces.
///
/// Given
/// \code
///   class vector {};
///   namespace foo {
///     class vector {};
///     namespace std {
///       class vector {};
///     }
///   }
///   namespace std {
///     inline namespace __1 {
///       class vector {}; // #1
///       namespace experimental {
///         class vector {};
///       }
///     }
///   }
/// \endcode
/// cxxRecordDecl(hasName("vector"), isInStdNamespace()) will match only #1.
AST_MATCHER(Decl, isInStdNamespace) { return Node.isInStdNamespace(); }

/// 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);
}

/// 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 used 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;
}

/// 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;
}

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

/// 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())))));
}

/// Matches the DecompositionDecl the binding belongs to.
///
/// For example, in:
/// \code
/// void foo()
/// {
///     int arr[3];
///     auto &[f, s, t] = arr;
///
///     f = 42;
/// }
/// \endcode
/// The matcher:
/// \code
///   bindingDecl(hasName("f"),
///                 forDecomposition(decompositionDecl())
/// \endcode
/// matches 'f' in 'auto &[f, s, t]'.
AST_MATCHER_P(BindingDecl, forDecomposition, internal::Matcher<ValueDecl>,
              InnerMatcher) {
  if (const ValueDecl *VD = Node.getDecomposedDecl())
    return InnerMatcher.matches(*VD, Finder, Builder);
  return false;
}

/// Matches the Nth binding of a DecompositionDecl.
///
/// For example, in:
/// \code
/// void foo()
/// {
///     int arr[3];
///     auto &[f, s, t] = arr;
///
///     f = 42;
/// }
/// \endcode
/// The matcher:
/// \code
///   decompositionDecl(hasBinding(0,
///   bindingDecl(hasName("f").bind("fBinding"))))
/// \endcode
/// matches the decomposition decl with 'f' bound to "fBinding".
AST_MATCHER_P2(DecompositionDecl, hasBinding, unsigned, N,
               internal::Matcher<BindingDecl>, InnerMatcher) {
  if (Node.bindings().size() <= N)
    return false;
  return InnerMatcher.matches(*Node.bindings()[N], Finder, Builder);
}

/// Matches any binding of a DecompositionDecl.
///
/// For example, in:
/// \code
/// void foo()
/// {
///     int arr[3];
///     auto &[f, s, t] = arr;
///
///     f = 42;
/// }
/// \endcode
/// The matcher:
/// \code
///   decompositionDecl(hasAnyBinding(bindingDecl(hasName("f").bind("fBinding"))))
/// \endcode
/// matches the decomposition decl with 'f' bound to "fBinding".
AST_MATCHER_P(DecompositionDecl, hasAnyBinding, internal::Matcher<BindingDecl>,
              InnerMatcher) {
  return llvm::any_of(Node.bindings(), [&](const auto *Binding) {
    return InnerMatcher.matches(*Binding, Finder, Builder);
  });
}

/// Matches declaration of the function the statement belongs to.
///
/// Deprecated. Use forCallable() to correctly handle the situation when
/// the declaration is not a function (but a block or an Objective-C method).
/// forFunction() not only fails to take non-functions into account but also
/// may match the wrong declaration in their presence.
///
/// 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 not match 'return v > 0'
AST_MATCHER_P(Stmt, forFunction, internal::Matcher<FunctionDecl>,
              InnerMatcher) {
  const auto &Parents = Finder->getASTContext().getParents(Node);

  llvm::SmallVector<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 {
      llvm::append_range(Stack, Finder->getASTContext().getParents(CurNode));
    }
  }
  return false;
}

/// Matches declaration of the function, method, or block the statement
/// 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(forCallable(functionDecl(hasName("operator="))))
///   matches 'return *this'
///   but does not match 'return v > 0'
///
/// Given:
/// \code
/// -(void) foo {
///   int x = 1;
///   dispatch_sync(queue, ^{ int y = 2; });
/// }
/// \endcode
/// declStmt(forCallable(objcMethodDecl()))
///   matches 'int x = 1'
///   but does not match 'int y = 2'.
/// whereas declStmt(forCallable(blockDecl()))
///   matches 'int y = 2'
///   but does not match 'int x = 1'.
AST_MATCHER_P(Stmt, forCallable, internal::Matcher<Decl>, InnerMatcher) {
  const auto &Parents = Finder->getASTContext().getParents(Node);

  llvm::SmallVector<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 if (const auto *ObjCMethodDeclNode = CurNode.get<ObjCMethodDecl>()) {
      if (InnerMatcher.matches(*ObjCMethodDeclNode, Finder, Builder)) {
        return true;
      }
    } else if (const auto *BlockDeclNode = CurNode.get<BlockDecl>()) {
      if (InnerMatcher.matches(*BlockDeclNode, Finder, Builder)) {
        return true;
      }
    } else {
      llvm::append_range(Stack, Finder->getASTContext().getParents(CurNode));
    }
  }
  return false;
}

/// Matches a declaration that has external formal linkage.
///
/// Example matches only z (matcher = varDecl(hasExternalFormalLinkage()))
/// \code
/// void f() {
///   int x;
///   static int y;
/// }
/// int z;
/// \endcode
///
/// Example matches f() because it has external formal linkage despite being
/// unique to the translation unit as though it has internal likage
/// (matcher = functionDecl(hasExternalFormalLinkage()))
///
/// \code
/// namespace {
/// void f() {}
/// }
/// \endcode
AST_MATCHER(NamedDecl, hasExternalFormalLinkage) {
  return Node.hasExternalFormalLinkage();
}

/// Matches a declaration that has default arguments.
///
/// Example matches y (matcher = parmVarDecl(hasDefaultArgument()))
/// \code
/// void x(int val) {}
/// void y(int val = 0) {}
/// \endcode
///
/// Deprecated. Use hasInitializer() instead to be able to
/// match on the contents of the default argument.  For example:
///
/// \code
/// void x(int val = 7) {}
/// void y(int val = 42) {}
/// \endcode
/// parmVarDecl(hasInitializer(integerLiteral(equals(42))))
///   matches the parameter of y
///
/// A matcher such as
///   parmVarDecl(hasInitializer(anything()))
/// is equivalent to parmVarDecl(hasDefaultArgument()).
AST_MATCHER(ParmVarDecl, hasDefaultArgument) {
  return Node.hasDefaultArg();
}

/// Matches array new expressions.
///
/// Given:
/// \code
///   MyClass *p1 = new MyClass[10];
/// \endcode
/// cxxNewExpr(isArray())
///   matches the expression 'new MyClass[10]'.
AST_MATCHER(CXXNewExpr, isArray) {
  return Node.isArray();
}

/// Matches placement new expression arguments.
///
/// Given:
/// \code
///   MyClass *p1 = new (Storage, 16) MyClass();
/// \endcode
/// cxxNewExpr(hasPlacementArg(1, integerLiteral(equals(16))))
///   matches the expression 'new (Storage, 16) MyClass()'.
AST_MATCHER_P2(CXXNewExpr, hasPlacementArg, unsigned, Index,
               internal::Matcher<Expr>, InnerMatcher) {
  return Node.getNumPlacementArgs() > Index &&
         InnerMatcher.matches(*Node.getPlacementArg(Index), Finder, Builder);
}

/// Matches any placement new expression arguments.
///
/// Given:
/// \code
///   MyClass *p1 = new (Storage) MyClass();
/// \endcode
/// cxxNewExpr(hasAnyPlacementArg(anything()))
///   matches the expression 'new (Storage, 16) MyClass()'.
AST_MATCHER_P(CXXNewExpr, hasAnyPlacementArg, internal::Matcher<Expr>,
              InnerMatcher) {
  return llvm::any_of(Node.placement_arguments(), [&](const Expr *Arg) {
    return InnerMatcher.matches(*Arg, Finder, Builder);
  });
}

/// Matches array new expressions with a given array size.
///
/// Given:
/// \code
///   MyClass *p1 = new MyClass[10];
/// \endcode
/// cxxNewExpr(hasArraySize(integerLiteral(equals(10))))
///   matches the expression 'new MyClass[10]'.
AST_MATCHER_P(CXXNewExpr, hasArraySize, internal::Matcher<Expr>, InnerMatcher) {
  return Node.isArray() && *Node.getArraySize() &&
         InnerMatcher.matches(**Node.getArraySize(), Finder, Builder);
}

/// Matches a class declaration that is defined.
///
/// Example matches x (matcher = cxxRecordDecl(hasDefinition()))
/// \code
/// class x {};
/// class y;
/// \endcode
AST_MATCHER(CXXRecordDecl, hasDefinition) {
  return Node.hasDefinition();
}

/// Matches C++11 scoped enum declaration.
///
/// Example matches Y (matcher = enumDecl(isScoped()))
/// \code
/// enum X {};
/// enum class Y {};
/// \endcode
AST_MATCHER(EnumDecl, isScoped) {
  return Node.isScoped();
}

/// Matches a function declared with a trailing return type.
///
/// Example matches Y (matcher = functionDecl(hasTrailingReturn()))
/// \code
/// int X() {}
/// auto Y() -> int {}
/// \endcode
AST_MATCHER(FunctionDecl, hasTrailingReturn) {
  if (const auto *F = Node.getType()->getAs<FunctionProtoType>())
    return F->hasTrailingReturn();
  return false;
}

/// Matches expressions that match InnerMatcher that are possibly wrapped in an
/// elidable constructor and other corresponding bookkeeping nodes.
///
/// In C++17, elidable copy constructors are no longer being generated in the
/// AST as it is not permitted by the standard. They are, however, part of the
/// AST in C++14 and earlier. So, a matcher must abstract over these differences
/// to work in all language modes. This matcher skips elidable constructor-call
/// AST nodes, `ExprWithCleanups` nodes wrapping elidable constructor-calls and
/// various implicit nodes inside the constructor calls, all of which will not
/// appear in the C++17 AST.
///
/// Given
///
/// \code
/// struct H {};
/// H G();
/// void f() {
///   H D = G();
/// }
/// \endcode
///
/// ``varDecl(hasInitializer(ignoringElidableConstructorCall(callExpr())))``
/// matches ``H D = G()`` in C++11 through C++17 (and beyond).
AST_MATCHER_P(Expr, ignoringElidableConstructorCall,
              ast_matchers::internal::Matcher<Expr>, InnerMatcher) {
  // E tracks the node that we are examining.
  const Expr *E = &Node;
  // If present, remove an outer `ExprWithCleanups` corresponding to the
  // underlying `CXXConstructExpr`. This check won't cover all cases of added
  // `ExprWithCleanups` corresponding to `CXXConstructExpr` nodes (because the
  // EWC is placed on the outermost node of the expression, which this may not
  // be), but, it still improves the coverage of this matcher.
  if (const auto *CleanupsExpr = dyn_cast<ExprWithCleanups>(&Node))
    E = CleanupsExpr->getSubExpr();
  if (const auto *CtorExpr = dyn_cast<CXXConstructExpr>(E)) {
    if (CtorExpr->isElidable()) {
      if (const auto *MaterializeTemp =
              dyn_cast<MaterializeTemporaryExpr>(CtorExpr->getArg(0))) {
        return InnerMatcher.matches(*MaterializeTemp->getSubExpr(), Finder,
                                    Builder);
      }
    }
  }
  return InnerMatcher.matches(Node, Finder, Builder);
}

//----------------------------------------------------------------------------//
// OpenMP handling.
//----------------------------------------------------------------------------//

/// Matches any ``#pragma omp`` executable directive.
///
/// Given
///
/// \code
///   #pragma omp parallel
///   #pragma omp parallel default(none)
///   #pragma omp taskyield
/// \endcode
///
/// ``ompExecutableDirective()`` matches ``omp parallel``,
/// ``omp parallel default(none)`` and ``omp taskyield``.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, OMPExecutableDirective>
    ompExecutableDirective;

/// Matches standalone OpenMP directives,
/// i.e., directives that can't have a structured block.
///
/// Given
///
/// \code
///   #pragma omp parallel
///   {}
///   #pragma omp taskyield
/// \endcode
///
/// ``ompExecutableDirective(isStandaloneDirective()))`` matches
/// ``omp taskyield``.
AST_MATCHER(OMPExecutableDirective, isStandaloneDirective) {
  return Node.isStandaloneDirective();
}

/// Matches the structured-block of the OpenMP executable directive
///
/// Prerequisite: the executable directive must not be standalone directive.
/// If it is, it will never match.
///
/// Given
///
/// \code
///    #pragma omp parallel
///    ;
///    #pragma omp parallel
///    {}
/// \endcode
///
/// ``ompExecutableDirective(hasStructuredBlock(nullStmt()))`` will match ``;``
AST_MATCHER_P(OMPExecutableDirective, hasStructuredBlock,
              internal::Matcher<Stmt>, InnerMatcher) {
  if (Node.isStandaloneDirective())
    return false; // Standalone directives have no structured blocks.
  return InnerMatcher.matches(*Node.getStructuredBlock(), Finder, Builder);
}

/// Matches any clause in an OpenMP directive.
///
/// Given
///
/// \code
///   #pragma omp parallel
///   #pragma omp parallel default(none)
/// \endcode
///
/// ``ompExecutableDirective(hasAnyClause(anything()))`` matches
/// ``omp parallel default(none)``.
AST_MATCHER_P(OMPExecutableDirective, hasAnyClause,
              internal::Matcher<OMPClause>, InnerMatcher) {
  ArrayRef<OMPClause *> Clauses = Node.clauses();
  return matchesFirstInPointerRange(InnerMatcher, Clauses.begin(),
                                    Clauses.end(), Finder,
                                    Builder) != Clauses.end();
}

/// Matches OpenMP ``default`` clause.
///
/// Given
///
/// \code
///   #pragma omp parallel default(none)
///   #pragma omp parallel default(shared)
///   #pragma omp parallel default(private)
///   #pragma omp parallel default(firstprivate)
///   #pragma omp parallel
/// \endcode
///
/// ``ompDefaultClause()`` matches ``default(none)``, ``default(shared)``,
/// `` default(private)`` and ``default(firstprivate)``
extern const internal::VariadicDynCastAllOfMatcher<OMPClause, OMPDefaultClause>
    ompDefaultClause;

/// Matches if the OpenMP ``default`` clause has ``none`` kind specified.
///
/// Given
///
/// \code
///   #pragma omp parallel
///   #pragma omp parallel default(none)
///   #pragma omp parallel default(shared)
///   #pragma omp parallel default(private)
///   #pragma omp parallel default(firstprivate)
/// \endcode
///
/// ``ompDefaultClause(isNoneKind())`` matches only ``default(none)``.
AST_MATCHER(OMPDefaultClause, isNoneKind) {
  return Node.getDefaultKind() == llvm::omp::OMP_DEFAULT_none;
}

/// Matches if the OpenMP ``default`` clause has ``shared`` kind specified.
///
/// Given
///
/// \code
///   #pragma omp parallel
///   #pragma omp parallel default(none)
///   #pragma omp parallel default(shared)
///   #pragma omp parallel default(private)
///   #pragma omp parallel default(firstprivate)
/// \endcode
///
/// ``ompDefaultClause(isSharedKind())`` matches only ``default(shared)``.
AST_MATCHER(OMPDefaultClause, isSharedKind) {
  return Node.getDefaultKind() == llvm::omp::OMP_DEFAULT_shared;
}

/// Matches if the OpenMP ``default`` clause has ``private`` kind
/// specified.
///
/// Given
///
/// \code
///   #pragma omp parallel
///   #pragma omp parallel default(none)
///   #pragma omp parallel default(shared)
///   #pragma omp parallel default(private)
///   #pragma omp parallel default(firstprivate)
/// \endcode
///
/// ``ompDefaultClause(isPrivateKind())`` matches only
/// ``default(private)``.
AST_MATCHER(OMPDefaultClause, isPrivateKind) {
  return Node.getDefaultKind() == llvm::omp::OMP_DEFAULT_private;
}

/// Matches if the OpenMP ``default`` clause has ``firstprivate`` kind
/// specified.
///
/// Given
///
/// \code
///   #pragma omp parallel
///   #pragma omp parallel default(none)
///   #pragma omp parallel default(shared)
///   #pragma omp parallel default(private)
///   #pragma omp parallel default(firstprivate)
/// \endcode
///
/// ``ompDefaultClause(isFirstPrivateKind())`` matches only
/// ``default(firstprivate)``.
AST_MATCHER(OMPDefaultClause, isFirstPrivateKind) {
  return Node.getDefaultKind() == llvm::omp::OMP_DEFAULT_firstprivate;
}

/// Matches if the OpenMP directive is allowed to contain the specified OpenMP
/// clause kind.
///
/// Given
///
/// \code
///   #pragma omp parallel
///   #pragma omp parallel for
///   #pragma omp          for
/// \endcode
///
/// `ompExecutableDirective(isAllowedToContainClause(OMPC_default))`` matches
/// ``omp parallel`` and ``omp parallel for``.
///
/// If the matcher is use from clang-query, ``OpenMPClauseKind`` parameter
/// should be passed as a quoted string. e.g.,
/// ``isAllowedToContainClauseKind("OMPC_default").``
AST_MATCHER_P(OMPExecutableDirective, isAllowedToContainClauseKind,
              OpenMPClauseKind, CKind) {
  return llvm::omp::isAllowedClauseForDirective(
      Node.getDirectiveKind(), CKind,
      Finder->getASTContext().getLangOpts().OpenMP);
}

//----------------------------------------------------------------------------//
// End OpenMP handling.
//----------------------------------------------------------------------------//

} // namespace ast_matchers
} // namespace clang

#endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERS_H
