//===- 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<VarDecl>,
              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
