- //===- ASTMatchersInternal.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 
- // 
- //===----------------------------------------------------------------------===// 
- // 
- //  Implements the base layer of the matcher framework. 
- // 
- //  Matchers are methods that return a Matcher<T> which provides a method 
- //  Matches(...) which is a predicate on an AST node. The Matches method's 
- //  parameters define the context of the match, which allows matchers to recurse 
- //  or store the current node as bound to a specific string, so that it can be 
- //  retrieved later. 
- // 
- //  In general, matchers have two parts: 
- //  1. A function Matcher<T> MatcherName(<arguments>) which returns a Matcher<T> 
- //     based on the arguments and optionally on template type deduction based 
- //     on the arguments. Matcher<T>s form an implicit reverse hierarchy 
- //     to clang's AST class hierarchy, meaning that you can use a Matcher<Base> 
- //     everywhere a Matcher<Derived> is required. 
- //  2. An implementation of a class derived from MatcherInterface<T>. 
- // 
- //  The matcher functions are defined in ASTMatchers.h. To make it possible 
- //  to implement both the matcher function and the implementation of the matcher 
- //  interface in one place, ASTMatcherMacros.h defines macros that allow 
- //  implementing a matcher in a single place. 
- // 
- //  This file contains the base classes needed to construct the actual matchers. 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H 
- #define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H 
-   
- #include "clang/AST/ASTTypeTraits.h" 
- #include "clang/AST/Decl.h" 
- #include "clang/AST/DeclCXX.h" 
- #include "clang/AST/DeclFriend.h" 
- #include "clang/AST/DeclTemplate.h" 
- #include "clang/AST/Expr.h" 
- #include "clang/AST/ExprCXX.h" 
- #include "clang/AST/ExprObjC.h" 
- #include "clang/AST/NestedNameSpecifier.h" 
- #include "clang/AST/Stmt.h" 
- #include "clang/AST/TemplateName.h" 
- #include "clang/AST/Type.h" 
- #include "clang/AST/TypeLoc.h" 
- #include "clang/Basic/LLVM.h" 
- #include "clang/Basic/OperatorKinds.h" 
- #include "llvm/ADT/APFloat.h" 
- #include "llvm/ADT/ArrayRef.h" 
- #include "llvm/ADT/IntrusiveRefCntPtr.h" 
- #include "llvm/ADT/STLExtras.h" 
- #include "llvm/ADT/SmallVector.h" 
- #include "llvm/ADT/StringRef.h" 
- #include "llvm/ADT/iterator.h" 
- #include "llvm/Support/Casting.h" 
- #include "llvm/Support/ManagedStatic.h" 
- #include "llvm/Support/Regex.h" 
- #include <algorithm> 
- #include <cassert> 
- #include <cstddef> 
- #include <cstdint> 
- #include <map> 
- #include <memory> 
- #include <optional> 
- #include <string> 
- #include <tuple> 
- #include <type_traits> 
- #include <utility> 
- #include <vector> 
-   
- namespace clang { 
-   
- class ASTContext; 
-   
- namespace ast_matchers { 
-   
- class BoundNodes; 
-   
- namespace internal { 
-   
- /// A type-list implementation. 
- /// 
- /// A "linked list" of types, accessible by using the ::head and ::tail 
- /// typedefs. 
- template <typename... Ts> struct TypeList {}; // Empty sentinel type list. 
-   
- template <typename T1, typename... Ts> struct TypeList<T1, Ts...> { 
-   /// The first type on the list. 
-   using head = T1; 
-   
-   /// A sublist with the tail. ie everything but the head. 
-   /// 
-   /// This type is used to do recursion. TypeList<>/EmptyTypeList indicates the 
-   /// end of the list. 
-   using tail = TypeList<Ts...>; 
- }; 
-   
- /// The empty type list. 
- using EmptyTypeList = TypeList<>; 
-   
- /// Helper meta-function to determine if some type \c T is present or 
- ///   a parent type in the list. 
- template <typename AnyTypeList, typename T> struct TypeListContainsSuperOf { 
-   static const bool value = 
-       std::is_base_of<typename AnyTypeList::head, T>::value || 
-       TypeListContainsSuperOf<typename AnyTypeList::tail, T>::value; 
- }; 
- template <typename T> struct TypeListContainsSuperOf<EmptyTypeList, T> { 
-   static const bool value = false; 
- }; 
-   
- /// Variadic function object. 
- /// 
- /// Most of the functions below that use VariadicFunction could be implemented 
- /// using plain C++11 variadic functions, but the function object allows us to 
- /// capture it on the dynamic matcher registry. 
- template <typename ResultT, typename ArgT, 
-           ResultT (*Func)(ArrayRef<const ArgT *>)> 
- struct VariadicFunction { 
-   ResultT operator()() const { return Func(std::nullopt); } 
-   
-   template <typename... ArgsT> 
-   ResultT operator()(const ArgT &Arg1, const ArgsT &... Args) const { 
-     return Execute(Arg1, static_cast<const ArgT &>(Args)...); 
-   } 
-   
-   // We also allow calls with an already created array, in case the caller 
-   // already had it. 
-   ResultT operator()(ArrayRef<ArgT> Args) const { 
-     return Func(llvm::to_vector<8>(llvm::make_pointer_range(Args))); 
-   } 
-   
- private: 
-   // Trampoline function to allow for implicit conversions to take place 
-   // before we make the array. 
-   template <typename... ArgsT> ResultT Execute(const ArgsT &... Args) const { 
-     const ArgT *const ArgsArray[] = {&Args...}; 
-     return Func(ArrayRef<const ArgT *>(ArgsArray, sizeof...(ArgsT))); 
-   } 
- }; 
-   
- /// Unifies obtaining the underlying type of a regular node through 
- /// `getType` and a TypedefNameDecl node through `getUnderlyingType`. 
- inline QualType getUnderlyingType(const Expr &Node) { return Node.getType(); } 
-   
- inline QualType getUnderlyingType(const ValueDecl &Node) { 
-   return Node.getType(); 
- } 
- inline QualType getUnderlyingType(const TypedefNameDecl &Node) { 
-   return Node.getUnderlyingType(); 
- } 
- inline QualType getUnderlyingType(const FriendDecl &Node) { 
-   if (const TypeSourceInfo *TSI = Node.getFriendType()) 
-     return TSI->getType(); 
-   return QualType(); 
- } 
- inline QualType getUnderlyingType(const CXXBaseSpecifier &Node) { 
-   return Node.getType(); 
- } 
-   
- /// Unifies obtaining a `TypeSourceInfo` from different node types. 
- template <typename T, 
-           std::enable_if_t<TypeListContainsSuperOf< 
-               TypeList<CXXBaseSpecifier, CXXCtorInitializer, 
-                        CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr, 
-                        CompoundLiteralExpr, DeclaratorDecl, ObjCPropertyDecl, 
-                        TemplateArgumentLoc, TypedefNameDecl>, 
-               T>::value> * = nullptr> 
- inline TypeSourceInfo *GetTypeSourceInfo(const T &Node) { 
-   return Node.getTypeSourceInfo(); 
- } 
- template <typename T, 
-           std::enable_if_t<TypeListContainsSuperOf< 
-               TypeList<CXXFunctionalCastExpr, ExplicitCastExpr>, T>::value> * = 
-               nullptr> 
- inline TypeSourceInfo *GetTypeSourceInfo(const T &Node) { 
-   return Node.getTypeInfoAsWritten(); 
- } 
- inline TypeSourceInfo *GetTypeSourceInfo(const BlockDecl &Node) { 
-   return Node.getSignatureAsWritten(); 
- } 
- inline TypeSourceInfo *GetTypeSourceInfo(const CXXNewExpr &Node) { 
-   return Node.getAllocatedTypeSourceInfo(); 
- } 
- inline TypeSourceInfo * 
- GetTypeSourceInfo(const ClassTemplateSpecializationDecl &Node) { 
-   return Node.getTypeAsWritten(); 
- } 
-   
- /// Unifies obtaining the FunctionProtoType pointer from both 
- /// FunctionProtoType and FunctionDecl nodes.. 
- inline const FunctionProtoType * 
- getFunctionProtoType(const FunctionProtoType &Node) { 
-   return &Node; 
- } 
-   
- inline const FunctionProtoType *getFunctionProtoType(const FunctionDecl &Node) { 
-   return Node.getType()->getAs<FunctionProtoType>(); 
- } 
-   
- /// Unifies obtaining the access specifier from Decl and CXXBaseSpecifier nodes. 
- inline clang::AccessSpecifier getAccessSpecifier(const Decl &Node) { 
-   return Node.getAccess(); 
- } 
-   
- inline clang::AccessSpecifier getAccessSpecifier(const CXXBaseSpecifier &Node) { 
-   return Node.getAccessSpecifier(); 
- } 
-   
- /// Internal version of BoundNodes. Holds all the bound nodes. 
- class BoundNodesMap { 
- public: 
-   /// Adds \c Node to the map with key \c ID. 
-   /// 
-   /// The node's base type should be in NodeBaseType or it will be unaccessible. 
-   void addNode(StringRef ID, const DynTypedNode &DynNode) { 
-     NodeMap[std::string(ID)] = DynNode; 
-   } 
-   
-   /// 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 { 
-     IDToNodeMap::const_iterator It = NodeMap.find(ID); 
-     if (It == NodeMap.end()) { 
-       return nullptr; 
-     } 
-     return It->second.get<T>(); 
-   } 
-   
-   DynTypedNode getNode(StringRef ID) const { 
-     IDToNodeMap::const_iterator It = NodeMap.find(ID); 
-     if (It == NodeMap.end()) { 
-       return DynTypedNode(); 
-     } 
-     return It->second; 
-   } 
-   
-   /// Imposes an order on BoundNodesMaps. 
-   bool operator<(const BoundNodesMap &Other) const { 
-     return NodeMap < Other.NodeMap; 
-   } 
-   
-   /// A map from IDs to the bound nodes. 
-   /// 
-   /// Note that we're using std::map here, as for memoization: 
-   /// - we need a comparison operator 
-   /// - we need an assignment operator 
-   using IDToNodeMap = std::map<std::string, DynTypedNode, std::less<>>; 
-   
-   const IDToNodeMap &getMap() const { 
-     return NodeMap; 
-   } 
-   
-   /// Returns \c true if this \c BoundNodesMap can be compared, i.e. all 
-   /// stored nodes have memoization data. 
-   bool isComparable() const { 
-     for (const auto &IDAndNode : NodeMap) { 
-       if (!IDAndNode.second.getMemoizationData()) 
-         return false; 
-     } 
-     return true; 
-   } 
-   
- private: 
-   IDToNodeMap NodeMap; 
- }; 
-   
- /// Creates BoundNodesTree objects. 
- /// 
- /// The tree builder is used during the matching process to insert the bound 
- /// nodes from the Id matcher. 
- class BoundNodesTreeBuilder { 
- public: 
-   /// A visitor interface to visit all BoundNodes results for a 
-   /// BoundNodesTree. 
-   class Visitor { 
-   public: 
-     virtual ~Visitor() = default; 
-   
-     /// Called multiple times during a single call to VisitMatches(...). 
-     /// 
-     /// 'BoundNodesView' contains the bound nodes for a single match. 
-     virtual void visitMatch(const BoundNodes& BoundNodesView) = 0; 
-   }; 
-   
-   /// Add a binding from an id to a node. 
-   void setBinding(StringRef Id, const DynTypedNode &DynNode) { 
-     if (Bindings.empty()) 
-       Bindings.emplace_back(); 
-     for (BoundNodesMap &Binding : Bindings) 
-       Binding.addNode(Id, DynNode); 
-   } 
-   
-   /// Adds a branch in the tree. 
-   void addMatch(const BoundNodesTreeBuilder &Bindings); 
-   
-   /// Visits all matches that this BoundNodesTree represents. 
-   /// 
-   /// The ownership of 'ResultVisitor' remains at the caller. 
-   void visitMatches(Visitor* ResultVisitor); 
-   
-   template <typename ExcludePredicate> 
-   bool removeBindings(const ExcludePredicate &Predicate) { 
-     llvm::erase_if(Bindings, Predicate); 
-     return !Bindings.empty(); 
-   } 
-   
-   /// Imposes an order on BoundNodesTreeBuilders. 
-   bool operator<(const BoundNodesTreeBuilder &Other) const { 
-     return Bindings < Other.Bindings; 
-   } 
-   
-   /// Returns \c true if this \c BoundNodesTreeBuilder can be compared, 
-   /// i.e. all stored node maps have memoization data. 
-   bool isComparable() const { 
-     for (const BoundNodesMap &NodesMap : Bindings) { 
-       if (!NodesMap.isComparable()) 
-         return false; 
-     } 
-     return true; 
-   } 
-   
- private: 
-   SmallVector<BoundNodesMap, 1> Bindings; 
- }; 
-   
- class ASTMatchFinder; 
-   
- /// Generic interface for all matchers. 
- /// 
- /// Used by the implementation of Matcher<T> and DynTypedMatcher. 
- /// In general, implement MatcherInterface<T> or SingleNodeMatcherInterface<T> 
- /// instead. 
- class DynMatcherInterface 
-     : public llvm::ThreadSafeRefCountedBase<DynMatcherInterface> { 
- public: 
-   virtual ~DynMatcherInterface() = default; 
-   
-   /// Returns true if \p DynNode can be matched. 
-   /// 
-   /// May bind \p DynNode to an ID via \p Builder, or recurse into 
-   /// the AST via \p Finder. 
-   virtual bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder, 
-                           BoundNodesTreeBuilder *Builder) const = 0; 
-   
-   virtual std::optional<clang::TraversalKind> TraversalKind() const { 
-     return std::nullopt; 
-   } 
- }; 
-   
- /// Generic interface for matchers on an AST node of type T. 
- /// 
- /// Implement this if your matcher may need to inspect the children or 
- /// descendants of the node or bind matched nodes to names. If you are 
- /// writing a simple matcher that only inspects properties of the 
- /// current node and doesn't care about its children or descendants, 
- /// implement SingleNodeMatcherInterface instead. 
- template <typename T> 
- class MatcherInterface : public DynMatcherInterface { 
- public: 
-   /// Returns true if 'Node' can be matched. 
-   /// 
-   /// May bind 'Node' to an ID via 'Builder', or recurse into 
-   /// the AST via 'Finder'. 
-   virtual bool matches(const T &Node, 
-                        ASTMatchFinder *Finder, 
-                        BoundNodesTreeBuilder *Builder) const = 0; 
-   
-   bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder, 
-                   BoundNodesTreeBuilder *Builder) const override { 
-     return matches(DynNode.getUnchecked<T>(), Finder, Builder); 
-   } 
- }; 
-   
- /// Interface for matchers that only evaluate properties on a single 
- /// node. 
- template <typename T> 
- class SingleNodeMatcherInterface : public MatcherInterface<T> { 
- public: 
-   /// Returns true if the matcher matches the provided node. 
-   /// 
-   /// A subclass must implement this instead of Matches(). 
-   virtual bool matchesNode(const T &Node) const = 0; 
-   
- private: 
-   /// Implements MatcherInterface::Matches. 
-   bool matches(const T &Node, 
-                ASTMatchFinder * /* Finder */, 
-                BoundNodesTreeBuilder * /*  Builder */) const override { 
-     return matchesNode(Node); 
-   } 
- }; 
-   
- template <typename> class Matcher; 
-   
- /// Matcher that works on a \c DynTypedNode. 
- /// 
- /// It is constructed from a \c Matcher<T> object and redirects most calls to 
- /// underlying matcher. 
- /// It checks whether the \c DynTypedNode is convertible into the type of the 
- /// underlying matcher and then do the actual match on the actual node, or 
- /// return false if it is not convertible. 
- class DynTypedMatcher { 
- public: 
-   /// Takes ownership of the provided implementation pointer. 
-   template <typename T> 
-   DynTypedMatcher(MatcherInterface<T> *Implementation) 
-       : SupportedKind(ASTNodeKind::getFromNodeKind<T>()), 
-         RestrictKind(SupportedKind), Implementation(Implementation) {} 
-   
-   /// Construct from a variadic function. 
-   enum VariadicOperator { 
-     /// Matches nodes for which all provided matchers match. 
-     VO_AllOf, 
-   
-     /// Matches nodes for which at least one of the provided matchers 
-     /// matches. 
-     VO_AnyOf, 
-   
-     /// Matches nodes for which at least one of the provided matchers 
-     /// matches, but doesn't stop at the first match. 
-     VO_EachOf, 
-   
-     /// Matches any node but executes all inner matchers to find result 
-     /// bindings. 
-     VO_Optionally, 
-   
-     /// Matches nodes that do not match the provided matcher. 
-     /// 
-     /// Uses the variadic matcher interface, but fails if 
-     /// InnerMatchers.size() != 1. 
-     VO_UnaryNot 
-   }; 
-   
-   static DynTypedMatcher 
-   constructVariadic(VariadicOperator Op, ASTNodeKind SupportedKind, 
-                     std::vector<DynTypedMatcher> InnerMatchers); 
-   
-   static DynTypedMatcher 
-   constructRestrictedWrapper(const DynTypedMatcher &InnerMatcher, 
-                              ASTNodeKind RestrictKind); 
-   
-   /// Get a "true" matcher for \p NodeKind. 
-   /// 
-   /// It only checks that the node is of the right kind. 
-   static DynTypedMatcher trueMatcher(ASTNodeKind NodeKind); 
-   
-   void setAllowBind(bool AB) { AllowBind = AB; } 
-   
-   /// Check whether this matcher could ever match a node of kind \p Kind. 
-   /// \return \c false if this matcher will never match such a node. Otherwise, 
-   /// return \c true. 
-   bool canMatchNodesOfKind(ASTNodeKind Kind) const; 
-   
-   /// Return a matcher that points to the same implementation, but 
-   ///   restricts the node types for \p Kind. 
-   DynTypedMatcher dynCastTo(const ASTNodeKind Kind) const; 
-   
-   /// Return a matcher that points to the same implementation, but sets the 
-   ///   traversal kind. 
-   /// 
-   /// If the traversal kind is already set, then \c TK overrides it. 
-   DynTypedMatcher withTraversalKind(TraversalKind TK); 
-   
-   /// Returns true if the matcher matches the given \c DynNode. 
-   bool matches(const DynTypedNode &DynNode, ASTMatchFinder *Finder, 
-                BoundNodesTreeBuilder *Builder) const; 
-   
-   /// Same as matches(), but skips the kind check. 
-   /// 
-   /// It is faster, but the caller must ensure the node is valid for the 
-   /// kind of this matcher. 
-   bool matchesNoKindCheck(const DynTypedNode &DynNode, ASTMatchFinder *Finder, 
-                           BoundNodesTreeBuilder *Builder) const; 
-   
-   /// Bind the specified \p ID to the matcher. 
-   /// \return A new matcher with the \p ID bound to it if this matcher supports 
-   ///   binding. Otherwise, returns an empty \c std::optional<>. 
-   std::optional<DynTypedMatcher> tryBind(StringRef ID) const; 
-   
-   /// Returns a unique \p ID for the matcher. 
-   /// 
-   /// Casting a Matcher<T> to Matcher<U> creates a matcher that has the 
-   /// same \c Implementation pointer, but different \c RestrictKind. We need to 
-   /// include both in the ID to make it unique. 
-   /// 
-   /// \c MatcherIDType supports operator< and provides strict weak ordering. 
-   using MatcherIDType = std::pair<ASTNodeKind, uint64_t>; 
-   MatcherIDType getID() const { 
-     /// FIXME: Document the requirements this imposes on matcher 
-     /// implementations (no new() implementation_ during a Matches()). 
-     return std::make_pair(RestrictKind, 
-                           reinterpret_cast<uint64_t>(Implementation.get())); 
-   } 
-   
-   /// Returns the type this matcher works on. 
-   /// 
-   /// \c matches() will always return false unless the node passed is of this 
-   /// or a derived type. 
-   ASTNodeKind getSupportedKind() const { return SupportedKind; } 
-   
-   /// Returns \c true if the passed \c DynTypedMatcher can be converted 
-   ///   to a \c Matcher<T>. 
-   /// 
-   /// This method verifies that the underlying matcher in \c Other can process 
-   /// nodes of types T. 
-   template <typename T> bool canConvertTo() const { 
-     return canConvertTo(ASTNodeKind::getFromNodeKind<T>()); 
-   } 
-   bool canConvertTo(ASTNodeKind To) const; 
-   
-   /// Construct a \c Matcher<T> interface around the dynamic matcher. 
-   /// 
-   /// This method asserts that \c canConvertTo() is \c true. Callers 
-   /// should call \c canConvertTo() first to make sure that \c this is 
-   /// compatible with T. 
-   template <typename T> Matcher<T> convertTo() const { 
-     assert(canConvertTo<T>()); 
-     return unconditionalConvertTo<T>(); 
-   } 
-   
-   /// Same as \c convertTo(), but does not check that the underlying 
-   ///   matcher can handle a value of T. 
-   /// 
-   /// If it is not compatible, then this matcher will never match anything. 
-   template <typename T> Matcher<T> unconditionalConvertTo() const; 
-   
-   /// Returns the \c TraversalKind respected by calls to `match()`, if any. 
-   /// 
-   /// Most matchers will not have a traversal kind set, instead relying on the 
-   /// surrounding context. For those, \c std::nullopt is returned. 
-   std::optional<clang::TraversalKind> getTraversalKind() const { 
-     return Implementation->TraversalKind(); 
-   } 
-   
- private: 
-   DynTypedMatcher(ASTNodeKind SupportedKind, ASTNodeKind RestrictKind, 
-                   IntrusiveRefCntPtr<DynMatcherInterface> Implementation) 
-       : SupportedKind(SupportedKind), RestrictKind(RestrictKind), 
-         Implementation(std::move(Implementation)) {} 
-   
-   bool AllowBind = false; 
-   ASTNodeKind SupportedKind; 
-   
-   /// A potentially stricter node kind. 
-   /// 
-   /// It allows to perform implicit and dynamic cast of matchers without 
-   /// needing to change \c Implementation. 
-   ASTNodeKind RestrictKind; 
-   IntrusiveRefCntPtr<DynMatcherInterface> Implementation; 
- }; 
-   
- /// Wrapper of a MatcherInterface<T> *that allows copying. 
- /// 
- /// A Matcher<Base> can be used anywhere a Matcher<Derived> is 
- /// required. This establishes an is-a relationship which is reverse 
- /// to the AST hierarchy. In other words, Matcher<T> is contravariant 
- /// with respect to T. The relationship is built via a type conversion 
- /// operator rather than a type hierarchy to be able to templatize the 
- /// type hierarchy instead of spelling it out. 
- template <typename T> 
- class Matcher { 
- public: 
-   /// Takes ownership of the provided implementation pointer. 
-   explicit Matcher(MatcherInterface<T> *Implementation) 
-       : Implementation(Implementation) {} 
-   
-   /// Implicitly converts \c Other to a Matcher<T>. 
-   /// 
-   /// Requires \c T to be derived from \c From. 
-   template <typename From> 
-   Matcher(const Matcher<From> &Other, 
-           std::enable_if_t<std::is_base_of<From, T>::value && 
-                            !std::is_same<From, T>::value> * = nullptr) 
-       : Implementation(restrictMatcher(Other.Implementation)) { 
-     assert(Implementation.getSupportedKind().isSame( 
-         ASTNodeKind::getFromNodeKind<T>())); 
-   } 
-   
-   /// Implicitly converts \c Matcher<Type> to \c Matcher<QualType>. 
-   /// 
-   /// The resulting matcher is not strict, i.e. ignores qualifiers. 
-   template <typename TypeT> 
-   Matcher(const Matcher<TypeT> &Other, 
-           std::enable_if_t<std::is_same<T, QualType>::value && 
-                            std::is_same<TypeT, Type>::value> * = nullptr) 
-       : Implementation(new TypeToQualType<TypeT>(Other)) {} 
-   
-   /// Convert \c this into a \c Matcher<T> by applying dyn_cast<> to the 
-   /// argument. 
-   /// \c To must be a base class of \c T. 
-   template <typename To> Matcher<To> dynCastTo() const & { 
-     static_assert(std::is_base_of<To, T>::value, "Invalid dynCast call."); 
-     return Matcher<To>(Implementation); 
-   } 
-   
-   template <typename To> Matcher<To> dynCastTo() && { 
-     static_assert(std::is_base_of<To, T>::value, "Invalid dynCast call."); 
-     return Matcher<To>(std::move(Implementation)); 
-   } 
-   
-   /// Forwards the call to the underlying MatcherInterface<T> pointer. 
-   bool matches(const T &Node, 
-                ASTMatchFinder *Finder, 
-                BoundNodesTreeBuilder *Builder) const { 
-     return Implementation.matches(DynTypedNode::create(Node), Finder, Builder); 
-   } 
-   
-   /// Returns an ID that uniquely identifies the matcher. 
-   DynTypedMatcher::MatcherIDType getID() const { 
-     return Implementation.getID(); 
-   } 
-   
-   /// Extract the dynamic matcher. 
-   /// 
-   /// The returned matcher keeps the same restrictions as \c this and remembers 
-   /// that it is meant to support nodes of type \c T. 
-   operator DynTypedMatcher() const & { return Implementation; } 
-   
-   operator DynTypedMatcher() && { return std::move(Implementation); } 
-   
-   /// Allows the conversion of a \c Matcher<Type> to a \c 
-   /// Matcher<QualType>. 
-   /// 
-   /// Depending on the constructor argument, the matcher is either strict, i.e. 
-   /// does only matches in the absence of qualifiers, or not, i.e. simply 
-   /// ignores any qualifiers. 
-   template <typename TypeT> 
-   class TypeToQualType : public MatcherInterface<QualType> { 
-     const DynTypedMatcher InnerMatcher; 
-   
-   public: 
-     TypeToQualType(const Matcher<TypeT> &InnerMatcher) 
-         : InnerMatcher(InnerMatcher) {} 
-   
-     bool matches(const QualType &Node, ASTMatchFinder *Finder, 
-                  BoundNodesTreeBuilder *Builder) const override { 
-       if (Node.isNull()) 
-         return false; 
-       return this->InnerMatcher.matches(DynTypedNode::create(*Node), Finder, 
-                                         Builder); 
-     } 
-   
-     std::optional<clang::TraversalKind> TraversalKind() const override { 
-       return this->InnerMatcher.getTraversalKind(); 
-     } 
-   }; 
-   
- private: 
-   // For Matcher<T> <=> Matcher<U> conversions. 
-   template <typename U> friend class Matcher; 
-   
-   // For DynTypedMatcher::unconditionalConvertTo<T>. 
-   friend class DynTypedMatcher; 
-   
-   static DynTypedMatcher restrictMatcher(const DynTypedMatcher &Other) { 
-     return Other.dynCastTo(ASTNodeKind::getFromNodeKind<T>()); 
-   } 
-   
-   explicit Matcher(const DynTypedMatcher &Implementation) 
-       : Implementation(restrictMatcher(Implementation)) { 
-     assert(this->Implementation.getSupportedKind().isSame( 
-         ASTNodeKind::getFromNodeKind<T>())); 
-   } 
-   
-   DynTypedMatcher Implementation; 
- };  // class Matcher 
-   
- /// A convenient helper for creating a Matcher<T> without specifying 
- /// the template type argument. 
- template <typename T> 
- inline Matcher<T> makeMatcher(MatcherInterface<T> *Implementation) { 
-   return Matcher<T>(Implementation); 
- } 
-   
- /// Interface that allows matchers to traverse the AST. 
- /// FIXME: Find a better name. 
- /// 
- /// This provides three entry methods for each base node type in the AST: 
- /// - \c matchesChildOf: 
- ///   Matches a matcher on every child node of the given node. Returns true 
- ///   if at least one child node could be matched. 
- /// - \c matchesDescendantOf: 
- ///   Matches a matcher on all descendant nodes of the given node. Returns true 
- ///   if at least one descendant matched. 
- /// - \c matchesAncestorOf: 
- ///   Matches a matcher on all ancestors of the given node. Returns true if 
- ///   at least one ancestor matched. 
- /// 
- /// FIXME: Currently we only allow Stmt and Decl nodes to start a traversal. 
- /// In the future, we want to implement this for all nodes for which it makes 
- /// sense. In the case of matchesAncestorOf, we'll want to implement it for 
- /// all nodes, as all nodes have ancestors. 
- class ASTMatchFinder { 
- public: 
-   /// Defines how bindings are processed on recursive matches. 
-   enum BindKind { 
-     /// Stop at the first match and only bind the first match. 
-     BK_First, 
-   
-     /// Create results for all combinations of bindings that match. 
-     BK_All 
-   }; 
-   
-   /// Defines which ancestors are considered for a match. 
-   enum AncestorMatchMode { 
-     /// All ancestors. 
-     AMM_All, 
-   
-     /// Direct parent only. 
-     AMM_ParentOnly 
-   }; 
-   
-   virtual ~ASTMatchFinder() = default; 
-   
-   /// Returns true if the given C++ class is directly or indirectly derived 
-   /// from a base type matching \c base. 
-   /// 
-   /// A class is not considered to be derived from itself. 
-   virtual bool classIsDerivedFrom(const CXXRecordDecl *Declaration, 
-                                   const Matcher<NamedDecl> &Base, 
-                                   BoundNodesTreeBuilder *Builder, 
-                                   bool Directly) = 0; 
-   
-   /// Returns true if the given Objective-C class is directly or indirectly 
-   /// derived from a base class matching \c base. 
-   /// 
-   /// A class is not considered to be derived from itself. 
-   virtual bool objcClassIsDerivedFrom(const ObjCInterfaceDecl *Declaration, 
-                                       const Matcher<NamedDecl> &Base, 
-                                       BoundNodesTreeBuilder *Builder, 
-                                       bool Directly) = 0; 
-   
-   template <typename T> 
-   bool matchesChildOf(const T &Node, const DynTypedMatcher &Matcher, 
-                       BoundNodesTreeBuilder *Builder, BindKind Bind) { 
-     static_assert(std::is_base_of<Decl, T>::value || 
-                       std::is_base_of<Stmt, T>::value || 
-                       std::is_base_of<NestedNameSpecifier, T>::value || 
-                       std::is_base_of<NestedNameSpecifierLoc, T>::value || 
-                       std::is_base_of<TypeLoc, T>::value || 
-                       std::is_base_of<QualType, T>::value || 
-                       std::is_base_of<Attr, T>::value, 
-                   "unsupported type for recursive matching"); 
-     return matchesChildOf(DynTypedNode::create(Node), getASTContext(), Matcher, 
-                           Builder, Bind); 
-   } 
-   
-   template <typename T> 
-   bool matchesDescendantOf(const T &Node, const DynTypedMatcher &Matcher, 
-                            BoundNodesTreeBuilder *Builder, BindKind Bind) { 
-     static_assert(std::is_base_of<Decl, T>::value || 
-                       std::is_base_of<Stmt, T>::value || 
-                       std::is_base_of<NestedNameSpecifier, T>::value || 
-                       std::is_base_of<NestedNameSpecifierLoc, T>::value || 
-                       std::is_base_of<TypeLoc, T>::value || 
-                       std::is_base_of<QualType, T>::value || 
-                       std::is_base_of<Attr, T>::value, 
-                   "unsupported type for recursive matching"); 
-     return matchesDescendantOf(DynTypedNode::create(Node), getASTContext(), 
-                                Matcher, Builder, Bind); 
-   } 
-   
-   // FIXME: Implement support for BindKind. 
-   template <typename T> 
-   bool matchesAncestorOf(const T &Node, const DynTypedMatcher &Matcher, 
-                          BoundNodesTreeBuilder *Builder, 
-                          AncestorMatchMode MatchMode) { 
-     static_assert(std::is_base_of<Decl, T>::value || 
-                       std::is_base_of<NestedNameSpecifierLoc, T>::value || 
-                       std::is_base_of<Stmt, T>::value || 
-                       std::is_base_of<TypeLoc, T>::value || 
-                       std::is_base_of<Attr, T>::value, 
-                   "type not allowed for recursive matching"); 
-     return matchesAncestorOf(DynTypedNode::create(Node), getASTContext(), 
-                              Matcher, Builder, MatchMode); 
-   } 
-   
-   virtual ASTContext &getASTContext() const = 0; 
-   
-   virtual bool IsMatchingInASTNodeNotSpelledInSource() const = 0; 
-   
-   virtual bool IsMatchingInASTNodeNotAsIs() const = 0; 
-   
-   bool isTraversalIgnoringImplicitNodes() const; 
-   
- protected: 
-   virtual bool matchesChildOf(const DynTypedNode &Node, ASTContext &Ctx, 
-                               const DynTypedMatcher &Matcher, 
-                               BoundNodesTreeBuilder *Builder, 
-                               BindKind Bind) = 0; 
-   
-   virtual bool matchesDescendantOf(const DynTypedNode &Node, ASTContext &Ctx, 
-                                    const DynTypedMatcher &Matcher, 
-                                    BoundNodesTreeBuilder *Builder, 
-                                    BindKind Bind) = 0; 
-   
-   virtual bool matchesAncestorOf(const DynTypedNode &Node, ASTContext &Ctx, 
-                                  const DynTypedMatcher &Matcher, 
-                                  BoundNodesTreeBuilder *Builder, 
-                                  AncestorMatchMode MatchMode) = 0; 
- private: 
-   friend struct ASTChildrenNotSpelledInSourceScope; 
-   virtual bool isMatchingChildrenNotSpelledInSource() const = 0; 
-   virtual void setMatchingChildrenNotSpelledInSource(bool Set) = 0; 
- }; 
-   
- struct ASTChildrenNotSpelledInSourceScope { 
-   ASTChildrenNotSpelledInSourceScope(ASTMatchFinder *V, bool B) 
-       : MV(V), MB(V->isMatchingChildrenNotSpelledInSource()) { 
-     V->setMatchingChildrenNotSpelledInSource(B); 
-   } 
-   ~ASTChildrenNotSpelledInSourceScope() { 
-     MV->setMatchingChildrenNotSpelledInSource(MB); 
-   } 
-   
- private: 
-   ASTMatchFinder *MV; 
-   bool MB; 
- }; 
-   
- /// Specialization of the conversion functions for QualType. 
- /// 
- /// This specialization provides the Matcher<Type>->Matcher<QualType> 
- /// conversion that the static API does. 
- template <> 
- inline Matcher<QualType> DynTypedMatcher::convertTo<QualType>() const { 
-   assert(canConvertTo<QualType>()); 
-   const ASTNodeKind SourceKind = getSupportedKind(); 
-   if (SourceKind.isSame(ASTNodeKind::getFromNodeKind<Type>())) { 
-     // We support implicit conversion from Matcher<Type> to Matcher<QualType> 
-     return unconditionalConvertTo<Type>(); 
-   } 
-   return unconditionalConvertTo<QualType>(); 
- } 
-   
- /// Finds the first node in a range that matches the given matcher. 
- template <typename MatcherT, typename IteratorT> 
- IteratorT matchesFirstInRange(const MatcherT &Matcher, IteratorT Start, 
-                               IteratorT End, ASTMatchFinder *Finder, 
-                               BoundNodesTreeBuilder *Builder) { 
-   for (IteratorT I = Start; I != End; ++I) { 
-     BoundNodesTreeBuilder Result(*Builder); 
-     if (Matcher.matches(*I, Finder, &Result)) { 
-       *Builder = std::move(Result); 
-       return I; 
-     } 
-   } 
-   return End; 
- } 
-   
- /// Finds the first node in a pointer range that matches the given 
- /// matcher. 
- template <typename MatcherT, typename IteratorT> 
- IteratorT matchesFirstInPointerRange(const MatcherT &Matcher, IteratorT Start, 
-                                      IteratorT End, ASTMatchFinder *Finder, 
-                                      BoundNodesTreeBuilder *Builder) { 
-   for (IteratorT I = Start; I != End; ++I) { 
-     BoundNodesTreeBuilder Result(*Builder); 
-     if (Matcher.matches(**I, Finder, &Result)) { 
-       *Builder = std::move(Result); 
-       return I; 
-     } 
-   } 
-   return End; 
- } 
-   
- template <typename T, std::enable_if_t<!std::is_base_of<FunctionDecl, T>::value> 
-                           * = nullptr> 
- inline bool isDefaultedHelper(const T *) { 
-   return false; 
- } 
- inline bool isDefaultedHelper(const FunctionDecl *FD) { 
-   return FD->isDefaulted(); 
- } 
-   
- // Metafunction to determine if type T has a member called getDecl. 
- template <typename Ty> 
- class has_getDecl { 
-   using yes = char[1]; 
-   using no = char[2]; 
-   
-   template <typename Inner> 
-   static yes& test(Inner *I, decltype(I->getDecl()) * = nullptr); 
-   
-   template <typename> 
-   static no& test(...); 
-   
- public: 
-   static const bool value = sizeof(test<Ty>(nullptr)) == sizeof(yes); 
- }; 
-   
- /// Matches overloaded operators with a specific name. 
- /// 
- /// The type argument ArgT is not used by this matcher but is used by 
- /// PolymorphicMatcher and should be StringRef. 
- template <typename T, typename ArgT> 
- class HasOverloadedOperatorNameMatcher : public SingleNodeMatcherInterface<T> { 
-   static_assert(std::is_same<T, CXXOperatorCallExpr>::value || 
-                 std::is_base_of<FunctionDecl, T>::value, 
-                 "unsupported class for matcher"); 
-   static_assert(std::is_same<ArgT, std::vector<std::string>>::value, 
-                 "argument type must be std::vector<std::string>"); 
-   
- public: 
-   explicit HasOverloadedOperatorNameMatcher(std::vector<std::string> Names) 
-       : SingleNodeMatcherInterface<T>(), Names(std::move(Names)) {} 
-   
-   bool matchesNode(const T &Node) const override { 
-     return matchesSpecialized(Node); 
-   } 
-   
- private: 
-   
-   /// CXXOperatorCallExpr exist only for calls to overloaded operators 
-   /// so this function returns true if the call is to an operator of the given 
-   /// name. 
-   bool matchesSpecialized(const CXXOperatorCallExpr &Node) const { 
-     return llvm::is_contained(Names, getOperatorSpelling(Node.getOperator())); 
-   } 
-   
-   /// Returns true only if CXXMethodDecl represents an overloaded 
-   /// operator and has the given operator name. 
-   bool matchesSpecialized(const FunctionDecl &Node) const { 
-     return Node.isOverloadedOperator() && 
-            llvm::is_contained( 
-                Names, getOperatorSpelling(Node.getOverloadedOperator())); 
-   } 
-   
-   std::vector<std::string> Names; 
- }; 
-   
- /// Matches named declarations with a specific name. 
- /// 
- /// See \c hasName() and \c hasAnyName() in ASTMatchers.h for details. 
- class HasNameMatcher : public SingleNodeMatcherInterface<NamedDecl> { 
-  public: 
-   explicit HasNameMatcher(std::vector<std::string> Names); 
-   
-   bool matchesNode(const NamedDecl &Node) const override; 
-   
- private: 
-   /// Unqualified match routine. 
-   /// 
-   /// It is much faster than the full match, but it only works for unqualified 
-   /// matches. 
-   bool matchesNodeUnqualified(const NamedDecl &Node) const; 
-   
-   /// Full match routine 
-   /// 
-   /// Fast implementation for the simple case of a named declaration at 
-   /// namespace or RecordDecl scope. 
-   /// It is slower than matchesNodeUnqualified, but faster than 
-   /// matchesNodeFullSlow. 
-   bool matchesNodeFullFast(const NamedDecl &Node) const; 
-   
-   /// Full match routine 
-   /// 
-   /// It generates the fully qualified name of the declaration (which is 
-   /// expensive) before trying to match. 
-   /// It is slower but simple and works on all cases. 
-   bool matchesNodeFullSlow(const NamedDecl &Node) const; 
-   
-   bool UseUnqualifiedMatch; 
-   std::vector<std::string> Names; 
- }; 
-   
- /// Trampoline function to use VariadicFunction<> to construct a 
- ///        HasNameMatcher. 
- Matcher<NamedDecl> hasAnyNameFunc(ArrayRef<const StringRef *> NameRefs); 
-   
- /// Trampoline function to use VariadicFunction<> to construct a 
- ///        hasAnySelector matcher. 
- Matcher<ObjCMessageExpr> hasAnySelectorFunc( 
-     ArrayRef<const StringRef *> NameRefs); 
-   
- /// Matches declarations for QualType and CallExpr. 
- /// 
- /// Type argument DeclMatcherT is required by PolymorphicMatcher but 
- /// not actually used. 
- template <typename T, typename DeclMatcherT> 
- class HasDeclarationMatcher : public MatcherInterface<T> { 
-   static_assert(std::is_same<DeclMatcherT, Matcher<Decl>>::value, 
-                 "instantiated with wrong types"); 
-   
-   DynTypedMatcher InnerMatcher; 
-   
- public: 
-   explicit HasDeclarationMatcher(const Matcher<Decl> &InnerMatcher) 
-       : InnerMatcher(InnerMatcher) {} 
-   
-   bool matches(const T &Node, ASTMatchFinder *Finder, 
-                BoundNodesTreeBuilder *Builder) const override { 
-     return matchesSpecialized(Node, Finder, Builder); 
-   } 
-   
- private: 
-   /// Forwards to matching on the underlying type of the QualType. 
-   bool matchesSpecialized(const QualType &Node, ASTMatchFinder *Finder, 
-                           BoundNodesTreeBuilder *Builder) const { 
-     if (Node.isNull()) 
-       return false; 
-   
-     return matchesSpecialized(*Node, Finder, Builder); 
-   } 
-   
-   /// Finds the best declaration for a type and returns whether the inner 
-   /// matcher matches on it. 
-   bool matchesSpecialized(const Type &Node, ASTMatchFinder *Finder, 
-                           BoundNodesTreeBuilder *Builder) const { 
-     // DeducedType does not have declarations of its own, so 
-     // match the deduced type instead. 
-     if (const auto *S = dyn_cast<DeducedType>(&Node)) { 
-       QualType DT = S->getDeducedType(); 
-       return !DT.isNull() ? matchesSpecialized(*DT, Finder, Builder) : false; 
-     } 
-   
-     // First, for any types that have a declaration, extract the declaration and 
-     // match on it. 
-     if (const auto *S = dyn_cast<TagType>(&Node)) { 
-       return matchesDecl(S->getDecl(), Finder, Builder); 
-     } 
-     if (const auto *S = dyn_cast<InjectedClassNameType>(&Node)) { 
-       return matchesDecl(S->getDecl(), Finder, Builder); 
-     } 
-     if (const auto *S = dyn_cast<TemplateTypeParmType>(&Node)) { 
-       return matchesDecl(S->getDecl(), Finder, Builder); 
-     } 
-     if (const auto *S = dyn_cast<TypedefType>(&Node)) { 
-       return matchesDecl(S->getDecl(), Finder, Builder); 
-     } 
-     if (const auto *S = dyn_cast<UnresolvedUsingType>(&Node)) { 
-       return matchesDecl(S->getDecl(), Finder, Builder); 
-     } 
-     if (const auto *S = dyn_cast<ObjCObjectType>(&Node)) { 
-       return matchesDecl(S->getInterface(), Finder, Builder); 
-     } 
-   
-     // A SubstTemplateTypeParmType exists solely to mark a type substitution 
-     // on the instantiated template. As users usually want to match the 
-     // template parameter on the uninitialized template, we can always desugar 
-     // one level without loss of expressivness. 
-     // For example, given: 
-     //   template<typename T> struct X { T t; } class A {}; X<A> a; 
-     // The following matcher will match, which otherwise would not: 
-     //   fieldDecl(hasType(pointerType())). 
-     if (const auto *S = dyn_cast<SubstTemplateTypeParmType>(&Node)) { 
-       return matchesSpecialized(S->getReplacementType(), Finder, Builder); 
-     } 
-   
-     // For template specialization types, we want to match the template 
-     // declaration, as long as the type is still dependent, and otherwise the 
-     // declaration of the instantiated tag type. 
-     if (const auto *S = dyn_cast<TemplateSpecializationType>(&Node)) { 
-       if (!S->isTypeAlias() && S->isSugared()) { 
-         // If the template is non-dependent, we want to match the instantiated 
-         // tag type. 
-         // For example, given: 
-         //   template<typename T> struct X {}; X<int> a; 
-         // The following matcher will match, which otherwise would not: 
-         //   templateSpecializationType(hasDeclaration(cxxRecordDecl())). 
-         return matchesSpecialized(*S->desugar(), Finder, Builder); 
-       } 
-       // If the template is dependent or an alias, match the template 
-       // declaration. 
-       return matchesDecl(S->getTemplateName().getAsTemplateDecl(), Finder, 
-                          Builder); 
-     } 
-   
-     // FIXME: We desugar elaborated types. This makes the assumption that users 
-     // do never want to match on whether a type is elaborated - there are 
-     // arguments for both sides; for now, continue desugaring. 
-     if (const auto *S = dyn_cast<ElaboratedType>(&Node)) { 
-       return matchesSpecialized(S->desugar(), Finder, Builder); 
-     } 
-     // Similarly types found via using declarations. 
-     // These are *usually* meaningless sugar, and this matches the historical 
-     // behavior prior to the introduction of UsingType. 
-     if (const auto *S = dyn_cast<UsingType>(&Node)) { 
-       return matchesSpecialized(S->desugar(), Finder, Builder); 
-     } 
-     return false; 
-   } 
-   
-   /// Extracts the Decl the DeclRefExpr references and returns whether 
-   /// the inner matcher matches on it. 
-   bool matchesSpecialized(const DeclRefExpr &Node, ASTMatchFinder *Finder, 
-                           BoundNodesTreeBuilder *Builder) const { 
-     return matchesDecl(Node.getDecl(), Finder, Builder); 
-   } 
-   
-   /// Extracts the Decl of the callee of a CallExpr and returns whether 
-   /// the inner matcher matches on it. 
-   bool matchesSpecialized(const CallExpr &Node, ASTMatchFinder *Finder, 
-                           BoundNodesTreeBuilder *Builder) const { 
-     return matchesDecl(Node.getCalleeDecl(), Finder, Builder); 
-   } 
-   
-   /// Extracts the Decl of the constructor call and returns whether the 
-   /// inner matcher matches on it. 
-   bool matchesSpecialized(const CXXConstructExpr &Node, 
-                           ASTMatchFinder *Finder, 
-                           BoundNodesTreeBuilder *Builder) const { 
-     return matchesDecl(Node.getConstructor(), Finder, Builder); 
-   } 
-   
-   bool matchesSpecialized(const ObjCIvarRefExpr &Node, 
-                           ASTMatchFinder *Finder, 
-                           BoundNodesTreeBuilder *Builder) const { 
-     return matchesDecl(Node.getDecl(), Finder, Builder); 
-   } 
-   
-   /// Extracts the operator new of the new call and returns whether the 
-   /// inner matcher matches on it. 
-   bool matchesSpecialized(const CXXNewExpr &Node, 
-                           ASTMatchFinder *Finder, 
-                           BoundNodesTreeBuilder *Builder) const { 
-     return matchesDecl(Node.getOperatorNew(), Finder, Builder); 
-   } 
-   
-   /// Extracts the \c ValueDecl a \c MemberExpr refers to and returns 
-   /// whether the inner matcher matches on it. 
-   bool matchesSpecialized(const MemberExpr &Node, 
-                           ASTMatchFinder *Finder, 
-                           BoundNodesTreeBuilder *Builder) const { 
-     return matchesDecl(Node.getMemberDecl(), Finder, Builder); 
-   } 
-   
-   /// Extracts the \c LabelDecl a \c AddrLabelExpr refers to and returns 
-   /// whether the inner matcher matches on it. 
-   bool matchesSpecialized(const AddrLabelExpr &Node, 
-                           ASTMatchFinder *Finder, 
-                           BoundNodesTreeBuilder *Builder) const { 
-     return matchesDecl(Node.getLabel(), Finder, Builder); 
-   } 
-   
-   /// Extracts the declaration of a LabelStmt and returns whether the 
-   /// inner matcher matches on it. 
-   bool matchesSpecialized(const LabelStmt &Node, ASTMatchFinder *Finder, 
-                           BoundNodesTreeBuilder *Builder) const { 
-     return matchesDecl(Node.getDecl(), Finder, Builder); 
-   } 
-   
-   /// Returns whether the inner matcher \c Node. Returns false if \c Node 
-   /// is \c NULL. 
-   bool matchesDecl(const Decl *Node, ASTMatchFinder *Finder, 
-                    BoundNodesTreeBuilder *Builder) const { 
-     return Node != nullptr && 
-            !(Finder->isTraversalIgnoringImplicitNodes() && 
-              Node->isImplicit()) && 
-            this->InnerMatcher.matches(DynTypedNode::create(*Node), Finder, 
-                                       Builder); 
-   } 
- }; 
-   
- /// IsBaseType<T>::value is true if T is a "base" type in the AST 
- /// node class hierarchies. 
- template <typename T> 
- struct IsBaseType { 
-   static const bool value = 
-       std::is_same<T, Decl>::value || std::is_same<T, Stmt>::value || 
-       std::is_same<T, QualType>::value || std::is_same<T, Type>::value || 
-       std::is_same<T, TypeLoc>::value || 
-       std::is_same<T, NestedNameSpecifier>::value || 
-       std::is_same<T, NestedNameSpecifierLoc>::value || 
-       std::is_same<T, CXXCtorInitializer>::value || 
-       std::is_same<T, TemplateArgumentLoc>::value || 
-       std::is_same<T, Attr>::value; 
- }; 
- template <typename T> 
- const bool IsBaseType<T>::value; 
-   
- /// A "type list" that contains all types. 
- /// 
- /// Useful for matchers like \c anything and \c unless. 
- using AllNodeBaseTypes = 
-     TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, QualType, 
-              Type, TypeLoc, CXXCtorInitializer, Attr>; 
-   
- /// Helper meta-function to extract the argument out of a function of 
- ///   type void(Arg). 
- /// 
- /// See AST_POLYMORPHIC_SUPPORTED_TYPES for details. 
- template <class T> struct ExtractFunctionArgMeta; 
- template <class T> struct ExtractFunctionArgMeta<void(T)> { 
-   using type = T; 
- }; 
-   
- template <class T, class Tuple, std::size_t... I> 
- constexpr T *new_from_tuple_impl(Tuple &&t, std::index_sequence<I...>) { 
-   return new T(std::get<I>(std::forward<Tuple>(t))...); 
- } 
-   
- template <class T, class Tuple> constexpr T *new_from_tuple(Tuple &&t) { 
-   return new_from_tuple_impl<T>( 
-       std::forward<Tuple>(t), 
-       std::make_index_sequence< 
-           std::tuple_size<std::remove_reference_t<Tuple>>::value>{}); 
- } 
-   
- /// Default type lists for ArgumentAdaptingMatcher matchers. 
- using AdaptativeDefaultFromTypes = AllNodeBaseTypes; 
- using AdaptativeDefaultToTypes = 
-     TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, TypeLoc, 
-              QualType, Attr>; 
-   
- /// All types that are supported by HasDeclarationMatcher above. 
- using HasDeclarationSupportedTypes = 
-     TypeList<CallExpr, CXXConstructExpr, CXXNewExpr, DeclRefExpr, EnumType, 
-              ElaboratedType, InjectedClassNameType, LabelStmt, AddrLabelExpr, 
-              MemberExpr, QualType, RecordType, TagType, 
-              TemplateSpecializationType, TemplateTypeParmType, TypedefType, 
-              UnresolvedUsingType, ObjCIvarRefExpr>; 
-   
- /// A Matcher that allows binding the node it matches to an id. 
- /// 
- /// BindableMatcher provides a \a bind() method that allows binding the 
- /// matched node to an id if the match was successful. 
- template <typename T> class BindableMatcher : public Matcher<T> { 
- public: 
-   explicit BindableMatcher(const Matcher<T> &M) : Matcher<T>(M) {} 
-   explicit BindableMatcher(MatcherInterface<T> *Implementation) 
-       : Matcher<T>(Implementation) {} 
-   
-   /// Returns a matcher that will bind the matched node on a match. 
-   /// 
-   /// The returned matcher is equivalent to this matcher, but will 
-   /// bind the matched node on a match. 
-   Matcher<T> bind(StringRef ID) const { 
-     return DynTypedMatcher(*this) 
-         .tryBind(ID) 
-         ->template unconditionalConvertTo<T>(); 
-   } 
-   
-   /// Same as Matcher<T>'s conversion operator, but enables binding on 
-   /// the returned matcher. 
-   operator DynTypedMatcher() const { 
-     DynTypedMatcher Result = static_cast<const Matcher<T> &>(*this); 
-     Result.setAllowBind(true); 
-     return Result; 
-   } 
- }; 
-   
- /// Matches any instance of the given NodeType. 
- /// 
- /// This is useful when a matcher syntactically requires a child matcher, 
- /// but the context doesn't care. See for example: anything(). 
- class TrueMatcher { 
- public: 
-   using ReturnTypes = AllNodeBaseTypes; 
-   
-   template <typename T> operator Matcher<T>() const { 
-     return DynTypedMatcher::trueMatcher(ASTNodeKind::getFromNodeKind<T>()) 
-         .template unconditionalConvertTo<T>(); 
-   } 
- }; 
-   
- /// Creates a Matcher<T> that matches if all inner matchers match. 
- template <typename T> 
- BindableMatcher<T> 
- makeAllOfComposite(ArrayRef<const Matcher<T> *> InnerMatchers) { 
-   // For the size() == 0 case, we return a "true" matcher. 
-   if (InnerMatchers.empty()) { 
-     return BindableMatcher<T>(TrueMatcher()); 
-   } 
-   // For the size() == 1 case, we simply return that one matcher. 
-   // No need to wrap it in a variadic operation. 
-   if (InnerMatchers.size() == 1) { 
-     return BindableMatcher<T>(*InnerMatchers[0]); 
-   } 
-   
-   using PI = llvm::pointee_iterator<const Matcher<T> *const *>; 
-   
-   std::vector<DynTypedMatcher> DynMatchers(PI(InnerMatchers.begin()), 
-                                            PI(InnerMatchers.end())); 
-   return BindableMatcher<T>( 
-       DynTypedMatcher::constructVariadic(DynTypedMatcher::VO_AllOf, 
-                                          ASTNodeKind::getFromNodeKind<T>(), 
-                                          std::move(DynMatchers)) 
-           .template unconditionalConvertTo<T>()); 
- } 
-   
- /// Creates a Matcher<T> that matches if 
- /// T is dyn_cast'able into InnerT and all inner matchers match. 
- /// 
- /// Returns BindableMatcher, as matchers that use dyn_cast have 
- /// the same object both to match on and to run submatchers on, 
- /// so there is no ambiguity with what gets bound. 
- template <typename T, typename InnerT> 
- BindableMatcher<T> 
- makeDynCastAllOfComposite(ArrayRef<const Matcher<InnerT> *> InnerMatchers) { 
-   return BindableMatcher<T>( 
-       makeAllOfComposite(InnerMatchers).template dynCastTo<T>()); 
- } 
-   
- /// A VariadicDynCastAllOfMatcher<SourceT, TargetT> object is a 
- /// variadic functor that takes a number of Matcher<TargetT> and returns a 
- /// Matcher<SourceT> that matches TargetT nodes that are matched by all of the 
- /// given matchers, if SourceT can be dynamically casted into TargetT. 
- /// 
- /// For example: 
- ///   const VariadicDynCastAllOfMatcher<Decl, CXXRecordDecl> record; 
- /// Creates a functor record(...) that creates a Matcher<Decl> given 
- /// a variable number of arguments of type Matcher<CXXRecordDecl>. 
- /// The returned matcher matches if the given Decl can by dynamically 
- /// casted to CXXRecordDecl and all given matchers match. 
- template <typename SourceT, typename TargetT> 
- class VariadicDynCastAllOfMatcher 
-     : public VariadicFunction<BindableMatcher<SourceT>, Matcher<TargetT>, 
-                               makeDynCastAllOfComposite<SourceT, TargetT>> { 
- public: 
-   VariadicDynCastAllOfMatcher() {} 
- }; 
-   
- /// A \c VariadicAllOfMatcher<T> object is a variadic functor that takes 
- /// a number of \c Matcher<T> and returns a \c Matcher<T> that matches \c T 
- /// nodes that are matched by all of the given matchers. 
- /// 
- /// For example: 
- ///   const VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier; 
- /// Creates a functor nestedNameSpecifier(...) that creates a 
- /// \c Matcher<NestedNameSpecifier> given a variable number of arguments of type 
- /// \c Matcher<NestedNameSpecifier>. 
- /// The returned matcher matches if all given matchers match. 
- template <typename T> 
- class VariadicAllOfMatcher 
-     : public VariadicFunction<BindableMatcher<T>, Matcher<T>, 
-                               makeAllOfComposite<T>> { 
- public: 
-   VariadicAllOfMatcher() {} 
- }; 
-   
- /// VariadicOperatorMatcher related types. 
- /// @{ 
-   
- /// Polymorphic matcher object that uses a \c 
- /// DynTypedMatcher::VariadicOperator operator. 
- /// 
- /// Input matchers can have any type (including other polymorphic matcher 
- /// types), and the actual Matcher<T> is generated on demand with an implicit 
- /// conversion operator. 
- template <typename... Ps> class VariadicOperatorMatcher { 
- public: 
-   VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, Ps &&... Params) 
-       : Op(Op), Params(std::forward<Ps>(Params)...) {} 
-   
-   template <typename T> operator Matcher<T>() const & { 
-     return DynTypedMatcher::constructVariadic( 
-                Op, ASTNodeKind::getFromNodeKind<T>(), 
-                getMatchers<T>(std::index_sequence_for<Ps...>())) 
-         .template unconditionalConvertTo<T>(); 
-   } 
-   
-   template <typename T> operator Matcher<T>() && { 
-     return DynTypedMatcher::constructVariadic( 
-                Op, ASTNodeKind::getFromNodeKind<T>(), 
-                getMatchers<T>(std::index_sequence_for<Ps...>())) 
-         .template unconditionalConvertTo<T>(); 
-   } 
-   
- private: 
-   // Helper method to unpack the tuple into a vector. 
-   template <typename T, std::size_t... Is> 
-   std::vector<DynTypedMatcher> getMatchers(std::index_sequence<Is...>) const & { 
-     return {Matcher<T>(std::get<Is>(Params))...}; 
-   } 
-   
-   template <typename T, std::size_t... Is> 
-   std::vector<DynTypedMatcher> getMatchers(std::index_sequence<Is...>) && { 
-     return {Matcher<T>(std::get<Is>(std::move(Params)))...}; 
-   } 
-   
-   const DynTypedMatcher::VariadicOperator Op; 
-   std::tuple<Ps...> Params; 
- }; 
-   
- /// Overloaded function object to generate VariadicOperatorMatcher 
- ///   objects from arbitrary matchers. 
- template <unsigned MinCount, unsigned MaxCount> 
- struct VariadicOperatorMatcherFunc { 
-   DynTypedMatcher::VariadicOperator Op; 
-   
-   template <typename... Ms> 
-   VariadicOperatorMatcher<Ms...> operator()(Ms &&... Ps) const { 
-     static_assert(MinCount <= sizeof...(Ms) && sizeof...(Ms) <= MaxCount, 
-                   "invalid number of parameters for variadic matcher"); 
-     return VariadicOperatorMatcher<Ms...>(Op, std::forward<Ms>(Ps)...); 
-   } 
- }; 
-   
- template <typename T, bool IsBaseOf, typename Head, typename Tail> 
- struct GetCladeImpl { 
-   using Type = Head; 
- }; 
- template <typename T, typename Head, typename Tail> 
- struct GetCladeImpl<T, false, Head, Tail> 
-     : GetCladeImpl<T, std::is_base_of<typename Tail::head, T>::value, 
-                    typename Tail::head, typename Tail::tail> {}; 
-   
- template <typename T, typename... U> 
- struct GetClade : GetCladeImpl<T, false, T, AllNodeBaseTypes> {}; 
-   
- template <typename CladeType, typename... MatcherTypes> 
- struct MapAnyOfMatcherImpl { 
-   
-   template <typename... InnerMatchers> 
-   BindableMatcher<CladeType> 
-   operator()(InnerMatchers &&... InnerMatcher) const { 
-     return VariadicAllOfMatcher<CladeType>()(std::apply( 
-         internal::VariadicOperatorMatcherFunc< 
-             0, std::numeric_limits<unsigned>::max()>{ 
-             internal::DynTypedMatcher::VO_AnyOf}, 
-         std::apply( 
-             [&](auto... Matcher) { 
-               return std::make_tuple(Matcher(InnerMatcher...)...); 
-             }, 
-             std::tuple< 
-                 VariadicDynCastAllOfMatcher<CladeType, MatcherTypes>...>()))); 
-   } 
- }; 
-   
- template <typename... MatcherTypes> 
- using MapAnyOfMatcher = 
-     MapAnyOfMatcherImpl<typename GetClade<MatcherTypes...>::Type, 
-                         MatcherTypes...>; 
-   
- template <typename... MatcherTypes> struct MapAnyOfHelper { 
-   using CladeType = typename GetClade<MatcherTypes...>::Type; 
-   
-   MapAnyOfMatcher<MatcherTypes...> with; 
-   
-   operator BindableMatcher<CladeType>() const { return with(); } 
-   
-   Matcher<CladeType> bind(StringRef ID) const { return with().bind(ID); } 
- }; 
-   
- template <template <typename ToArg, typename FromArg> class ArgumentAdapterT, 
-           typename T, typename ToTypes> 
- class ArgumentAdaptingMatcherFuncAdaptor { 
- public: 
-   explicit ArgumentAdaptingMatcherFuncAdaptor(const Matcher<T> &InnerMatcher) 
-       : InnerMatcher(InnerMatcher) {} 
-   
-   using ReturnTypes = ToTypes; 
-   
-   template <typename To> operator Matcher<To>() const & { 
-     return Matcher<To>(new ArgumentAdapterT<To, T>(InnerMatcher)); 
-   } 
-   
-   template <typename To> operator Matcher<To>() && { 
-     return Matcher<To>(new ArgumentAdapterT<To, T>(std::move(InnerMatcher))); 
-   } 
-   
- private: 
-   Matcher<T> InnerMatcher; 
- }; 
-   
- /// Converts a \c Matcher<T> to a matcher of desired type \c To by 
- /// "adapting" a \c To into a \c T. 
- /// 
- /// The \c ArgumentAdapterT argument specifies how the adaptation is done. 
- /// 
- /// For example: 
- ///   \c ArgumentAdaptingMatcher<HasMatcher, T>(InnerMatcher); 
- /// Given that \c InnerMatcher is of type \c Matcher<T>, this returns a matcher 
- /// that is convertible into any matcher of type \c To by constructing 
- /// \c HasMatcher<To, T>(InnerMatcher). 
- /// 
- /// If a matcher does not need knowledge about the inner type, prefer to use 
- /// PolymorphicMatcher. 
- template <template <typename ToArg, typename FromArg> class ArgumentAdapterT, 
-           typename FromTypes = AdaptativeDefaultFromTypes, 
-           typename ToTypes = AdaptativeDefaultToTypes> 
- struct ArgumentAdaptingMatcherFunc { 
-   template <typename T> 
-   static ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes> 
-   create(const Matcher<T> &InnerMatcher) { 
-     return ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>( 
-         InnerMatcher); 
-   } 
-   
-   template <typename T> 
-   ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes> 
-   operator()(const Matcher<T> &InnerMatcher) const { 
-     return create(InnerMatcher); 
-   } 
-   
-   template <typename... T> 
-   ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, 
-                                      typename GetClade<T...>::Type, ToTypes> 
-   operator()(const MapAnyOfHelper<T...> &InnerMatcher) const { 
-     return create(InnerMatcher.with()); 
-   } 
- }; 
-   
- template <typename T> class TraversalMatcher : public MatcherInterface<T> { 
-   DynTypedMatcher InnerMatcher; 
-   clang::TraversalKind Traversal; 
-   
- public: 
-   explicit TraversalMatcher(clang::TraversalKind TK, 
-                             const Matcher<T> &InnerMatcher) 
-       : InnerMatcher(InnerMatcher), Traversal(TK) {} 
-   
-   bool matches(const T &Node, ASTMatchFinder *Finder, 
-                BoundNodesTreeBuilder *Builder) const override { 
-     return this->InnerMatcher.matches(DynTypedNode::create(Node), Finder, 
-                                       Builder); 
-   } 
-   
-   std::optional<clang::TraversalKind> TraversalKind() const override { 
-     if (auto NestedKind = this->InnerMatcher.getTraversalKind()) 
-       return NestedKind; 
-     return Traversal; 
-   } 
- }; 
-   
- template <typename MatcherType> class TraversalWrapper { 
- public: 
-   TraversalWrapper(TraversalKind TK, const MatcherType &InnerMatcher) 
-       : TK(TK), InnerMatcher(InnerMatcher) {} 
-   
-   template <typename T> operator Matcher<T>() const & { 
-     return internal::DynTypedMatcher::constructRestrictedWrapper( 
-                new internal::TraversalMatcher<T>(TK, InnerMatcher), 
-                ASTNodeKind::getFromNodeKind<T>()) 
-         .template unconditionalConvertTo<T>(); 
-   } 
-   
-   template <typename T> operator Matcher<T>() && { 
-     return internal::DynTypedMatcher::constructRestrictedWrapper( 
-                new internal::TraversalMatcher<T>(TK, std::move(InnerMatcher)), 
-                ASTNodeKind::getFromNodeKind<T>()) 
-         .template unconditionalConvertTo<T>(); 
-   } 
-   
- private: 
-   TraversalKind TK; 
-   MatcherType InnerMatcher; 
- }; 
-   
- /// A PolymorphicMatcher<MatcherT, P1, ..., PN> object can be 
- /// created from N parameters p1, ..., pN (of type P1, ..., PN) and 
- /// used as a Matcher<T> where a MatcherT<T, P1, ..., PN>(p1, ..., pN) 
- /// can be constructed. 
- /// 
- /// For example: 
- /// - PolymorphicMatcher<IsDefinitionMatcher>() 
- ///   creates an object that can be used as a Matcher<T> for any type T 
- ///   where an IsDefinitionMatcher<T>() can be constructed. 
- /// - PolymorphicMatcher<ValueEqualsMatcher, int>(42) 
- ///   creates an object that can be used as a Matcher<T> for any type T 
- ///   where a ValueEqualsMatcher<T, int>(42) can be constructed. 
- template <template <typename T, typename... Params> class MatcherT, 
-           typename ReturnTypesF, typename... ParamTypes> 
- class PolymorphicMatcher { 
- public: 
-   PolymorphicMatcher(const ParamTypes &... Params) : Params(Params...) {} 
-   
-   using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type; 
-   
-   template <typename T> operator Matcher<T>() const & { 
-     static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value, 
-                   "right polymorphic conversion"); 
-     return Matcher<T>(new_from_tuple<MatcherT<T, ParamTypes...>>(Params)); 
-   } 
-   
-   template <typename T> operator Matcher<T>() && { 
-     static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value, 
-                   "right polymorphic conversion"); 
-     return Matcher<T>( 
-         new_from_tuple<MatcherT<T, ParamTypes...>>(std::move(Params))); 
-   } 
-   
- private: 
-   std::tuple<ParamTypes...> Params; 
- }; 
-   
- /// Matches nodes of type T that have child nodes of type ChildT for 
- /// which a specified child matcher matches. 
- /// 
- /// ChildT must be an AST base type. 
- template <typename T, typename ChildT> 
- class HasMatcher : public MatcherInterface<T> { 
-   DynTypedMatcher InnerMatcher; 
-   
- public: 
-   explicit HasMatcher(const Matcher<ChildT> &InnerMatcher) 
-       : InnerMatcher(InnerMatcher) {} 
-   
-   bool matches(const T &Node, ASTMatchFinder *Finder, 
-                BoundNodesTreeBuilder *Builder) const override { 
-     return Finder->matchesChildOf(Node, this->InnerMatcher, Builder, 
-                                   ASTMatchFinder::BK_First); 
-   } 
- }; 
-   
- /// Matches nodes of type T that have child nodes of type ChildT for 
- /// which a specified child matcher matches. ChildT must be an AST base 
- /// type. 
- /// As opposed to the HasMatcher, the ForEachMatcher will produce a match 
- /// for each child that matches. 
- template <typename T, typename ChildT> 
- class ForEachMatcher : public MatcherInterface<T> { 
-   static_assert(IsBaseType<ChildT>::value, 
-                 "for each only accepts base type matcher"); 
-   
-   DynTypedMatcher InnerMatcher; 
-   
- public: 
-   explicit ForEachMatcher(const Matcher<ChildT> &InnerMatcher) 
-       : InnerMatcher(InnerMatcher) {} 
-   
-   bool matches(const T &Node, ASTMatchFinder *Finder, 
-                BoundNodesTreeBuilder *Builder) const override { 
-     return Finder->matchesChildOf( 
-         Node, this->InnerMatcher, Builder, 
-         ASTMatchFinder::BK_All); 
-   } 
- }; 
-   
- /// @} 
-   
- template <typename T> 
- inline Matcher<T> DynTypedMatcher::unconditionalConvertTo() const { 
-   return Matcher<T>(*this); 
- } 
-   
- /// Matches nodes of type T that have at least one descendant node of 
- /// type DescendantT for which the given inner matcher matches. 
- /// 
- /// DescendantT must be an AST base type. 
- template <typename T, typename DescendantT> 
- class HasDescendantMatcher : public MatcherInterface<T> { 
-   static_assert(IsBaseType<DescendantT>::value, 
-                 "has descendant only accepts base type matcher"); 
-   
-   DynTypedMatcher DescendantMatcher; 
-   
- public: 
-   explicit HasDescendantMatcher(const Matcher<DescendantT> &DescendantMatcher) 
-       : DescendantMatcher(DescendantMatcher) {} 
-   
-   bool matches(const T &Node, ASTMatchFinder *Finder, 
-                BoundNodesTreeBuilder *Builder) const override { 
-     return Finder->matchesDescendantOf(Node, this->DescendantMatcher, Builder, 
-                                        ASTMatchFinder::BK_First); 
-   } 
- }; 
-   
- /// Matches nodes of type \c T that have a parent node of type \c ParentT 
- /// for which the given inner matcher matches. 
- /// 
- /// \c ParentT must be an AST base type. 
- template <typename T, typename ParentT> 
- class HasParentMatcher : public MatcherInterface<T> { 
-   static_assert(IsBaseType<ParentT>::value, 
-                 "has parent only accepts base type matcher"); 
-   
-   DynTypedMatcher ParentMatcher; 
-   
- public: 
-   explicit HasParentMatcher(const Matcher<ParentT> &ParentMatcher) 
-       : ParentMatcher(ParentMatcher) {} 
-   
-   bool matches(const T &Node, ASTMatchFinder *Finder, 
-                BoundNodesTreeBuilder *Builder) const override { 
-     return Finder->matchesAncestorOf(Node, this->ParentMatcher, Builder, 
-                                      ASTMatchFinder::AMM_ParentOnly); 
-   } 
- }; 
-   
- /// Matches nodes of type \c T that have at least one ancestor node of 
- /// type \c AncestorT for which the given inner matcher matches. 
- /// 
- /// \c AncestorT must be an AST base type. 
- template <typename T, typename AncestorT> 
- class HasAncestorMatcher : public MatcherInterface<T> { 
-   static_assert(IsBaseType<AncestorT>::value, 
-                 "has ancestor only accepts base type matcher"); 
-   
-   DynTypedMatcher AncestorMatcher; 
-   
- public: 
-   explicit HasAncestorMatcher(const Matcher<AncestorT> &AncestorMatcher) 
-       : AncestorMatcher(AncestorMatcher) {} 
-   
-   bool matches(const T &Node, ASTMatchFinder *Finder, 
-                BoundNodesTreeBuilder *Builder) const override { 
-     return Finder->matchesAncestorOf(Node, this->AncestorMatcher, Builder, 
-                                      ASTMatchFinder::AMM_All); 
-   } 
- }; 
-   
- /// Matches nodes of type T that have at least one descendant node of 
- /// type DescendantT for which the given inner matcher matches. 
- /// 
- /// DescendantT must be an AST base type. 
- /// As opposed to HasDescendantMatcher, ForEachDescendantMatcher will match 
- /// for each descendant node that matches instead of only for the first. 
- template <typename T, typename DescendantT> 
- class ForEachDescendantMatcher : public MatcherInterface<T> { 
-   static_assert(IsBaseType<DescendantT>::value, 
-                 "for each descendant only accepts base type matcher"); 
-   
-   DynTypedMatcher DescendantMatcher; 
-   
- public: 
-   explicit ForEachDescendantMatcher( 
-       const Matcher<DescendantT> &DescendantMatcher) 
-       : DescendantMatcher(DescendantMatcher) {} 
-   
-   bool matches(const T &Node, ASTMatchFinder *Finder, 
-                BoundNodesTreeBuilder *Builder) const override { 
-     return Finder->matchesDescendantOf(Node, this->DescendantMatcher, Builder, 
-                                        ASTMatchFinder::BK_All); 
-   } 
- }; 
-   
- /// Matches on nodes that have a getValue() method if getValue() equals 
- /// the value the ValueEqualsMatcher was constructed with. 
- template <typename T, typename ValueT> 
- class ValueEqualsMatcher : public SingleNodeMatcherInterface<T> { 
-   static_assert(std::is_base_of<CharacterLiteral, T>::value || 
-                 std::is_base_of<CXXBoolLiteralExpr, T>::value || 
-                 std::is_base_of<FloatingLiteral, T>::value || 
-                 std::is_base_of<IntegerLiteral, T>::value, 
-                 "the node must have a getValue method"); 
-   
- public: 
-   explicit ValueEqualsMatcher(const ValueT &ExpectedValue) 
-       : ExpectedValue(ExpectedValue) {} 
-   
-   bool matchesNode(const T &Node) const override { 
-     return Node.getValue() == ExpectedValue; 
-   } 
-   
- private: 
-   ValueT ExpectedValue; 
- }; 
-   
- /// Template specializations to easily write matchers for floating point 
- /// literals. 
- template <> 
- inline bool ValueEqualsMatcher<FloatingLiteral, double>::matchesNode( 
-     const FloatingLiteral &Node) const { 
-   if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle()) 
-     return Node.getValue().convertToFloat() == ExpectedValue; 
-   if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble()) 
-     return Node.getValue().convertToDouble() == ExpectedValue; 
-   return false; 
- } 
- template <> 
- inline bool ValueEqualsMatcher<FloatingLiteral, float>::matchesNode( 
-     const FloatingLiteral &Node) const { 
-   if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle()) 
-     return Node.getValue().convertToFloat() == ExpectedValue; 
-   if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble()) 
-     return Node.getValue().convertToDouble() == ExpectedValue; 
-   return false; 
- } 
- template <> 
- inline bool ValueEqualsMatcher<FloatingLiteral, llvm::APFloat>::matchesNode( 
-     const FloatingLiteral &Node) const { 
-   return ExpectedValue.compare(Node.getValue()) == llvm::APFloat::cmpEqual; 
- } 
-   
- /// Matches nodes of type \c TLoc for which the inner 
- /// \c Matcher<T> matches. 
- template <typename TLoc, typename T> 
- class LocMatcher : public MatcherInterface<TLoc> { 
-   DynTypedMatcher InnerMatcher; 
-   
- public: 
-   explicit LocMatcher(const Matcher<T> &InnerMatcher) 
-       : InnerMatcher(InnerMatcher) {} 
-   
-   bool matches(const TLoc &Node, ASTMatchFinder *Finder, 
-                BoundNodesTreeBuilder *Builder) const override { 
-     if (!Node) 
-       return false; 
-     return this->InnerMatcher.matches(extract(Node), Finder, Builder); 
-   } 
-   
- private: 
-   static DynTypedNode extract(const NestedNameSpecifierLoc &Loc) { 
-     return DynTypedNode::create(*Loc.getNestedNameSpecifier()); 
-   } 
- }; 
-   
- /// Matches \c TypeLocs based on an inner matcher matching a certain 
- /// \c QualType. 
- /// 
- /// Used to implement the \c loc() matcher. 
- class TypeLocTypeMatcher : public MatcherInterface<TypeLoc> { 
-   DynTypedMatcher InnerMatcher; 
-   
- public: 
-   explicit TypeLocTypeMatcher(const Matcher<QualType> &InnerMatcher) 
-       : InnerMatcher(InnerMatcher) {} 
-   
-   bool matches(const TypeLoc &Node, ASTMatchFinder *Finder, 
-                BoundNodesTreeBuilder *Builder) const override { 
-     if (!Node) 
-       return false; 
-     return this->InnerMatcher.matches(DynTypedNode::create(Node.getType()), 
-                                       Finder, Builder); 
-   } 
- }; 
-   
- /// Matches nodes of type \c T for which the inner matcher matches on a 
- /// another node of type \c T that can be reached using a given traverse 
- /// function. 
- template <typename T> class TypeTraverseMatcher : public MatcherInterface<T> { 
-   DynTypedMatcher InnerMatcher; 
-   
- public: 
-   explicit TypeTraverseMatcher(const Matcher<QualType> &InnerMatcher, 
-                                QualType (T::*TraverseFunction)() const) 
-       : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {} 
-   
-   bool matches(const T &Node, ASTMatchFinder *Finder, 
-                BoundNodesTreeBuilder *Builder) const override { 
-     QualType NextNode = (Node.*TraverseFunction)(); 
-     if (NextNode.isNull()) 
-       return false; 
-     return this->InnerMatcher.matches(DynTypedNode::create(NextNode), Finder, 
-                                       Builder); 
-   } 
-   
- private: 
-   QualType (T::*TraverseFunction)() const; 
- }; 
-   
- /// Matches nodes of type \c T in a ..Loc hierarchy, for which the inner 
- /// matcher matches on a another node of type \c T that can be reached using a 
- /// given traverse function. 
- template <typename T> 
- class TypeLocTraverseMatcher : public MatcherInterface<T> { 
-   DynTypedMatcher InnerMatcher; 
-   
- public: 
-   explicit TypeLocTraverseMatcher(const Matcher<TypeLoc> &InnerMatcher, 
-                                   TypeLoc (T::*TraverseFunction)() const) 
-       : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {} 
-   
-   bool matches(const T &Node, ASTMatchFinder *Finder, 
-                BoundNodesTreeBuilder *Builder) const override { 
-     TypeLoc NextNode = (Node.*TraverseFunction)(); 
-     if (!NextNode) 
-       return false; 
-     return this->InnerMatcher.matches(DynTypedNode::create(NextNode), Finder, 
-                                       Builder); 
-   } 
-   
- private: 
-   TypeLoc (T::*TraverseFunction)() const; 
- }; 
-   
- /// Converts a \c Matcher<InnerT> to a \c Matcher<OuterT>, where 
- /// \c OuterT is any type that is supported by \c Getter. 
- /// 
- /// \code Getter<OuterT>::value() \endcode returns a 
- /// \code InnerTBase (OuterT::*)() \endcode, which is used to adapt a \c OuterT 
- /// object into a \c InnerT 
- template <typename InnerTBase, 
-           template <typename OuterT> class Getter, 
-           template <typename OuterT> class MatcherImpl, 
-           typename ReturnTypesF> 
- class TypeTraversePolymorphicMatcher { 
- private: 
-   using Self = TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl, 
-                                               ReturnTypesF>; 
-   
-   static Self create(ArrayRef<const Matcher<InnerTBase> *> InnerMatchers); 
-   
- public: 
-   using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type; 
-   
-   explicit TypeTraversePolymorphicMatcher( 
-       ArrayRef<const Matcher<InnerTBase> *> InnerMatchers) 
-       : InnerMatcher(makeAllOfComposite(InnerMatchers)) {} 
-   
-   template <typename OuterT> operator Matcher<OuterT>() const { 
-     return Matcher<OuterT>( 
-         new MatcherImpl<OuterT>(InnerMatcher, Getter<OuterT>::value())); 
-   } 
-   
-   struct Func 
-       : public VariadicFunction<Self, Matcher<InnerTBase>, &Self::create> { 
-     Func() {} 
-   }; 
-   
- private: 
-   Matcher<InnerTBase> InnerMatcher; 
- }; 
-   
- /// A simple memoizer of T(*)() functions. 
- /// 
- /// It will call the passed 'Func' template parameter at most once. 
- /// Used to support AST_MATCHER_FUNCTION() macro. 
- template <typename Matcher, Matcher (*Func)()> class MemoizedMatcher { 
-   struct Wrapper { 
-     Wrapper() : M(Func()) {} 
-   
-     Matcher M; 
-   }; 
-   
- public: 
-   static const Matcher &getInstance() { 
-     static llvm::ManagedStatic<Wrapper> Instance; 
-     return Instance->M; 
-   } 
- }; 
-   
- // Define the create() method out of line to silence a GCC warning about 
- // the struct "Func" having greater visibility than its base, which comes from 
- // using the flag -fvisibility-inlines-hidden. 
- template <typename InnerTBase, template <typename OuterT> class Getter, 
-           template <typename OuterT> class MatcherImpl, typename ReturnTypesF> 
- TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl, ReturnTypesF> 
- TypeTraversePolymorphicMatcher< 
-     InnerTBase, Getter, MatcherImpl, 
-     ReturnTypesF>::create(ArrayRef<const Matcher<InnerTBase> *> InnerMatchers) { 
-   return Self(InnerMatchers); 
- } 
-   
- // FIXME: unify ClassTemplateSpecializationDecl and TemplateSpecializationType's 
- // APIs for accessing the template argument list. 
- inline ArrayRef<TemplateArgument> 
- getTemplateSpecializationArgs(const ClassTemplateSpecializationDecl &D) { 
-   return D.getTemplateArgs().asArray(); 
- } 
-   
- inline ArrayRef<TemplateArgument> 
- getTemplateSpecializationArgs(const TemplateSpecializationType &T) { 
-   return T.template_arguments(); 
- } 
-   
- inline ArrayRef<TemplateArgument> 
- getTemplateSpecializationArgs(const FunctionDecl &FD) { 
-   if (const auto* TemplateArgs = FD.getTemplateSpecializationArgs()) 
-     return TemplateArgs->asArray(); 
-   return ArrayRef<TemplateArgument>(); 
- } 
-   
- struct NotEqualsBoundNodePredicate { 
-   bool operator()(const internal::BoundNodesMap &Nodes) const { 
-     return Nodes.getNode(ID) != Node; 
-   } 
-   
-   std::string ID; 
-   DynTypedNode Node; 
- }; 
-   
- template <typename Ty, typename Enable = void> struct GetBodyMatcher { 
-   static const Stmt *get(const Ty &Node) { return Node.getBody(); } 
- }; 
-   
- template <typename Ty> 
- struct GetBodyMatcher< 
-     Ty, std::enable_if_t<std::is_base_of<FunctionDecl, Ty>::value>> { 
-   static const Stmt *get(const Ty &Node) { 
-     return Node.doesThisDeclarationHaveABody() ? Node.getBody() : nullptr; 
-   } 
- }; 
-   
- template <typename NodeType> 
- inline std::optional<BinaryOperatorKind> 
- equivalentBinaryOperator(const NodeType &Node) { 
-   return Node.getOpcode(); 
- } 
-   
- template <> 
- inline std::optional<BinaryOperatorKind> 
- equivalentBinaryOperator<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) { 
-   if (Node.getNumArgs() != 2) 
-     return std::nullopt; 
-   switch (Node.getOperator()) { 
-   default: 
-     return std::nullopt; 
-   case OO_ArrowStar: 
-     return BO_PtrMemI; 
-   case OO_Star: 
-     return BO_Mul; 
-   case OO_Slash: 
-     return BO_Div; 
-   case OO_Percent: 
-     return BO_Rem; 
-   case OO_Plus: 
-     return BO_Add; 
-   case OO_Minus: 
-     return BO_Sub; 
-   case OO_LessLess: 
-     return BO_Shl; 
-   case OO_GreaterGreater: 
-     return BO_Shr; 
-   case OO_Spaceship: 
-     return BO_Cmp; 
-   case OO_Less: 
-     return BO_LT; 
-   case OO_Greater: 
-     return BO_GT; 
-   case OO_LessEqual: 
-     return BO_LE; 
-   case OO_GreaterEqual: 
-     return BO_GE; 
-   case OO_EqualEqual: 
-     return BO_EQ; 
-   case OO_ExclaimEqual: 
-     return BO_NE; 
-   case OO_Amp: 
-     return BO_And; 
-   case OO_Caret: 
-     return BO_Xor; 
-   case OO_Pipe: 
-     return BO_Or; 
-   case OO_AmpAmp: 
-     return BO_LAnd; 
-   case OO_PipePipe: 
-     return BO_LOr; 
-   case OO_Equal: 
-     return BO_Assign; 
-   case OO_StarEqual: 
-     return BO_MulAssign; 
-   case OO_SlashEqual: 
-     return BO_DivAssign; 
-   case OO_PercentEqual: 
-     return BO_RemAssign; 
-   case OO_PlusEqual: 
-     return BO_AddAssign; 
-   case OO_MinusEqual: 
-     return BO_SubAssign; 
-   case OO_LessLessEqual: 
-     return BO_ShlAssign; 
-   case OO_GreaterGreaterEqual: 
-     return BO_ShrAssign; 
-   case OO_AmpEqual: 
-     return BO_AndAssign; 
-   case OO_CaretEqual: 
-     return BO_XorAssign; 
-   case OO_PipeEqual: 
-     return BO_OrAssign; 
-   case OO_Comma: 
-     return BO_Comma; 
-   } 
- } 
-   
- template <typename NodeType> 
- inline std::optional<UnaryOperatorKind> 
- equivalentUnaryOperator(const NodeType &Node) { 
-   return Node.getOpcode(); 
- } 
-   
- template <> 
- inline std::optional<UnaryOperatorKind> 
- equivalentUnaryOperator<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) { 
-   if (Node.getNumArgs() != 1 && Node.getOperator() != OO_PlusPlus && 
-       Node.getOperator() != OO_MinusMinus) 
-     return std::nullopt; 
-   switch (Node.getOperator()) { 
-   default: 
-     return std::nullopt; 
-   case OO_Plus: 
-     return UO_Plus; 
-   case OO_Minus: 
-     return UO_Minus; 
-   case OO_Amp: 
-     return UO_AddrOf; 
-   case OO_Star: 
-     return UO_Deref; 
-   case OO_Tilde: 
-     return UO_Not; 
-   case OO_Exclaim: 
-     return UO_LNot; 
-   case OO_PlusPlus: { 
-     const auto *FD = Node.getDirectCallee(); 
-     if (!FD) 
-       return std::nullopt; 
-     return FD->getNumParams() > 0 ? UO_PostInc : UO_PreInc; 
-   } 
-   case OO_MinusMinus: { 
-     const auto *FD = Node.getDirectCallee(); 
-     if (!FD) 
-       return std::nullopt; 
-     return FD->getNumParams() > 0 ? UO_PostDec : UO_PreDec; 
-   } 
-   case OO_Coawait: 
-     return UO_Coawait; 
-   } 
- } 
-   
- template <typename NodeType> inline const Expr *getLHS(const NodeType &Node) { 
-   return Node.getLHS(); 
- } 
- template <> 
- inline const Expr * 
- getLHS<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) { 
-   if (!internal::equivalentBinaryOperator(Node)) 
-     return nullptr; 
-   return Node.getArg(0); 
- } 
- template <typename NodeType> inline const Expr *getRHS(const NodeType &Node) { 
-   return Node.getRHS(); 
- } 
- template <> 
- inline const Expr * 
- getRHS<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) { 
-   if (!internal::equivalentBinaryOperator(Node)) 
-     return nullptr; 
-   return Node.getArg(1); 
- } 
- template <typename NodeType> 
- inline const Expr *getSubExpr(const NodeType &Node) { 
-   return Node.getSubExpr(); 
- } 
- template <> 
- inline const Expr * 
- getSubExpr<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) { 
-   if (!internal::equivalentUnaryOperator(Node)) 
-     return nullptr; 
-   return Node.getArg(0); 
- } 
-   
- template <typename Ty> 
- struct HasSizeMatcher { 
-   static bool hasSize(const Ty &Node, unsigned int N) { 
-     return Node.getSize() == N; 
-   } 
- }; 
-   
- template <> 
- inline bool HasSizeMatcher<StringLiteral>::hasSize( 
-     const StringLiteral &Node, unsigned int N) { 
-   return Node.getLength() == N; 
- } 
-   
- template <typename Ty> 
- struct GetSourceExpressionMatcher { 
-   static const Expr *get(const Ty &Node) { 
-     return Node.getSubExpr(); 
-   } 
- }; 
-   
- template <> 
- inline const Expr *GetSourceExpressionMatcher<OpaqueValueExpr>::get( 
-     const OpaqueValueExpr &Node) { 
-   return Node.getSourceExpr(); 
- } 
-   
- template <typename Ty> 
- struct CompoundStmtMatcher { 
-   static const CompoundStmt *get(const Ty &Node) { 
-     return &Node; 
-   } 
- }; 
-   
- template <> 
- inline const CompoundStmt * 
- CompoundStmtMatcher<StmtExpr>::get(const StmtExpr &Node) { 
-   return Node.getSubStmt(); 
- } 
-   
- /// If \p Loc is (transitively) expanded from macro \p MacroName, returns the 
- /// location (in the chain of expansions) at which \p MacroName was 
- /// expanded. Since the macro may have been expanded inside a series of 
- /// expansions, that location may itself be a MacroID. 
- std::optional<SourceLocation> getExpansionLocOfMacro(StringRef MacroName, 
-                                                      SourceLocation Loc, 
-                                                      const ASTContext &Context); 
-   
- inline std::optional<StringRef> getOpName(const UnaryOperator &Node) { 
-   return Node.getOpcodeStr(Node.getOpcode()); 
- } 
- inline std::optional<StringRef> getOpName(const BinaryOperator &Node) { 
-   return Node.getOpcodeStr(); 
- } 
- inline StringRef getOpName(const CXXRewrittenBinaryOperator &Node) { 
-   return Node.getOpcodeStr(); 
- } 
- inline std::optional<StringRef> getOpName(const CXXOperatorCallExpr &Node) { 
-   auto optBinaryOpcode = equivalentBinaryOperator(Node); 
-   if (!optBinaryOpcode) { 
-     auto optUnaryOpcode = equivalentUnaryOperator(Node); 
-     if (!optUnaryOpcode) 
-       return std::nullopt; 
-     return UnaryOperator::getOpcodeStr(*optUnaryOpcode); 
-   } 
-   return BinaryOperator::getOpcodeStr(*optBinaryOpcode); 
- } 
-   
- /// Matches overloaded operators with a specific name. 
- /// 
- /// The type argument ArgT is not used by this matcher but is used by 
- /// PolymorphicMatcher and should be std::vector<std::string>>. 
- template <typename T, typename ArgT = std::vector<std::string>> 
- class HasAnyOperatorNameMatcher : public SingleNodeMatcherInterface<T> { 
-   static_assert(std::is_same<T, BinaryOperator>::value || 
-                     std::is_same<T, CXXOperatorCallExpr>::value || 
-                     std::is_same<T, CXXRewrittenBinaryOperator>::value || 
-                     std::is_same<T, UnaryOperator>::value, 
-                 "Matcher only supports `BinaryOperator`, `UnaryOperator`, " 
-                 "`CXXOperatorCallExpr` and `CXXRewrittenBinaryOperator`"); 
-   static_assert(std::is_same<ArgT, std::vector<std::string>>::value, 
-                 "Matcher ArgT must be std::vector<std::string>"); 
-   
- public: 
-   explicit HasAnyOperatorNameMatcher(std::vector<std::string> Names) 
-       : SingleNodeMatcherInterface<T>(), Names(std::move(Names)) {} 
-   
-   bool matchesNode(const T &Node) const override { 
-     std::optional<StringRef> OptOpName = getOpName(Node); 
-     return OptOpName && llvm::is_contained(Names, *OptOpName); 
-   } 
-   
- private: 
-   static std::optional<StringRef> getOpName(const UnaryOperator &Node) { 
-     return Node.getOpcodeStr(Node.getOpcode()); 
-   } 
-   static std::optional<StringRef> getOpName(const BinaryOperator &Node) { 
-     return Node.getOpcodeStr(); 
-   } 
-   static StringRef getOpName(const CXXRewrittenBinaryOperator &Node) { 
-     return Node.getOpcodeStr(); 
-   } 
-   static std::optional<StringRef> getOpName(const CXXOperatorCallExpr &Node) { 
-     auto optBinaryOpcode = equivalentBinaryOperator(Node); 
-     if (!optBinaryOpcode) { 
-       auto optUnaryOpcode = equivalentUnaryOperator(Node); 
-       if (!optUnaryOpcode) 
-         return std::nullopt; 
-       return UnaryOperator::getOpcodeStr(*optUnaryOpcode); 
-     } 
-     return BinaryOperator::getOpcodeStr(*optBinaryOpcode); 
-   } 
-   
-   std::vector<std::string> Names; 
- }; 
-   
- using HasOpNameMatcher = 
-     PolymorphicMatcher<HasAnyOperatorNameMatcher, 
-                        void( 
-                            TypeList<BinaryOperator, CXXOperatorCallExpr, 
-                                     CXXRewrittenBinaryOperator, UnaryOperator>), 
-                        std::vector<std::string>>; 
-   
- HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef<const StringRef *> NameRefs); 
-   
- using HasOverloadOpNameMatcher = 
-     PolymorphicMatcher<HasOverloadedOperatorNameMatcher, 
-                        void(TypeList<CXXOperatorCallExpr, FunctionDecl>), 
-                        std::vector<std::string>>; 
-   
- HasOverloadOpNameMatcher 
- hasAnyOverloadedOperatorNameFunc(ArrayRef<const StringRef *> NameRefs); 
-   
- /// Returns true if \p Node has a base specifier matching \p BaseSpec. 
- /// 
- /// A class is not considered to be derived from itself. 
- bool matchesAnyBase(const CXXRecordDecl &Node, 
-                     const Matcher<CXXBaseSpecifier> &BaseSpecMatcher, 
-                     ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder); 
-   
- std::shared_ptr<llvm::Regex> createAndVerifyRegex(StringRef Regex, 
-                                                   llvm::Regex::RegexFlags Flags, 
-                                                   StringRef MatcherID); 
-   
- inline bool 
- MatchTemplateArgLocAt(const DeclRefExpr &Node, unsigned int Index, 
-                       internal::Matcher<TemplateArgumentLoc> InnerMatcher, 
-                       internal::ASTMatchFinder *Finder, 
-                       internal::BoundNodesTreeBuilder *Builder) { 
-   llvm::ArrayRef<TemplateArgumentLoc> ArgLocs = Node.template_arguments(); 
-   return Index < ArgLocs.size() && 
-          InnerMatcher.matches(ArgLocs[Index], Finder, Builder); 
- } 
-   
- inline bool 
- MatchTemplateArgLocAt(const TemplateSpecializationTypeLoc &Node, 
-                       unsigned int Index, 
-                       internal::Matcher<TemplateArgumentLoc> InnerMatcher, 
-                       internal::ASTMatchFinder *Finder, 
-                       internal::BoundNodesTreeBuilder *Builder) { 
-   return !Node.isNull() && Index < Node.getNumArgs() && 
-          InnerMatcher.matches(Node.getArgLoc(Index), Finder, Builder); 
- } 
-   
- } // namespace internal 
-   
- } // namespace ast_matchers 
-   
- } // namespace clang 
-   
- #endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H 
-