//===- 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 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 if the call expression's callee's declaration matches the
/// given matcher.
///
/// Example matches y.x() (matcher = callExpr(callee(
///                                    cxxMethodDecl(hasName("x")))))
/// \code
///   class Y { public: void x(); };
///   void z() { Y y; y.x(); }
/// \endcode
AST_MATCHER_P_OVERLOAD(CallExpr, callee, internal::Matcher<Decl>, InnerMatcher,
                       1) {
  return callExpr(hasDeclaration(InnerMatcher)).matches(Node, Finder, Builder);
}

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