10b57cec5SDimitry Andric //===- ASTMatchersInternal.h - Structural query framework -------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric //  Implements the base layer of the matcher framework.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //  Matchers are methods that return a Matcher<T> which provides a method
120b57cec5SDimitry Andric //  Matches(...) which is a predicate on an AST node. The Matches method's
130b57cec5SDimitry Andric //  parameters define the context of the match, which allows matchers to recurse
140b57cec5SDimitry Andric //  or store the current node as bound to a specific string, so that it can be
150b57cec5SDimitry Andric //  retrieved later.
160b57cec5SDimitry Andric //
170b57cec5SDimitry Andric //  In general, matchers have two parts:
180b57cec5SDimitry Andric //  1. A function Matcher<T> MatcherName(<arguments>) which returns a Matcher<T>
190b57cec5SDimitry Andric //     based on the arguments and optionally on template type deduction based
200b57cec5SDimitry Andric //     on the arguments. Matcher<T>s form an implicit reverse hierarchy
210b57cec5SDimitry Andric //     to clang's AST class hierarchy, meaning that you can use a Matcher<Base>
220b57cec5SDimitry Andric //     everywhere a Matcher<Derived> is required.
230b57cec5SDimitry Andric //  2. An implementation of a class derived from MatcherInterface<T>.
240b57cec5SDimitry Andric //
250b57cec5SDimitry Andric //  The matcher functions are defined in ASTMatchers.h. To make it possible
260b57cec5SDimitry Andric //  to implement both the matcher function and the implementation of the matcher
270b57cec5SDimitry Andric //  interface in one place, ASTMatcherMacros.h defines macros that allow
280b57cec5SDimitry Andric //  implementing a matcher in a single place.
290b57cec5SDimitry Andric //
300b57cec5SDimitry Andric //  This file contains the base classes needed to construct the actual matchers.
310b57cec5SDimitry Andric //
320b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric #ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H
350b57cec5SDimitry Andric #define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric #include "clang/AST/ASTTypeTraits.h"
380b57cec5SDimitry Andric #include "clang/AST/Decl.h"
390b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h"
400b57cec5SDimitry Andric #include "clang/AST/DeclFriend.h"
410b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h"
420b57cec5SDimitry Andric #include "clang/AST/Expr.h"
430b57cec5SDimitry Andric #include "clang/AST/ExprCXX.h"
440b57cec5SDimitry Andric #include "clang/AST/ExprObjC.h"
450b57cec5SDimitry Andric #include "clang/AST/NestedNameSpecifier.h"
460b57cec5SDimitry Andric #include "clang/AST/Stmt.h"
470b57cec5SDimitry Andric #include "clang/AST/TemplateName.h"
480b57cec5SDimitry Andric #include "clang/AST/Type.h"
490b57cec5SDimitry Andric #include "clang/AST/TypeLoc.h"
500b57cec5SDimitry Andric #include "clang/Basic/LLVM.h"
510b57cec5SDimitry Andric #include "clang/Basic/OperatorKinds.h"
520b57cec5SDimitry Andric #include "llvm/ADT/APFloat.h"
530b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
540b57cec5SDimitry Andric #include "llvm/ADT/IntrusiveRefCntPtr.h"
550b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
560b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
570b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
580b57cec5SDimitry Andric #include "llvm/ADT/iterator.h"
590b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
600b57cec5SDimitry Andric #include "llvm/Support/ManagedStatic.h"
615ffd83dbSDimitry Andric #include "llvm/Support/Regex.h"
620b57cec5SDimitry Andric #include <algorithm>
630b57cec5SDimitry Andric #include <cassert>
640b57cec5SDimitry Andric #include <cstddef>
650b57cec5SDimitry Andric #include <cstdint>
660b57cec5SDimitry Andric #include <map>
675ffd83dbSDimitry Andric #include <memory>
68bdd1243dSDimitry Andric #include <optional>
690b57cec5SDimitry Andric #include <string>
700b57cec5SDimitry Andric #include <tuple>
710b57cec5SDimitry Andric #include <type_traits>
720b57cec5SDimitry Andric #include <utility>
730b57cec5SDimitry Andric #include <vector>
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric namespace clang {
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric class ASTContext;
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric namespace ast_matchers {
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric class BoundNodes;
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric namespace internal {
840b57cec5SDimitry Andric 
85fe6060f1SDimitry Andric /// A type-list implementation.
86fe6060f1SDimitry Andric ///
87fe6060f1SDimitry Andric /// A "linked list" of types, accessible by using the ::head and ::tail
88fe6060f1SDimitry Andric /// typedefs.
89fe6060f1SDimitry Andric template <typename... Ts> struct TypeList {}; // Empty sentinel type list.
90fe6060f1SDimitry Andric 
91fe6060f1SDimitry Andric template <typename T1, typename... Ts> struct TypeList<T1, Ts...> {
92fe6060f1SDimitry Andric   /// The first type on the list.
93fe6060f1SDimitry Andric   using head = T1;
94fe6060f1SDimitry Andric 
95fe6060f1SDimitry Andric   /// A sublist with the tail. ie everything but the head.
96fe6060f1SDimitry Andric   ///
97fe6060f1SDimitry Andric   /// This type is used to do recursion. TypeList<>/EmptyTypeList indicates the
98fe6060f1SDimitry Andric   /// end of the list.
99fe6060f1SDimitry Andric   using tail = TypeList<Ts...>;
100fe6060f1SDimitry Andric };
101fe6060f1SDimitry Andric 
102fe6060f1SDimitry Andric /// The empty type list.
103fe6060f1SDimitry Andric using EmptyTypeList = TypeList<>;
104fe6060f1SDimitry Andric 
105fe6060f1SDimitry Andric /// Helper meta-function to determine if some type \c T is present or
106fe6060f1SDimitry Andric ///   a parent type in the list.
107fe6060f1SDimitry Andric template <typename AnyTypeList, typename T> struct TypeListContainsSuperOf {
108fe6060f1SDimitry Andric   static const bool value =
109fe6060f1SDimitry Andric       std::is_base_of<typename AnyTypeList::head, T>::value ||
110fe6060f1SDimitry Andric       TypeListContainsSuperOf<typename AnyTypeList::tail, T>::value;
111fe6060f1SDimitry Andric };
112fe6060f1SDimitry Andric template <typename T> struct TypeListContainsSuperOf<EmptyTypeList, T> {
113fe6060f1SDimitry Andric   static const bool value = false;
114fe6060f1SDimitry Andric };
115fe6060f1SDimitry Andric 
1160b57cec5SDimitry Andric /// Variadic function object.
1170b57cec5SDimitry Andric ///
1180b57cec5SDimitry Andric /// Most of the functions below that use VariadicFunction could be implemented
1190b57cec5SDimitry Andric /// using plain C++11 variadic functions, but the function object allows us to
1200b57cec5SDimitry Andric /// capture it on the dynamic matcher registry.
1210b57cec5SDimitry Andric template <typename ResultT, typename ArgT,
1220b57cec5SDimitry Andric           ResultT (*Func)(ArrayRef<const ArgT *>)>
1230b57cec5SDimitry Andric struct VariadicFunction {
124bdd1243dSDimitry Andric   ResultT operator()() const { return Func(std::nullopt); }
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric   template <typename... ArgsT>
1270b57cec5SDimitry Andric   ResultT operator()(const ArgT &Arg1, const ArgsT &... Args) const {
1280b57cec5SDimitry Andric     return Execute(Arg1, static_cast<const ArgT &>(Args)...);
1290b57cec5SDimitry Andric   }
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric   // We also allow calls with an already created array, in case the caller
1320b57cec5SDimitry Andric   // already had it.
1330b57cec5SDimitry Andric   ResultT operator()(ArrayRef<ArgT> Args) const {
13481ad6265SDimitry Andric     return Func(llvm::to_vector<8>(llvm::make_pointer_range(Args)));
1350b57cec5SDimitry Andric   }
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric private:
1380b57cec5SDimitry Andric   // Trampoline function to allow for implicit conversions to take place
1390b57cec5SDimitry Andric   // before we make the array.
1400b57cec5SDimitry Andric   template <typename... ArgsT> ResultT Execute(const ArgsT &... Args) const {
1410b57cec5SDimitry Andric     const ArgT *const ArgsArray[] = {&Args...};
1420b57cec5SDimitry Andric     return Func(ArrayRef<const ArgT *>(ArgsArray, sizeof...(ArgsT)));
1430b57cec5SDimitry Andric   }
1440b57cec5SDimitry Andric };
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric /// Unifies obtaining the underlying type of a regular node through
1470b57cec5SDimitry Andric /// `getType` and a TypedefNameDecl node through `getUnderlyingType`.
1480b57cec5SDimitry Andric inline QualType getUnderlyingType(const Expr &Node) { return Node.getType(); }
1490b57cec5SDimitry Andric 
1500b57cec5SDimitry Andric inline QualType getUnderlyingType(const ValueDecl &Node) {
1510b57cec5SDimitry Andric   return Node.getType();
1520b57cec5SDimitry Andric }
1530b57cec5SDimitry Andric inline QualType getUnderlyingType(const TypedefNameDecl &Node) {
1540b57cec5SDimitry Andric   return Node.getUnderlyingType();
1550b57cec5SDimitry Andric }
1560b57cec5SDimitry Andric inline QualType getUnderlyingType(const FriendDecl &Node) {
1570b57cec5SDimitry Andric   if (const TypeSourceInfo *TSI = Node.getFriendType())
1580b57cec5SDimitry Andric     return TSI->getType();
1590b57cec5SDimitry Andric   return QualType();
1600b57cec5SDimitry Andric }
1615ffd83dbSDimitry Andric inline QualType getUnderlyingType(const CXXBaseSpecifier &Node) {
1625ffd83dbSDimitry Andric   return Node.getType();
1635ffd83dbSDimitry Andric }
1640b57cec5SDimitry Andric 
165fe6060f1SDimitry Andric /// Unifies obtaining a `TypeSourceInfo` from different node types.
166fe6060f1SDimitry Andric template <typename T,
167fe6060f1SDimitry Andric           std::enable_if_t<TypeListContainsSuperOf<
168fe6060f1SDimitry Andric               TypeList<CXXBaseSpecifier, CXXCtorInitializer,
169fe6060f1SDimitry Andric                        CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr,
170fe6060f1SDimitry Andric                        CompoundLiteralExpr, DeclaratorDecl, ObjCPropertyDecl,
171fe6060f1SDimitry Andric                        TemplateArgumentLoc, TypedefNameDecl>,
172fe6060f1SDimitry Andric               T>::value> * = nullptr>
173fe6060f1SDimitry Andric inline TypeSourceInfo *GetTypeSourceInfo(const T &Node) {
174fe6060f1SDimitry Andric   return Node.getTypeSourceInfo();
175fe6060f1SDimitry Andric }
176fe6060f1SDimitry Andric template <typename T,
177fe6060f1SDimitry Andric           std::enable_if_t<TypeListContainsSuperOf<
178fe6060f1SDimitry Andric               TypeList<CXXFunctionalCastExpr, ExplicitCastExpr>, T>::value> * =
179fe6060f1SDimitry Andric               nullptr>
180fe6060f1SDimitry Andric inline TypeSourceInfo *GetTypeSourceInfo(const T &Node) {
181fe6060f1SDimitry Andric   return Node.getTypeInfoAsWritten();
182fe6060f1SDimitry Andric }
183fe6060f1SDimitry Andric inline TypeSourceInfo *GetTypeSourceInfo(const BlockDecl &Node) {
184fe6060f1SDimitry Andric   return Node.getSignatureAsWritten();
185fe6060f1SDimitry Andric }
186fe6060f1SDimitry Andric inline TypeSourceInfo *GetTypeSourceInfo(const CXXNewExpr &Node) {
187fe6060f1SDimitry Andric   return Node.getAllocatedTypeSourceInfo();
188fe6060f1SDimitry Andric }
189fe6060f1SDimitry Andric inline TypeSourceInfo *
190fe6060f1SDimitry Andric GetTypeSourceInfo(const ClassTemplateSpecializationDecl &Node) {
191fe6060f1SDimitry Andric   return Node.getTypeAsWritten();
192fe6060f1SDimitry Andric }
193fe6060f1SDimitry Andric 
1940b57cec5SDimitry Andric /// Unifies obtaining the FunctionProtoType pointer from both
1950b57cec5SDimitry Andric /// FunctionProtoType and FunctionDecl nodes..
1960b57cec5SDimitry Andric inline const FunctionProtoType *
1970b57cec5SDimitry Andric getFunctionProtoType(const FunctionProtoType &Node) {
1980b57cec5SDimitry Andric   return &Node;
1990b57cec5SDimitry Andric }
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric inline const FunctionProtoType *getFunctionProtoType(const FunctionDecl &Node) {
2020b57cec5SDimitry Andric   return Node.getType()->getAs<FunctionProtoType>();
2030b57cec5SDimitry Andric }
2040b57cec5SDimitry Andric 
2055ffd83dbSDimitry Andric /// Unifies obtaining the access specifier from Decl and CXXBaseSpecifier nodes.
2065ffd83dbSDimitry Andric inline clang::AccessSpecifier getAccessSpecifier(const Decl &Node) {
2075ffd83dbSDimitry Andric   return Node.getAccess();
2085ffd83dbSDimitry Andric }
2095ffd83dbSDimitry Andric 
2105ffd83dbSDimitry Andric inline clang::AccessSpecifier getAccessSpecifier(const CXXBaseSpecifier &Node) {
2115ffd83dbSDimitry Andric   return Node.getAccessSpecifier();
2125ffd83dbSDimitry Andric }
2135ffd83dbSDimitry Andric 
2140b57cec5SDimitry Andric /// Internal version of BoundNodes. Holds all the bound nodes.
2150b57cec5SDimitry Andric class BoundNodesMap {
2160b57cec5SDimitry Andric public:
2170b57cec5SDimitry Andric   /// Adds \c Node to the map with key \c ID.
2180b57cec5SDimitry Andric   ///
2190b57cec5SDimitry Andric   /// The node's base type should be in NodeBaseType or it will be unaccessible.
2205ffd83dbSDimitry Andric   void addNode(StringRef ID, const DynTypedNode &DynNode) {
2215ffd83dbSDimitry Andric     NodeMap[std::string(ID)] = DynNode;
2220b57cec5SDimitry Andric   }
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric   /// Returns the AST node bound to \c ID.
2250b57cec5SDimitry Andric   ///
2260b57cec5SDimitry Andric   /// Returns NULL if there was no node bound to \c ID or if there is a node but
2270b57cec5SDimitry Andric   /// it cannot be converted to the specified type.
2280b57cec5SDimitry Andric   template <typename T>
2290b57cec5SDimitry Andric   const T *getNodeAs(StringRef ID) const {
2300b57cec5SDimitry Andric     IDToNodeMap::const_iterator It = NodeMap.find(ID);
2310b57cec5SDimitry Andric     if (It == NodeMap.end()) {
2320b57cec5SDimitry Andric       return nullptr;
2330b57cec5SDimitry Andric     }
2340b57cec5SDimitry Andric     return It->second.get<T>();
2350b57cec5SDimitry Andric   }
2360b57cec5SDimitry Andric 
2375ffd83dbSDimitry Andric   DynTypedNode getNode(StringRef ID) const {
2380b57cec5SDimitry Andric     IDToNodeMap::const_iterator It = NodeMap.find(ID);
2390b57cec5SDimitry Andric     if (It == NodeMap.end()) {
2405ffd83dbSDimitry Andric       return DynTypedNode();
2410b57cec5SDimitry Andric     }
2420b57cec5SDimitry Andric     return It->second;
2430b57cec5SDimitry Andric   }
2440b57cec5SDimitry Andric 
2450b57cec5SDimitry Andric   /// Imposes an order on BoundNodesMaps.
2460b57cec5SDimitry Andric   bool operator<(const BoundNodesMap &Other) const {
2470b57cec5SDimitry Andric     return NodeMap < Other.NodeMap;
2480b57cec5SDimitry Andric   }
2490b57cec5SDimitry Andric 
2500b57cec5SDimitry Andric   /// A map from IDs to the bound nodes.
2510b57cec5SDimitry Andric   ///
2520b57cec5SDimitry Andric   /// Note that we're using std::map here, as for memoization:
2530b57cec5SDimitry Andric   /// - we need a comparison operator
2540b57cec5SDimitry Andric   /// - we need an assignment operator
2555ffd83dbSDimitry Andric   using IDToNodeMap = std::map<std::string, DynTypedNode, std::less<>>;
2560b57cec5SDimitry Andric 
2570b57cec5SDimitry Andric   const IDToNodeMap &getMap() const {
2580b57cec5SDimitry Andric     return NodeMap;
2590b57cec5SDimitry Andric   }
2600b57cec5SDimitry Andric 
2610b57cec5SDimitry Andric   /// Returns \c true if this \c BoundNodesMap can be compared, i.e. all
2620b57cec5SDimitry Andric   /// stored nodes have memoization data.
2630b57cec5SDimitry Andric   bool isComparable() const {
2640b57cec5SDimitry Andric     for (const auto &IDAndNode : NodeMap) {
2650b57cec5SDimitry Andric       if (!IDAndNode.second.getMemoizationData())
2660b57cec5SDimitry Andric         return false;
2670b57cec5SDimitry Andric     }
2680b57cec5SDimitry Andric     return true;
2690b57cec5SDimitry Andric   }
2700b57cec5SDimitry Andric 
2710b57cec5SDimitry Andric private:
2720b57cec5SDimitry Andric   IDToNodeMap NodeMap;
2730b57cec5SDimitry Andric };
2740b57cec5SDimitry Andric 
2750b57cec5SDimitry Andric /// Creates BoundNodesTree objects.
2760b57cec5SDimitry Andric ///
2770b57cec5SDimitry Andric /// The tree builder is used during the matching process to insert the bound
2780b57cec5SDimitry Andric /// nodes from the Id matcher.
2790b57cec5SDimitry Andric class BoundNodesTreeBuilder {
2800b57cec5SDimitry Andric public:
2810b57cec5SDimitry Andric   /// A visitor interface to visit all BoundNodes results for a
2820b57cec5SDimitry Andric   /// BoundNodesTree.
2830b57cec5SDimitry Andric   class Visitor {
2840b57cec5SDimitry Andric   public:
2850b57cec5SDimitry Andric     virtual ~Visitor() = default;
2860b57cec5SDimitry Andric 
2870b57cec5SDimitry Andric     /// Called multiple times during a single call to VisitMatches(...).
2880b57cec5SDimitry Andric     ///
2890b57cec5SDimitry Andric     /// 'BoundNodesView' contains the bound nodes for a single match.
2900b57cec5SDimitry Andric     virtual void visitMatch(const BoundNodes& BoundNodesView) = 0;
2910b57cec5SDimitry Andric   };
2920b57cec5SDimitry Andric 
2930b57cec5SDimitry Andric   /// Add a binding from an id to a node.
2945ffd83dbSDimitry Andric   void setBinding(StringRef Id, const DynTypedNode &DynNode) {
2950b57cec5SDimitry Andric     if (Bindings.empty())
2960b57cec5SDimitry Andric       Bindings.emplace_back();
2970b57cec5SDimitry Andric     for (BoundNodesMap &Binding : Bindings)
2980b57cec5SDimitry Andric       Binding.addNode(Id, DynNode);
2990b57cec5SDimitry Andric   }
3000b57cec5SDimitry Andric 
3010b57cec5SDimitry Andric   /// Adds a branch in the tree.
3020b57cec5SDimitry Andric   void addMatch(const BoundNodesTreeBuilder &Bindings);
3030b57cec5SDimitry Andric 
3040b57cec5SDimitry Andric   /// Visits all matches that this BoundNodesTree represents.
3050b57cec5SDimitry Andric   ///
3060b57cec5SDimitry Andric   /// The ownership of 'ResultVisitor' remains at the caller.
3070b57cec5SDimitry Andric   void visitMatches(Visitor* ResultVisitor);
3080b57cec5SDimitry Andric 
3090b57cec5SDimitry Andric   template <typename ExcludePredicate>
3100b57cec5SDimitry Andric   bool removeBindings(const ExcludePredicate &Predicate) {
311349cc55cSDimitry Andric     llvm::erase_if(Bindings, Predicate);
3120b57cec5SDimitry Andric     return !Bindings.empty();
3130b57cec5SDimitry Andric   }
3140b57cec5SDimitry Andric 
3150b57cec5SDimitry Andric   /// Imposes an order on BoundNodesTreeBuilders.
3160b57cec5SDimitry Andric   bool operator<(const BoundNodesTreeBuilder &Other) const {
3170b57cec5SDimitry Andric     return Bindings < Other.Bindings;
3180b57cec5SDimitry Andric   }
3190b57cec5SDimitry Andric 
3200b57cec5SDimitry Andric   /// Returns \c true if this \c BoundNodesTreeBuilder can be compared,
3210b57cec5SDimitry Andric   /// i.e. all stored node maps have memoization data.
3220b57cec5SDimitry Andric   bool isComparable() const {
3230b57cec5SDimitry Andric     for (const BoundNodesMap &NodesMap : Bindings) {
3240b57cec5SDimitry Andric       if (!NodesMap.isComparable())
3250b57cec5SDimitry Andric         return false;
3260b57cec5SDimitry Andric     }
3270b57cec5SDimitry Andric     return true;
3280b57cec5SDimitry Andric   }
3290b57cec5SDimitry Andric 
3300b57cec5SDimitry Andric private:
3310b57cec5SDimitry Andric   SmallVector<BoundNodesMap, 1> Bindings;
3320b57cec5SDimitry Andric };
3330b57cec5SDimitry Andric 
3340b57cec5SDimitry Andric class ASTMatchFinder;
3350b57cec5SDimitry Andric 
3360b57cec5SDimitry Andric /// Generic interface for all matchers.
3370b57cec5SDimitry Andric ///
3380b57cec5SDimitry Andric /// Used by the implementation of Matcher<T> and DynTypedMatcher.
3390b57cec5SDimitry Andric /// In general, implement MatcherInterface<T> or SingleNodeMatcherInterface<T>
3400b57cec5SDimitry Andric /// instead.
3410b57cec5SDimitry Andric class DynMatcherInterface
3420b57cec5SDimitry Andric     : public llvm::ThreadSafeRefCountedBase<DynMatcherInterface> {
3430b57cec5SDimitry Andric public:
3440b57cec5SDimitry Andric   virtual ~DynMatcherInterface() = default;
3450b57cec5SDimitry Andric 
3460b57cec5SDimitry Andric   /// Returns true if \p DynNode can be matched.
3470b57cec5SDimitry Andric   ///
3480b57cec5SDimitry Andric   /// May bind \p DynNode to an ID via \p Builder, or recurse into
3490b57cec5SDimitry Andric   /// the AST via \p Finder.
3505ffd83dbSDimitry Andric   virtual bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
3510b57cec5SDimitry Andric                           BoundNodesTreeBuilder *Builder) const = 0;
352480093f4SDimitry Andric 
353bdd1243dSDimitry Andric   virtual std::optional<clang::TraversalKind> TraversalKind() const {
354bdd1243dSDimitry Andric     return std::nullopt;
355480093f4SDimitry Andric   }
3560b57cec5SDimitry Andric };
3570b57cec5SDimitry Andric 
3580b57cec5SDimitry Andric /// Generic interface for matchers on an AST node of type T.
3590b57cec5SDimitry Andric ///
3600b57cec5SDimitry Andric /// Implement this if your matcher may need to inspect the children or
3610b57cec5SDimitry Andric /// descendants of the node or bind matched nodes to names. If you are
3620b57cec5SDimitry Andric /// writing a simple matcher that only inspects properties of the
3630b57cec5SDimitry Andric /// current node and doesn't care about its children or descendants,
3640b57cec5SDimitry Andric /// implement SingleNodeMatcherInterface instead.
3650b57cec5SDimitry Andric template <typename T>
3660b57cec5SDimitry Andric class MatcherInterface : public DynMatcherInterface {
3670b57cec5SDimitry Andric public:
3680b57cec5SDimitry Andric   /// Returns true if 'Node' can be matched.
3690b57cec5SDimitry Andric   ///
3700b57cec5SDimitry Andric   /// May bind 'Node' to an ID via 'Builder', or recurse into
3710b57cec5SDimitry Andric   /// the AST via 'Finder'.
3720b57cec5SDimitry Andric   virtual bool matches(const T &Node,
3730b57cec5SDimitry Andric                        ASTMatchFinder *Finder,
3740b57cec5SDimitry Andric                        BoundNodesTreeBuilder *Builder) const = 0;
3750b57cec5SDimitry Andric 
3765ffd83dbSDimitry Andric   bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
3770b57cec5SDimitry Andric                   BoundNodesTreeBuilder *Builder) const override {
3780b57cec5SDimitry Andric     return matches(DynNode.getUnchecked<T>(), Finder, Builder);
3790b57cec5SDimitry Andric   }
3800b57cec5SDimitry Andric };
3810b57cec5SDimitry Andric 
3820b57cec5SDimitry Andric /// Interface for matchers that only evaluate properties on a single
3830b57cec5SDimitry Andric /// node.
3840b57cec5SDimitry Andric template <typename T>
3850b57cec5SDimitry Andric class SingleNodeMatcherInterface : public MatcherInterface<T> {
3860b57cec5SDimitry Andric public:
3870b57cec5SDimitry Andric   /// Returns true if the matcher matches the provided node.
3880b57cec5SDimitry Andric   ///
3890b57cec5SDimitry Andric   /// A subclass must implement this instead of Matches().
3900b57cec5SDimitry Andric   virtual bool matchesNode(const T &Node) const = 0;
3910b57cec5SDimitry Andric 
3920b57cec5SDimitry Andric private:
3930b57cec5SDimitry Andric   /// Implements MatcherInterface::Matches.
3940b57cec5SDimitry Andric   bool matches(const T &Node,
3950b57cec5SDimitry Andric                ASTMatchFinder * /* Finder */,
3960b57cec5SDimitry Andric                BoundNodesTreeBuilder * /*  Builder */) const override {
3970b57cec5SDimitry Andric     return matchesNode(Node);
3980b57cec5SDimitry Andric   }
3990b57cec5SDimitry Andric };
4000b57cec5SDimitry Andric 
4010b57cec5SDimitry Andric template <typename> class Matcher;
4020b57cec5SDimitry Andric 
4030b57cec5SDimitry Andric /// Matcher that works on a \c DynTypedNode.
4040b57cec5SDimitry Andric ///
4050b57cec5SDimitry Andric /// It is constructed from a \c Matcher<T> object and redirects most calls to
4060b57cec5SDimitry Andric /// underlying matcher.
4070b57cec5SDimitry Andric /// It checks whether the \c DynTypedNode is convertible into the type of the
4080b57cec5SDimitry Andric /// underlying matcher and then do the actual match on the actual node, or
4090b57cec5SDimitry Andric /// return false if it is not convertible.
4100b57cec5SDimitry Andric class DynTypedMatcher {
4110b57cec5SDimitry Andric public:
4120b57cec5SDimitry Andric   /// Takes ownership of the provided implementation pointer.
4130b57cec5SDimitry Andric   template <typename T>
4140b57cec5SDimitry Andric   DynTypedMatcher(MatcherInterface<T> *Implementation)
4155ffd83dbSDimitry Andric       : SupportedKind(ASTNodeKind::getFromNodeKind<T>()),
4160b57cec5SDimitry Andric         RestrictKind(SupportedKind), Implementation(Implementation) {}
4170b57cec5SDimitry Andric 
4180b57cec5SDimitry Andric   /// Construct from a variadic function.
4190b57cec5SDimitry Andric   enum VariadicOperator {
4200b57cec5SDimitry Andric     /// Matches nodes for which all provided matchers match.
4210b57cec5SDimitry Andric     VO_AllOf,
4220b57cec5SDimitry Andric 
4230b57cec5SDimitry Andric     /// Matches nodes for which at least one of the provided matchers
4240b57cec5SDimitry Andric     /// matches.
4250b57cec5SDimitry Andric     VO_AnyOf,
4260b57cec5SDimitry Andric 
4270b57cec5SDimitry Andric     /// Matches nodes for which at least one of the provided matchers
4280b57cec5SDimitry Andric     /// matches, but doesn't stop at the first match.
4290b57cec5SDimitry Andric     VO_EachOf,
4300b57cec5SDimitry Andric 
431480093f4SDimitry Andric     /// Matches any node but executes all inner matchers to find result
432480093f4SDimitry Andric     /// bindings.
433480093f4SDimitry Andric     VO_Optionally,
434480093f4SDimitry Andric 
4350b57cec5SDimitry Andric     /// Matches nodes that do not match the provided matcher.
4360b57cec5SDimitry Andric     ///
4370b57cec5SDimitry Andric     /// Uses the variadic matcher interface, but fails if
4380b57cec5SDimitry Andric     /// InnerMatchers.size() != 1.
4390b57cec5SDimitry Andric     VO_UnaryNot
4400b57cec5SDimitry Andric   };
4410b57cec5SDimitry Andric 
4420b57cec5SDimitry Andric   static DynTypedMatcher
4435ffd83dbSDimitry Andric   constructVariadic(VariadicOperator Op, ASTNodeKind SupportedKind,
4440b57cec5SDimitry Andric                     std::vector<DynTypedMatcher> InnerMatchers);
4450b57cec5SDimitry Andric 
446480093f4SDimitry Andric   static DynTypedMatcher
447480093f4SDimitry Andric   constructRestrictedWrapper(const DynTypedMatcher &InnerMatcher,
4485ffd83dbSDimitry Andric                              ASTNodeKind RestrictKind);
449480093f4SDimitry Andric 
4500b57cec5SDimitry Andric   /// Get a "true" matcher for \p NodeKind.
4510b57cec5SDimitry Andric   ///
4520b57cec5SDimitry Andric   /// It only checks that the node is of the right kind.
4535ffd83dbSDimitry Andric   static DynTypedMatcher trueMatcher(ASTNodeKind NodeKind);
4540b57cec5SDimitry Andric 
4550b57cec5SDimitry Andric   void setAllowBind(bool AB) { AllowBind = AB; }
4560b57cec5SDimitry Andric 
4570b57cec5SDimitry Andric   /// Check whether this matcher could ever match a node of kind \p Kind.
4580b57cec5SDimitry Andric   /// \return \c false if this matcher will never match such a node. Otherwise,
4590b57cec5SDimitry Andric   /// return \c true.
4605ffd83dbSDimitry Andric   bool canMatchNodesOfKind(ASTNodeKind Kind) const;
4610b57cec5SDimitry Andric 
4620b57cec5SDimitry Andric   /// Return a matcher that points to the same implementation, but
4630b57cec5SDimitry Andric   ///   restricts the node types for \p Kind.
4645ffd83dbSDimitry Andric   DynTypedMatcher dynCastTo(const ASTNodeKind Kind) const;
4655ffd83dbSDimitry Andric 
466bdd1243dSDimitry Andric   /// Return a matcher that points to the same implementation, but sets the
4675ffd83dbSDimitry Andric   ///   traversal kind.
4685ffd83dbSDimitry Andric   ///
4695ffd83dbSDimitry Andric   /// If the traversal kind is already set, then \c TK overrides it.
4705ffd83dbSDimitry Andric   DynTypedMatcher withTraversalKind(TraversalKind TK);
4710b57cec5SDimitry Andric 
4720b57cec5SDimitry Andric   /// Returns true if the matcher matches the given \c DynNode.
4735ffd83dbSDimitry Andric   bool matches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
4745ffd83dbSDimitry Andric                BoundNodesTreeBuilder *Builder) const;
4750b57cec5SDimitry Andric 
4760b57cec5SDimitry Andric   /// Same as matches(), but skips the kind check.
4770b57cec5SDimitry Andric   ///
4780b57cec5SDimitry Andric   /// It is faster, but the caller must ensure the node is valid for the
4790b57cec5SDimitry Andric   /// kind of this matcher.
4805ffd83dbSDimitry Andric   bool matchesNoKindCheck(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
4810b57cec5SDimitry Andric                           BoundNodesTreeBuilder *Builder) const;
4820b57cec5SDimitry Andric 
4830b57cec5SDimitry Andric   /// Bind the specified \p ID to the matcher.
4840b57cec5SDimitry Andric   /// \return A new matcher with the \p ID bound to it if this matcher supports
485bdd1243dSDimitry Andric   ///   binding. Otherwise, returns an empty \c std::optional<>.
486bdd1243dSDimitry Andric   std::optional<DynTypedMatcher> tryBind(StringRef ID) const;
4870b57cec5SDimitry Andric 
4880b57cec5SDimitry Andric   /// Returns a unique \p ID for the matcher.
4890b57cec5SDimitry Andric   ///
4900b57cec5SDimitry Andric   /// Casting a Matcher<T> to Matcher<U> creates a matcher that has the
4910b57cec5SDimitry Andric   /// same \c Implementation pointer, but different \c RestrictKind. We need to
4920b57cec5SDimitry Andric   /// include both in the ID to make it unique.
4930b57cec5SDimitry Andric   ///
4940b57cec5SDimitry Andric   /// \c MatcherIDType supports operator< and provides strict weak ordering.
4955ffd83dbSDimitry Andric   using MatcherIDType = std::pair<ASTNodeKind, uint64_t>;
4960b57cec5SDimitry Andric   MatcherIDType getID() const {
4970b57cec5SDimitry Andric     /// FIXME: Document the requirements this imposes on matcher
4980b57cec5SDimitry Andric     /// implementations (no new() implementation_ during a Matches()).
4990b57cec5SDimitry Andric     return std::make_pair(RestrictKind,
5000b57cec5SDimitry Andric                           reinterpret_cast<uint64_t>(Implementation.get()));
5010b57cec5SDimitry Andric   }
5020b57cec5SDimitry Andric 
5030b57cec5SDimitry Andric   /// Returns the type this matcher works on.
5040b57cec5SDimitry Andric   ///
5050b57cec5SDimitry Andric   /// \c matches() will always return false unless the node passed is of this
5060b57cec5SDimitry Andric   /// or a derived type.
5075ffd83dbSDimitry Andric   ASTNodeKind getSupportedKind() const { return SupportedKind; }
5080b57cec5SDimitry Andric 
5090b57cec5SDimitry Andric   /// Returns \c true if the passed \c DynTypedMatcher can be converted
5100b57cec5SDimitry Andric   ///   to a \c Matcher<T>.
5110b57cec5SDimitry Andric   ///
5120b57cec5SDimitry Andric   /// This method verifies that the underlying matcher in \c Other can process
5130b57cec5SDimitry Andric   /// nodes of types T.
5140b57cec5SDimitry Andric   template <typename T> bool canConvertTo() const {
5155ffd83dbSDimitry Andric     return canConvertTo(ASTNodeKind::getFromNodeKind<T>());
5160b57cec5SDimitry Andric   }
5175ffd83dbSDimitry Andric   bool canConvertTo(ASTNodeKind To) const;
5180b57cec5SDimitry Andric 
5190b57cec5SDimitry Andric   /// Construct a \c Matcher<T> interface around the dynamic matcher.
5200b57cec5SDimitry Andric   ///
5210b57cec5SDimitry Andric   /// This method asserts that \c canConvertTo() is \c true. Callers
5220b57cec5SDimitry Andric   /// should call \c canConvertTo() first to make sure that \c this is
5230b57cec5SDimitry Andric   /// compatible with T.
5240b57cec5SDimitry Andric   template <typename T> Matcher<T> convertTo() const {
5250b57cec5SDimitry Andric     assert(canConvertTo<T>());
5260b57cec5SDimitry Andric     return unconditionalConvertTo<T>();
5270b57cec5SDimitry Andric   }
5280b57cec5SDimitry Andric 
5290b57cec5SDimitry Andric   /// Same as \c convertTo(), but does not check that the underlying
5300b57cec5SDimitry Andric   ///   matcher can handle a value of T.
5310b57cec5SDimitry Andric   ///
5320b57cec5SDimitry Andric   /// If it is not compatible, then this matcher will never match anything.
5330b57cec5SDimitry Andric   template <typename T> Matcher<T> unconditionalConvertTo() const;
5340b57cec5SDimitry Andric 
5355ffd83dbSDimitry Andric   /// Returns the \c TraversalKind respected by calls to `match()`, if any.
5365ffd83dbSDimitry Andric   ///
5375ffd83dbSDimitry Andric   /// Most matchers will not have a traversal kind set, instead relying on the
538bdd1243dSDimitry Andric   /// surrounding context. For those, \c std::nullopt is returned.
539bdd1243dSDimitry Andric   std::optional<clang::TraversalKind> getTraversalKind() const {
5405ffd83dbSDimitry Andric     return Implementation->TraversalKind();
5415ffd83dbSDimitry Andric   }
5425ffd83dbSDimitry Andric 
5430b57cec5SDimitry Andric private:
5445ffd83dbSDimitry Andric   DynTypedMatcher(ASTNodeKind SupportedKind, ASTNodeKind RestrictKind,
5450b57cec5SDimitry Andric                   IntrusiveRefCntPtr<DynMatcherInterface> Implementation)
5460b57cec5SDimitry Andric       : SupportedKind(SupportedKind), RestrictKind(RestrictKind),
5470b57cec5SDimitry Andric         Implementation(std::move(Implementation)) {}
5480b57cec5SDimitry Andric 
5490b57cec5SDimitry Andric   bool AllowBind = false;
5505ffd83dbSDimitry Andric   ASTNodeKind SupportedKind;
5510b57cec5SDimitry Andric 
5520b57cec5SDimitry Andric   /// A potentially stricter node kind.
5530b57cec5SDimitry Andric   ///
5540b57cec5SDimitry Andric   /// It allows to perform implicit and dynamic cast of matchers without
5550b57cec5SDimitry Andric   /// needing to change \c Implementation.
5565ffd83dbSDimitry Andric   ASTNodeKind RestrictKind;
5570b57cec5SDimitry Andric   IntrusiveRefCntPtr<DynMatcherInterface> Implementation;
5580b57cec5SDimitry Andric };
5590b57cec5SDimitry Andric 
5600b57cec5SDimitry Andric /// Wrapper of a MatcherInterface<T> *that allows copying.
5610b57cec5SDimitry Andric ///
5620b57cec5SDimitry Andric /// A Matcher<Base> can be used anywhere a Matcher<Derived> is
5630b57cec5SDimitry Andric /// required. This establishes an is-a relationship which is reverse
5640b57cec5SDimitry Andric /// to the AST hierarchy. In other words, Matcher<T> is contravariant
5650b57cec5SDimitry Andric /// with respect to T. The relationship is built via a type conversion
5660b57cec5SDimitry Andric /// operator rather than a type hierarchy to be able to templatize the
5670b57cec5SDimitry Andric /// type hierarchy instead of spelling it out.
5680b57cec5SDimitry Andric template <typename T>
5690b57cec5SDimitry Andric class Matcher {
5700b57cec5SDimitry Andric public:
5710b57cec5SDimitry Andric   /// Takes ownership of the provided implementation pointer.
5720b57cec5SDimitry Andric   explicit Matcher(MatcherInterface<T> *Implementation)
5730b57cec5SDimitry Andric       : Implementation(Implementation) {}
5740b57cec5SDimitry Andric 
5750b57cec5SDimitry Andric   /// Implicitly converts \c Other to a Matcher<T>.
5760b57cec5SDimitry Andric   ///
5770b57cec5SDimitry Andric   /// Requires \c T to be derived from \c From.
5780b57cec5SDimitry Andric   template <typename From>
5790b57cec5SDimitry Andric   Matcher(const Matcher<From> &Other,
5805ffd83dbSDimitry Andric           std::enable_if_t<std::is_base_of<From, T>::value &&
5815ffd83dbSDimitry Andric                            !std::is_same<From, T>::value> * = nullptr)
5820b57cec5SDimitry Andric       : Implementation(restrictMatcher(Other.Implementation)) {
5830b57cec5SDimitry Andric     assert(Implementation.getSupportedKind().isSame(
5845ffd83dbSDimitry Andric         ASTNodeKind::getFromNodeKind<T>()));
5850b57cec5SDimitry Andric   }
5860b57cec5SDimitry Andric 
5870b57cec5SDimitry Andric   /// Implicitly converts \c Matcher<Type> to \c Matcher<QualType>.
5880b57cec5SDimitry Andric   ///
5890b57cec5SDimitry Andric   /// The resulting matcher is not strict, i.e. ignores qualifiers.
5900b57cec5SDimitry Andric   template <typename TypeT>
5910b57cec5SDimitry Andric   Matcher(const Matcher<TypeT> &Other,
5925ffd83dbSDimitry Andric           std::enable_if_t<std::is_same<T, QualType>::value &&
5935ffd83dbSDimitry Andric                            std::is_same<TypeT, Type>::value> * = nullptr)
5940b57cec5SDimitry Andric       : Implementation(new TypeToQualType<TypeT>(Other)) {}
5950b57cec5SDimitry Andric 
5960b57cec5SDimitry Andric   /// Convert \c this into a \c Matcher<T> by applying dyn_cast<> to the
5970b57cec5SDimitry Andric   /// argument.
5980b57cec5SDimitry Andric   /// \c To must be a base class of \c T.
59981ad6265SDimitry Andric   template <typename To> Matcher<To> dynCastTo() const & {
6000b57cec5SDimitry Andric     static_assert(std::is_base_of<To, T>::value, "Invalid dynCast call.");
6010b57cec5SDimitry Andric     return Matcher<To>(Implementation);
6020b57cec5SDimitry Andric   }
6030b57cec5SDimitry Andric 
604fe6060f1SDimitry Andric   template <typename To> Matcher<To> dynCastTo() && {
605fe6060f1SDimitry Andric     static_assert(std::is_base_of<To, T>::value, "Invalid dynCast call.");
606fe6060f1SDimitry Andric     return Matcher<To>(std::move(Implementation));
607fe6060f1SDimitry Andric   }
608fe6060f1SDimitry Andric 
6090b57cec5SDimitry Andric   /// Forwards the call to the underlying MatcherInterface<T> pointer.
6100b57cec5SDimitry Andric   bool matches(const T &Node,
6110b57cec5SDimitry Andric                ASTMatchFinder *Finder,
6120b57cec5SDimitry Andric                BoundNodesTreeBuilder *Builder) const {
6135ffd83dbSDimitry Andric     return Implementation.matches(DynTypedNode::create(Node), Finder, Builder);
6140b57cec5SDimitry Andric   }
6150b57cec5SDimitry Andric 
6160b57cec5SDimitry Andric   /// Returns an ID that uniquely identifies the matcher.
6170b57cec5SDimitry Andric   DynTypedMatcher::MatcherIDType getID() const {
6180b57cec5SDimitry Andric     return Implementation.getID();
6190b57cec5SDimitry Andric   }
6200b57cec5SDimitry Andric 
6210b57cec5SDimitry Andric   /// Extract the dynamic matcher.
6220b57cec5SDimitry Andric   ///
6230b57cec5SDimitry Andric   /// The returned matcher keeps the same restrictions as \c this and remembers
6240b57cec5SDimitry Andric   /// that it is meant to support nodes of type \c T.
62581ad6265SDimitry Andric   operator DynTypedMatcher() const & { return Implementation; }
626fe6060f1SDimitry Andric 
627fe6060f1SDimitry Andric   operator DynTypedMatcher() && { return std::move(Implementation); }
6280b57cec5SDimitry Andric 
6290b57cec5SDimitry Andric   /// Allows the conversion of a \c Matcher<Type> to a \c
6300b57cec5SDimitry Andric   /// Matcher<QualType>.
6310b57cec5SDimitry Andric   ///
6320b57cec5SDimitry Andric   /// Depending on the constructor argument, the matcher is either strict, i.e.
6330b57cec5SDimitry Andric   /// does only matches in the absence of qualifiers, or not, i.e. simply
6340b57cec5SDimitry Andric   /// ignores any qualifiers.
6350b57cec5SDimitry Andric   template <typename TypeT>
6365ffd83dbSDimitry Andric   class TypeToQualType : public MatcherInterface<QualType> {
6375ffd83dbSDimitry Andric     const DynTypedMatcher InnerMatcher;
6385ffd83dbSDimitry Andric 
6390b57cec5SDimitry Andric   public:
6400b57cec5SDimitry Andric     TypeToQualType(const Matcher<TypeT> &InnerMatcher)
6415ffd83dbSDimitry Andric         : InnerMatcher(InnerMatcher) {}
6420b57cec5SDimitry Andric 
6430b57cec5SDimitry Andric     bool matches(const QualType &Node, ASTMatchFinder *Finder,
6440b57cec5SDimitry Andric                  BoundNodesTreeBuilder *Builder) const override {
6450b57cec5SDimitry Andric       if (Node.isNull())
6460b57cec5SDimitry Andric         return false;
6475ffd83dbSDimitry Andric       return this->InnerMatcher.matches(DynTypedNode::create(*Node), Finder,
6485ffd83dbSDimitry Andric                                         Builder);
6490b57cec5SDimitry Andric     }
650e8d8bef9SDimitry Andric 
651bdd1243dSDimitry Andric     std::optional<clang::TraversalKind> TraversalKind() const override {
652e8d8bef9SDimitry Andric       return this->InnerMatcher.getTraversalKind();
653e8d8bef9SDimitry Andric     }
6540b57cec5SDimitry Andric   };
6550b57cec5SDimitry Andric 
6560b57cec5SDimitry Andric private:
6570b57cec5SDimitry Andric   // For Matcher<T> <=> Matcher<U> conversions.
6580b57cec5SDimitry Andric   template <typename U> friend class Matcher;
6590b57cec5SDimitry Andric 
6600b57cec5SDimitry Andric   // For DynTypedMatcher::unconditionalConvertTo<T>.
6610b57cec5SDimitry Andric   friend class DynTypedMatcher;
6620b57cec5SDimitry Andric 
6630b57cec5SDimitry Andric   static DynTypedMatcher restrictMatcher(const DynTypedMatcher &Other) {
6645ffd83dbSDimitry Andric     return Other.dynCastTo(ASTNodeKind::getFromNodeKind<T>());
6650b57cec5SDimitry Andric   }
6660b57cec5SDimitry Andric 
6670b57cec5SDimitry Andric   explicit Matcher(const DynTypedMatcher &Implementation)
6680b57cec5SDimitry Andric       : Implementation(restrictMatcher(Implementation)) {
6695ffd83dbSDimitry Andric     assert(this->Implementation.getSupportedKind().isSame(
6705ffd83dbSDimitry Andric         ASTNodeKind::getFromNodeKind<T>()));
6710b57cec5SDimitry Andric   }
6720b57cec5SDimitry Andric 
6730b57cec5SDimitry Andric   DynTypedMatcher Implementation;
6740b57cec5SDimitry Andric };  // class Matcher
6750b57cec5SDimitry Andric 
6760b57cec5SDimitry Andric /// A convenient helper for creating a Matcher<T> without specifying
6770b57cec5SDimitry Andric /// the template type argument.
6780b57cec5SDimitry Andric template <typename T>
6790b57cec5SDimitry Andric inline Matcher<T> makeMatcher(MatcherInterface<T> *Implementation) {
6800b57cec5SDimitry Andric   return Matcher<T>(Implementation);
6810b57cec5SDimitry Andric }
6820b57cec5SDimitry Andric 
683e8d8bef9SDimitry Andric /// Interface that allows matchers to traverse the AST.
684e8d8bef9SDimitry Andric /// FIXME: Find a better name.
685e8d8bef9SDimitry Andric ///
686e8d8bef9SDimitry Andric /// This provides three entry methods for each base node type in the AST:
687e8d8bef9SDimitry Andric /// - \c matchesChildOf:
688e8d8bef9SDimitry Andric ///   Matches a matcher on every child node of the given node. Returns true
689e8d8bef9SDimitry Andric ///   if at least one child node could be matched.
690e8d8bef9SDimitry Andric /// - \c matchesDescendantOf:
691e8d8bef9SDimitry Andric ///   Matches a matcher on all descendant nodes of the given node. Returns true
692e8d8bef9SDimitry Andric ///   if at least one descendant matched.
693e8d8bef9SDimitry Andric /// - \c matchesAncestorOf:
694e8d8bef9SDimitry Andric ///   Matches a matcher on all ancestors of the given node. Returns true if
695e8d8bef9SDimitry Andric ///   at least one ancestor matched.
696e8d8bef9SDimitry Andric ///
697e8d8bef9SDimitry Andric /// FIXME: Currently we only allow Stmt and Decl nodes to start a traversal.
698e8d8bef9SDimitry Andric /// In the future, we want to implement this for all nodes for which it makes
699e8d8bef9SDimitry Andric /// sense. In the case of matchesAncestorOf, we'll want to implement it for
700e8d8bef9SDimitry Andric /// all nodes, as all nodes have ancestors.
701e8d8bef9SDimitry Andric class ASTMatchFinder {
702e8d8bef9SDimitry Andric public:
703e8d8bef9SDimitry Andric   /// Defines how bindings are processed on recursive matches.
704e8d8bef9SDimitry Andric   enum BindKind {
705e8d8bef9SDimitry Andric     /// Stop at the first match and only bind the first match.
706e8d8bef9SDimitry Andric     BK_First,
707e8d8bef9SDimitry Andric 
708e8d8bef9SDimitry Andric     /// Create results for all combinations of bindings that match.
709e8d8bef9SDimitry Andric     BK_All
710e8d8bef9SDimitry Andric   };
711e8d8bef9SDimitry Andric 
712e8d8bef9SDimitry Andric   /// Defines which ancestors are considered for a match.
713e8d8bef9SDimitry Andric   enum AncestorMatchMode {
714e8d8bef9SDimitry Andric     /// All ancestors.
715e8d8bef9SDimitry Andric     AMM_All,
716e8d8bef9SDimitry Andric 
717e8d8bef9SDimitry Andric     /// Direct parent only.
718e8d8bef9SDimitry Andric     AMM_ParentOnly
719e8d8bef9SDimitry Andric   };
720e8d8bef9SDimitry Andric 
721e8d8bef9SDimitry Andric   virtual ~ASTMatchFinder() = default;
722e8d8bef9SDimitry Andric 
723e8d8bef9SDimitry Andric   /// Returns true if the given C++ class is directly or indirectly derived
724e8d8bef9SDimitry Andric   /// from a base type matching \c base.
725e8d8bef9SDimitry Andric   ///
726e8d8bef9SDimitry Andric   /// A class is not considered to be derived from itself.
727e8d8bef9SDimitry Andric   virtual bool classIsDerivedFrom(const CXXRecordDecl *Declaration,
728e8d8bef9SDimitry Andric                                   const Matcher<NamedDecl> &Base,
729e8d8bef9SDimitry Andric                                   BoundNodesTreeBuilder *Builder,
730e8d8bef9SDimitry Andric                                   bool Directly) = 0;
731e8d8bef9SDimitry Andric 
732e8d8bef9SDimitry Andric   /// Returns true if the given Objective-C class is directly or indirectly
733e8d8bef9SDimitry Andric   /// derived from a base class matching \c base.
734e8d8bef9SDimitry Andric   ///
735e8d8bef9SDimitry Andric   /// A class is not considered to be derived from itself.
736e8d8bef9SDimitry Andric   virtual bool objcClassIsDerivedFrom(const ObjCInterfaceDecl *Declaration,
737e8d8bef9SDimitry Andric                                       const Matcher<NamedDecl> &Base,
738e8d8bef9SDimitry Andric                                       BoundNodesTreeBuilder *Builder,
739e8d8bef9SDimitry Andric                                       bool Directly) = 0;
740e8d8bef9SDimitry Andric 
741e8d8bef9SDimitry Andric   template <typename T>
742e8d8bef9SDimitry Andric   bool matchesChildOf(const T &Node, const DynTypedMatcher &Matcher,
743e8d8bef9SDimitry Andric                       BoundNodesTreeBuilder *Builder, BindKind Bind) {
744e8d8bef9SDimitry Andric     static_assert(std::is_base_of<Decl, T>::value ||
745e8d8bef9SDimitry Andric                       std::is_base_of<Stmt, T>::value ||
746e8d8bef9SDimitry Andric                       std::is_base_of<NestedNameSpecifier, T>::value ||
747e8d8bef9SDimitry Andric                       std::is_base_of<NestedNameSpecifierLoc, T>::value ||
748e8d8bef9SDimitry Andric                       std::is_base_of<TypeLoc, T>::value ||
749349cc55cSDimitry Andric                       std::is_base_of<QualType, T>::value ||
750349cc55cSDimitry Andric                       std::is_base_of<Attr, T>::value,
751e8d8bef9SDimitry Andric                   "unsupported type for recursive matching");
752e8d8bef9SDimitry Andric     return matchesChildOf(DynTypedNode::create(Node), getASTContext(), Matcher,
753e8d8bef9SDimitry Andric                           Builder, Bind);
754e8d8bef9SDimitry Andric   }
755e8d8bef9SDimitry Andric 
756e8d8bef9SDimitry Andric   template <typename T>
757e8d8bef9SDimitry Andric   bool matchesDescendantOf(const T &Node, const DynTypedMatcher &Matcher,
758e8d8bef9SDimitry Andric                            BoundNodesTreeBuilder *Builder, BindKind Bind) {
759e8d8bef9SDimitry Andric     static_assert(std::is_base_of<Decl, T>::value ||
760e8d8bef9SDimitry Andric                       std::is_base_of<Stmt, T>::value ||
761e8d8bef9SDimitry Andric                       std::is_base_of<NestedNameSpecifier, T>::value ||
762e8d8bef9SDimitry Andric                       std::is_base_of<NestedNameSpecifierLoc, T>::value ||
763e8d8bef9SDimitry Andric                       std::is_base_of<TypeLoc, T>::value ||
764349cc55cSDimitry Andric                       std::is_base_of<QualType, T>::value ||
765349cc55cSDimitry Andric                       std::is_base_of<Attr, T>::value,
766e8d8bef9SDimitry Andric                   "unsupported type for recursive matching");
767e8d8bef9SDimitry Andric     return matchesDescendantOf(DynTypedNode::create(Node), getASTContext(),
768e8d8bef9SDimitry Andric                                Matcher, Builder, Bind);
769e8d8bef9SDimitry Andric   }
770e8d8bef9SDimitry Andric 
771e8d8bef9SDimitry Andric   // FIXME: Implement support for BindKind.
772e8d8bef9SDimitry Andric   template <typename T>
773e8d8bef9SDimitry Andric   bool matchesAncestorOf(const T &Node, const DynTypedMatcher &Matcher,
774e8d8bef9SDimitry Andric                          BoundNodesTreeBuilder *Builder,
775e8d8bef9SDimitry Andric                          AncestorMatchMode MatchMode) {
776e8d8bef9SDimitry Andric     static_assert(std::is_base_of<Decl, T>::value ||
777e8d8bef9SDimitry Andric                       std::is_base_of<NestedNameSpecifierLoc, T>::value ||
778e8d8bef9SDimitry Andric                       std::is_base_of<Stmt, T>::value ||
779349cc55cSDimitry Andric                       std::is_base_of<TypeLoc, T>::value ||
780349cc55cSDimitry Andric                       std::is_base_of<Attr, T>::value,
781e8d8bef9SDimitry Andric                   "type not allowed for recursive matching");
782e8d8bef9SDimitry Andric     return matchesAncestorOf(DynTypedNode::create(Node), getASTContext(),
783e8d8bef9SDimitry Andric                              Matcher, Builder, MatchMode);
784e8d8bef9SDimitry Andric   }
785e8d8bef9SDimitry Andric 
786e8d8bef9SDimitry Andric   virtual ASTContext &getASTContext() const = 0;
787e8d8bef9SDimitry Andric 
788e8d8bef9SDimitry Andric   virtual bool IsMatchingInASTNodeNotSpelledInSource() const = 0;
789e8d8bef9SDimitry Andric 
790e8d8bef9SDimitry Andric   virtual bool IsMatchingInASTNodeNotAsIs() const = 0;
791e8d8bef9SDimitry Andric 
792e8d8bef9SDimitry Andric   bool isTraversalIgnoringImplicitNodes() const;
793e8d8bef9SDimitry Andric 
794e8d8bef9SDimitry Andric protected:
795e8d8bef9SDimitry Andric   virtual bool matchesChildOf(const DynTypedNode &Node, ASTContext &Ctx,
796e8d8bef9SDimitry Andric                               const DynTypedMatcher &Matcher,
797e8d8bef9SDimitry Andric                               BoundNodesTreeBuilder *Builder,
798e8d8bef9SDimitry Andric                               BindKind Bind) = 0;
799e8d8bef9SDimitry Andric 
800e8d8bef9SDimitry Andric   virtual bool matchesDescendantOf(const DynTypedNode &Node, ASTContext &Ctx,
801e8d8bef9SDimitry Andric                                    const DynTypedMatcher &Matcher,
802e8d8bef9SDimitry Andric                                    BoundNodesTreeBuilder *Builder,
803e8d8bef9SDimitry Andric                                    BindKind Bind) = 0;
804e8d8bef9SDimitry Andric 
805e8d8bef9SDimitry Andric   virtual bool matchesAncestorOf(const DynTypedNode &Node, ASTContext &Ctx,
806e8d8bef9SDimitry Andric                                  const DynTypedMatcher &Matcher,
807e8d8bef9SDimitry Andric                                  BoundNodesTreeBuilder *Builder,
808e8d8bef9SDimitry Andric                                  AncestorMatchMode MatchMode) = 0;
809e8d8bef9SDimitry Andric private:
810e8d8bef9SDimitry Andric   friend struct ASTChildrenNotSpelledInSourceScope;
811e8d8bef9SDimitry Andric   virtual bool isMatchingChildrenNotSpelledInSource() const = 0;
812e8d8bef9SDimitry Andric   virtual void setMatchingChildrenNotSpelledInSource(bool Set) = 0;
813e8d8bef9SDimitry Andric };
814e8d8bef9SDimitry Andric 
815e8d8bef9SDimitry Andric struct ASTChildrenNotSpelledInSourceScope {
816e8d8bef9SDimitry Andric   ASTChildrenNotSpelledInSourceScope(ASTMatchFinder *V, bool B)
817e8d8bef9SDimitry Andric       : MV(V), MB(V->isMatchingChildrenNotSpelledInSource()) {
818e8d8bef9SDimitry Andric     V->setMatchingChildrenNotSpelledInSource(B);
819e8d8bef9SDimitry Andric   }
820e8d8bef9SDimitry Andric   ~ASTChildrenNotSpelledInSourceScope() {
821e8d8bef9SDimitry Andric     MV->setMatchingChildrenNotSpelledInSource(MB);
822e8d8bef9SDimitry Andric   }
823e8d8bef9SDimitry Andric 
824e8d8bef9SDimitry Andric private:
825e8d8bef9SDimitry Andric   ASTMatchFinder *MV;
826e8d8bef9SDimitry Andric   bool MB;
827e8d8bef9SDimitry Andric };
828e8d8bef9SDimitry Andric 
8290b57cec5SDimitry Andric /// Specialization of the conversion functions for QualType.
8300b57cec5SDimitry Andric ///
8310b57cec5SDimitry Andric /// This specialization provides the Matcher<Type>->Matcher<QualType>
8320b57cec5SDimitry Andric /// conversion that the static API does.
8330b57cec5SDimitry Andric template <>
8340b57cec5SDimitry Andric inline Matcher<QualType> DynTypedMatcher::convertTo<QualType>() const {
8350b57cec5SDimitry Andric   assert(canConvertTo<QualType>());
8365ffd83dbSDimitry Andric   const ASTNodeKind SourceKind = getSupportedKind();
8375ffd83dbSDimitry Andric   if (SourceKind.isSame(ASTNodeKind::getFromNodeKind<Type>())) {
8380b57cec5SDimitry Andric     // We support implicit conversion from Matcher<Type> to Matcher<QualType>
8390b57cec5SDimitry Andric     return unconditionalConvertTo<Type>();
8400b57cec5SDimitry Andric   }
8410b57cec5SDimitry Andric   return unconditionalConvertTo<QualType>();
8420b57cec5SDimitry Andric }
8430b57cec5SDimitry Andric 
8440b57cec5SDimitry Andric /// Finds the first node in a range that matches the given matcher.
8450b57cec5SDimitry Andric template <typename MatcherT, typename IteratorT>
846e8d8bef9SDimitry Andric IteratorT matchesFirstInRange(const MatcherT &Matcher, IteratorT Start,
8470b57cec5SDimitry Andric                               IteratorT End, ASTMatchFinder *Finder,
8480b57cec5SDimitry Andric                               BoundNodesTreeBuilder *Builder) {
8490b57cec5SDimitry Andric   for (IteratorT I = Start; I != End; ++I) {
8500b57cec5SDimitry Andric     BoundNodesTreeBuilder Result(*Builder);
8510b57cec5SDimitry Andric     if (Matcher.matches(*I, Finder, &Result)) {
8520b57cec5SDimitry Andric       *Builder = std::move(Result);
853e8d8bef9SDimitry Andric       return I;
8540b57cec5SDimitry Andric     }
8550b57cec5SDimitry Andric   }
856e8d8bef9SDimitry Andric   return End;
8570b57cec5SDimitry Andric }
8580b57cec5SDimitry Andric 
8590b57cec5SDimitry Andric /// Finds the first node in a pointer range that matches the given
8600b57cec5SDimitry Andric /// matcher.
8610b57cec5SDimitry Andric template <typename MatcherT, typename IteratorT>
862e8d8bef9SDimitry Andric IteratorT matchesFirstInPointerRange(const MatcherT &Matcher, IteratorT Start,
8630b57cec5SDimitry Andric                                      IteratorT End, ASTMatchFinder *Finder,
8640b57cec5SDimitry Andric                                      BoundNodesTreeBuilder *Builder) {
8650b57cec5SDimitry Andric   for (IteratorT I = Start; I != End; ++I) {
8660b57cec5SDimitry Andric     BoundNodesTreeBuilder Result(*Builder);
8670b57cec5SDimitry Andric     if (Matcher.matches(**I, Finder, &Result)) {
8680b57cec5SDimitry Andric       *Builder = std::move(Result);
869e8d8bef9SDimitry Andric       return I;
8700b57cec5SDimitry Andric     }
8710b57cec5SDimitry Andric   }
872e8d8bef9SDimitry Andric   return End;
873e8d8bef9SDimitry Andric }
874e8d8bef9SDimitry Andric 
875e8d8bef9SDimitry Andric template <typename T, std::enable_if_t<!std::is_base_of<FunctionDecl, T>::value>
876e8d8bef9SDimitry Andric                           * = nullptr>
877e8d8bef9SDimitry Andric inline bool isDefaultedHelper(const T *) {
8780b57cec5SDimitry Andric   return false;
8790b57cec5SDimitry Andric }
880e8d8bef9SDimitry Andric inline bool isDefaultedHelper(const FunctionDecl *FD) {
881e8d8bef9SDimitry Andric   return FD->isDefaulted();
882e8d8bef9SDimitry Andric }
8830b57cec5SDimitry Andric 
8840b57cec5SDimitry Andric // Metafunction to determine if type T has a member called getDecl.
8850b57cec5SDimitry Andric template <typename Ty>
8860b57cec5SDimitry Andric class has_getDecl {
8870b57cec5SDimitry Andric   using yes = char[1];
8880b57cec5SDimitry Andric   using no = char[2];
8890b57cec5SDimitry Andric 
8900b57cec5SDimitry Andric   template <typename Inner>
8910b57cec5SDimitry Andric   static yes& test(Inner *I, decltype(I->getDecl()) * = nullptr);
8920b57cec5SDimitry Andric 
8930b57cec5SDimitry Andric   template <typename>
8940b57cec5SDimitry Andric   static no& test(...);
8950b57cec5SDimitry Andric 
8960b57cec5SDimitry Andric public:
8970b57cec5SDimitry Andric   static const bool value = sizeof(test<Ty>(nullptr)) == sizeof(yes);
8980b57cec5SDimitry Andric };
8990b57cec5SDimitry Andric 
9000b57cec5SDimitry Andric /// Matches overloaded operators with a specific name.
9010b57cec5SDimitry Andric ///
9020b57cec5SDimitry Andric /// The type argument ArgT is not used by this matcher but is used by
903fe6060f1SDimitry Andric /// PolymorphicMatcher and should be StringRef.
9040b57cec5SDimitry Andric template <typename T, typename ArgT>
9050b57cec5SDimitry Andric class HasOverloadedOperatorNameMatcher : public SingleNodeMatcherInterface<T> {
9060b57cec5SDimitry Andric   static_assert(std::is_same<T, CXXOperatorCallExpr>::value ||
9070b57cec5SDimitry Andric                 std::is_base_of<FunctionDecl, T>::value,
9080b57cec5SDimitry Andric                 "unsupported class for matcher");
9095ffd83dbSDimitry Andric   static_assert(std::is_same<ArgT, std::vector<std::string>>::value,
9105ffd83dbSDimitry Andric                 "argument type must be std::vector<std::string>");
9110b57cec5SDimitry Andric 
9120b57cec5SDimitry Andric public:
9135ffd83dbSDimitry Andric   explicit HasOverloadedOperatorNameMatcher(std::vector<std::string> Names)
9145ffd83dbSDimitry Andric       : SingleNodeMatcherInterface<T>(), Names(std::move(Names)) {}
9150b57cec5SDimitry Andric 
9160b57cec5SDimitry Andric   bool matchesNode(const T &Node) const override {
9170b57cec5SDimitry Andric     return matchesSpecialized(Node);
9180b57cec5SDimitry Andric   }
9190b57cec5SDimitry Andric 
9200b57cec5SDimitry Andric private:
9210b57cec5SDimitry Andric 
9220b57cec5SDimitry Andric   /// CXXOperatorCallExpr exist only for calls to overloaded operators
9230b57cec5SDimitry Andric   /// so this function returns true if the call is to an operator of the given
9240b57cec5SDimitry Andric   /// name.
9250b57cec5SDimitry Andric   bool matchesSpecialized(const CXXOperatorCallExpr &Node) const {
9265ffd83dbSDimitry Andric     return llvm::is_contained(Names, getOperatorSpelling(Node.getOperator()));
9270b57cec5SDimitry Andric   }
9280b57cec5SDimitry Andric 
9290b57cec5SDimitry Andric   /// Returns true only if CXXMethodDecl represents an overloaded
9300b57cec5SDimitry Andric   /// operator and has the given operator name.
9310b57cec5SDimitry Andric   bool matchesSpecialized(const FunctionDecl &Node) const {
9320b57cec5SDimitry Andric     return Node.isOverloadedOperator() &&
9335ffd83dbSDimitry Andric            llvm::is_contained(
9345ffd83dbSDimitry Andric                Names, getOperatorSpelling(Node.getOverloadedOperator()));
9350b57cec5SDimitry Andric   }
9360b57cec5SDimitry Andric 
937fe6060f1SDimitry Andric   std::vector<std::string> Names;
9380b57cec5SDimitry Andric };
9390b57cec5SDimitry Andric 
9400b57cec5SDimitry Andric /// Matches named declarations with a specific name.
9410b57cec5SDimitry Andric ///
9420b57cec5SDimitry Andric /// See \c hasName() and \c hasAnyName() in ASTMatchers.h for details.
9430b57cec5SDimitry Andric class HasNameMatcher : public SingleNodeMatcherInterface<NamedDecl> {
9440b57cec5SDimitry Andric  public:
9450b57cec5SDimitry Andric   explicit HasNameMatcher(std::vector<std::string> Names);
9460b57cec5SDimitry Andric 
9470b57cec5SDimitry Andric   bool matchesNode(const NamedDecl &Node) const override;
9480b57cec5SDimitry Andric 
9490b57cec5SDimitry Andric private:
9500b57cec5SDimitry Andric   /// Unqualified match routine.
9510b57cec5SDimitry Andric   ///
9520b57cec5SDimitry Andric   /// It is much faster than the full match, but it only works for unqualified
9530b57cec5SDimitry Andric   /// matches.
9540b57cec5SDimitry Andric   bool matchesNodeUnqualified(const NamedDecl &Node) const;
9550b57cec5SDimitry Andric 
9560b57cec5SDimitry Andric   /// Full match routine
9570b57cec5SDimitry Andric   ///
9580b57cec5SDimitry Andric   /// Fast implementation for the simple case of a named declaration at
9590b57cec5SDimitry Andric   /// namespace or RecordDecl scope.
9600b57cec5SDimitry Andric   /// It is slower than matchesNodeUnqualified, but faster than
9610b57cec5SDimitry Andric   /// matchesNodeFullSlow.
9620b57cec5SDimitry Andric   bool matchesNodeFullFast(const NamedDecl &Node) const;
9630b57cec5SDimitry Andric 
9640b57cec5SDimitry Andric   /// Full match routine
9650b57cec5SDimitry Andric   ///
9660b57cec5SDimitry Andric   /// It generates the fully qualified name of the declaration (which is
9670b57cec5SDimitry Andric   /// expensive) before trying to match.
9680b57cec5SDimitry Andric   /// It is slower but simple and works on all cases.
9690b57cec5SDimitry Andric   bool matchesNodeFullSlow(const NamedDecl &Node) const;
9700b57cec5SDimitry Andric 
971fe6060f1SDimitry Andric   bool UseUnqualifiedMatch;
972fe6060f1SDimitry Andric   std::vector<std::string> Names;
9730b57cec5SDimitry Andric };
9740b57cec5SDimitry Andric 
9750b57cec5SDimitry Andric /// Trampoline function to use VariadicFunction<> to construct a
9760b57cec5SDimitry Andric ///        HasNameMatcher.
9770b57cec5SDimitry Andric Matcher<NamedDecl> hasAnyNameFunc(ArrayRef<const StringRef *> NameRefs);
9780b57cec5SDimitry Andric 
9790b57cec5SDimitry Andric /// Trampoline function to use VariadicFunction<> to construct a
9800b57cec5SDimitry Andric ///        hasAnySelector matcher.
9810b57cec5SDimitry Andric Matcher<ObjCMessageExpr> hasAnySelectorFunc(
9820b57cec5SDimitry Andric     ArrayRef<const StringRef *> NameRefs);
9830b57cec5SDimitry Andric 
9840b57cec5SDimitry Andric /// Matches declarations for QualType and CallExpr.
9850b57cec5SDimitry Andric ///
986fe6060f1SDimitry Andric /// Type argument DeclMatcherT is required by PolymorphicMatcher but
9870b57cec5SDimitry Andric /// not actually used.
9880b57cec5SDimitry Andric template <typename T, typename DeclMatcherT>
9895ffd83dbSDimitry Andric class HasDeclarationMatcher : public MatcherInterface<T> {
9900b57cec5SDimitry Andric   static_assert(std::is_same<DeclMatcherT, Matcher<Decl>>::value,
9910b57cec5SDimitry Andric                 "instantiated with wrong types");
9920b57cec5SDimitry Andric 
993fe6060f1SDimitry Andric   DynTypedMatcher InnerMatcher;
9945ffd83dbSDimitry Andric 
9950b57cec5SDimitry Andric public:
9960b57cec5SDimitry Andric   explicit HasDeclarationMatcher(const Matcher<Decl> &InnerMatcher)
9975ffd83dbSDimitry Andric       : InnerMatcher(InnerMatcher) {}
9980b57cec5SDimitry Andric 
9990b57cec5SDimitry Andric   bool matches(const T &Node, ASTMatchFinder *Finder,
10000b57cec5SDimitry Andric                BoundNodesTreeBuilder *Builder) const override {
10010b57cec5SDimitry Andric     return matchesSpecialized(Node, Finder, Builder);
10020b57cec5SDimitry Andric   }
10030b57cec5SDimitry Andric 
10040b57cec5SDimitry Andric private:
10050b57cec5SDimitry Andric   /// Forwards to matching on the underlying type of the QualType.
10060b57cec5SDimitry Andric   bool matchesSpecialized(const QualType &Node, ASTMatchFinder *Finder,
10070b57cec5SDimitry Andric                           BoundNodesTreeBuilder *Builder) const {
10080b57cec5SDimitry Andric     if (Node.isNull())
10090b57cec5SDimitry Andric       return false;
10100b57cec5SDimitry Andric 
10110b57cec5SDimitry Andric     return matchesSpecialized(*Node, Finder, Builder);
10120b57cec5SDimitry Andric   }
10130b57cec5SDimitry Andric 
10140b57cec5SDimitry Andric   /// Finds the best declaration for a type and returns whether the inner
10150b57cec5SDimitry Andric   /// matcher matches on it.
10160b57cec5SDimitry Andric   bool matchesSpecialized(const Type &Node, ASTMatchFinder *Finder,
10170b57cec5SDimitry Andric                           BoundNodesTreeBuilder *Builder) const {
10180b57cec5SDimitry Andric     // DeducedType does not have declarations of its own, so
10190b57cec5SDimitry Andric     // match the deduced type instead.
10200b57cec5SDimitry Andric     if (const auto *S = dyn_cast<DeducedType>(&Node)) {
1021349cc55cSDimitry Andric       QualType DT = S->getDeducedType();
1022349cc55cSDimitry Andric       return !DT.isNull() ? matchesSpecialized(*DT, Finder, Builder) : false;
10230b57cec5SDimitry Andric     }
10240b57cec5SDimitry Andric 
10250b57cec5SDimitry Andric     // First, for any types that have a declaration, extract the declaration and
10260b57cec5SDimitry Andric     // match on it.
1027349cc55cSDimitry Andric     if (const auto *S = dyn_cast<TagType>(&Node)) {
10280b57cec5SDimitry Andric       return matchesDecl(S->getDecl(), Finder, Builder);
10290b57cec5SDimitry Andric     }
1030349cc55cSDimitry Andric     if (const auto *S = dyn_cast<InjectedClassNameType>(&Node)) {
10310b57cec5SDimitry Andric       return matchesDecl(S->getDecl(), Finder, Builder);
10320b57cec5SDimitry Andric     }
1033349cc55cSDimitry Andric     if (const auto *S = dyn_cast<TemplateTypeParmType>(&Node)) {
10340b57cec5SDimitry Andric       return matchesDecl(S->getDecl(), Finder, Builder);
10350b57cec5SDimitry Andric     }
1036349cc55cSDimitry Andric     if (const auto *S = dyn_cast<TypedefType>(&Node)) {
10370b57cec5SDimitry Andric       return matchesDecl(S->getDecl(), Finder, Builder);
10380b57cec5SDimitry Andric     }
1039349cc55cSDimitry Andric     if (const auto *S = dyn_cast<UnresolvedUsingType>(&Node)) {
10400b57cec5SDimitry Andric       return matchesDecl(S->getDecl(), Finder, Builder);
10410b57cec5SDimitry Andric     }
1042349cc55cSDimitry Andric     if (const auto *S = dyn_cast<ObjCObjectType>(&Node)) {
10430b57cec5SDimitry Andric       return matchesDecl(S->getInterface(), Finder, Builder);
10440b57cec5SDimitry Andric     }
10450b57cec5SDimitry Andric 
10460b57cec5SDimitry Andric     // A SubstTemplateTypeParmType exists solely to mark a type substitution
10470b57cec5SDimitry Andric     // on the instantiated template. As users usually want to match the
10480b57cec5SDimitry Andric     // template parameter on the uninitialized template, we can always desugar
10490b57cec5SDimitry Andric     // one level without loss of expressivness.
10500b57cec5SDimitry Andric     // For example, given:
10510b57cec5SDimitry Andric     //   template<typename T> struct X { T t; } class A {}; X<A> a;
10520b57cec5SDimitry Andric     // The following matcher will match, which otherwise would not:
10530b57cec5SDimitry Andric     //   fieldDecl(hasType(pointerType())).
1054349cc55cSDimitry Andric     if (const auto *S = dyn_cast<SubstTemplateTypeParmType>(&Node)) {
10550b57cec5SDimitry Andric       return matchesSpecialized(S->getReplacementType(), Finder, Builder);
10560b57cec5SDimitry Andric     }
10570b57cec5SDimitry Andric 
10580b57cec5SDimitry Andric     // For template specialization types, we want to match the template
10590b57cec5SDimitry Andric     // declaration, as long as the type is still dependent, and otherwise the
10600b57cec5SDimitry Andric     // declaration of the instantiated tag type.
1061349cc55cSDimitry Andric     if (const auto *S = dyn_cast<TemplateSpecializationType>(&Node)) {
10620b57cec5SDimitry Andric       if (!S->isTypeAlias() && S->isSugared()) {
10630b57cec5SDimitry Andric         // If the template is non-dependent, we want to match the instantiated
10640b57cec5SDimitry Andric         // tag type.
10650b57cec5SDimitry Andric         // For example, given:
10660b57cec5SDimitry Andric         //   template<typename T> struct X {}; X<int> a;
10670b57cec5SDimitry Andric         // The following matcher will match, which otherwise would not:
10680b57cec5SDimitry Andric         //   templateSpecializationType(hasDeclaration(cxxRecordDecl())).
10690b57cec5SDimitry Andric         return matchesSpecialized(*S->desugar(), Finder, Builder);
10700b57cec5SDimitry Andric       }
10710b57cec5SDimitry Andric       // If the template is dependent or an alias, match the template
10720b57cec5SDimitry Andric       // declaration.
10730b57cec5SDimitry Andric       return matchesDecl(S->getTemplateName().getAsTemplateDecl(), Finder,
10740b57cec5SDimitry Andric                          Builder);
10750b57cec5SDimitry Andric     }
10760b57cec5SDimitry Andric 
10770b57cec5SDimitry Andric     // FIXME: We desugar elaborated types. This makes the assumption that users
10780b57cec5SDimitry Andric     // do never want to match on whether a type is elaborated - there are
10790b57cec5SDimitry Andric     // arguments for both sides; for now, continue desugaring.
1080349cc55cSDimitry Andric     if (const auto *S = dyn_cast<ElaboratedType>(&Node)) {
10810b57cec5SDimitry Andric       return matchesSpecialized(S->desugar(), Finder, Builder);
10820b57cec5SDimitry Andric     }
10830eae32dcSDimitry Andric     // Similarly types found via using declarations.
10840eae32dcSDimitry Andric     // These are *usually* meaningless sugar, and this matches the historical
10850eae32dcSDimitry Andric     // behavior prior to the introduction of UsingType.
10860eae32dcSDimitry Andric     if (const auto *S = dyn_cast<UsingType>(&Node)) {
10870eae32dcSDimitry Andric       return matchesSpecialized(S->desugar(), Finder, Builder);
10880eae32dcSDimitry Andric     }
10890b57cec5SDimitry Andric     return false;
10900b57cec5SDimitry Andric   }
10910b57cec5SDimitry Andric 
10920b57cec5SDimitry Andric   /// Extracts the Decl the DeclRefExpr references and returns whether
10930b57cec5SDimitry Andric   /// the inner matcher matches on it.
10940b57cec5SDimitry Andric   bool matchesSpecialized(const DeclRefExpr &Node, ASTMatchFinder *Finder,
10950b57cec5SDimitry Andric                           BoundNodesTreeBuilder *Builder) const {
10960b57cec5SDimitry Andric     return matchesDecl(Node.getDecl(), Finder, Builder);
10970b57cec5SDimitry Andric   }
10980b57cec5SDimitry Andric 
10990b57cec5SDimitry Andric   /// Extracts the Decl of the callee of a CallExpr and returns whether
11000b57cec5SDimitry Andric   /// the inner matcher matches on it.
11010b57cec5SDimitry Andric   bool matchesSpecialized(const CallExpr &Node, ASTMatchFinder *Finder,
11020b57cec5SDimitry Andric                           BoundNodesTreeBuilder *Builder) const {
11030b57cec5SDimitry Andric     return matchesDecl(Node.getCalleeDecl(), Finder, Builder);
11040b57cec5SDimitry Andric   }
11050b57cec5SDimitry Andric 
11060b57cec5SDimitry Andric   /// Extracts the Decl of the constructor call and returns whether the
11070b57cec5SDimitry Andric   /// inner matcher matches on it.
11080b57cec5SDimitry Andric   bool matchesSpecialized(const CXXConstructExpr &Node,
11090b57cec5SDimitry Andric                           ASTMatchFinder *Finder,
11100b57cec5SDimitry Andric                           BoundNodesTreeBuilder *Builder) const {
11110b57cec5SDimitry Andric     return matchesDecl(Node.getConstructor(), Finder, Builder);
11120b57cec5SDimitry Andric   }
11130b57cec5SDimitry Andric 
11140b57cec5SDimitry Andric   bool matchesSpecialized(const ObjCIvarRefExpr &Node,
11150b57cec5SDimitry Andric                           ASTMatchFinder *Finder,
11160b57cec5SDimitry Andric                           BoundNodesTreeBuilder *Builder) const {
11170b57cec5SDimitry Andric     return matchesDecl(Node.getDecl(), Finder, Builder);
11180b57cec5SDimitry Andric   }
11190b57cec5SDimitry Andric 
11200b57cec5SDimitry Andric   /// Extracts the operator new of the new call and returns whether the
11210b57cec5SDimitry Andric   /// inner matcher matches on it.
11220b57cec5SDimitry Andric   bool matchesSpecialized(const CXXNewExpr &Node,
11230b57cec5SDimitry Andric                           ASTMatchFinder *Finder,
11240b57cec5SDimitry Andric                           BoundNodesTreeBuilder *Builder) const {
11250b57cec5SDimitry Andric     return matchesDecl(Node.getOperatorNew(), Finder, Builder);
11260b57cec5SDimitry Andric   }
11270b57cec5SDimitry Andric 
11280b57cec5SDimitry Andric   /// Extracts the \c ValueDecl a \c MemberExpr refers to and returns
11290b57cec5SDimitry Andric   /// whether the inner matcher matches on it.
11300b57cec5SDimitry Andric   bool matchesSpecialized(const MemberExpr &Node,
11310b57cec5SDimitry Andric                           ASTMatchFinder *Finder,
11320b57cec5SDimitry Andric                           BoundNodesTreeBuilder *Builder) const {
11330b57cec5SDimitry Andric     return matchesDecl(Node.getMemberDecl(), Finder, Builder);
11340b57cec5SDimitry Andric   }
11350b57cec5SDimitry Andric 
11360b57cec5SDimitry Andric   /// Extracts the \c LabelDecl a \c AddrLabelExpr refers to and returns
11370b57cec5SDimitry Andric   /// whether the inner matcher matches on it.
11380b57cec5SDimitry Andric   bool matchesSpecialized(const AddrLabelExpr &Node,
11390b57cec5SDimitry Andric                           ASTMatchFinder *Finder,
11400b57cec5SDimitry Andric                           BoundNodesTreeBuilder *Builder) const {
11410b57cec5SDimitry Andric     return matchesDecl(Node.getLabel(), Finder, Builder);
11420b57cec5SDimitry Andric   }
11430b57cec5SDimitry Andric 
11440b57cec5SDimitry Andric   /// Extracts the declaration of a LabelStmt and returns whether the
11450b57cec5SDimitry Andric   /// inner matcher matches on it.
11460b57cec5SDimitry Andric   bool matchesSpecialized(const LabelStmt &Node, ASTMatchFinder *Finder,
11470b57cec5SDimitry Andric                           BoundNodesTreeBuilder *Builder) const {
11480b57cec5SDimitry Andric     return matchesDecl(Node.getDecl(), Finder, Builder);
11490b57cec5SDimitry Andric   }
11500b57cec5SDimitry Andric 
11510b57cec5SDimitry Andric   /// Returns whether the inner matcher \c Node. Returns false if \c Node
11520b57cec5SDimitry Andric   /// is \c NULL.
11530b57cec5SDimitry Andric   bool matchesDecl(const Decl *Node, ASTMatchFinder *Finder,
11540b57cec5SDimitry Andric                    BoundNodesTreeBuilder *Builder) const {
1155e8d8bef9SDimitry Andric     return Node != nullptr &&
1156e8d8bef9SDimitry Andric            !(Finder->isTraversalIgnoringImplicitNodes() &&
1157e8d8bef9SDimitry Andric              Node->isImplicit()) &&
1158e8d8bef9SDimitry Andric            this->InnerMatcher.matches(DynTypedNode::create(*Node), Finder,
1159e8d8bef9SDimitry Andric                                       Builder);
11600b57cec5SDimitry Andric   }
11610b57cec5SDimitry Andric };
11620b57cec5SDimitry Andric 
11630b57cec5SDimitry Andric /// IsBaseType<T>::value is true if T is a "base" type in the AST
11640b57cec5SDimitry Andric /// node class hierarchies.
11650b57cec5SDimitry Andric template <typename T>
11660b57cec5SDimitry Andric struct IsBaseType {
11670b57cec5SDimitry Andric   static const bool value =
1168e8d8bef9SDimitry Andric       std::is_same<T, Decl>::value || std::is_same<T, Stmt>::value ||
1169e8d8bef9SDimitry Andric       std::is_same<T, QualType>::value || std::is_same<T, Type>::value ||
11700b57cec5SDimitry Andric       std::is_same<T, TypeLoc>::value ||
11710b57cec5SDimitry Andric       std::is_same<T, NestedNameSpecifier>::value ||
11720b57cec5SDimitry Andric       std::is_same<T, NestedNameSpecifierLoc>::value ||
1173e8d8bef9SDimitry Andric       std::is_same<T, CXXCtorInitializer>::value ||
1174349cc55cSDimitry Andric       std::is_same<T, TemplateArgumentLoc>::value ||
1175349cc55cSDimitry Andric       std::is_same<T, Attr>::value;
11760b57cec5SDimitry Andric };
11770b57cec5SDimitry Andric template <typename T>
11780b57cec5SDimitry Andric const bool IsBaseType<T>::value;
11790b57cec5SDimitry Andric 
11800b57cec5SDimitry Andric /// A "type list" that contains all types.
11810b57cec5SDimitry Andric ///
11820b57cec5SDimitry Andric /// Useful for matchers like \c anything and \c unless.
11830b57cec5SDimitry Andric using AllNodeBaseTypes =
11840b57cec5SDimitry Andric     TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, QualType,
1185349cc55cSDimitry Andric              Type, TypeLoc, CXXCtorInitializer, Attr>;
11860b57cec5SDimitry Andric 
11870b57cec5SDimitry Andric /// Helper meta-function to extract the argument out of a function of
11880b57cec5SDimitry Andric ///   type void(Arg).
11890b57cec5SDimitry Andric ///
11900b57cec5SDimitry Andric /// See AST_POLYMORPHIC_SUPPORTED_TYPES for details.
11910b57cec5SDimitry Andric template <class T> struct ExtractFunctionArgMeta;
11920b57cec5SDimitry Andric template <class T> struct ExtractFunctionArgMeta<void(T)> {
11930b57cec5SDimitry Andric   using type = T;
11940b57cec5SDimitry Andric };
11950b57cec5SDimitry Andric 
1196fe6060f1SDimitry Andric template <class T, class Tuple, std::size_t... I>
1197fe6060f1SDimitry Andric constexpr T *new_from_tuple_impl(Tuple &&t, std::index_sequence<I...>) {
1198fe6060f1SDimitry Andric   return new T(std::get<I>(std::forward<Tuple>(t))...);
1199fe6060f1SDimitry Andric }
1200fe6060f1SDimitry Andric 
1201fe6060f1SDimitry Andric template <class T, class Tuple> constexpr T *new_from_tuple(Tuple &&t) {
1202fe6060f1SDimitry Andric   return new_from_tuple_impl<T>(
1203fe6060f1SDimitry Andric       std::forward<Tuple>(t),
1204fe6060f1SDimitry Andric       std::make_index_sequence<
1205fe6060f1SDimitry Andric           std::tuple_size<std::remove_reference_t<Tuple>>::value>{});
1206fe6060f1SDimitry Andric }
1207fe6060f1SDimitry Andric 
12080b57cec5SDimitry Andric /// Default type lists for ArgumentAdaptingMatcher matchers.
12090b57cec5SDimitry Andric using AdaptativeDefaultFromTypes = AllNodeBaseTypes;
12100b57cec5SDimitry Andric using AdaptativeDefaultToTypes =
12110b57cec5SDimitry Andric     TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, TypeLoc,
1212349cc55cSDimitry Andric              QualType, Attr>;
12130b57cec5SDimitry Andric 
12140b57cec5SDimitry Andric /// All types that are supported by HasDeclarationMatcher above.
12150b57cec5SDimitry Andric using HasDeclarationSupportedTypes =
12160b57cec5SDimitry Andric     TypeList<CallExpr, CXXConstructExpr, CXXNewExpr, DeclRefExpr, EnumType,
12170b57cec5SDimitry Andric              ElaboratedType, InjectedClassNameType, LabelStmt, AddrLabelExpr,
12180b57cec5SDimitry Andric              MemberExpr, QualType, RecordType, TagType,
12190b57cec5SDimitry Andric              TemplateSpecializationType, TemplateTypeParmType, TypedefType,
12200b57cec5SDimitry Andric              UnresolvedUsingType, ObjCIvarRefExpr>;
12210b57cec5SDimitry Andric 
1222e8d8bef9SDimitry Andric /// A Matcher that allows binding the node it matches to an id.
1223e8d8bef9SDimitry Andric ///
1224e8d8bef9SDimitry Andric /// BindableMatcher provides a \a bind() method that allows binding the
1225e8d8bef9SDimitry Andric /// matched node to an id if the match was successful.
1226e8d8bef9SDimitry Andric template <typename T> class BindableMatcher : public Matcher<T> {
1227e8d8bef9SDimitry Andric public:
1228e8d8bef9SDimitry Andric   explicit BindableMatcher(const Matcher<T> &M) : Matcher<T>(M) {}
1229e8d8bef9SDimitry Andric   explicit BindableMatcher(MatcherInterface<T> *Implementation)
1230e8d8bef9SDimitry Andric       : Matcher<T>(Implementation) {}
1231e8d8bef9SDimitry Andric 
1232e8d8bef9SDimitry Andric   /// Returns a matcher that will bind the matched node on a match.
1233e8d8bef9SDimitry Andric   ///
1234e8d8bef9SDimitry Andric   /// The returned matcher is equivalent to this matcher, but will
1235e8d8bef9SDimitry Andric   /// bind the matched node on a match.
1236e8d8bef9SDimitry Andric   Matcher<T> bind(StringRef ID) const {
1237e8d8bef9SDimitry Andric     return DynTypedMatcher(*this)
1238e8d8bef9SDimitry Andric         .tryBind(ID)
1239e8d8bef9SDimitry Andric         ->template unconditionalConvertTo<T>();
1240e8d8bef9SDimitry Andric   }
1241e8d8bef9SDimitry Andric 
1242e8d8bef9SDimitry Andric   /// Same as Matcher<T>'s conversion operator, but enables binding on
1243e8d8bef9SDimitry Andric   /// the returned matcher.
1244e8d8bef9SDimitry Andric   operator DynTypedMatcher() const {
1245e8d8bef9SDimitry Andric     DynTypedMatcher Result = static_cast<const Matcher<T> &>(*this);
1246e8d8bef9SDimitry Andric     Result.setAllowBind(true);
1247e8d8bef9SDimitry Andric     return Result;
1248e8d8bef9SDimitry Andric   }
1249e8d8bef9SDimitry Andric };
1250e8d8bef9SDimitry Andric 
1251e8d8bef9SDimitry Andric /// Matches any instance of the given NodeType.
1252e8d8bef9SDimitry Andric ///
1253e8d8bef9SDimitry Andric /// This is useful when a matcher syntactically requires a child matcher,
1254e8d8bef9SDimitry Andric /// but the context doesn't care. See for example: anything().
1255e8d8bef9SDimitry Andric class TrueMatcher {
1256e8d8bef9SDimitry Andric public:
1257e8d8bef9SDimitry Andric   using ReturnTypes = AllNodeBaseTypes;
1258e8d8bef9SDimitry Andric 
1259e8d8bef9SDimitry Andric   template <typename T> operator Matcher<T>() const {
1260e8d8bef9SDimitry Andric     return DynTypedMatcher::trueMatcher(ASTNodeKind::getFromNodeKind<T>())
1261e8d8bef9SDimitry Andric         .template unconditionalConvertTo<T>();
1262e8d8bef9SDimitry Andric   }
1263e8d8bef9SDimitry Andric };
1264e8d8bef9SDimitry Andric 
1265e8d8bef9SDimitry Andric /// Creates a Matcher<T> that matches if all inner matchers match.
1266e8d8bef9SDimitry Andric template <typename T>
1267e8d8bef9SDimitry Andric BindableMatcher<T>
1268e8d8bef9SDimitry Andric makeAllOfComposite(ArrayRef<const Matcher<T> *> InnerMatchers) {
1269e8d8bef9SDimitry Andric   // For the size() == 0 case, we return a "true" matcher.
1270e8d8bef9SDimitry Andric   if (InnerMatchers.empty()) {
1271e8d8bef9SDimitry Andric     return BindableMatcher<T>(TrueMatcher());
1272e8d8bef9SDimitry Andric   }
1273e8d8bef9SDimitry Andric   // For the size() == 1 case, we simply return that one matcher.
1274e8d8bef9SDimitry Andric   // No need to wrap it in a variadic operation.
1275e8d8bef9SDimitry Andric   if (InnerMatchers.size() == 1) {
1276e8d8bef9SDimitry Andric     return BindableMatcher<T>(*InnerMatchers[0]);
1277e8d8bef9SDimitry Andric   }
1278e8d8bef9SDimitry Andric 
1279e8d8bef9SDimitry Andric   using PI = llvm::pointee_iterator<const Matcher<T> *const *>;
1280e8d8bef9SDimitry Andric 
1281e8d8bef9SDimitry Andric   std::vector<DynTypedMatcher> DynMatchers(PI(InnerMatchers.begin()),
1282e8d8bef9SDimitry Andric                                            PI(InnerMatchers.end()));
1283e8d8bef9SDimitry Andric   return BindableMatcher<T>(
1284e8d8bef9SDimitry Andric       DynTypedMatcher::constructVariadic(DynTypedMatcher::VO_AllOf,
1285e8d8bef9SDimitry Andric                                          ASTNodeKind::getFromNodeKind<T>(),
1286e8d8bef9SDimitry Andric                                          std::move(DynMatchers))
1287e8d8bef9SDimitry Andric           .template unconditionalConvertTo<T>());
1288e8d8bef9SDimitry Andric }
1289e8d8bef9SDimitry Andric 
1290e8d8bef9SDimitry Andric /// Creates a Matcher<T> that matches if
1291e8d8bef9SDimitry Andric /// T is dyn_cast'able into InnerT and all inner matchers match.
1292e8d8bef9SDimitry Andric ///
1293e8d8bef9SDimitry Andric /// Returns BindableMatcher, as matchers that use dyn_cast have
1294e8d8bef9SDimitry Andric /// the same object both to match on and to run submatchers on,
1295e8d8bef9SDimitry Andric /// so there is no ambiguity with what gets bound.
1296e8d8bef9SDimitry Andric template <typename T, typename InnerT>
1297e8d8bef9SDimitry Andric BindableMatcher<T>
1298e8d8bef9SDimitry Andric makeDynCastAllOfComposite(ArrayRef<const Matcher<InnerT> *> InnerMatchers) {
1299e8d8bef9SDimitry Andric   return BindableMatcher<T>(
1300e8d8bef9SDimitry Andric       makeAllOfComposite(InnerMatchers).template dynCastTo<T>());
1301e8d8bef9SDimitry Andric }
1302e8d8bef9SDimitry Andric 
1303e8d8bef9SDimitry Andric /// A VariadicDynCastAllOfMatcher<SourceT, TargetT> object is a
1304e8d8bef9SDimitry Andric /// variadic functor that takes a number of Matcher<TargetT> and returns a
1305e8d8bef9SDimitry Andric /// Matcher<SourceT> that matches TargetT nodes that are matched by all of the
1306e8d8bef9SDimitry Andric /// given matchers, if SourceT can be dynamically casted into TargetT.
1307e8d8bef9SDimitry Andric ///
1308e8d8bef9SDimitry Andric /// For example:
1309e8d8bef9SDimitry Andric ///   const VariadicDynCastAllOfMatcher<Decl, CXXRecordDecl> record;
1310e8d8bef9SDimitry Andric /// Creates a functor record(...) that creates a Matcher<Decl> given
1311e8d8bef9SDimitry Andric /// a variable number of arguments of type Matcher<CXXRecordDecl>.
1312e8d8bef9SDimitry Andric /// The returned matcher matches if the given Decl can by dynamically
1313e8d8bef9SDimitry Andric /// casted to CXXRecordDecl and all given matchers match.
1314e8d8bef9SDimitry Andric template <typename SourceT, typename TargetT>
1315e8d8bef9SDimitry Andric class VariadicDynCastAllOfMatcher
1316e8d8bef9SDimitry Andric     : public VariadicFunction<BindableMatcher<SourceT>, Matcher<TargetT>,
1317e8d8bef9SDimitry Andric                               makeDynCastAllOfComposite<SourceT, TargetT>> {
1318e8d8bef9SDimitry Andric public:
1319e8d8bef9SDimitry Andric   VariadicDynCastAllOfMatcher() {}
1320e8d8bef9SDimitry Andric };
1321e8d8bef9SDimitry Andric 
1322e8d8bef9SDimitry Andric /// A \c VariadicAllOfMatcher<T> object is a variadic functor that takes
1323e8d8bef9SDimitry Andric /// a number of \c Matcher<T> and returns a \c Matcher<T> that matches \c T
1324e8d8bef9SDimitry Andric /// nodes that are matched by all of the given matchers.
1325e8d8bef9SDimitry Andric ///
1326e8d8bef9SDimitry Andric /// For example:
1327e8d8bef9SDimitry Andric ///   const VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier;
1328e8d8bef9SDimitry Andric /// Creates a functor nestedNameSpecifier(...) that creates a
1329e8d8bef9SDimitry Andric /// \c Matcher<NestedNameSpecifier> given a variable number of arguments of type
1330e8d8bef9SDimitry Andric /// \c Matcher<NestedNameSpecifier>.
1331e8d8bef9SDimitry Andric /// The returned matcher matches if all given matchers match.
1332e8d8bef9SDimitry Andric template <typename T>
1333e8d8bef9SDimitry Andric class VariadicAllOfMatcher
1334e8d8bef9SDimitry Andric     : public VariadicFunction<BindableMatcher<T>, Matcher<T>,
1335e8d8bef9SDimitry Andric                               makeAllOfComposite<T>> {
1336e8d8bef9SDimitry Andric public:
1337e8d8bef9SDimitry Andric   VariadicAllOfMatcher() {}
1338e8d8bef9SDimitry Andric };
1339e8d8bef9SDimitry Andric 
1340e8d8bef9SDimitry Andric /// VariadicOperatorMatcher related types.
1341e8d8bef9SDimitry Andric /// @{
1342e8d8bef9SDimitry Andric 
1343e8d8bef9SDimitry Andric /// Polymorphic matcher object that uses a \c
1344e8d8bef9SDimitry Andric /// DynTypedMatcher::VariadicOperator operator.
1345e8d8bef9SDimitry Andric ///
1346e8d8bef9SDimitry Andric /// Input matchers can have any type (including other polymorphic matcher
1347e8d8bef9SDimitry Andric /// types), and the actual Matcher<T> is generated on demand with an implicit
1348e8d8bef9SDimitry Andric /// conversion operator.
1349e8d8bef9SDimitry Andric template <typename... Ps> class VariadicOperatorMatcher {
1350e8d8bef9SDimitry Andric public:
1351e8d8bef9SDimitry Andric   VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, Ps &&... Params)
1352e8d8bef9SDimitry Andric       : Op(Op), Params(std::forward<Ps>(Params)...) {}
1353e8d8bef9SDimitry Andric 
135481ad6265SDimitry Andric   template <typename T> operator Matcher<T>() const & {
1355e8d8bef9SDimitry Andric     return DynTypedMatcher::constructVariadic(
1356e8d8bef9SDimitry Andric                Op, ASTNodeKind::getFromNodeKind<T>(),
1357e8d8bef9SDimitry Andric                getMatchers<T>(std::index_sequence_for<Ps...>()))
1358e8d8bef9SDimitry Andric         .template unconditionalConvertTo<T>();
1359e8d8bef9SDimitry Andric   }
1360e8d8bef9SDimitry Andric 
1361fe6060f1SDimitry Andric   template <typename T> operator Matcher<T>() && {
1362fe6060f1SDimitry Andric     return DynTypedMatcher::constructVariadic(
1363fe6060f1SDimitry Andric                Op, ASTNodeKind::getFromNodeKind<T>(),
1364fe6060f1SDimitry Andric                getMatchers<T>(std::index_sequence_for<Ps...>()))
1365fe6060f1SDimitry Andric         .template unconditionalConvertTo<T>();
1366fe6060f1SDimitry Andric   }
136781ad6265SDimitry Andric 
1368e8d8bef9SDimitry Andric private:
1369e8d8bef9SDimitry Andric   // Helper method to unpack the tuple into a vector.
1370e8d8bef9SDimitry Andric   template <typename T, std::size_t... Is>
137181ad6265SDimitry Andric   std::vector<DynTypedMatcher> getMatchers(std::index_sequence<Is...>) const & {
1372e8d8bef9SDimitry Andric     return {Matcher<T>(std::get<Is>(Params))...};
1373e8d8bef9SDimitry Andric   }
1374e8d8bef9SDimitry Andric 
1375fe6060f1SDimitry Andric   template <typename T, std::size_t... Is>
1376fe6060f1SDimitry Andric   std::vector<DynTypedMatcher> getMatchers(std::index_sequence<Is...>) && {
1377fe6060f1SDimitry Andric     return {Matcher<T>(std::get<Is>(std::move(Params)))...};
1378fe6060f1SDimitry Andric   }
1379fe6060f1SDimitry Andric 
1380e8d8bef9SDimitry Andric   const DynTypedMatcher::VariadicOperator Op;
1381e8d8bef9SDimitry Andric   std::tuple<Ps...> Params;
1382e8d8bef9SDimitry Andric };
1383e8d8bef9SDimitry Andric 
1384e8d8bef9SDimitry Andric /// Overloaded function object to generate VariadicOperatorMatcher
1385e8d8bef9SDimitry Andric ///   objects from arbitrary matchers.
1386e8d8bef9SDimitry Andric template <unsigned MinCount, unsigned MaxCount>
1387e8d8bef9SDimitry Andric struct VariadicOperatorMatcherFunc {
1388e8d8bef9SDimitry Andric   DynTypedMatcher::VariadicOperator Op;
1389e8d8bef9SDimitry Andric 
1390e8d8bef9SDimitry Andric   template <typename... Ms>
1391e8d8bef9SDimitry Andric   VariadicOperatorMatcher<Ms...> operator()(Ms &&... Ps) const {
1392e8d8bef9SDimitry Andric     static_assert(MinCount <= sizeof...(Ms) && sizeof...(Ms) <= MaxCount,
1393e8d8bef9SDimitry Andric                   "invalid number of parameters for variadic matcher");
1394e8d8bef9SDimitry Andric     return VariadicOperatorMatcher<Ms...>(Op, std::forward<Ms>(Ps)...);
1395e8d8bef9SDimitry Andric   }
1396e8d8bef9SDimitry Andric };
1397e8d8bef9SDimitry Andric 
1398e8d8bef9SDimitry Andric template <typename T, bool IsBaseOf, typename Head, typename Tail>
1399e8d8bef9SDimitry Andric struct GetCladeImpl {
1400e8d8bef9SDimitry Andric   using Type = Head;
1401e8d8bef9SDimitry Andric };
1402e8d8bef9SDimitry Andric template <typename T, typename Head, typename Tail>
1403e8d8bef9SDimitry Andric struct GetCladeImpl<T, false, Head, Tail>
1404e8d8bef9SDimitry Andric     : GetCladeImpl<T, std::is_base_of<typename Tail::head, T>::value,
1405e8d8bef9SDimitry Andric                    typename Tail::head, typename Tail::tail> {};
1406e8d8bef9SDimitry Andric 
1407e8d8bef9SDimitry Andric template <typename T, typename... U>
1408e8d8bef9SDimitry Andric struct GetClade : GetCladeImpl<T, false, T, AllNodeBaseTypes> {};
1409e8d8bef9SDimitry Andric 
1410e8d8bef9SDimitry Andric template <typename CladeType, typename... MatcherTypes>
1411e8d8bef9SDimitry Andric struct MapAnyOfMatcherImpl {
1412e8d8bef9SDimitry Andric 
1413e8d8bef9SDimitry Andric   template <typename... InnerMatchers>
1414e8d8bef9SDimitry Andric   BindableMatcher<CladeType>
1415e8d8bef9SDimitry Andric   operator()(InnerMatchers &&... InnerMatcher) const {
1416bdd1243dSDimitry Andric     return VariadicAllOfMatcher<CladeType>()(std::apply(
1417e8d8bef9SDimitry Andric         internal::VariadicOperatorMatcherFunc<
1418e8d8bef9SDimitry Andric             0, std::numeric_limits<unsigned>::max()>{
1419e8d8bef9SDimitry Andric             internal::DynTypedMatcher::VO_AnyOf},
1420bdd1243dSDimitry Andric         std::apply(
1421e8d8bef9SDimitry Andric             [&](auto... Matcher) {
1422fe6060f1SDimitry Andric               return std::make_tuple(Matcher(InnerMatcher...)...);
1423e8d8bef9SDimitry Andric             },
1424e8d8bef9SDimitry Andric             std::tuple<
1425e8d8bef9SDimitry Andric                 VariadicDynCastAllOfMatcher<CladeType, MatcherTypes>...>())));
1426e8d8bef9SDimitry Andric   }
1427e8d8bef9SDimitry Andric };
1428e8d8bef9SDimitry Andric 
1429e8d8bef9SDimitry Andric template <typename... MatcherTypes>
1430e8d8bef9SDimitry Andric using MapAnyOfMatcher =
1431e8d8bef9SDimitry Andric     MapAnyOfMatcherImpl<typename GetClade<MatcherTypes...>::Type,
1432e8d8bef9SDimitry Andric                         MatcherTypes...>;
1433e8d8bef9SDimitry Andric 
1434e8d8bef9SDimitry Andric template <typename... MatcherTypes> struct MapAnyOfHelper {
1435e8d8bef9SDimitry Andric   using CladeType = typename GetClade<MatcherTypes...>::Type;
1436e8d8bef9SDimitry Andric 
1437e8d8bef9SDimitry Andric   MapAnyOfMatcher<MatcherTypes...> with;
1438e8d8bef9SDimitry Andric 
1439e8d8bef9SDimitry Andric   operator BindableMatcher<CladeType>() const { return with(); }
1440e8d8bef9SDimitry Andric 
1441e8d8bef9SDimitry Andric   Matcher<CladeType> bind(StringRef ID) const { return with().bind(ID); }
1442e8d8bef9SDimitry Andric };
1443e8d8bef9SDimitry Andric 
1444480093f4SDimitry Andric template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
1445480093f4SDimitry Andric           typename T, typename ToTypes>
1446480093f4SDimitry Andric class ArgumentAdaptingMatcherFuncAdaptor {
1447480093f4SDimitry Andric public:
1448480093f4SDimitry Andric   explicit ArgumentAdaptingMatcherFuncAdaptor(const Matcher<T> &InnerMatcher)
1449480093f4SDimitry Andric       : InnerMatcher(InnerMatcher) {}
1450480093f4SDimitry Andric 
1451480093f4SDimitry Andric   using ReturnTypes = ToTypes;
1452480093f4SDimitry Andric 
145381ad6265SDimitry Andric   template <typename To> operator Matcher<To>() const & {
1454480093f4SDimitry Andric     return Matcher<To>(new ArgumentAdapterT<To, T>(InnerMatcher));
1455480093f4SDimitry Andric   }
1456480093f4SDimitry Andric 
1457fe6060f1SDimitry Andric   template <typename To> operator Matcher<To>() && {
1458fe6060f1SDimitry Andric     return Matcher<To>(new ArgumentAdapterT<To, T>(std::move(InnerMatcher)));
1459fe6060f1SDimitry Andric   }
1460fe6060f1SDimitry Andric 
1461480093f4SDimitry Andric private:
1462fe6060f1SDimitry Andric   Matcher<T> InnerMatcher;
1463480093f4SDimitry Andric };
1464480093f4SDimitry Andric 
14650b57cec5SDimitry Andric /// Converts a \c Matcher<T> to a matcher of desired type \c To by
14660b57cec5SDimitry Andric /// "adapting" a \c To into a \c T.
14670b57cec5SDimitry Andric ///
14680b57cec5SDimitry Andric /// The \c ArgumentAdapterT argument specifies how the adaptation is done.
14690b57cec5SDimitry Andric ///
14700b57cec5SDimitry Andric /// For example:
14710b57cec5SDimitry Andric ///   \c ArgumentAdaptingMatcher<HasMatcher, T>(InnerMatcher);
14720b57cec5SDimitry Andric /// Given that \c InnerMatcher is of type \c Matcher<T>, this returns a matcher
14730b57cec5SDimitry Andric /// that is convertible into any matcher of type \c To by constructing
14740b57cec5SDimitry Andric /// \c HasMatcher<To, T>(InnerMatcher).
14750b57cec5SDimitry Andric ///
14760b57cec5SDimitry Andric /// If a matcher does not need knowledge about the inner type, prefer to use
1477fe6060f1SDimitry Andric /// PolymorphicMatcher.
14780b57cec5SDimitry Andric template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
14790b57cec5SDimitry Andric           typename FromTypes = AdaptativeDefaultFromTypes,
14800b57cec5SDimitry Andric           typename ToTypes = AdaptativeDefaultToTypes>
14810b57cec5SDimitry Andric struct ArgumentAdaptingMatcherFunc {
1482480093f4SDimitry Andric   template <typename T>
1483480093f4SDimitry Andric   static ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>
1484480093f4SDimitry Andric   create(const Matcher<T> &InnerMatcher) {
1485480093f4SDimitry Andric     return ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>(
1486480093f4SDimitry Andric         InnerMatcher);
14870b57cec5SDimitry Andric   }
14880b57cec5SDimitry Andric 
1489480093f4SDimitry Andric   template <typename T>
1490480093f4SDimitry Andric   ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>
1491480093f4SDimitry Andric   operator()(const Matcher<T> &InnerMatcher) const {
1492480093f4SDimitry Andric     return create(InnerMatcher);
1493480093f4SDimitry Andric   }
1494e8d8bef9SDimitry Andric 
1495e8d8bef9SDimitry Andric   template <typename... T>
1496e8d8bef9SDimitry Andric   ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT,
1497e8d8bef9SDimitry Andric                                      typename GetClade<T...>::Type, ToTypes>
1498e8d8bef9SDimitry Andric   operator()(const MapAnyOfHelper<T...> &InnerMatcher) const {
1499e8d8bef9SDimitry Andric     return create(InnerMatcher.with());
1500e8d8bef9SDimitry Andric   }
15010b57cec5SDimitry Andric };
15020b57cec5SDimitry Andric 
15035ffd83dbSDimitry Andric template <typename T> class TraversalMatcher : public MatcherInterface<T> {
1504fe6060f1SDimitry Andric   DynTypedMatcher InnerMatcher;
15055ffd83dbSDimitry Andric   clang::TraversalKind Traversal;
1506480093f4SDimitry Andric 
1507480093f4SDimitry Andric public:
15085ffd83dbSDimitry Andric   explicit TraversalMatcher(clang::TraversalKind TK,
15095ffd83dbSDimitry Andric                             const Matcher<T> &InnerMatcher)
15105ffd83dbSDimitry Andric       : InnerMatcher(InnerMatcher), Traversal(TK) {}
15110b57cec5SDimitry Andric 
1512480093f4SDimitry Andric   bool matches(const T &Node, ASTMatchFinder *Finder,
1513480093f4SDimitry Andric                BoundNodesTreeBuilder *Builder) const override {
15145ffd83dbSDimitry Andric     return this->InnerMatcher.matches(DynTypedNode::create(Node), Finder,
15155ffd83dbSDimitry Andric                                       Builder);
15160b57cec5SDimitry Andric   }
1517480093f4SDimitry Andric 
1518bdd1243dSDimitry Andric   std::optional<clang::TraversalKind> TraversalKind() const override {
1519e8d8bef9SDimitry Andric     if (auto NestedKind = this->InnerMatcher.getTraversalKind())
1520e8d8bef9SDimitry Andric       return NestedKind;
1521480093f4SDimitry Andric     return Traversal;
1522480093f4SDimitry Andric   }
1523480093f4SDimitry Andric };
1524480093f4SDimitry Andric 
1525480093f4SDimitry Andric template <typename MatcherType> class TraversalWrapper {
1526480093f4SDimitry Andric public:
15275ffd83dbSDimitry Andric   TraversalWrapper(TraversalKind TK, const MatcherType &InnerMatcher)
1528480093f4SDimitry Andric       : TK(TK), InnerMatcher(InnerMatcher) {}
1529480093f4SDimitry Andric 
153081ad6265SDimitry Andric   template <typename T> operator Matcher<T>() const & {
1531480093f4SDimitry Andric     return internal::DynTypedMatcher::constructRestrictedWrapper(
1532480093f4SDimitry Andric                new internal::TraversalMatcher<T>(TK, InnerMatcher),
15335ffd83dbSDimitry Andric                ASTNodeKind::getFromNodeKind<T>())
1534480093f4SDimitry Andric         .template unconditionalConvertTo<T>();
1535480093f4SDimitry Andric   }
1536480093f4SDimitry Andric 
1537fe6060f1SDimitry Andric   template <typename T> operator Matcher<T>() && {
1538fe6060f1SDimitry Andric     return internal::DynTypedMatcher::constructRestrictedWrapper(
1539fe6060f1SDimitry Andric                new internal::TraversalMatcher<T>(TK, std::move(InnerMatcher)),
1540fe6060f1SDimitry Andric                ASTNodeKind::getFromNodeKind<T>())
1541fe6060f1SDimitry Andric         .template unconditionalConvertTo<T>();
1542fe6060f1SDimitry Andric   }
1543fe6060f1SDimitry Andric 
1544480093f4SDimitry Andric private:
15455ffd83dbSDimitry Andric   TraversalKind TK;
1546480093f4SDimitry Andric   MatcherType InnerMatcher;
15470b57cec5SDimitry Andric };
15480b57cec5SDimitry Andric 
1549fe6060f1SDimitry Andric /// A PolymorphicMatcher<MatcherT, P1, ..., PN> object can be
15500b57cec5SDimitry Andric /// created from N parameters p1, ..., pN (of type P1, ..., PN) and
15510b57cec5SDimitry Andric /// used as a Matcher<T> where a MatcherT<T, P1, ..., PN>(p1, ..., pN)
15520b57cec5SDimitry Andric /// can be constructed.
15530b57cec5SDimitry Andric ///
15540b57cec5SDimitry Andric /// For example:
1555fe6060f1SDimitry Andric /// - PolymorphicMatcher<IsDefinitionMatcher>()
15560b57cec5SDimitry Andric ///   creates an object that can be used as a Matcher<T> for any type T
15570b57cec5SDimitry Andric ///   where an IsDefinitionMatcher<T>() can be constructed.
1558fe6060f1SDimitry Andric /// - PolymorphicMatcher<ValueEqualsMatcher, int>(42)
15590b57cec5SDimitry Andric ///   creates an object that can be used as a Matcher<T> for any type T
15600b57cec5SDimitry Andric ///   where a ValueEqualsMatcher<T, int>(42) can be constructed.
1561fe6060f1SDimitry Andric template <template <typename T, typename... Params> class MatcherT,
1562fe6060f1SDimitry Andric           typename ReturnTypesF, typename... ParamTypes>
1563fe6060f1SDimitry Andric class PolymorphicMatcher {
15640b57cec5SDimitry Andric public:
1565fe6060f1SDimitry Andric   PolymorphicMatcher(const ParamTypes &... Params) : Params(Params...) {}
15660b57cec5SDimitry Andric 
15670b57cec5SDimitry Andric   using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
15680b57cec5SDimitry Andric 
156981ad6265SDimitry Andric   template <typename T> operator Matcher<T>() const & {
15700b57cec5SDimitry Andric     static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
15710b57cec5SDimitry Andric                   "right polymorphic conversion");
1572fe6060f1SDimitry Andric     return Matcher<T>(new_from_tuple<MatcherT<T, ParamTypes...>>(Params));
15730b57cec5SDimitry Andric   }
15740b57cec5SDimitry Andric 
1575fe6060f1SDimitry Andric   template <typename T> operator Matcher<T>() && {
1576fe6060f1SDimitry Andric     static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
1577fe6060f1SDimitry Andric                   "right polymorphic conversion");
1578fe6060f1SDimitry Andric     return Matcher<T>(
1579fe6060f1SDimitry Andric         new_from_tuple<MatcherT<T, ParamTypes...>>(std::move(Params)));
1580fe6060f1SDimitry Andric   }
1581fe6060f1SDimitry Andric 
15820b57cec5SDimitry Andric private:
1583fe6060f1SDimitry Andric   std::tuple<ParamTypes...> Params;
15840b57cec5SDimitry Andric };
15850b57cec5SDimitry Andric 
15860b57cec5SDimitry Andric /// Matches nodes of type T that have child nodes of type ChildT for
15870b57cec5SDimitry Andric /// which a specified child matcher matches.
15880b57cec5SDimitry Andric ///
15890b57cec5SDimitry Andric /// ChildT must be an AST base type.
15900b57cec5SDimitry Andric template <typename T, typename ChildT>
15915ffd83dbSDimitry Andric class HasMatcher : public MatcherInterface<T> {
1592fe6060f1SDimitry Andric   DynTypedMatcher InnerMatcher;
15935ffd83dbSDimitry Andric 
15940b57cec5SDimitry Andric public:
15955ffd83dbSDimitry Andric   explicit HasMatcher(const Matcher<ChildT> &InnerMatcher)
15965ffd83dbSDimitry Andric       : InnerMatcher(InnerMatcher) {}
15970b57cec5SDimitry Andric 
15980b57cec5SDimitry Andric   bool matches(const T &Node, ASTMatchFinder *Finder,
15990b57cec5SDimitry Andric                BoundNodesTreeBuilder *Builder) const override {
16000b57cec5SDimitry Andric     return Finder->matchesChildOf(Node, this->InnerMatcher, Builder,
16010b57cec5SDimitry Andric                                   ASTMatchFinder::BK_First);
16020b57cec5SDimitry Andric   }
16030b57cec5SDimitry Andric };
16040b57cec5SDimitry Andric 
16050b57cec5SDimitry Andric /// Matches nodes of type T that have child nodes of type ChildT for
16060b57cec5SDimitry Andric /// which a specified child matcher matches. ChildT must be an AST base
16070b57cec5SDimitry Andric /// type.
16080b57cec5SDimitry Andric /// As opposed to the HasMatcher, the ForEachMatcher will produce a match
16090b57cec5SDimitry Andric /// for each child that matches.
16100b57cec5SDimitry Andric template <typename T, typename ChildT>
16115ffd83dbSDimitry Andric class ForEachMatcher : public MatcherInterface<T> {
16120b57cec5SDimitry Andric   static_assert(IsBaseType<ChildT>::value,
16130b57cec5SDimitry Andric                 "for each only accepts base type matcher");
16140b57cec5SDimitry Andric 
1615fe6060f1SDimitry Andric   DynTypedMatcher InnerMatcher;
16165ffd83dbSDimitry Andric 
16170b57cec5SDimitry Andric public:
16185ffd83dbSDimitry Andric   explicit ForEachMatcher(const Matcher<ChildT> &InnerMatcher)
16195ffd83dbSDimitry Andric       : InnerMatcher(InnerMatcher) {}
16200b57cec5SDimitry Andric 
16210b57cec5SDimitry Andric   bool matches(const T &Node, ASTMatchFinder *Finder,
16220b57cec5SDimitry Andric                BoundNodesTreeBuilder *Builder) const override {
16230b57cec5SDimitry Andric     return Finder->matchesChildOf(
16240b57cec5SDimitry Andric         Node, this->InnerMatcher, Builder,
16250b57cec5SDimitry Andric         ASTMatchFinder::BK_All);
16260b57cec5SDimitry Andric   }
16270b57cec5SDimitry Andric };
16280b57cec5SDimitry Andric 
16290b57cec5SDimitry Andric /// @}
16300b57cec5SDimitry Andric 
16310b57cec5SDimitry Andric template <typename T>
16320b57cec5SDimitry Andric inline Matcher<T> DynTypedMatcher::unconditionalConvertTo() const {
16330b57cec5SDimitry Andric   return Matcher<T>(*this);
16340b57cec5SDimitry Andric }
16350b57cec5SDimitry Andric 
16360b57cec5SDimitry Andric /// Matches nodes of type T that have at least one descendant node of
16370b57cec5SDimitry Andric /// type DescendantT for which the given inner matcher matches.
16380b57cec5SDimitry Andric ///
16390b57cec5SDimitry Andric /// DescendantT must be an AST base type.
16400b57cec5SDimitry Andric template <typename T, typename DescendantT>
16415ffd83dbSDimitry Andric class HasDescendantMatcher : public MatcherInterface<T> {
16420b57cec5SDimitry Andric   static_assert(IsBaseType<DescendantT>::value,
16430b57cec5SDimitry Andric                 "has descendant only accepts base type matcher");
16440b57cec5SDimitry Andric 
1645fe6060f1SDimitry Andric   DynTypedMatcher DescendantMatcher;
16465ffd83dbSDimitry Andric 
16470b57cec5SDimitry Andric public:
16480b57cec5SDimitry Andric   explicit HasDescendantMatcher(const Matcher<DescendantT> &DescendantMatcher)
16495ffd83dbSDimitry Andric       : DescendantMatcher(DescendantMatcher) {}
16500b57cec5SDimitry Andric 
16510b57cec5SDimitry Andric   bool matches(const T &Node, ASTMatchFinder *Finder,
16520b57cec5SDimitry Andric                BoundNodesTreeBuilder *Builder) const override {
16535ffd83dbSDimitry Andric     return Finder->matchesDescendantOf(Node, this->DescendantMatcher, Builder,
16540b57cec5SDimitry Andric                                        ASTMatchFinder::BK_First);
16550b57cec5SDimitry Andric   }
16560b57cec5SDimitry Andric };
16570b57cec5SDimitry Andric 
16580b57cec5SDimitry Andric /// Matches nodes of type \c T that have a parent node of type \c ParentT
16590b57cec5SDimitry Andric /// for which the given inner matcher matches.
16600b57cec5SDimitry Andric ///
16610b57cec5SDimitry Andric /// \c ParentT must be an AST base type.
16620b57cec5SDimitry Andric template <typename T, typename ParentT>
16635ffd83dbSDimitry Andric class HasParentMatcher : public MatcherInterface<T> {
16640b57cec5SDimitry Andric   static_assert(IsBaseType<ParentT>::value,
16650b57cec5SDimitry Andric                 "has parent only accepts base type matcher");
16660b57cec5SDimitry Andric 
1667fe6060f1SDimitry Andric   DynTypedMatcher ParentMatcher;
16685ffd83dbSDimitry Andric 
16690b57cec5SDimitry Andric public:
16700b57cec5SDimitry Andric   explicit HasParentMatcher(const Matcher<ParentT> &ParentMatcher)
16715ffd83dbSDimitry Andric       : ParentMatcher(ParentMatcher) {}
16720b57cec5SDimitry Andric 
16730b57cec5SDimitry Andric   bool matches(const T &Node, ASTMatchFinder *Finder,
16740b57cec5SDimitry Andric                BoundNodesTreeBuilder *Builder) const override {
16755ffd83dbSDimitry Andric     return Finder->matchesAncestorOf(Node, this->ParentMatcher, Builder,
16760b57cec5SDimitry Andric                                      ASTMatchFinder::AMM_ParentOnly);
16770b57cec5SDimitry Andric   }
16780b57cec5SDimitry Andric };
16790b57cec5SDimitry Andric 
16800b57cec5SDimitry Andric /// Matches nodes of type \c T that have at least one ancestor node of
16810b57cec5SDimitry Andric /// type \c AncestorT for which the given inner matcher matches.
16820b57cec5SDimitry Andric ///
16830b57cec5SDimitry Andric /// \c AncestorT must be an AST base type.
16840b57cec5SDimitry Andric template <typename T, typename AncestorT>
16855ffd83dbSDimitry Andric class HasAncestorMatcher : public MatcherInterface<T> {
16860b57cec5SDimitry Andric   static_assert(IsBaseType<AncestorT>::value,
16870b57cec5SDimitry Andric                 "has ancestor only accepts base type matcher");
16880b57cec5SDimitry Andric 
1689fe6060f1SDimitry Andric   DynTypedMatcher AncestorMatcher;
16905ffd83dbSDimitry Andric 
16910b57cec5SDimitry Andric public:
16920b57cec5SDimitry Andric   explicit HasAncestorMatcher(const Matcher<AncestorT> &AncestorMatcher)
16935ffd83dbSDimitry Andric       : AncestorMatcher(AncestorMatcher) {}
16940b57cec5SDimitry Andric 
16950b57cec5SDimitry Andric   bool matches(const T &Node, ASTMatchFinder *Finder,
16960b57cec5SDimitry Andric                BoundNodesTreeBuilder *Builder) const override {
16975ffd83dbSDimitry Andric     return Finder->matchesAncestorOf(Node, this->AncestorMatcher, Builder,
16980b57cec5SDimitry Andric                                      ASTMatchFinder::AMM_All);
16990b57cec5SDimitry Andric   }
17000b57cec5SDimitry Andric };
17010b57cec5SDimitry Andric 
17020b57cec5SDimitry Andric /// Matches nodes of type T that have at least one descendant node of
17030b57cec5SDimitry Andric /// type DescendantT for which the given inner matcher matches.
17040b57cec5SDimitry Andric ///
17050b57cec5SDimitry Andric /// DescendantT must be an AST base type.
17060b57cec5SDimitry Andric /// As opposed to HasDescendantMatcher, ForEachDescendantMatcher will match
17070b57cec5SDimitry Andric /// for each descendant node that matches instead of only for the first.
17080b57cec5SDimitry Andric template <typename T, typename DescendantT>
17095ffd83dbSDimitry Andric class ForEachDescendantMatcher : public MatcherInterface<T> {
17100b57cec5SDimitry Andric   static_assert(IsBaseType<DescendantT>::value,
17110b57cec5SDimitry Andric                 "for each descendant only accepts base type matcher");
17120b57cec5SDimitry Andric 
1713fe6060f1SDimitry Andric   DynTypedMatcher DescendantMatcher;
17145ffd83dbSDimitry Andric 
17150b57cec5SDimitry Andric public:
17160b57cec5SDimitry Andric   explicit ForEachDescendantMatcher(
17170b57cec5SDimitry Andric       const Matcher<DescendantT> &DescendantMatcher)
17185ffd83dbSDimitry Andric       : DescendantMatcher(DescendantMatcher) {}
17190b57cec5SDimitry Andric 
17200b57cec5SDimitry Andric   bool matches(const T &Node, ASTMatchFinder *Finder,
17210b57cec5SDimitry Andric                BoundNodesTreeBuilder *Builder) const override {
17225ffd83dbSDimitry Andric     return Finder->matchesDescendantOf(Node, this->DescendantMatcher, Builder,
17230b57cec5SDimitry Andric                                        ASTMatchFinder::BK_All);
17240b57cec5SDimitry Andric   }
17250b57cec5SDimitry Andric };
17260b57cec5SDimitry Andric 
17270b57cec5SDimitry Andric /// Matches on nodes that have a getValue() method if getValue() equals
17280b57cec5SDimitry Andric /// the value the ValueEqualsMatcher was constructed with.
17290b57cec5SDimitry Andric template <typename T, typename ValueT>
17300b57cec5SDimitry Andric class ValueEqualsMatcher : public SingleNodeMatcherInterface<T> {
17310b57cec5SDimitry Andric   static_assert(std::is_base_of<CharacterLiteral, T>::value ||
17320b57cec5SDimitry Andric                 std::is_base_of<CXXBoolLiteralExpr, T>::value ||
17330b57cec5SDimitry Andric                 std::is_base_of<FloatingLiteral, T>::value ||
17340b57cec5SDimitry Andric                 std::is_base_of<IntegerLiteral, T>::value,
17350b57cec5SDimitry Andric                 "the node must have a getValue method");
17360b57cec5SDimitry Andric 
17370b57cec5SDimitry Andric public:
17380b57cec5SDimitry Andric   explicit ValueEqualsMatcher(const ValueT &ExpectedValue)
17390b57cec5SDimitry Andric       : ExpectedValue(ExpectedValue) {}
17400b57cec5SDimitry Andric 
17410b57cec5SDimitry Andric   bool matchesNode(const T &Node) const override {
17420b57cec5SDimitry Andric     return Node.getValue() == ExpectedValue;
17430b57cec5SDimitry Andric   }
17440b57cec5SDimitry Andric 
17450b57cec5SDimitry Andric private:
1746fe6060f1SDimitry Andric   ValueT ExpectedValue;
17470b57cec5SDimitry Andric };
17480b57cec5SDimitry Andric 
17490b57cec5SDimitry Andric /// Template specializations to easily write matchers for floating point
17500b57cec5SDimitry Andric /// literals.
17510b57cec5SDimitry Andric template <>
17520b57cec5SDimitry Andric inline bool ValueEqualsMatcher<FloatingLiteral, double>::matchesNode(
17530b57cec5SDimitry Andric     const FloatingLiteral &Node) const {
17540b57cec5SDimitry Andric   if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle())
17550b57cec5SDimitry Andric     return Node.getValue().convertToFloat() == ExpectedValue;
17560b57cec5SDimitry Andric   if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble())
17570b57cec5SDimitry Andric     return Node.getValue().convertToDouble() == ExpectedValue;
17580b57cec5SDimitry Andric   return false;
17590b57cec5SDimitry Andric }
17600b57cec5SDimitry Andric template <>
17610b57cec5SDimitry Andric inline bool ValueEqualsMatcher<FloatingLiteral, float>::matchesNode(
17620b57cec5SDimitry Andric     const FloatingLiteral &Node) const {
17630b57cec5SDimitry Andric   if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle())
17640b57cec5SDimitry Andric     return Node.getValue().convertToFloat() == ExpectedValue;
17650b57cec5SDimitry Andric   if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble())
17660b57cec5SDimitry Andric     return Node.getValue().convertToDouble() == ExpectedValue;
17670b57cec5SDimitry Andric   return false;
17680b57cec5SDimitry Andric }
17690b57cec5SDimitry Andric template <>
17700b57cec5SDimitry Andric inline bool ValueEqualsMatcher<FloatingLiteral, llvm::APFloat>::matchesNode(
17710b57cec5SDimitry Andric     const FloatingLiteral &Node) const {
17720b57cec5SDimitry Andric   return ExpectedValue.compare(Node.getValue()) == llvm::APFloat::cmpEqual;
17730b57cec5SDimitry Andric }
17740b57cec5SDimitry Andric 
17750b57cec5SDimitry Andric /// Matches nodes of type \c TLoc for which the inner
17760b57cec5SDimitry Andric /// \c Matcher<T> matches.
17770b57cec5SDimitry Andric template <typename TLoc, typename T>
17785ffd83dbSDimitry Andric class LocMatcher : public MatcherInterface<TLoc> {
1779fe6060f1SDimitry Andric   DynTypedMatcher InnerMatcher;
17805ffd83dbSDimitry Andric 
17810b57cec5SDimitry Andric public:
17820b57cec5SDimitry Andric   explicit LocMatcher(const Matcher<T> &InnerMatcher)
17835ffd83dbSDimitry Andric       : InnerMatcher(InnerMatcher) {}
17840b57cec5SDimitry Andric 
17850b57cec5SDimitry Andric   bool matches(const TLoc &Node, ASTMatchFinder *Finder,
17860b57cec5SDimitry Andric                BoundNodesTreeBuilder *Builder) const override {
17870b57cec5SDimitry Andric     if (!Node)
17880b57cec5SDimitry Andric       return false;
17890b57cec5SDimitry Andric     return this->InnerMatcher.matches(extract(Node), Finder, Builder);
17900b57cec5SDimitry Andric   }
17910b57cec5SDimitry Andric 
17920b57cec5SDimitry Andric private:
17935ffd83dbSDimitry Andric   static DynTypedNode extract(const NestedNameSpecifierLoc &Loc) {
17945ffd83dbSDimitry Andric     return DynTypedNode::create(*Loc.getNestedNameSpecifier());
17950b57cec5SDimitry Andric   }
17960b57cec5SDimitry Andric };
17970b57cec5SDimitry Andric 
17980b57cec5SDimitry Andric /// Matches \c TypeLocs based on an inner matcher matching a certain
17990b57cec5SDimitry Andric /// \c QualType.
18000b57cec5SDimitry Andric ///
18010b57cec5SDimitry Andric /// Used to implement the \c loc() matcher.
18025ffd83dbSDimitry Andric class TypeLocTypeMatcher : public MatcherInterface<TypeLoc> {
1803fe6060f1SDimitry Andric   DynTypedMatcher InnerMatcher;
18045ffd83dbSDimitry Andric 
18050b57cec5SDimitry Andric public:
18060b57cec5SDimitry Andric   explicit TypeLocTypeMatcher(const Matcher<QualType> &InnerMatcher)
18075ffd83dbSDimitry Andric       : InnerMatcher(InnerMatcher) {}
18080b57cec5SDimitry Andric 
18090b57cec5SDimitry Andric   bool matches(const TypeLoc &Node, ASTMatchFinder *Finder,
18100b57cec5SDimitry Andric                BoundNodesTreeBuilder *Builder) const override {
18110b57cec5SDimitry Andric     if (!Node)
18120b57cec5SDimitry Andric       return false;
18135ffd83dbSDimitry Andric     return this->InnerMatcher.matches(DynTypedNode::create(Node.getType()),
18145ffd83dbSDimitry Andric                                       Finder, Builder);
18150b57cec5SDimitry Andric   }
18160b57cec5SDimitry Andric };
18170b57cec5SDimitry Andric 
18180b57cec5SDimitry Andric /// Matches nodes of type \c T for which the inner matcher matches on a
18190b57cec5SDimitry Andric /// another node of type \c T that can be reached using a given traverse
18200b57cec5SDimitry Andric /// function.
18215ffd83dbSDimitry Andric template <typename T> class TypeTraverseMatcher : public MatcherInterface<T> {
1822fe6060f1SDimitry Andric   DynTypedMatcher InnerMatcher;
18235ffd83dbSDimitry Andric 
18240b57cec5SDimitry Andric public:
18250b57cec5SDimitry Andric   explicit TypeTraverseMatcher(const Matcher<QualType> &InnerMatcher,
18260b57cec5SDimitry Andric                                QualType (T::*TraverseFunction)() const)
18275ffd83dbSDimitry Andric       : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {}
18280b57cec5SDimitry Andric 
18290b57cec5SDimitry Andric   bool matches(const T &Node, ASTMatchFinder *Finder,
18300b57cec5SDimitry Andric                BoundNodesTreeBuilder *Builder) const override {
18310b57cec5SDimitry Andric     QualType NextNode = (Node.*TraverseFunction)();
18320b57cec5SDimitry Andric     if (NextNode.isNull())
18330b57cec5SDimitry Andric       return false;
18345ffd83dbSDimitry Andric     return this->InnerMatcher.matches(DynTypedNode::create(NextNode), Finder,
18355ffd83dbSDimitry Andric                                       Builder);
18360b57cec5SDimitry Andric   }
18370b57cec5SDimitry Andric 
18380b57cec5SDimitry Andric private:
18390b57cec5SDimitry Andric   QualType (T::*TraverseFunction)() const;
18400b57cec5SDimitry Andric };
18410b57cec5SDimitry Andric 
18420b57cec5SDimitry Andric /// Matches nodes of type \c T in a ..Loc hierarchy, for which the inner
18430b57cec5SDimitry Andric /// matcher matches on a another node of type \c T that can be reached using a
18440b57cec5SDimitry Andric /// given traverse function.
18450b57cec5SDimitry Andric template <typename T>
18465ffd83dbSDimitry Andric class TypeLocTraverseMatcher : public MatcherInterface<T> {
1847fe6060f1SDimitry Andric   DynTypedMatcher InnerMatcher;
18485ffd83dbSDimitry Andric 
18490b57cec5SDimitry Andric public:
18500b57cec5SDimitry Andric   explicit TypeLocTraverseMatcher(const Matcher<TypeLoc> &InnerMatcher,
18510b57cec5SDimitry Andric                                   TypeLoc (T::*TraverseFunction)() const)
18525ffd83dbSDimitry Andric       : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {}
18530b57cec5SDimitry Andric 
18540b57cec5SDimitry Andric   bool matches(const T &Node, ASTMatchFinder *Finder,
18550b57cec5SDimitry Andric                BoundNodesTreeBuilder *Builder) const override {
18560b57cec5SDimitry Andric     TypeLoc NextNode = (Node.*TraverseFunction)();
18570b57cec5SDimitry Andric     if (!NextNode)
18580b57cec5SDimitry Andric       return false;
18595ffd83dbSDimitry Andric     return this->InnerMatcher.matches(DynTypedNode::create(NextNode), Finder,
18605ffd83dbSDimitry Andric                                       Builder);
18610b57cec5SDimitry Andric   }
18620b57cec5SDimitry Andric 
18630b57cec5SDimitry Andric private:
18640b57cec5SDimitry Andric   TypeLoc (T::*TraverseFunction)() const;
18650b57cec5SDimitry Andric };
18660b57cec5SDimitry Andric 
18670b57cec5SDimitry Andric /// Converts a \c Matcher<InnerT> to a \c Matcher<OuterT>, where
18680b57cec5SDimitry Andric /// \c OuterT is any type that is supported by \c Getter.
18690b57cec5SDimitry Andric ///
18700b57cec5SDimitry Andric /// \code Getter<OuterT>::value() \endcode returns a
18710b57cec5SDimitry Andric /// \code InnerTBase (OuterT::*)() \endcode, which is used to adapt a \c OuterT
18720b57cec5SDimitry Andric /// object into a \c InnerT
18730b57cec5SDimitry Andric template <typename InnerTBase,
18740b57cec5SDimitry Andric           template <typename OuterT> class Getter,
18750b57cec5SDimitry Andric           template <typename OuterT> class MatcherImpl,
18760b57cec5SDimitry Andric           typename ReturnTypesF>
18770b57cec5SDimitry Andric class TypeTraversePolymorphicMatcher {
18780b57cec5SDimitry Andric private:
18790b57cec5SDimitry Andric   using Self = TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl,
18800b57cec5SDimitry Andric                                               ReturnTypesF>;
18810b57cec5SDimitry Andric 
18820b57cec5SDimitry Andric   static Self create(ArrayRef<const Matcher<InnerTBase> *> InnerMatchers);
18830b57cec5SDimitry Andric 
18840b57cec5SDimitry Andric public:
18850b57cec5SDimitry Andric   using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
18860b57cec5SDimitry Andric 
18870b57cec5SDimitry Andric   explicit TypeTraversePolymorphicMatcher(
18880b57cec5SDimitry Andric       ArrayRef<const Matcher<InnerTBase> *> InnerMatchers)
18890b57cec5SDimitry Andric       : InnerMatcher(makeAllOfComposite(InnerMatchers)) {}
18900b57cec5SDimitry Andric 
18910b57cec5SDimitry Andric   template <typename OuterT> operator Matcher<OuterT>() const {
18920b57cec5SDimitry Andric     return Matcher<OuterT>(
18930b57cec5SDimitry Andric         new MatcherImpl<OuterT>(InnerMatcher, Getter<OuterT>::value()));
18940b57cec5SDimitry Andric   }
18950b57cec5SDimitry Andric 
18960b57cec5SDimitry Andric   struct Func
18970b57cec5SDimitry Andric       : public VariadicFunction<Self, Matcher<InnerTBase>, &Self::create> {
18980b57cec5SDimitry Andric     Func() {}
18990b57cec5SDimitry Andric   };
19000b57cec5SDimitry Andric 
19010b57cec5SDimitry Andric private:
1902fe6060f1SDimitry Andric   Matcher<InnerTBase> InnerMatcher;
19030b57cec5SDimitry Andric };
19040b57cec5SDimitry Andric 
19050b57cec5SDimitry Andric /// A simple memoizer of T(*)() functions.
19060b57cec5SDimitry Andric ///
19070b57cec5SDimitry Andric /// It will call the passed 'Func' template parameter at most once.
19080b57cec5SDimitry Andric /// Used to support AST_MATCHER_FUNCTION() macro.
19090b57cec5SDimitry Andric template <typename Matcher, Matcher (*Func)()> class MemoizedMatcher {
19100b57cec5SDimitry Andric   struct Wrapper {
19110b57cec5SDimitry Andric     Wrapper() : M(Func()) {}
19120b57cec5SDimitry Andric 
19130b57cec5SDimitry Andric     Matcher M;
19140b57cec5SDimitry Andric   };
19150b57cec5SDimitry Andric 
19160b57cec5SDimitry Andric public:
19170b57cec5SDimitry Andric   static const Matcher &getInstance() {
19180b57cec5SDimitry Andric     static llvm::ManagedStatic<Wrapper> Instance;
19190b57cec5SDimitry Andric     return Instance->M;
19200b57cec5SDimitry Andric   }
19210b57cec5SDimitry Andric };
19220b57cec5SDimitry Andric 
19230b57cec5SDimitry Andric // Define the create() method out of line to silence a GCC warning about
19240b57cec5SDimitry Andric // the struct "Func" having greater visibility than its base, which comes from
19250b57cec5SDimitry Andric // using the flag -fvisibility-inlines-hidden.
19260b57cec5SDimitry Andric template <typename InnerTBase, template <typename OuterT> class Getter,
19270b57cec5SDimitry Andric           template <typename OuterT> class MatcherImpl, typename ReturnTypesF>
19280b57cec5SDimitry Andric TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl, ReturnTypesF>
19290b57cec5SDimitry Andric TypeTraversePolymorphicMatcher<
19300b57cec5SDimitry Andric     InnerTBase, Getter, MatcherImpl,
19310b57cec5SDimitry Andric     ReturnTypesF>::create(ArrayRef<const Matcher<InnerTBase> *> InnerMatchers) {
19320b57cec5SDimitry Andric   return Self(InnerMatchers);
19330b57cec5SDimitry Andric }
19340b57cec5SDimitry Andric 
19350b57cec5SDimitry Andric // FIXME: unify ClassTemplateSpecializationDecl and TemplateSpecializationType's
19360b57cec5SDimitry Andric // APIs for accessing the template argument list.
19370b57cec5SDimitry Andric inline ArrayRef<TemplateArgument>
19380b57cec5SDimitry Andric getTemplateSpecializationArgs(const ClassTemplateSpecializationDecl &D) {
19390b57cec5SDimitry Andric   return D.getTemplateArgs().asArray();
19400b57cec5SDimitry Andric }
19410b57cec5SDimitry Andric 
19420b57cec5SDimitry Andric inline ArrayRef<TemplateArgument>
19430b57cec5SDimitry Andric getTemplateSpecializationArgs(const TemplateSpecializationType &T) {
1944bdd1243dSDimitry Andric   return T.template_arguments();
19450b57cec5SDimitry Andric }
19460b57cec5SDimitry Andric 
19470b57cec5SDimitry Andric inline ArrayRef<TemplateArgument>
19480b57cec5SDimitry Andric getTemplateSpecializationArgs(const FunctionDecl &FD) {
19490b57cec5SDimitry Andric   if (const auto* TemplateArgs = FD.getTemplateSpecializationArgs())
19500b57cec5SDimitry Andric     return TemplateArgs->asArray();
19510b57cec5SDimitry Andric   return ArrayRef<TemplateArgument>();
19520b57cec5SDimitry Andric }
19530b57cec5SDimitry Andric 
19540b57cec5SDimitry Andric struct NotEqualsBoundNodePredicate {
19550b57cec5SDimitry Andric   bool operator()(const internal::BoundNodesMap &Nodes) const {
19560b57cec5SDimitry Andric     return Nodes.getNode(ID) != Node;
19570b57cec5SDimitry Andric   }
19580b57cec5SDimitry Andric 
19590b57cec5SDimitry Andric   std::string ID;
19605ffd83dbSDimitry Andric   DynTypedNode Node;
19610b57cec5SDimitry Andric };
19620b57cec5SDimitry Andric 
1963e8d8bef9SDimitry Andric template <typename Ty, typename Enable = void> struct GetBodyMatcher {
1964e8d8bef9SDimitry Andric   static const Stmt *get(const Ty &Node) { return Node.getBody(); }
1965e8d8bef9SDimitry Andric };
1966e8d8bef9SDimitry Andric 
19670b57cec5SDimitry Andric template <typename Ty>
1968bdd1243dSDimitry Andric struct GetBodyMatcher<
1969bdd1243dSDimitry Andric     Ty, std::enable_if_t<std::is_base_of<FunctionDecl, Ty>::value>> {
19700b57cec5SDimitry Andric   static const Stmt *get(const Ty &Node) {
1971e8d8bef9SDimitry Andric     return Node.doesThisDeclarationHaveABody() ? Node.getBody() : nullptr;
19720b57cec5SDimitry Andric   }
19730b57cec5SDimitry Andric };
19740b57cec5SDimitry Andric 
1975e8d8bef9SDimitry Andric template <typename NodeType>
1976bdd1243dSDimitry Andric inline std::optional<BinaryOperatorKind>
1977e8d8bef9SDimitry Andric equivalentBinaryOperator(const NodeType &Node) {
1978e8d8bef9SDimitry Andric   return Node.getOpcode();
1979e8d8bef9SDimitry Andric }
1980e8d8bef9SDimitry Andric 
19810b57cec5SDimitry Andric template <>
1982bdd1243dSDimitry Andric inline std::optional<BinaryOperatorKind>
1983e8d8bef9SDimitry Andric equivalentBinaryOperator<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
1984e8d8bef9SDimitry Andric   if (Node.getNumArgs() != 2)
1985bdd1243dSDimitry Andric     return std::nullopt;
1986e8d8bef9SDimitry Andric   switch (Node.getOperator()) {
1987e8d8bef9SDimitry Andric   default:
1988bdd1243dSDimitry Andric     return std::nullopt;
1989e8d8bef9SDimitry Andric   case OO_ArrowStar:
1990e8d8bef9SDimitry Andric     return BO_PtrMemI;
1991e8d8bef9SDimitry Andric   case OO_Star:
1992e8d8bef9SDimitry Andric     return BO_Mul;
1993e8d8bef9SDimitry Andric   case OO_Slash:
1994e8d8bef9SDimitry Andric     return BO_Div;
1995e8d8bef9SDimitry Andric   case OO_Percent:
1996e8d8bef9SDimitry Andric     return BO_Rem;
1997e8d8bef9SDimitry Andric   case OO_Plus:
1998e8d8bef9SDimitry Andric     return BO_Add;
1999e8d8bef9SDimitry Andric   case OO_Minus:
2000e8d8bef9SDimitry Andric     return BO_Sub;
2001e8d8bef9SDimitry Andric   case OO_LessLess:
2002e8d8bef9SDimitry Andric     return BO_Shl;
2003e8d8bef9SDimitry Andric   case OO_GreaterGreater:
2004e8d8bef9SDimitry Andric     return BO_Shr;
2005e8d8bef9SDimitry Andric   case OO_Spaceship:
2006e8d8bef9SDimitry Andric     return BO_Cmp;
2007e8d8bef9SDimitry Andric   case OO_Less:
2008e8d8bef9SDimitry Andric     return BO_LT;
2009e8d8bef9SDimitry Andric   case OO_Greater:
2010e8d8bef9SDimitry Andric     return BO_GT;
2011e8d8bef9SDimitry Andric   case OO_LessEqual:
2012e8d8bef9SDimitry Andric     return BO_LE;
2013e8d8bef9SDimitry Andric   case OO_GreaterEqual:
2014e8d8bef9SDimitry Andric     return BO_GE;
2015e8d8bef9SDimitry Andric   case OO_EqualEqual:
2016e8d8bef9SDimitry Andric     return BO_EQ;
2017e8d8bef9SDimitry Andric   case OO_ExclaimEqual:
2018e8d8bef9SDimitry Andric     return BO_NE;
2019e8d8bef9SDimitry Andric   case OO_Amp:
2020e8d8bef9SDimitry Andric     return BO_And;
2021e8d8bef9SDimitry Andric   case OO_Caret:
2022e8d8bef9SDimitry Andric     return BO_Xor;
2023e8d8bef9SDimitry Andric   case OO_Pipe:
2024e8d8bef9SDimitry Andric     return BO_Or;
2025e8d8bef9SDimitry Andric   case OO_AmpAmp:
2026e8d8bef9SDimitry Andric     return BO_LAnd;
2027e8d8bef9SDimitry Andric   case OO_PipePipe:
2028e8d8bef9SDimitry Andric     return BO_LOr;
2029e8d8bef9SDimitry Andric   case OO_Equal:
2030e8d8bef9SDimitry Andric     return BO_Assign;
2031e8d8bef9SDimitry Andric   case OO_StarEqual:
2032e8d8bef9SDimitry Andric     return BO_MulAssign;
2033e8d8bef9SDimitry Andric   case OO_SlashEqual:
2034e8d8bef9SDimitry Andric     return BO_DivAssign;
2035e8d8bef9SDimitry Andric   case OO_PercentEqual:
2036e8d8bef9SDimitry Andric     return BO_RemAssign;
2037e8d8bef9SDimitry Andric   case OO_PlusEqual:
2038e8d8bef9SDimitry Andric     return BO_AddAssign;
2039e8d8bef9SDimitry Andric   case OO_MinusEqual:
2040e8d8bef9SDimitry Andric     return BO_SubAssign;
2041e8d8bef9SDimitry Andric   case OO_LessLessEqual:
2042e8d8bef9SDimitry Andric     return BO_ShlAssign;
2043e8d8bef9SDimitry Andric   case OO_GreaterGreaterEqual:
2044e8d8bef9SDimitry Andric     return BO_ShrAssign;
2045e8d8bef9SDimitry Andric   case OO_AmpEqual:
2046e8d8bef9SDimitry Andric     return BO_AndAssign;
2047e8d8bef9SDimitry Andric   case OO_CaretEqual:
2048e8d8bef9SDimitry Andric     return BO_XorAssign;
2049e8d8bef9SDimitry Andric   case OO_PipeEqual:
2050e8d8bef9SDimitry Andric     return BO_OrAssign;
2051e8d8bef9SDimitry Andric   case OO_Comma:
2052e8d8bef9SDimitry Andric     return BO_Comma;
2053e8d8bef9SDimitry Andric   }
2054e8d8bef9SDimitry Andric }
2055e8d8bef9SDimitry Andric 
2056e8d8bef9SDimitry Andric template <typename NodeType>
2057bdd1243dSDimitry Andric inline std::optional<UnaryOperatorKind>
2058e8d8bef9SDimitry Andric equivalentUnaryOperator(const NodeType &Node) {
2059e8d8bef9SDimitry Andric   return Node.getOpcode();
2060e8d8bef9SDimitry Andric }
2061e8d8bef9SDimitry Andric 
2062e8d8bef9SDimitry Andric template <>
2063bdd1243dSDimitry Andric inline std::optional<UnaryOperatorKind>
2064e8d8bef9SDimitry Andric equivalentUnaryOperator<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
2065fe6060f1SDimitry Andric   if (Node.getNumArgs() != 1 && Node.getOperator() != OO_PlusPlus &&
2066fe6060f1SDimitry Andric       Node.getOperator() != OO_MinusMinus)
2067bdd1243dSDimitry Andric     return std::nullopt;
2068e8d8bef9SDimitry Andric   switch (Node.getOperator()) {
2069e8d8bef9SDimitry Andric   default:
2070bdd1243dSDimitry Andric     return std::nullopt;
2071e8d8bef9SDimitry Andric   case OO_Plus:
2072e8d8bef9SDimitry Andric     return UO_Plus;
2073e8d8bef9SDimitry Andric   case OO_Minus:
2074e8d8bef9SDimitry Andric     return UO_Minus;
2075e8d8bef9SDimitry Andric   case OO_Amp:
2076e8d8bef9SDimitry Andric     return UO_AddrOf;
2077fe6060f1SDimitry Andric   case OO_Star:
2078fe6060f1SDimitry Andric     return UO_Deref;
2079e8d8bef9SDimitry Andric   case OO_Tilde:
2080e8d8bef9SDimitry Andric     return UO_Not;
2081e8d8bef9SDimitry Andric   case OO_Exclaim:
2082e8d8bef9SDimitry Andric     return UO_LNot;
2083e8d8bef9SDimitry Andric   case OO_PlusPlus: {
2084e8d8bef9SDimitry Andric     const auto *FD = Node.getDirectCallee();
2085e8d8bef9SDimitry Andric     if (!FD)
2086bdd1243dSDimitry Andric       return std::nullopt;
2087e8d8bef9SDimitry Andric     return FD->getNumParams() > 0 ? UO_PostInc : UO_PreInc;
2088e8d8bef9SDimitry Andric   }
2089e8d8bef9SDimitry Andric   case OO_MinusMinus: {
2090e8d8bef9SDimitry Andric     const auto *FD = Node.getDirectCallee();
2091e8d8bef9SDimitry Andric     if (!FD)
2092bdd1243dSDimitry Andric       return std::nullopt;
2093e8d8bef9SDimitry Andric     return FD->getNumParams() > 0 ? UO_PostDec : UO_PreDec;
2094e8d8bef9SDimitry Andric   }
2095e8d8bef9SDimitry Andric   case OO_Coawait:
2096e8d8bef9SDimitry Andric     return UO_Coawait;
2097e8d8bef9SDimitry Andric   }
2098e8d8bef9SDimitry Andric }
2099e8d8bef9SDimitry Andric 
2100e8d8bef9SDimitry Andric template <typename NodeType> inline const Expr *getLHS(const NodeType &Node) {
2101e8d8bef9SDimitry Andric   return Node.getLHS();
2102e8d8bef9SDimitry Andric }
2103e8d8bef9SDimitry Andric template <>
2104e8d8bef9SDimitry Andric inline const Expr *
2105e8d8bef9SDimitry Andric getLHS<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
2106e8d8bef9SDimitry Andric   if (!internal::equivalentBinaryOperator(Node))
2107e8d8bef9SDimitry Andric     return nullptr;
2108e8d8bef9SDimitry Andric   return Node.getArg(0);
2109e8d8bef9SDimitry Andric }
2110e8d8bef9SDimitry Andric template <typename NodeType> inline const Expr *getRHS(const NodeType &Node) {
2111e8d8bef9SDimitry Andric   return Node.getRHS();
2112e8d8bef9SDimitry Andric }
2113e8d8bef9SDimitry Andric template <>
2114e8d8bef9SDimitry Andric inline const Expr *
2115e8d8bef9SDimitry Andric getRHS<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
2116e8d8bef9SDimitry Andric   if (!internal::equivalentBinaryOperator(Node))
2117e8d8bef9SDimitry Andric     return nullptr;
2118e8d8bef9SDimitry Andric   return Node.getArg(1);
2119e8d8bef9SDimitry Andric }
2120e8d8bef9SDimitry Andric template <typename NodeType>
2121e8d8bef9SDimitry Andric inline const Expr *getSubExpr(const NodeType &Node) {
2122e8d8bef9SDimitry Andric   return Node.getSubExpr();
2123e8d8bef9SDimitry Andric }
2124e8d8bef9SDimitry Andric template <>
2125e8d8bef9SDimitry Andric inline const Expr *
2126e8d8bef9SDimitry Andric getSubExpr<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
2127e8d8bef9SDimitry Andric   if (!internal::equivalentUnaryOperator(Node))
2128e8d8bef9SDimitry Andric     return nullptr;
2129e8d8bef9SDimitry Andric   return Node.getArg(0);
21300b57cec5SDimitry Andric }
21310b57cec5SDimitry Andric 
21320b57cec5SDimitry Andric template <typename Ty>
21330b57cec5SDimitry Andric struct HasSizeMatcher {
21340b57cec5SDimitry Andric   static bool hasSize(const Ty &Node, unsigned int N) {
21350b57cec5SDimitry Andric     return Node.getSize() == N;
21360b57cec5SDimitry Andric   }
21370b57cec5SDimitry Andric };
21380b57cec5SDimitry Andric 
21390b57cec5SDimitry Andric template <>
21400b57cec5SDimitry Andric inline bool HasSizeMatcher<StringLiteral>::hasSize(
21410b57cec5SDimitry Andric     const StringLiteral &Node, unsigned int N) {
21420b57cec5SDimitry Andric   return Node.getLength() == N;
21430b57cec5SDimitry Andric }
21440b57cec5SDimitry Andric 
21450b57cec5SDimitry Andric template <typename Ty>
21460b57cec5SDimitry Andric struct GetSourceExpressionMatcher {
21470b57cec5SDimitry Andric   static const Expr *get(const Ty &Node) {
21480b57cec5SDimitry Andric     return Node.getSubExpr();
21490b57cec5SDimitry Andric   }
21500b57cec5SDimitry Andric };
21510b57cec5SDimitry Andric 
21520b57cec5SDimitry Andric template <>
21530b57cec5SDimitry Andric inline const Expr *GetSourceExpressionMatcher<OpaqueValueExpr>::get(
21540b57cec5SDimitry Andric     const OpaqueValueExpr &Node) {
21550b57cec5SDimitry Andric   return Node.getSourceExpr();
21560b57cec5SDimitry Andric }
21570b57cec5SDimitry Andric 
21580b57cec5SDimitry Andric template <typename Ty>
21590b57cec5SDimitry Andric struct CompoundStmtMatcher {
21600b57cec5SDimitry Andric   static const CompoundStmt *get(const Ty &Node) {
21610b57cec5SDimitry Andric     return &Node;
21620b57cec5SDimitry Andric   }
21630b57cec5SDimitry Andric };
21640b57cec5SDimitry Andric 
21650b57cec5SDimitry Andric template <>
21660b57cec5SDimitry Andric inline const CompoundStmt *
21670b57cec5SDimitry Andric CompoundStmtMatcher<StmtExpr>::get(const StmtExpr &Node) {
21680b57cec5SDimitry Andric   return Node.getSubStmt();
21690b57cec5SDimitry Andric }
21700b57cec5SDimitry Andric 
21715ffd83dbSDimitry Andric /// If \p Loc is (transitively) expanded from macro \p MacroName, returns the
21725ffd83dbSDimitry Andric /// location (in the chain of expansions) at which \p MacroName was
21735ffd83dbSDimitry Andric /// expanded. Since the macro may have been expanded inside a series of
21745ffd83dbSDimitry Andric /// expansions, that location may itself be a MacroID.
2175bdd1243dSDimitry Andric std::optional<SourceLocation> getExpansionLocOfMacro(StringRef MacroName,
2176bdd1243dSDimitry Andric                                                      SourceLocation Loc,
21775ffd83dbSDimitry Andric                                                      const ASTContext &Context);
21785ffd83dbSDimitry Andric 
2179bdd1243dSDimitry Andric inline std::optional<StringRef> getOpName(const UnaryOperator &Node) {
2180e8d8bef9SDimitry Andric   return Node.getOpcodeStr(Node.getOpcode());
2181e8d8bef9SDimitry Andric }
2182bdd1243dSDimitry Andric inline std::optional<StringRef> getOpName(const BinaryOperator &Node) {
2183e8d8bef9SDimitry Andric   return Node.getOpcodeStr();
2184e8d8bef9SDimitry Andric }
2185e8d8bef9SDimitry Andric inline StringRef getOpName(const CXXRewrittenBinaryOperator &Node) {
2186e8d8bef9SDimitry Andric   return Node.getOpcodeStr();
2187e8d8bef9SDimitry Andric }
2188bdd1243dSDimitry Andric inline std::optional<StringRef> getOpName(const CXXOperatorCallExpr &Node) {
2189e8d8bef9SDimitry Andric   auto optBinaryOpcode = equivalentBinaryOperator(Node);
2190e8d8bef9SDimitry Andric   if (!optBinaryOpcode) {
2191e8d8bef9SDimitry Andric     auto optUnaryOpcode = equivalentUnaryOperator(Node);
2192e8d8bef9SDimitry Andric     if (!optUnaryOpcode)
2193bdd1243dSDimitry Andric       return std::nullopt;
2194e8d8bef9SDimitry Andric     return UnaryOperator::getOpcodeStr(*optUnaryOpcode);
2195e8d8bef9SDimitry Andric   }
2196e8d8bef9SDimitry Andric   return BinaryOperator::getOpcodeStr(*optBinaryOpcode);
2197e8d8bef9SDimitry Andric }
21987a6dacacSDimitry Andric inline StringRef getOpName(const CXXFoldExpr &Node) {
21997a6dacacSDimitry Andric   return BinaryOperator::getOpcodeStr(Node.getOperator());
22007a6dacacSDimitry Andric }
2201e8d8bef9SDimitry Andric 
22025ffd83dbSDimitry Andric /// Matches overloaded operators with a specific name.
22035ffd83dbSDimitry Andric ///
22045ffd83dbSDimitry Andric /// The type argument ArgT is not used by this matcher but is used by
2205fe6060f1SDimitry Andric /// PolymorphicMatcher and should be std::vector<std::string>>.
22065ffd83dbSDimitry Andric template <typename T, typename ArgT = std::vector<std::string>>
22075ffd83dbSDimitry Andric class HasAnyOperatorNameMatcher : public SingleNodeMatcherInterface<T> {
22085ffd83dbSDimitry Andric   static_assert(std::is_same<T, BinaryOperator>::value ||
2209e8d8bef9SDimitry Andric                     std::is_same<T, CXXOperatorCallExpr>::value ||
2210e8d8bef9SDimitry Andric                     std::is_same<T, CXXRewrittenBinaryOperator>::value ||
22115ffd83dbSDimitry Andric                     std::is_same<T, UnaryOperator>::value,
2212e8d8bef9SDimitry Andric                 "Matcher only supports `BinaryOperator`, `UnaryOperator`, "
2213e8d8bef9SDimitry Andric                 "`CXXOperatorCallExpr` and `CXXRewrittenBinaryOperator`");
22145ffd83dbSDimitry Andric   static_assert(std::is_same<ArgT, std::vector<std::string>>::value,
22155ffd83dbSDimitry Andric                 "Matcher ArgT must be std::vector<std::string>");
22165ffd83dbSDimitry Andric 
22175ffd83dbSDimitry Andric public:
22185ffd83dbSDimitry Andric   explicit HasAnyOperatorNameMatcher(std::vector<std::string> Names)
22195ffd83dbSDimitry Andric       : SingleNodeMatcherInterface<T>(), Names(std::move(Names)) {}
22205ffd83dbSDimitry Andric 
22215ffd83dbSDimitry Andric   bool matchesNode(const T &Node) const override {
2222bdd1243dSDimitry Andric     std::optional<StringRef> OptOpName = getOpName(Node);
2223349cc55cSDimitry Andric     return OptOpName && llvm::is_contained(Names, *OptOpName);
22245ffd83dbSDimitry Andric   }
22255ffd83dbSDimitry Andric 
22265ffd83dbSDimitry Andric private:
2227bdd1243dSDimitry Andric   static std::optional<StringRef> getOpName(const UnaryOperator &Node) {
22285ffd83dbSDimitry Andric     return Node.getOpcodeStr(Node.getOpcode());
22295ffd83dbSDimitry Andric   }
2230bdd1243dSDimitry Andric   static std::optional<StringRef> getOpName(const BinaryOperator &Node) {
22315ffd83dbSDimitry Andric     return Node.getOpcodeStr();
22325ffd83dbSDimitry Andric   }
2233e8d8bef9SDimitry Andric   static StringRef getOpName(const CXXRewrittenBinaryOperator &Node) {
2234e8d8bef9SDimitry Andric     return Node.getOpcodeStr();
2235e8d8bef9SDimitry Andric   }
2236bdd1243dSDimitry Andric   static std::optional<StringRef> getOpName(const CXXOperatorCallExpr &Node) {
2237e8d8bef9SDimitry Andric     auto optBinaryOpcode = equivalentBinaryOperator(Node);
2238e8d8bef9SDimitry Andric     if (!optBinaryOpcode) {
2239e8d8bef9SDimitry Andric       auto optUnaryOpcode = equivalentUnaryOperator(Node);
2240e8d8bef9SDimitry Andric       if (!optUnaryOpcode)
2241bdd1243dSDimitry Andric         return std::nullopt;
2242e8d8bef9SDimitry Andric       return UnaryOperator::getOpcodeStr(*optUnaryOpcode);
2243e8d8bef9SDimitry Andric     }
2244e8d8bef9SDimitry Andric     return BinaryOperator::getOpcodeStr(*optBinaryOpcode);
2245e8d8bef9SDimitry Andric   }
22465ffd83dbSDimitry Andric 
2247fe6060f1SDimitry Andric   std::vector<std::string> Names;
22485ffd83dbSDimitry Andric };
22495ffd83dbSDimitry Andric 
2250fe6060f1SDimitry Andric using HasOpNameMatcher =
2251fe6060f1SDimitry Andric     PolymorphicMatcher<HasAnyOperatorNameMatcher,
2252fe6060f1SDimitry Andric                        void(
2253fe6060f1SDimitry Andric                            TypeList<BinaryOperator, CXXOperatorCallExpr,
2254fe6060f1SDimitry Andric                                     CXXRewrittenBinaryOperator, UnaryOperator>),
2255fe6060f1SDimitry Andric                        std::vector<std::string>>;
22565ffd83dbSDimitry Andric 
22575ffd83dbSDimitry Andric HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef<const StringRef *> NameRefs);
22585ffd83dbSDimitry Andric 
2259fe6060f1SDimitry Andric using HasOverloadOpNameMatcher =
2260fe6060f1SDimitry Andric     PolymorphicMatcher<HasOverloadedOperatorNameMatcher,
2261fe6060f1SDimitry Andric                        void(TypeList<CXXOperatorCallExpr, FunctionDecl>),
2262fe6060f1SDimitry Andric                        std::vector<std::string>>;
22635ffd83dbSDimitry Andric 
22645ffd83dbSDimitry Andric HasOverloadOpNameMatcher
22655ffd83dbSDimitry Andric hasAnyOverloadedOperatorNameFunc(ArrayRef<const StringRef *> NameRefs);
22665ffd83dbSDimitry Andric 
22675ffd83dbSDimitry Andric /// Returns true if \p Node has a base specifier matching \p BaseSpec.
22685ffd83dbSDimitry Andric ///
22695ffd83dbSDimitry Andric /// A class is not considered to be derived from itself.
22705ffd83dbSDimitry Andric bool matchesAnyBase(const CXXRecordDecl &Node,
22715ffd83dbSDimitry Andric                     const Matcher<CXXBaseSpecifier> &BaseSpecMatcher,
22725ffd83dbSDimitry Andric                     ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder);
22735ffd83dbSDimitry Andric 
22745ffd83dbSDimitry Andric std::shared_ptr<llvm::Regex> createAndVerifyRegex(StringRef Regex,
22755ffd83dbSDimitry Andric                                                   llvm::Regex::RegexFlags Flags,
22765ffd83dbSDimitry Andric                                                   StringRef MatcherID);
22775ffd83dbSDimitry Andric 
2278349cc55cSDimitry Andric inline bool
2279349cc55cSDimitry Andric MatchTemplateArgLocAt(const DeclRefExpr &Node, unsigned int Index,
2280349cc55cSDimitry Andric                       internal::Matcher<TemplateArgumentLoc> InnerMatcher,
2281349cc55cSDimitry Andric                       internal::ASTMatchFinder *Finder,
2282349cc55cSDimitry Andric                       internal::BoundNodesTreeBuilder *Builder) {
2283349cc55cSDimitry Andric   llvm::ArrayRef<TemplateArgumentLoc> ArgLocs = Node.template_arguments();
2284349cc55cSDimitry Andric   return Index < ArgLocs.size() &&
2285349cc55cSDimitry Andric          InnerMatcher.matches(ArgLocs[Index], Finder, Builder);
2286349cc55cSDimitry Andric }
2287349cc55cSDimitry Andric 
2288349cc55cSDimitry Andric inline bool
2289349cc55cSDimitry Andric MatchTemplateArgLocAt(const TemplateSpecializationTypeLoc &Node,
2290349cc55cSDimitry Andric                       unsigned int Index,
2291349cc55cSDimitry Andric                       internal::Matcher<TemplateArgumentLoc> InnerMatcher,
2292349cc55cSDimitry Andric                       internal::ASTMatchFinder *Finder,
2293349cc55cSDimitry Andric                       internal::BoundNodesTreeBuilder *Builder) {
2294349cc55cSDimitry Andric   return !Node.isNull() && Index < Node.getNumArgs() &&
2295349cc55cSDimitry Andric          InnerMatcher.matches(Node.getArgLoc(Index), Finder, Builder);
2296349cc55cSDimitry Andric }
2297349cc55cSDimitry Andric 
22980b57cec5SDimitry Andric } // namespace internal
22990b57cec5SDimitry Andric 
23000b57cec5SDimitry Andric } // namespace ast_matchers
23010b57cec5SDimitry Andric 
23020b57cec5SDimitry Andric } // namespace clang
23030b57cec5SDimitry Andric 
23040b57cec5SDimitry Andric #endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H
2305