14da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//===--- ASTMatchersInternal.h - Structural query framework -----*- C++ -*-===// 24da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// 34da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// The LLVM Compiler Infrastructure 44da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// 54da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// This file is distributed under the University of Illinois Open Source 64da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// License. See LICENSE.TXT for details. 74da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// 84da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//===----------------------------------------------------------------------===// 94da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// 104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// Implements the base layer of the matcher framework. 114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// 124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// Matchers are methods that return a Matcher<T> which provides a method 134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// Matches(...) which is a predicate on an AST node. The Matches method's 144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// parameters define the context of the match, which allows matchers to recurse 154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// or store the current node as bound to a specific string, so that it can be 164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// retrieved later. 174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// 184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// In general, matchers have two parts: 194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// 1. A function Matcher<T> MatcherName(<arguments>) which returns a Matcher<T> 204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// based on the arguments and optionally on template type deduction based 214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// on the arguments. Matcher<T>s form an implicit reverse hierarchy 224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// to clang's AST class hierarchy, meaning that you can use a Matcher<Base> 234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// everywhere a Matcher<Derived> is required. 244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// 2. An implementation of a class derived from MatcherInterface<T>. 254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// 264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// The matcher functions are defined in ASTMatchers.h. To make it possible 274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// to implement both the matcher function and the implementation of the matcher 284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// interface in one place, ASTMatcherMacros.h defines macros that allow 294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// implementing a matcher in a single place. 304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// 314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// This file contains the base classes needed to construct the actual matchers. 324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// 334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//===----------------------------------------------------------------------===// 344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#ifndef LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_INTERNAL_H 364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_INTERNAL_H 374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 38ff9a01000ff74a994aa3da26ea2ec732c97291b7Manuel Klimek#include "clang/AST/ASTTypeTraits.h" 39c30bf45115860b8de8628295f0d9cd86998841deReid Kleckner#include "clang/AST/Decl.h" 40b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen#include "clang/AST/DeclCXX.h" 414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#include "clang/AST/ExprCXX.h" 42c30bf45115860b8de8628295f0d9cd86998841deReid Kleckner#include "clang/AST/Stmt.h" 43b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen#include "clang/AST/StmtCXX.h" 44ec2a396c6f11b4017e30f1865f7b62c5a42425b8Manuel Klimek#include "clang/AST/Type.h" 45b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen#include "llvm/ADT/Optional.h" 464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#include "llvm/ADT/VariadicFunction.h" 474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#include <map> 484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#include <string> 494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#include <vector> 504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 512db5abb43b7a7fce4771063f6a5de561780c1335Daniel Jaspernamespace clang { 522db5abb43b7a7fce4771063f6a5de561780c1335Daniel Jaspernamespace ast_matchers { 532db5abb43b7a7fce4771063f6a5de561780c1335Daniel Jasper 544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekclass BoundNodes; 554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimeknamespace internal { 574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 58ec2a396c6f11b4017e30f1865f7b62c5a42425b8Manuel Klimek/// \brief Internal version of BoundNodes. Holds all the bound nodes. 59ec2a396c6f11b4017e30f1865f7b62c5a42425b8Manuel Klimekclass BoundNodesMap { 60ec2a396c6f11b4017e30f1865f7b62c5a42425b8Manuel Klimekpublic: 61ec2a396c6f11b4017e30f1865f7b62c5a42425b8Manuel Klimek /// \brief Adds \c Node to the map with key \c ID. 62ec2a396c6f11b4017e30f1865f7b62c5a42425b8Manuel Klimek /// 63ec2a396c6f11b4017e30f1865f7b62c5a42425b8Manuel Klimek /// The node's base type should be in NodeBaseType or it will be unaccessible. 64ec2a396c6f11b4017e30f1865f7b62c5a42425b8Manuel Klimek template <typename T> 65ec2a396c6f11b4017e30f1865f7b62c5a42425b8Manuel Klimek void addNode(StringRef ID, const T* Node) { 66a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek NodeMap[ID] = ast_type_traits::DynTypedNode::create(*Node); 6766341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek } 68ec2a396c6f11b4017e30f1865f7b62c5a42425b8Manuel Klimek 69ec2a396c6f11b4017e30f1865f7b62c5a42425b8Manuel Klimek /// \brief Returns the AST node bound to \c ID. 70ec2a396c6f11b4017e30f1865f7b62c5a42425b8Manuel Klimek /// 71ec2a396c6f11b4017e30f1865f7b62c5a42425b8Manuel Klimek /// Returns NULL if there was no node bound to \c ID or if there is a node but 72ec2a396c6f11b4017e30f1865f7b62c5a42425b8Manuel Klimek /// it cannot be converted to the specified type. 73ec2a396c6f11b4017e30f1865f7b62c5a42425b8Manuel Klimek template <typename T> 74a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek const T *getNodeAs(StringRef ID) const { 75ec2a396c6f11b4017e30f1865f7b62c5a42425b8Manuel Klimek IDToNodeMap::const_iterator It = NodeMap.find(ID); 76ec2a396c6f11b4017e30f1865f7b62c5a42425b8Manuel Klimek if (It == NodeMap.end()) { 776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 78ec2a396c6f11b4017e30f1865f7b62c5a42425b8Manuel Klimek } 7966341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek return It->second.get<T>(); 80ec2a396c6f11b4017e30f1865f7b62c5a42425b8Manuel Klimek } 81ec2a396c6f11b4017e30f1865f7b62c5a42425b8Manuel Klimek 82cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek ast_type_traits::DynTypedNode getNode(StringRef ID) const { 83cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek IDToNodeMap::const_iterator It = NodeMap.find(ID); 84cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek if (It == NodeMap.end()) { 85cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek return ast_type_traits::DynTypedNode(); 86cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek } 87cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek return It->second; 88cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek } 89cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek 90054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek /// \brief Imposes an order on BoundNodesMaps. 91054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek bool operator<(const BoundNodesMap &Other) const { 92054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek return NodeMap < Other.NodeMap; 93054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek } 94ec2a396c6f11b4017e30f1865f7b62c5a42425b8Manuel Klimek 9566341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek /// \brief A map from IDs to the bound nodes. 96054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek /// 97054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek /// Note that we're using std::map here, as for memoization: 98054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek /// - we need a comparison operator 99054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek /// - we need an assignment operator 10066341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek typedef std::map<std::string, ast_type_traits::DynTypedNode> IDToNodeMap; 101ec2a396c6f11b4017e30f1865f7b62c5a42425b8Manuel Klimek 1023f0e0402d8cd40b428f975f1a3607dbbd94d2ca6Peter Collingbourne const IDToNodeMap &getMap() const { 1033f0e0402d8cd40b428f975f1a3607dbbd94d2ca6Peter Collingbourne return NodeMap; 1043f0e0402d8cd40b428f975f1a3607dbbd94d2ca6Peter Collingbourne } 1053f0e0402d8cd40b428f975f1a3607dbbd94d2ca6Peter Collingbourne 1063f0e0402d8cd40b428f975f1a3607dbbd94d2ca6Peter Collingbourneprivate: 107ec2a396c6f11b4017e30f1865f7b62c5a42425b8Manuel Klimek IDToNodeMap NodeMap; 108ec2a396c6f11b4017e30f1865f7b62c5a42425b8Manuel Klimek}; 109ec2a396c6f11b4017e30f1865f7b62c5a42425b8Manuel Klimek 110054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek/// \brief Creates BoundNodesTree objects. 1114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// 112054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek/// The tree builder is used during the matching process to insert the bound 113054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek/// nodes from the Id matcher. 114054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimekclass BoundNodesTreeBuilder { 1154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekpublic: 1164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// \brief A visitor interface to visit all BoundNodes results for a 1174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// BoundNodesTree. 1184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek class Visitor { 1194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek public: 1204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek virtual ~Visitor() {} 1214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 1224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// \brief Called multiple times during a single call to VisitMatches(...). 1234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// 1244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// 'BoundNodesView' contains the bound nodes for a single match. 1254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek virtual void visitMatch(const BoundNodes& BoundNodesView) = 0; 1264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek }; 1274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 128054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek /// \brief Add a binding from an id to a node. 129054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek template <typename T> void setBinding(const std::string &Id, const T *Node) { 130054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek if (Bindings.empty()) 131054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek Bindings.push_back(BoundNodesMap()); 132054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek for (unsigned i = 0, e = Bindings.size(); i != e; ++i) 133054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek Bindings[i].addNode(Id, Node); 134054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek } 1354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 136054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek /// \brief Adds a branch in the tree. 137054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek void addMatch(const BoundNodesTreeBuilder &Bindings); 1384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 1394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// \brief Visits all matches that this BoundNodesTree represents. 1404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// 1414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// The ownership of 'ResultVisitor' remains at the caller. 1424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek void visitMatches(Visitor* ResultVisitor); 1434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 144cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek template <typename ExcludePredicate> 145cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek bool removeBindings(const ExcludePredicate &Predicate) { 146cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek Bindings.erase(std::remove_if(Bindings.begin(), Bindings.end(), Predicate), 147cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek Bindings.end()); 148cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek return !Bindings.empty(); 149cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek } 150cf52ca6bb6dd76a1bd967bc422287fafafa1e45aManuel Klimek 151054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek /// \brief Imposes an order on BoundNodesTreeBuilders. 152054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek bool operator<(const BoundNodesTreeBuilder &Other) const { 153054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek return Bindings < Other.Bindings; 15466341c596f93d0c6475d839db94072b8ebd1cf5bManuel Klimek } 1554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 1564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekprivate: 157054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek SmallVector<BoundNodesMap, 16> Bindings; 1584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}; 1594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 1604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekclass ASTMatchFinder; 1614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 1624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief Generic interface for matchers on an AST node of type T. 1634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// 1644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// Implement this if your matcher may need to inspect the children or 1654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// descendants of the node or bind matched nodes to names. If you are 1664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// writing a simple matcher that only inspects properties of the 1674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// current node and doesn't care about its children or descendants, 1684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// implement SingleNodeMatcherInterface instead. 1694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektemplate <typename T> 170cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenkoclass MatcherInterface : public RefCountedBaseVPTR { 1714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekpublic: 1724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek virtual ~MatcherInterface() {} 1734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 1744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// \brief Returns true if 'Node' can be matched. 1754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// 1764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// May bind 'Node' to an ID via 'Builder', or recurse into 1774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// the AST via 'Finder'. 1784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek virtual bool matches(const T &Node, 1794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek ASTMatchFinder *Finder, 1804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek BoundNodesTreeBuilder *Builder) const = 0; 1814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}; 1824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 183a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek/// \brief Interface for matchers that only evaluate properties on a single 184a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek/// node. 1854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektemplate <typename T> 1864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekclass SingleNodeMatcherInterface : public MatcherInterface<T> { 1874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekpublic: 1884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// \brief Returns true if the matcher matches the provided node. 1894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// 1904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// A subclass must implement this instead of Matches(). 1914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek virtual bool matchesNode(const T &Node) const = 0; 1924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 1934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekprivate: 1944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// Implements MatcherInterface::Matches. 195651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool matches(const T &Node, 196651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ASTMatchFinder * /* Finder */, 197651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BoundNodesTreeBuilder * /* Builder */) const override { 1984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek return matchesNode(Node); 1994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } 2004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}; 2014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 2024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief Wrapper of a MatcherInterface<T> *that allows copying. 2034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// 2044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// A Matcher<Base> can be used anywhere a Matcher<Derived> is 2054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// required. This establishes an is-a relationship which is reverse 2064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// to the AST hierarchy. In other words, Matcher<T> is contravariant 2074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// with respect to T. The relationship is built via a type conversion 2084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// operator rather than a type hierarchy to be able to templatize the 2094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// type hierarchy instead of spelling it out. 2104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektemplate <typename T> 211b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquenclass Matcher { 2124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekpublic: 2134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// \brief Takes ownership of the provided implementation pointer. 2144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek explicit Matcher(MatcherInterface<T> *Implementation) 2154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek : Implementation(Implementation) {} 2164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 217b3278162bd6d34783607d4bfe8814df73e8ef8c1Daniel Jasper /// \brief Implicitly converts \c Other to a Matcher<T>. 218b3278162bd6d34783607d4bfe8814df73e8ef8c1Daniel Jasper /// 219b3278162bd6d34783607d4bfe8814df73e8ef8c1Daniel Jasper /// Requires \c T to be derived from \c From. 220b3278162bd6d34783607d4bfe8814df73e8ef8c1Daniel Jasper template <typename From> 221b3278162bd6d34783607d4bfe8814df73e8ef8c1Daniel Jasper Matcher(const Matcher<From> &Other, 222651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines typename std::enable_if<std::is_base_of<From, T>::value && 223651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines !std::is_same<From, T>::value>::type * = 0) 224b3278162bd6d34783607d4bfe8814df73e8ef8c1Daniel Jasper : Implementation(new ImplicitCastMatcher<From>(Other)) {} 225b3278162bd6d34783607d4bfe8814df73e8ef8c1Daniel Jasper 226ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper /// \brief Implicitly converts \c Matcher<Type> to \c Matcher<QualType>. 227ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper /// 228ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper /// The resulting matcher is not strict, i.e. ignores qualifiers. 229ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper template <typename TypeT> 230ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper Matcher(const Matcher<TypeT> &Other, 231651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines typename std::enable_if< 232651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_same<T, QualType>::value && 233651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_same<TypeT, Type>::value>::type* = 0) 234ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper : Implementation(new TypeToQualType<TypeT>(Other)) {} 235ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper 2364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// \brief Forwards the call to the underlying MatcherInterface<T> pointer. 2374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek bool matches(const T &Node, 2384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek ASTMatchFinder *Finder, 2394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek BoundNodesTreeBuilder *Builder) const { 240054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek if (Implementation->matches(Node, Finder, Builder)) 241054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek return true; 242054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek // Delete all bindings when a matcher does not match. 243054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek // This prevents unexpected exposure of bound nodes in unmatches 244054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek // branches of the match tree. 245054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek *Builder = BoundNodesTreeBuilder(); 246054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek return false; 2474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } 2484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 2494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// \brief Returns an ID that uniquely identifies the matcher. 2504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek uint64_t getID() const { 2514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// FIXME: Document the requirements this imposes on matcher 2524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// implementations (no new() implementation_ during a Matches()). 253ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return reinterpret_cast<uint64_t>(Implementation.get()); 2544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } 2554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 256ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper /// \brief Allows the conversion of a \c Matcher<Type> to a \c 257ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper /// Matcher<QualType>. 258ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper /// 259ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper /// Depending on the constructor argument, the matcher is either strict, i.e. 260ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper /// does only matches in the absence of qualifiers, or not, i.e. simply 261ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper /// ignores any qualifiers. 262ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper template <typename TypeT> 263ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper class TypeToQualType : public MatcherInterface<QualType> { 264ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper public: 265ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper TypeToQualType(const Matcher<TypeT> &InnerMatcher) 266ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper : InnerMatcher(InnerMatcher) {} 267ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper 268651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool matches(const QualType &Node, ASTMatchFinder *Finder, 269651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BoundNodesTreeBuilder *Builder) const override { 270ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper if (Node.isNull()) 271ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper return false; 272ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper return InnerMatcher.matches(*Node, Finder, Builder); 273ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper } 274ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper private: 275ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper const Matcher<TypeT> InnerMatcher; 276ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper }; 277ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper 2784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekprivate: 279b3278162bd6d34783607d4bfe8814df73e8ef8c1Daniel Jasper /// \brief Allows conversion from Matcher<Base> to Matcher<T> if T 280b3278162bd6d34783607d4bfe8814df73e8ef8c1Daniel Jasper /// is derived from Base. 281b3278162bd6d34783607d4bfe8814df73e8ef8c1Daniel Jasper template <typename Base> 282b3278162bd6d34783607d4bfe8814df73e8ef8c1Daniel Jasper class ImplicitCastMatcher : public MatcherInterface<T> { 2834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek public: 284b3278162bd6d34783607d4bfe8814df73e8ef8c1Daniel Jasper explicit ImplicitCastMatcher(const Matcher<Base> &From) 2854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek : From(From) {} 2864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 287651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool matches(const T &Node, ASTMatchFinder *Finder, 288651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BoundNodesTreeBuilder *Builder) const override { 2894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek return From.matches(Node, Finder, Builder); 2904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } 2914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 2924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek private: 293b3278162bd6d34783607d4bfe8814df73e8ef8c1Daniel Jasper const Matcher<Base> From; 2944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek }; 2954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 296cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko IntrusiveRefCntPtr< MatcherInterface<T> > Implementation; 2974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}; // class Matcher 2984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 2994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief A convenient helper for creating a Matcher<T> without specifying 3004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// the template type argument. 3014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektemplate <typename T> 3024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekinline Matcher<T> makeMatcher(MatcherInterface<T> *Implementation) { 3034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek return Matcher<T>(Implementation); 3044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek} 3054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 306b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquentemplate <typename T> class BindableMatcher; 307b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen 308b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen/// \brief Matcher that works on a \c DynTypedNode. 309b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen/// 310b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen/// It is constructed from a \c Matcher<T> object and redirects most calls to 311b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen/// underlying matcher. 312b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen/// It checks whether the \c DynTypedNode is convertible into the type of the 313b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen/// underlying matcher and then do the actual match on the actual node, or 314b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen/// return false if it is not convertible. 315b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquenclass DynTypedMatcher { 316b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquenpublic: 317b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// \brief Construct from a \c Matcher<T>. Copies the matcher. 318b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen template <typename T> inline DynTypedMatcher(const Matcher<T> &M); 319b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen 320b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// \brief Construct from a bindable \c Matcher<T>. Copies the matcher. 321b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// 322b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// This version enables \c tryBind() on the \c DynTypedMatcher. 323b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen template <typename T> inline DynTypedMatcher(const BindableMatcher<T> &M); 324b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen 325b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// \brief Returns true if the matcher matches the given \c DynNode. 326b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen bool matches(const ast_type_traits::DynTypedNode DynNode, 327b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const { 328b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen return Storage->matches(DynNode, Finder, Builder); 329b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen } 330b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen 331b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// \brief Bind the specified \p ID to the matcher. 332b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// \return A new matcher with the \p ID bound to it if this matcher supports 333b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// binding. Otherwise, returns an empty \c Optional<>. 334b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const { 335b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen return Storage->tryBind(ID); 336b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen } 337b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen 338b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// \brief Returns a unique \p ID for the matcher. 339b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen uint64_t getID() const { return Storage->getID(); } 340b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen 341b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// \brief Returns the type this matcher works on. 342b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// 343b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// \c matches() will always return false unless the node passed is of this 344b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// or a derived type. 345b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen ast_type_traits::ASTNodeKind getSupportedKind() const { 346b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen return Storage->getSupportedKind(); 347b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen } 348b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen 349b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// \brief Returns \c true if the passed \c DynTypedMatcher can be converted 350b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// to a \c Matcher<T>. 351b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// 352b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// This method verifies that the underlying matcher in \c Other can process 353b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// nodes of types T. 354b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen template <typename T> bool canConvertTo() const { 355b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen return getSupportedKind().isBaseOf( 356b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen ast_type_traits::ASTNodeKind::getFromNodeKind<T>()); 357b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen } 358b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen 359b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// \brief Construct a \c Matcher<T> interface around the dynamic matcher. 360b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// 361b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// This method asserts that \c canConvertTo() is \c true. Callers 362b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// should call \c canConvertTo() first to make sure that \c this is 363b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// compatible with T. 364b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen template <typename T> Matcher<T> convertTo() const { 365b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen assert(canConvertTo<T>()); 366b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen return unconditionalConvertTo<T>(); 367b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen } 368b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen 369b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// \brief Same as \c convertTo(), but does not check that the underlying 370b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// matcher can handle a value of T. 371b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// 372b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// If it is not compatible, then this matcher will never match anything. 373651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines template <typename T> Matcher<T> unconditionalConvertTo() const; 374b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen 375b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquenprivate: 376b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen class MatcherStorage : public RefCountedBaseVPTR { 377b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen public: 378b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen MatcherStorage(ast_type_traits::ASTNodeKind SupportedKind, uint64_t ID) 379b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen : SupportedKind(SupportedKind), ID(ID) {} 380b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen virtual ~MatcherStorage(); 381b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen 382b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen virtual bool matches(const ast_type_traits::DynTypedNode DynNode, 383b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen ASTMatchFinder *Finder, 384b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen BoundNodesTreeBuilder *Builder) const = 0; 385b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen 386b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen virtual llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const = 0; 387b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen 388b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen ast_type_traits::ASTNodeKind getSupportedKind() const { 389b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen return SupportedKind; 390b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen } 391b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen 392b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen uint64_t getID() const { return ID; } 393b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen 394b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen private: 395b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen const ast_type_traits::ASTNodeKind SupportedKind; 396b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen const uint64_t ID; 397b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen }; 398b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen 399b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen /// \brief Typed implementation of \c MatcherStorage. 400b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen template <typename T> class TypedMatcherStorage; 401b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen 402b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen IntrusiveRefCntPtr<const MatcherStorage> Storage; 403b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen}; 404b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen 405b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquentemplate <typename T> 406b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquenclass DynTypedMatcher::TypedMatcherStorage : public MatcherStorage { 407b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquenpublic: 408b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen TypedMatcherStorage(const Matcher<T> &Other, bool AllowBind) 409b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen : MatcherStorage(ast_type_traits::ASTNodeKind::getFromNodeKind<T>(), 410b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen Other.getID()), 411b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen InnerMatcher(Other), AllowBind(AllowBind) {} 412b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen 413b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen bool matches(const ast_type_traits::DynTypedNode DynNode, 414651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ASTMatchFinder *Finder, 415651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BoundNodesTreeBuilder *Builder) const override { 416b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen if (const T *Node = DynNode.get<T>()) { 417b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen return InnerMatcher.matches(*Node, Finder, Builder); 418b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen } 419b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen return false; 420b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen } 421b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen 422651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const override { 423b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen if (!AllowBind) 424b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen return llvm::Optional<DynTypedMatcher>(); 425b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen return DynTypedMatcher(BindableMatcher<T>(InnerMatcher).bind(ID)); 426b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen } 427b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen 428b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquenprivate: 429b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen const Matcher<T> InnerMatcher; 430b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen const bool AllowBind; 431b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen}; 432b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen 433b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquentemplate <typename T> 434b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaqueninline DynTypedMatcher::DynTypedMatcher(const Matcher<T> &M) 435b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen : Storage(new TypedMatcherStorage<T>(M, false)) {} 436b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen 437b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquentemplate <typename T> 438b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaqueninline DynTypedMatcher::DynTypedMatcher(const BindableMatcher<T> &M) 439b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen : Storage(new TypedMatcherStorage<T>(M, true)) {} 440b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen 44176c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen/// \brief Specialization of the conversion functions for QualType. 44276c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen/// 44376c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen/// These specializations provide the Matcher<Type>->Matcher<QualType> 44476c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen/// conversion that the static API does. 445b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquentemplate <> inline bool DynTypedMatcher::canConvertTo<QualType>() const { 446b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind(); 44776c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen return SourceKind.isSame( 44876c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen ast_type_traits::ASTNodeKind::getFromNodeKind<Type>()) || 44976c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen SourceKind.isSame( 45076c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen ast_type_traits::ASTNodeKind::getFromNodeKind<QualType>()); 45176c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen} 45276c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen 45376c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquentemplate <> 454b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaqueninline Matcher<QualType> DynTypedMatcher::convertTo<QualType>() const { 455b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen assert(canConvertTo<QualType>()); 456b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind(); 45776c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen if (SourceKind.isSame( 45876c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen ast_type_traits::ASTNodeKind::getFromNodeKind<Type>())) { 45976c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen // We support implicit conversion from Matcher<Type> to Matcher<QualType> 460b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen return unconditionalConvertTo<Type>(); 46176c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen } 462b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen return unconditionalConvertTo<QualType>(); 46376c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen} 46476c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen 465054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek/// \brief Finds the first node in a range that matches the given matcher. 466054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimektemplate <typename MatcherT, typename IteratorT> 467054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimekbool matchesFirstInRange(const MatcherT &Matcher, IteratorT Start, 468054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek IteratorT End, ASTMatchFinder *Finder, 469054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek BoundNodesTreeBuilder *Builder) { 470054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek for (IteratorT I = Start; I != End; ++I) { 471054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek BoundNodesTreeBuilder Result(*Builder); 472054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek if (Matcher.matches(*I, Finder, &Result)) { 473054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek *Builder = Result; 474054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek return true; 475054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek } 476054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek } 477054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek return false; 478054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek} 479054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek 480054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek/// \brief Finds the first node in a pointer range that matches the given 481054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek/// matcher. 482054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimektemplate <typename MatcherT, typename IteratorT> 483054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimekbool matchesFirstInPointerRange(const MatcherT &Matcher, IteratorT Start, 484054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek IteratorT End, ASTMatchFinder *Finder, 485054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek BoundNodesTreeBuilder *Builder) { 486054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek for (IteratorT I = Start; I != End; ++I) { 487054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek BoundNodesTreeBuilder Result(*Builder); 488054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek if (Matcher.matches(**I, Finder, &Result)) { 489054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek *Builder = Result; 490054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek return true; 491054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek } 492054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek } 493054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek return false; 494054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek} 495054d049174eb1ec8e93a4a0831c0d8caac00cb3aManuel Klimek 496b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane/// \brief Metafunction to determine if type T has a member called getDecl. 497b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vanetemplate <typename T> struct has_getDecl { 498b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane struct Default { int getDecl; }; 499b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane struct Derived : T, Default { }; 500b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane 501b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane template<typename C, C> struct CheckT; 502b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane 503b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane // If T::getDecl exists, an ambiguity arises and CheckT will 504b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane // not be instantiable. This makes f(...) the only available 505b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane // overload. 506b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane template<typename C> 507b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane static char (&f(CheckT<int Default::*, &C::getDecl>*))[1]; 508b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane template<typename C> static char (&f(...))[2]; 509b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane 5106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines static bool const value = sizeof(f<Derived>(nullptr)) == 2; 511b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane}; 512b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane 5136a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane/// \brief Matches overloaded operators with a specific name. 5146a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane/// 5156a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane/// The type argument ArgT is not used by this matcher but is used by 5166a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane/// PolymorphicMatcherWithParam1 and should be StringRef. 5176a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vanetemplate <typename T, typename ArgT> 5186a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vaneclass HasOverloadedOperatorNameMatcher : public SingleNodeMatcherInterface<T> { 519651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static_assert(std::is_same<T, CXXOperatorCallExpr>::value || 520651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_same<T, CXXMethodDecl>::value, 521651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "unsupported class for matcher"); 522651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static_assert(std::is_same<ArgT, StringRef>::value, 523651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "argument type must be StringRef"); 524651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 5256a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vanepublic: 5266a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane explicit HasOverloadedOperatorNameMatcher(const StringRef Name) 5276a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane : SingleNodeMatcherInterface<T>(), Name(Name) {} 5286a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane 529651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool matchesNode(const T &Node) const override { 5306a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane return matchesSpecialized(Node); 5316a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane } 5326a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane 5336a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vaneprivate: 5346a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane 5356a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane /// \brief CXXOperatorCallExpr exist only for calls to overloaded operators 5366a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane /// so this function returns true if the call is to an operator of the given 5376a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane /// name. 5386a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane bool matchesSpecialized(const CXXOperatorCallExpr &Node) const { 5396a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane return getOperatorSpelling(Node.getOperator()) == Name; 5406a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane } 5416a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane 5426a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane /// \brief Returns true only if CXXMethodDecl represents an overloaded 5436a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane /// operator and has the given operator name. 5446a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane bool matchesSpecialized(const CXXMethodDecl &Node) const { 5456a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane return Node.isOverloadedOperator() && 5466a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane getOperatorSpelling(Node.getOverloadedOperator()) == Name; 5476a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane } 5486a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane 5496a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane std::string Name; 5506a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane}; 5516a19a97e57c8678adb0505a07c97d7ccadc8fe4eEdwin Vane 5524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief Matches declarations for QualType and CallExpr. 5534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// 5544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// Type argument DeclMatcherT is required by PolymorphicMatcherWithParam1 but 5554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// not actually used. 5564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektemplate <typename T, typename DeclMatcherT> 5574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekclass HasDeclarationMatcher : public MatcherInterface<T> { 558651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static_assert(std::is_same<DeclMatcherT, Matcher<Decl>>::value, 559651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "instantiated with wrong types"); 560651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 5614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekpublic: 562e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper explicit HasDeclarationMatcher(const Matcher<Decl> &InnerMatcher) 5634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek : InnerMatcher(InnerMatcher) {} 5644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 565651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool matches(const T &Node, ASTMatchFinder *Finder, 566651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BoundNodesTreeBuilder *Builder) const override { 5674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek return matchesSpecialized(Node, Finder, Builder); 5684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } 5694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 5704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekprivate: 571523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane /// \brief If getDecl exists as a member of U, returns whether the inner 572523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane /// matcher matches Node.getDecl(). 573523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane template <typename U> 574b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane bool matchesSpecialized( 575b45083d08377a8b9528401fdafd7210e78895dbeEdwin Vane const U &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder, 576651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines typename std::enable_if<has_getDecl<U>::value, int>::type = 0) const { 577523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane return matchesDecl(Node.getDecl(), Finder, Builder); 578523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane } 579523806028d812a7f29636c59a8bc0e7e3d3fd9aeEdwin Vane 580189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel Jasper /// \brief Extracts the CXXRecordDecl or EnumDecl of a QualType and returns 581189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel Jasper /// whether the inner matcher matches on it. 582e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper bool matchesSpecialized(const QualType &Node, ASTMatchFinder *Finder, 5834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek BoundNodesTreeBuilder *Builder) const { 5844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// FIXME: Add other ways to convert... 585e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper if (Node.isNull()) 586e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper return false; 587189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel Jasper if (const EnumType *AsEnum = dyn_cast<EnumType>(Node.getTypePtr())) 588189f2e421d06526ea8b4a3dcd9f4a072e10a859cDaniel Jasper return matchesDecl(AsEnum->getDecl(), Finder, Builder); 589c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper return matchesDecl(Node->getAsCXXRecordDecl(), Finder, Builder); 5904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } 5914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 5923abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane /// \brief Gets the TemplateDecl from a TemplateSpecializationType 5933abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane /// and returns whether the inner matches on it. 5943abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane bool matchesSpecialized(const TemplateSpecializationType &Node, 5953abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane ASTMatchFinder *Finder, 5963abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane BoundNodesTreeBuilder *Builder) const { 5973abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane return matchesDecl(Node.getTemplateName().getAsTemplateDecl(), 5983abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane Finder, Builder); 5993abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane } 6003abf77872ca6c520903f9174cf6cd89a50df2714Edwin Vane 6014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// \brief Extracts the Decl of the callee of a CallExpr and returns whether 6024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// the inner matcher matches on it. 603e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper bool matchesSpecialized(const CallExpr &Node, ASTMatchFinder *Finder, 6044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek BoundNodesTreeBuilder *Builder) const { 605c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper return matchesDecl(Node.getCalleeDecl(), Finder, Builder); 6064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } 6074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 6084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// \brief Extracts the Decl of the constructor call and returns whether the 6094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// inner matcher matches on it. 610e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper bool matchesSpecialized(const CXXConstructExpr &Node, 6114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek ASTMatchFinder *Finder, 6124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek BoundNodesTreeBuilder *Builder) const { 613c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper return matchesDecl(Node.getConstructor(), Finder, Builder); 614c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper } 615c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper 616c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper /// \brief Extracts the \c ValueDecl a \c MemberExpr refers to and returns 617c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper /// whether the inner matcher matches on it. 618c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper bool matchesSpecialized(const MemberExpr &Node, 619c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper ASTMatchFinder *Finder, 620c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper BoundNodesTreeBuilder *Builder) const { 621c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper return matchesDecl(Node.getMemberDecl(), Finder, Builder); 622c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper } 623c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper 624c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper /// \brief Returns whether the inner matcher \c Node. Returns false if \c Node 625c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper /// is \c NULL. 626c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper bool matchesDecl(const Decl *Node, 627c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper ASTMatchFinder *Finder, 628c711af2ddbbb1d46223cc9379d32a203fb5bc7f4Daniel Jasper BoundNodesTreeBuilder *Builder) const { 6296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return Node != nullptr && InnerMatcher.matches(*Node, Finder, Builder); 6304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } 6314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 632e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper const Matcher<Decl> InnerMatcher; 6334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}; 6344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 6354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief IsBaseType<T>::value is true if T is a "base" type in the AST 636a267cf6f87dc695143d65fc61ec1744564f55932Daniel Jasper/// node class hierarchies. 6374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektemplate <typename T> 6384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekstruct IsBaseType { 6394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek static const bool value = 640651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_same<T, Decl>::value || 641651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_same<T, Stmt>::value || 642651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_same<T, QualType>::value || 643651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_same<T, Type>::value || 644651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_same<T, TypeLoc>::value || 645651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_same<T, NestedNameSpecifier>::value || 646651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_same<T, NestedNameSpecifierLoc>::value || 647651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_same<T, CXXCtorInitializer>::value; 6484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}; 6494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektemplate <typename T> 6504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekconst bool IsBaseType<T>::value; 6514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 6524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief Interface that allows matchers to traverse the AST. 6534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// FIXME: Find a better name. 6544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// 655579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek/// This provides three entry methods for each base node type in the AST: 656579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek/// - \c matchesChildOf: 6574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// Matches a matcher on every child node of the given node. Returns true 6584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// if at least one child node could be matched. 659579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek/// - \c matchesDescendantOf: 6604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// Matches a matcher on all descendant nodes of the given node. Returns true 6614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// if at least one descendant matched. 662579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek/// - \c matchesAncestorOf: 663579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek/// Matches a matcher on all ancestors of the given node. Returns true if 664579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek/// at least one ancestor matched. 665579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek/// 666579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek/// FIXME: Currently we only allow Stmt and Decl nodes to start a traversal. 667579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek/// In the future, we wan to implement this for all nodes for which it makes 668579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek/// sense. In the case of matchesAncestorOf, we'll want to implement it for 669579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek/// all nodes, as all nodes have ancestors. 6704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekclass ASTMatchFinder { 6714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekpublic: 6724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// \brief Defines how we descend a level in the AST when we pass 6734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// through expressions. 6744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek enum TraversalKind { 6754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// Will traverse any child nodes. 6764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek TK_AsIs, 6774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// Will not traverse implicit casts and parentheses. 6784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek TK_IgnoreImplicitCastsAndParentheses 6794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek }; 6804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 6814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// \brief Defines how bindings are processed on recursive matches. 6824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek enum BindKind { 6834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// Stop at the first match and only bind the first match. 6844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek BK_First, 6854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// Create results for all combinations of bindings that match. 6864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek BK_All 6874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek }; 6884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 689c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper /// \brief Defines which ancestors are considered for a match. 690c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper enum AncestorMatchMode { 691c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper /// All ancestors. 692c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper AMM_All, 693c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper /// Direct parent only. 694c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper AMM_ParentOnly 695c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper }; 696c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper 6974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek virtual ~ASTMatchFinder() {} 6984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 6994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// \brief Returns true if the given class is directly or indirectly derived 70020b802d186dfc5db9b4a9ce83e9f31fa5aa4efccDaniel Jasper /// from a base type matching \c base. 7014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// 7024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// A class is considered to be also derived from itself. 703e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper virtual bool classIsDerivedFrom(const CXXRecordDecl *Declaration, 70420b802d186dfc5db9b4a9ce83e9f31fa5aa4efccDaniel Jasper const Matcher<NamedDecl> &Base, 70520b802d186dfc5db9b4a9ce83e9f31fa5aa4efccDaniel Jasper BoundNodesTreeBuilder *Builder) = 0; 7064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 707a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek template <typename T> 708a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek bool matchesChildOf(const T &Node, 709a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek const DynTypedMatcher &Matcher, 710a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek BoundNodesTreeBuilder *Builder, 711a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek TraversalKind Traverse, 712a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek BindKind Bind) { 713651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static_assert(std::is_base_of<Decl, T>::value || 714651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_base_of<Stmt, T>::value || 715651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_base_of<NestedNameSpecifier, T>::value || 716651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_base_of<NestedNameSpecifierLoc, T>::value || 717651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_base_of<TypeLoc, T>::value || 718651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_base_of<QualType, T>::value, 719651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "unsupported type for recursive matching"); 720d1ce3c178b9c648687591b190e0d252124fc2459Daniel Jasper return matchesChildOf(ast_type_traits::DynTypedNode::create(Node), 721a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek Matcher, Builder, Traverse, Bind); 722a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek } 723a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek 724a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek template <typename T> 725a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek bool matchesDescendantOf(const T &Node, 726a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek const DynTypedMatcher &Matcher, 727a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek BoundNodesTreeBuilder *Builder, 728a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek BindKind Bind) { 729651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static_assert(std::is_base_of<Decl, T>::value || 730651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_base_of<Stmt, T>::value || 731651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_base_of<NestedNameSpecifier, T>::value || 732651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_base_of<NestedNameSpecifierLoc, T>::value || 733651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_base_of<TypeLoc, T>::value || 734651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_base_of<QualType, T>::value, 735651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "unsupported type for recursive matching"); 736a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek return matchesDescendantOf(ast_type_traits::DynTypedNode::create(Node), 737a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek Matcher, Builder, Bind); 738a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek } 739a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek 740579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek // FIXME: Implement support for BindKind. 741579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek template <typename T> 742579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek bool matchesAncestorOf(const T &Node, 743579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek const DynTypedMatcher &Matcher, 744c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper BoundNodesTreeBuilder *Builder, 745c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper AncestorMatchMode MatchMode) { 746651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static_assert(std::is_base_of<Decl, T>::value || 747651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_base_of<Stmt, T>::value, 748651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "only Decl or Stmt allowed for recursive matching"); 749579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek return matchesAncestorOf(ast_type_traits::DynTypedNode::create(Node), 750c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper Matcher, Builder, MatchMode); 751579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek } 752579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek 7537f2d4804510799a1a19d72b2b089e48370ab8686Manuel Klimek virtual ASTContext &getASTContext() const = 0; 7547f2d4804510799a1a19d72b2b089e48370ab8686Manuel Klimek 755a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimekprotected: 756a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek virtual bool matchesChildOf(const ast_type_traits::DynTypedNode &Node, 757a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek const DynTypedMatcher &Matcher, 7584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek BoundNodesTreeBuilder *Builder, 7594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek TraversalKind Traverse, 7604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek BindKind Bind) = 0; 7614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 762a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek virtual bool matchesDescendantOf(const ast_type_traits::DynTypedNode &Node, 763a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek const DynTypedMatcher &Matcher, 7644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek BoundNodesTreeBuilder *Builder, 7654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek BindKind Bind) = 0; 766579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek 767579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek virtual bool matchesAncestorOf(const ast_type_traits::DynTypedNode &Node, 768579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek const DynTypedMatcher &Matcher, 769c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper BoundNodesTreeBuilder *Builder, 770c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper AncestorMatchMode MatchMode) = 0; 7714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}; 7724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 7736c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen/// \brief A type-list implementation. 774ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// 7756c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen/// A list is declared as a tree of type list nodes, where the leafs are the 7766c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen/// types. 7776c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen/// However, it is used as a "linked list" of types, by using the ::head and 7786c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen/// ::tail typedefs. 7796c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen/// Each node supports up to 4 children (instead of just 2) to reduce the 7806c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen/// nesting required by large lists. 781ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquentemplate <typename T1 = void, typename T2 = void, typename T3 = void, 7826c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen typename T4 = void> 783ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquenstruct TypeList { 7846c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen /// \brief Implementation detail. Combined with the specializations below, 7856c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen /// this typedef allows for flattening of nested structures. 7866c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen typedef TypeList<T1, T2, T3, T4> self; 7876c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen 788ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen /// \brief The first type on the list. 789ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen typedef T1 head; 790ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen 791651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// \brief A sublist with the tail. ie everything but the head. 792ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen /// 793ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen /// This type is used to do recursion. TypeList<>/EmptyTypeList indicates the 794ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen /// end of the list. 7956c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen typedef typename TypeList<T2, T3, T4>::self tail; 796ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen}; 797ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen 7986c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen/// \brief Template specialization to allow nested lists. 7996c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen/// 8006c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen/// First element is a typelist. Pop its first element. 8016c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquentemplate <typename Sub1, typename Sub2, typename Sub3, typename Sub4, 8026c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen typename T2, typename T3, typename T4> 8036c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquenstruct TypeList<TypeList<Sub1, Sub2, Sub3, Sub4>, T2, T3, 8046c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen T4> : public TypeList<Sub1, 8056c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen typename TypeList<Sub2, Sub3, Sub4>::self, 8066c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen typename TypeList<T2, T3, T4>::self> {}; 8076c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen 8086c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen/// \brief Template specialization to allow nested lists. 8096c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen/// 8106c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen/// First element is an empty typelist. Skip it. 8116c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquentemplate <typename T2, typename T3, typename T4> 8126c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquenstruct TypeList<TypeList<>, T2, T3, T4> : public TypeList<T2, T3, T4> { 813ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen}; 814ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen 815ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// \brief The empty type list. 816ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquentypedef TypeList<> EmptyTypeList; 817ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen 8186c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen/// \brief Helper meta-function to determine if some type \c T is present or 8196c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen/// a parent type in the list. 8206c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquentemplate <typename AnyTypeList, typename T> 8216c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquenstruct TypeListContainsSuperOf { 8226c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen static const bool value = 823651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_base_of<typename AnyTypeList::head, T>::value || 8246c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen TypeListContainsSuperOf<typename AnyTypeList::tail, T>::value; 8256c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen}; 8266c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquentemplate <typename T> 8276c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquenstruct TypeListContainsSuperOf<EmptyTypeList, T> { 8286c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen static const bool value = false; 8296c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen}; 8306c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen 831ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// \brief A "type list" that contains all types. 832ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// 833ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// Useful for matchers like \c anything and \c unless. 8346c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquentypedef TypeList< 8356c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc>, 8366c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen TypeList<QualType, Type, TypeLoc, CXXCtorInitializer> > AllNodeBaseTypes; 837ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen 838ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// \brief Helper meta-function to extract the argument out of a function of 839ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// type void(Arg). 840ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// 841ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// See AST_POLYMORPHIC_SUPPORTED_TYPES_* for details. 842ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquentemplate <class T> struct ExtractFunctionArgMeta; 843ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquentemplate <class T> struct ExtractFunctionArgMeta<void(T)> { 844ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen typedef T type; 845ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen}; 846ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen 8476de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquen/// \brief Default type lists for ArgumentAdaptingMatcher matchers. 8486de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquentypedef AllNodeBaseTypes AdaptativeDefaultFromTypes; 8496c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquentypedef TypeList<TypeList<Decl, Stmt, NestedNameSpecifier>, 8506c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen TypeList<NestedNameSpecifierLoc, TypeLoc, QualType> > 8516c1dc7870f457803a9b256ed868da82532be820bSamuel BenzaquenAdaptativeDefaultToTypes; 8526c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen 8536c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen/// \brief All types that are supported by HasDeclarationMatcher above. 8546c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquentypedef TypeList<TypeList<CallExpr, CXXConstructExpr, DeclRefExpr, EnumType>, 8556c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen TypeList<InjectedClassNameType, LabelStmt, MemberExpr>, 8566c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen TypeList<QualType, RecordType, TagType>, 8576c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen TypeList<TemplateSpecializationType, TemplateTypeParmType, 8586c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen TypedefType, UnresolvedUsingType> > 8596c1dc7870f457803a9b256ed868da82532be820bSamuel BenzaquenHasDeclarationSupportedTypes; 8606de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquen 8616de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquen/// \brief Converts a \c Matcher<T> to a matcher of desired type \c To by 8626de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquen/// "adapting" a \c To into a \c T. 8636de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquen/// 8646de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquen/// The \c ArgumentAdapterT argument specifies how the adaptation is done. 8656de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquen/// 8666de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquen/// For example: 8676de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquen/// \c ArgumentAdaptingMatcher<HasMatcher, T>(InnerMatcher); 8686de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquen/// Given that \c InnerMatcher is of type \c Matcher<T>, this returns a matcher 8696de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquen/// that is convertible into any matcher of type \c To by constructing 8706de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquen/// \c HasMatcher<To, T>(InnerMatcher). 8716de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquen/// 8726de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquen/// If a matcher does not need knowledge about the inner type, prefer to use 8736de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquen/// PolymorphicMatcherWithParam1. 8746de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquentemplate <template <typename ToArg, typename FromArg> class ArgumentAdapterT, 875ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen typename FromTypes = AdaptativeDefaultFromTypes, 8766de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquen typename ToTypes = AdaptativeDefaultToTypes> 877ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquenstruct ArgumentAdaptingMatcherFunc { 878ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen template <typename T> class Adaptor { 879ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen public: 880ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen explicit Adaptor(const Matcher<T> &InnerMatcher) 881ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen : InnerMatcher(InnerMatcher) {} 8826de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquen 883ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen typedef ToTypes ReturnTypes; 8846de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquen 885ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen template <typename To> operator Matcher<To>() const { 886ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen return Matcher<To>(new ArgumentAdapterT<To, T>(InnerMatcher)); 887ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen } 888ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen 889ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen private: 890ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen const Matcher<T> InnerMatcher; 891ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen }; 892ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen 893ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen template <typename T> 894ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen static Adaptor<T> create(const Matcher<T> &InnerMatcher) { 895ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen return Adaptor<T>(InnerMatcher); 8966de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquen } 8976de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquen 898ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen template <typename T> 899ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen Adaptor<T> operator()(const Matcher<T> &InnerMatcher) const { 900ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen return create(InnerMatcher); 901ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen } 9026de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquen}; 9036de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquen 9044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief A PolymorphicMatcherWithParamN<MatcherT, P1, ..., PN> object can be 9054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// created from N parameters p1, ..., pN (of type P1, ..., PN) and 9064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// used as a Matcher<T> where a MatcherT<T, P1, ..., PN>(p1, ..., pN) 9074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// can be constructed. 9084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// 9094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// For example: 9104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// - PolymorphicMatcherWithParam0<IsDefinitionMatcher>() 9114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// creates an object that can be used as a Matcher<T> for any type T 9124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// where an IsDefinitionMatcher<T>() can be constructed. 9134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// - PolymorphicMatcherWithParam1<ValueEqualsMatcher, int>(42) 9144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// creates an object that can be used as a Matcher<T> for any type T 9154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// where a ValueEqualsMatcher<T, int>(42) can be constructed. 916ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquentemplate <template <typename T> class MatcherT, 917ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen typename ReturnTypesF = void(AllNodeBaseTypes)> 9184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekclass PolymorphicMatcherWithParam0 { 9194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekpublic: 920ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes; 9214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek template <typename T> 9224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek operator Matcher<T>() const { 923651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value, 924651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "right polymorphic conversion"); 9254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek return Matcher<T>(new MatcherT<T>()); 9264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } 9274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}; 9284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 9294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektemplate <template <typename T, typename P1> class MatcherT, 930ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen typename P1, 931ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen typename ReturnTypesF = void(AllNodeBaseTypes)> 9324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekclass PolymorphicMatcherWithParam1 { 9334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekpublic: 9344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek explicit PolymorphicMatcherWithParam1(const P1 &Param1) 9354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek : Param1(Param1) {} 9364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 937ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes; 938ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen 9394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek template <typename T> 9404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek operator Matcher<T>() const { 941651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value, 942651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "right polymorphic conversion"); 9434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek return Matcher<T>(new MatcherT<T, P1>(Param1)); 9444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } 9454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 9464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekprivate: 9474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek const P1 Param1; 9484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}; 9494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 9504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektemplate <template <typename T, typename P1, typename P2> class MatcherT, 951ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen typename P1, typename P2, 952ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen typename ReturnTypesF = void(AllNodeBaseTypes)> 9534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekclass PolymorphicMatcherWithParam2 { 9544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekpublic: 9554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek PolymorphicMatcherWithParam2(const P1 &Param1, const P2 &Param2) 9564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek : Param1(Param1), Param2(Param2) {} 9574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 958ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes; 959ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen 9604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek template <typename T> 9614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek operator Matcher<T>() const { 962651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value, 963651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "right polymorphic conversion"); 9644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek return Matcher<T>(new MatcherT<T, P1, P2>(Param1, Param2)); 9654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } 9664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 9674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekprivate: 9684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek const P1 Param1; 9694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek const P2 Param2; 9704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}; 9714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 9724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief Matches any instance of the given NodeType. 9734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// 9744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// This is useful when a matcher syntactically requires a child matcher, 9754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// but the context doesn't care. See for example: anything(). 9764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// 9774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// FIXME: Alternatively we could also create a IsAMatcher or something 9784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// that checks that a dyn_cast is possible. This is purely needed for the 9794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// difference between calling for example: 9804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// record() 9814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// and 9824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// record(SomeMatcher) 9834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// In the second case we need the correct type we were dyn_cast'ed to in order 9844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// to get the right type for the inner matcher. In the first case we don't need 9854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// that, but we use the type conversion anyway and insert a TrueMatcher. 9864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektemplate <typename T> 9874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekclass TrueMatcher : public SingleNodeMatcherInterface<T> { 9884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekpublic: 989651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool matchesNode(const T &Node) const override { 9904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek return true; 9914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } 9924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}; 9934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 9944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief Matcher<T> that wraps an inner Matcher<T> and binds the matched node 9954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// to an ID if the inner matcher matches on the node. 9964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektemplate <typename T> 9974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekclass IdMatcher : public MatcherInterface<T> { 9984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekpublic: 9994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// \brief Creates an IdMatcher that binds to 'ID' if 'InnerMatcher' matches 10004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek /// the node. 10014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek IdMatcher(StringRef ID, const Matcher<T> &InnerMatcher) 10024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek : ID(ID), InnerMatcher(InnerMatcher) {} 10034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 1004651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool matches(const T &Node, ASTMatchFinder *Finder, 1005651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BoundNodesTreeBuilder *Builder) const override { 10064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek bool Result = InnerMatcher.matches(Node, Finder, Builder); 10074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek if (Result) { 1008e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper Builder->setBinding(ID, &Node); 10094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } 10104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek return Result; 10114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } 10124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 10134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekprivate: 10144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek const std::string ID; 10154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek const Matcher<T> InnerMatcher; 10164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}; 10174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 10189f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimek/// \brief A Matcher that allows binding the node it matches to an id. 10199f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimek/// 10209f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimek/// BindableMatcher provides a \a bind() method that allows binding the 10219f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimek/// matched node to an id if the match was successful. 10229f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimektemplate <typename T> 10239f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimekclass BindableMatcher : public Matcher<T> { 10249f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimekpublic: 10257156ffff6de12d8a14b0597f1ca5053115cf5773Samuel Benzaquen explicit BindableMatcher(const Matcher<T> &M) : Matcher<T>(M) {} 10267156ffff6de12d8a14b0597f1ca5053115cf5773Samuel Benzaquen explicit BindableMatcher(MatcherInterface<T> *Implementation) 10279f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimek : Matcher<T>(Implementation) {} 10289f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimek 10299f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimek /// \brief Returns a matcher that will bind the matched node on a match. 10309f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimek /// 10319f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimek /// The returned matcher is equivalent to this matcher, but will 10329f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimek /// bind the matched node on a match. 10339f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimek Matcher<T> bind(StringRef ID) const { 10349f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimek return Matcher<T>(new IdMatcher<T>(ID, *this)); 10359f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimek } 10369f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimek}; 10379f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimek 10384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief Matches nodes of type T that have child nodes of type ChildT for 10394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// which a specified child matcher matches. 10404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// 10414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// ChildT must be an AST base type. 10424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektemplate <typename T, typename ChildT> 10434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekclass HasMatcher : public MatcherInterface<T> { 1044651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static_assert(IsBaseType<ChildT>::value, 1045651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "has only accepts base type matcher"); 1046651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 10474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekpublic: 10484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek explicit HasMatcher(const Matcher<ChildT> &ChildMatcher) 10494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek : ChildMatcher(ChildMatcher) {} 10504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 1051651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool matches(const T &Node, ASTMatchFinder *Finder, 1052651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BoundNodesTreeBuilder *Builder) const override { 10534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek return Finder->matchesChildOf( 10544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek Node, ChildMatcher, Builder, 10554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses, 10564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek ASTMatchFinder::BK_First); 10574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } 10584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 10594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek private: 1060a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek const Matcher<ChildT> ChildMatcher; 10614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}; 10624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 10634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief Matches nodes of type T that have child nodes of type ChildT for 10644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// which a specified child matcher matches. ChildT must be an AST base 10654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// type. 10664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// As opposed to the HasMatcher, the ForEachMatcher will produce a match 10674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// for each child that matches. 10684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektemplate <typename T, typename ChildT> 10694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekclass ForEachMatcher : public MatcherInterface<T> { 1070651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static_assert(IsBaseType<ChildT>::value, 1071651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "for each only accepts base type matcher"); 1072651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 10734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek public: 10744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek explicit ForEachMatcher(const Matcher<ChildT> &ChildMatcher) 10754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek : ChildMatcher(ChildMatcher) {} 10764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 1077651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool matches(const T& Node, ASTMatchFinder* Finder, 1078651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BoundNodesTreeBuilder* Builder) const override { 10794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek return Finder->matchesChildOf( 10804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek Node, ChildMatcher, Builder, 10814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses, 10824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek ASTMatchFinder::BK_All); 10834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } 10844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 10854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekprivate: 1086a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek const Matcher<ChildT> ChildMatcher; 10874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}; 10884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 1089d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen/// \brief VariadicOperatorMatcher related types. 1090d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen/// @{ 1091d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen 1092d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen/// \brief Function signature for any variadic operator. It takes the inner 1093d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen/// matchers as an array of DynTypedMatcher. 1094d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquentypedef bool (*VariadicOperatorFunction)( 1095d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen const ast_type_traits::DynTypedNode DynNode, ASTMatchFinder *Finder, 1096b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen BoundNodesTreeBuilder *Builder, ArrayRef<DynTypedMatcher> InnerMatchers); 1097d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen 1098d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen/// \brief \c MatcherInterface<T> implementation for an variadic operator. 1099d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquentemplate <typename T> 1100d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquenclass VariadicOperatorMatcherInterface : public MatcherInterface<T> { 11014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekpublic: 1102d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen VariadicOperatorMatcherInterface(VariadicOperatorFunction Func, 1103651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<DynTypedMatcher> InnerMatchers) 1104651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : Func(Func), InnerMatchers(std::move(InnerMatchers)) {} 11054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 1106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool matches(const T &Node, ASTMatchFinder *Finder, 1107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BoundNodesTreeBuilder *Builder) const override { 1108d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen return Func(ast_type_traits::DynTypedNode::create(Node), Finder, Builder, 1109d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen InnerMatchers); 11104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } 11114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 11124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekprivate: 1113d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen const VariadicOperatorFunction Func; 1114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const std::vector<DynTypedMatcher> InnerMatchers; 11154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}; 11164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 1117d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen/// \brief "No argument" placeholder to use as template paratemers. 1118d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquenstruct VariadicOperatorNoArg {}; 1119d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen 1120d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen/// \brief Polymorphic matcher object that uses a \c VariadicOperatorFunction 1121d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen/// operator. 11224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// 1123d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen/// Input matchers can have any type (including other polymorphic matcher 1124d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen/// types), and the actual Matcher<T> is generated on demand with an implicit 1125d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen/// coversion operator. 1126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <typename P1, typename P2 = VariadicOperatorNoArg, 1127d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen typename P3 = VariadicOperatorNoArg, 1128d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen typename P4 = VariadicOperatorNoArg, 1129ef8225444452a1486bd721f3285301fe84643b00Stephen Hines typename P5 = VariadicOperatorNoArg, 1130ef8225444452a1486bd721f3285301fe84643b00Stephen Hines typename P6 = VariadicOperatorNoArg, 1131ef8225444452a1486bd721f3285301fe84643b00Stephen Hines typename P7 = VariadicOperatorNoArg, 1132ef8225444452a1486bd721f3285301fe84643b00Stephen Hines typename P8 = VariadicOperatorNoArg, 1133ef8225444452a1486bd721f3285301fe84643b00Stephen Hines typename P9 = VariadicOperatorNoArg> 1134d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquenclass VariadicOperatorMatcher { 11357387673f83b8b37f660422947c9990778ba88193Manuel Klimekpublic: 1136d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen VariadicOperatorMatcher(VariadicOperatorFunction Func, const P1 &Param1, 1137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const P2 &Param2 = VariadicOperatorNoArg(), 1138d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen const P3 &Param3 = VariadicOperatorNoArg(), 1139d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen const P4 &Param4 = VariadicOperatorNoArg(), 1140ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const P5 &Param5 = VariadicOperatorNoArg(), 1141ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const P6 &Param6 = VariadicOperatorNoArg(), 1142ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const P7 &Param7 = VariadicOperatorNoArg(), 1143ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const P8 &Param8 = VariadicOperatorNoArg(), 1144ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const P9 &Param9 = VariadicOperatorNoArg()) 1145d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen : Func(Func), Param1(Param1), Param2(Param2), Param3(Param3), 1146ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Param4(Param4), Param5(Param5), Param6(Param6), Param7(Param7), 1147ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Param8(Param8), Param9(Param9) {} 1148d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen 1149d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen template <typename T> operator Matcher<T>() const { 1150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<DynTypedMatcher> Matchers; 1151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addMatcher<T>(Param1, Matchers); 1152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addMatcher<T>(Param2, Matchers); 1153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addMatcher<T>(Param3, Matchers); 1154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addMatcher<T>(Param4, Matchers); 1155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addMatcher<T>(Param5, Matchers); 1156ef8225444452a1486bd721f3285301fe84643b00Stephen Hines addMatcher<T>(Param6, Matchers); 1157ef8225444452a1486bd721f3285301fe84643b00Stephen Hines addMatcher<T>(Param7, Matchers); 1158ef8225444452a1486bd721f3285301fe84643b00Stephen Hines addMatcher<T>(Param8, Matchers); 1159ef8225444452a1486bd721f3285301fe84643b00Stephen Hines addMatcher<T>(Param9, Matchers); 1160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return Matcher<T>( 1161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines new VariadicOperatorMatcherInterface<T>(Func, std::move(Matchers))); 11627387673f83b8b37f660422947c9990778ba88193Manuel Klimek } 11637387673f83b8b37f660422947c9990778ba88193Manuel Klimek 1164d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquenprivate: 1165d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen template <typename T> 1166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static void addMatcher(const Matcher<T> &M, 1167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<DynTypedMatcher> &Matchers) { 1168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Matchers.push_back(M); 11697387673f83b8b37f660422947c9990778ba88193Manuel Klimek } 11707387673f83b8b37f660422947c9990778ba88193Manuel Klimek 1171d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen /// \brief Overload to ignore \c VariadicOperatorNoArg arguments. 1172d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen template <typename T> 1173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static void addMatcher(VariadicOperatorNoArg, 1174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<DynTypedMatcher> &Matchers) {} 1175d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen 1176d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen const VariadicOperatorFunction Func; 1177d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen const P1 Param1; 1178d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen const P2 Param2; 1179d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen const P3 Param3; 1180d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen const P4 Param4; 1181d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen const P5 Param5; 1182ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const P6 Param6; 1183ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const P7 Param7; 1184ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const P8 Param8; 1185ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const P9 Param9; 11867387673f83b8b37f660422947c9990778ba88193Manuel Klimek}; 11877387673f83b8b37f660422947c9990778ba88193Manuel Klimek 1188d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen/// \brief Overloaded function object to generate VariadicOperatorMatcher 1189d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen/// objects from arbitrary matchers. 11907387673f83b8b37f660422947c9990778ba88193Manuel Klimek/// 1191ef8225444452a1486bd721f3285301fe84643b00Stephen Hines/// It supports 1-9 argument overloaded operator(). More can be added if needed. 1192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <unsigned MinCount, unsigned MaxCount> 1193d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquenstruct VariadicOperatorMatcherFunc { 1194d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen VariadicOperatorFunction Func; 11954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 1196651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines template <unsigned Count, typename T> 1197651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines struct EnableIfValidArity 1198651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : public std::enable_if<MinCount <= Count && Count <= MaxCount, T> {}; 1199651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines template <typename M1> 1201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines typename EnableIfValidArity<1, VariadicOperatorMatcher<M1> >::type 1202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines operator()(const M1 &P1) const { 1203651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return VariadicOperatorMatcher<M1>(Func, P1); 1204651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1205d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen template <typename M1, typename M2> 1206651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines typename EnableIfValidArity<2, VariadicOperatorMatcher<M1, M2> >::type 1207651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines operator()(const M1 &P1, const M2 &P2) const { 1208d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen return VariadicOperatorMatcher<M1, M2>(Func, P1, P2); 1209d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen } 1210d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen template <typename M1, typename M2, typename M3> 1211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines typename EnableIfValidArity<3, VariadicOperatorMatcher<M1, M2, M3> >::type 1212651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines operator()(const M1 &P1, const M2 &P2, const M3 &P3) const { 1213d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen return VariadicOperatorMatcher<M1, M2, M3>(Func, P1, P2, P3); 1214d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen } 1215d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen template <typename M1, typename M2, typename M3, typename M4> 1216651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines typename EnableIfValidArity<4, VariadicOperatorMatcher<M1, M2, M3, M4> >::type 1217d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4) const { 1218d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen return VariadicOperatorMatcher<M1, M2, M3, M4>(Func, P1, P2, P3, P4); 1219d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen } 1220d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen template <typename M1, typename M2, typename M3, typename M4, typename M5> 1221651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines typename EnableIfValidArity< 1222651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 5, VariadicOperatorMatcher<M1, M2, M3, M4, M5> >::type 1223d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, 1224d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen const M5 &P5) const { 1225d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen return VariadicOperatorMatcher<M1, M2, M3, M4, M5>(Func, P1, P2, P3, P4, 1226d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen P5); 12274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } 1228ef8225444452a1486bd721f3285301fe84643b00Stephen Hines template <typename M1, typename M2, typename M3, typename M4, typename M5, 1229ef8225444452a1486bd721f3285301fe84643b00Stephen Hines typename M6> 1230ef8225444452a1486bd721f3285301fe84643b00Stephen Hines typename EnableIfValidArity< 1231ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 6, VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6> >::type 1232ef8225444452a1486bd721f3285301fe84643b00Stephen Hines operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, 1233ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const M5 &P5, const M6 &P6) const { 1234ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6>( 1235ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Func, P1, P2, P3, P4, P5, P6); 1236ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 1237ef8225444452a1486bd721f3285301fe84643b00Stephen Hines template <typename M1, typename M2, typename M3, typename M4, typename M5, 1238ef8225444452a1486bd721f3285301fe84643b00Stephen Hines typename M6, typename M7> 1239ef8225444452a1486bd721f3285301fe84643b00Stephen Hines typename EnableIfValidArity< 1240ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 7, VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7> >::type 1241ef8225444452a1486bd721f3285301fe84643b00Stephen Hines operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, 1242ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const M5 &P5, const M6 &P6, const M7 &P7) const { 1243ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7>( 1244ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Func, P1, P2, P3, P4, P5, P6, P7); 1245ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 1246ef8225444452a1486bd721f3285301fe84643b00Stephen Hines template <typename M1, typename M2, typename M3, typename M4, typename M5, 1247ef8225444452a1486bd721f3285301fe84643b00Stephen Hines typename M6, typename M7, typename M8> 1248ef8225444452a1486bd721f3285301fe84643b00Stephen Hines typename EnableIfValidArity< 1249ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 8, VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8> >::type 1250ef8225444452a1486bd721f3285301fe84643b00Stephen Hines operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, 1251ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const M5 &P5, const M6 &P6, const M7 &P7, const M8 &P8) const { 1252ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8>( 1253ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Func, P1, P2, P3, P4, P5, P6, P7, P8); 1254ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 1255ef8225444452a1486bd721f3285301fe84643b00Stephen Hines template <typename M1, typename M2, typename M3, typename M4, typename M5, 1256ef8225444452a1486bd721f3285301fe84643b00Stephen Hines typename M6, typename M7, typename M8, typename M9> 1257ef8225444452a1486bd721f3285301fe84643b00Stephen Hines typename EnableIfValidArity< 1258ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 9, VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8, M9> >::type 1259ef8225444452a1486bd721f3285301fe84643b00Stephen Hines operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, 1260ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const M5 &P5, const M6 &P6, const M7 &P7, const M8 &P8, 1261ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const M9 &P9) const { 1262ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8, M9>( 1263ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Func, P1, P2, P3, P4, P5, P6, P7, P8, P9); 1264ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 12654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}; 12664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 1267d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen/// @} 1268d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen 1269651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// \brief Matches nodes that do not match the provided matcher. 1270651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// 1271651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// Uses the variadic matcher interface, but fails if InnerMatchers.size()!=1. 1272651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesbool NotUnaryOperator(const ast_type_traits::DynTypedNode DynNode, 1273651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder, 1274651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArrayRef<DynTypedMatcher> InnerMatchers); 1275651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1276d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen/// \brief Matches nodes for which all provided matchers match. 1277b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquenbool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode, 1278b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen ASTMatchFinder *Finder, 1279b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen BoundNodesTreeBuilder *Builder, 1280b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen ArrayRef<DynTypedMatcher> InnerMatchers); 1281d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen 1282d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen/// \brief Matches nodes for which at least one of the provided matchers 1283d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen/// matches, but doesn't stop at the first match. 1284b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquenbool EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode, 1285b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen ASTMatchFinder *Finder, 1286b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen BoundNodesTreeBuilder *Builder, 1287b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen ArrayRef<DynTypedMatcher> InnerMatchers); 1288d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen 1289d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen/// \brief Matches nodes for which at least one of the provided matchers 1290d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen/// matches. 1291b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquenbool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode, 1292b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen ASTMatchFinder *Finder, 1293b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen BoundNodesTreeBuilder *Builder, 1294b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen ArrayRef<DynTypedMatcher> InnerMatchers); 1295d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen 1296651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <typename T> 1297651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesinline Matcher<T> DynTypedMatcher::unconditionalConvertTo() const { 1298651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return Matcher<T>(new VariadicOperatorMatcherInterface<T>( 1299651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AllOfVariadicOperator, llvm::makeArrayRef(*this))); 1300651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 1301651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1302a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper/// \brief Creates a Matcher<T> that matches if all inner matchers match. 1303a7564433191601cb8851196b8dde39392c9c05eeDaniel Jaspertemplate<typename T> 1304a7564433191601cb8851196b8dde39392c9c05eeDaniel JasperBindableMatcher<T> makeAllOfComposite( 1305a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper ArrayRef<const Matcher<T> *> InnerMatchers) { 1306651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<DynTypedMatcher> DynMatchers; 1307651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) { 1308651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DynMatchers.push_back(*InnerMatchers[i]); 1309651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1310d36e46350b50907425bba0db1b3ddfb46cc1637fSamuel Benzaquen return BindableMatcher<T>(new VariadicOperatorMatcherInterface<T>( 1311651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AllOfVariadicOperator, std::move(DynMatchers))); 1312a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper} 1313a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper 13144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief Creates a Matcher<T> that matches if 13154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// T is dyn_cast'able into InnerT and all inner matchers match. 13169f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimek/// 13179f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimek/// Returns BindableMatcher, as matchers that use dyn_cast have 13189f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimek/// the same object both to match on and to run submatchers on, 13199f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimek/// so there is no ambiguity with what gets bound. 13204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektemplate<typename T, typename InnerT> 13219f17408d50c1d76c5eab435e4ceb924cc10757abManuel KlimekBindableMatcher<T> makeDynCastAllOfComposite( 13224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek ArrayRef<const Matcher<InnerT> *> InnerMatchers) { 1323b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen return BindableMatcher<T>(DynTypedMatcher(makeAllOfComposite(InnerMatchers)) 1324b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen .unconditionalConvertTo<T>()); 13254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek} 13264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 13274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief Matches nodes of type T that have at least one descendant node of 13284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// type DescendantT for which the given inner matcher matches. 13294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// 13304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// DescendantT must be an AST base type. 13314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektemplate <typename T, typename DescendantT> 13324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekclass HasDescendantMatcher : public MatcherInterface<T> { 1333651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static_assert(IsBaseType<DescendantT>::value, 1334651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "has descendant only accepts base type matcher"); 1335651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 13364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekpublic: 13374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek explicit HasDescendantMatcher(const Matcher<DescendantT> &DescendantMatcher) 13384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek : DescendantMatcher(DescendantMatcher) {} 13394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 1340651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool matches(const T &Node, ASTMatchFinder *Finder, 1341651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BoundNodesTreeBuilder *Builder) const override { 13424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek return Finder->matchesDescendantOf( 13434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek Node, DescendantMatcher, Builder, ASTMatchFinder::BK_First); 13444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } 13454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 13464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek private: 1347a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek const Matcher<DescendantT> DescendantMatcher; 13484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}; 13494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 1350c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper/// \brief Matches nodes of type \c T that have a parent node of type \c ParentT 1351c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper/// for which the given inner matcher matches. 1352c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper/// 1353c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper/// \c ParentT must be an AST base type. 1354c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jaspertemplate <typename T, typename ParentT> 1355c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasperclass HasParentMatcher : public MatcherInterface<T> { 1356651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static_assert(IsBaseType<ParentT>::value, 1357651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "has parent only accepts base type matcher"); 1358651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1359c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasperpublic: 1360c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper explicit HasParentMatcher(const Matcher<ParentT> &ParentMatcher) 1361c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper : ParentMatcher(ParentMatcher) {} 1362c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper 1363651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool matches(const T &Node, ASTMatchFinder *Finder, 1364651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BoundNodesTreeBuilder *Builder) const override { 1365c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper return Finder->matchesAncestorOf( 1366c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper Node, ParentMatcher, Builder, ASTMatchFinder::AMM_ParentOnly); 1367c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper } 1368c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper 1369c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper private: 1370c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper const Matcher<ParentT> ParentMatcher; 1371c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper}; 1372c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper 1373579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek/// \brief Matches nodes of type \c T that have at least one ancestor node of 1374579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek/// type \c AncestorT for which the given inner matcher matches. 1375579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek/// 1376579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek/// \c AncestorT must be an AST base type. 1377579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimektemplate <typename T, typename AncestorT> 1378579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimekclass HasAncestorMatcher : public MatcherInterface<T> { 1379651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static_assert(IsBaseType<AncestorT>::value, 1380651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "has ancestor only accepts base type matcher"); 1381651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1382579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimekpublic: 1383579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek explicit HasAncestorMatcher(const Matcher<AncestorT> &AncestorMatcher) 1384579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek : AncestorMatcher(AncestorMatcher) {} 1385579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek 1386651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool matches(const T &Node, ASTMatchFinder *Finder, 1387651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BoundNodesTreeBuilder *Builder) const override { 1388579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek return Finder->matchesAncestorOf( 1389c99a3ad8c2bf29da45a0c64b88d58bfbd2f78ef2Daniel Jasper Node, AncestorMatcher, Builder, ASTMatchFinder::AMM_All); 1390579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek } 1391579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek 1392579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek private: 1393579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek const Matcher<AncestorT> AncestorMatcher; 1394579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek}; 1395579b120038ca817e0ce423303ebc1b4e0c6cbbe1Manuel Klimek 13964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief Matches nodes of type T that have at least one descendant node of 13974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// type DescendantT for which the given inner matcher matches. 13984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// 13994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// DescendantT must be an AST base type. 14004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// As opposed to HasDescendantMatcher, ForEachDescendantMatcher will match 14014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// for each descendant node that matches instead of only for the first. 14024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektemplate <typename T, typename DescendantT> 14034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekclass ForEachDescendantMatcher : public MatcherInterface<T> { 1404651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static_assert(IsBaseType<DescendantT>::value, 1405651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "for each descendant only accepts base type matcher"); 1406651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 14074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek public: 14084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek explicit ForEachDescendantMatcher( 14094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek const Matcher<DescendantT>& DescendantMatcher) 14104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek : DescendantMatcher(DescendantMatcher) {} 14114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 1412651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool matches(const T& Node, ASTMatchFinder* Finder, 1413651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BoundNodesTreeBuilder* Builder) const override { 14144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek return Finder->matchesDescendantOf(Node, DescendantMatcher, Builder, 14154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek ASTMatchFinder::BK_All); 14164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } 14174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 14184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekprivate: 1419a78d0d6203a990b88c9c3e4c4f2a277001e8bd46Manuel Klimek const Matcher<DescendantT> DescendantMatcher; 14204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}; 14214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 14224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief Matches on nodes that have a getValue() method if getValue() equals 14234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// the value the ValueEqualsMatcher was constructed with. 14244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektemplate <typename T, typename ValueT> 14254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekclass ValueEqualsMatcher : public SingleNodeMatcherInterface<T> { 1426651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static_assert(std::is_base_of<CharacterLiteral, T>::value || 1427651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_base_of<CXXBoolLiteralExpr, T>::value || 1428651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_base_of<FloatingLiteral, T>::value || 1429651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::is_base_of<IntegerLiteral, T>::value, 1430651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "the node must have a getValue method"); 1431651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 14324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekpublic: 14334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek explicit ValueEqualsMatcher(const ValueT &ExpectedValue) 14344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek : ExpectedValue(ExpectedValue) {} 14354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 1436651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool matchesNode(const T &Node) const override { 14374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek return Node.getValue() == ExpectedValue; 14384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } 14394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 14404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekprivate: 14414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek const ValueT ExpectedValue; 14424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}; 14434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 14444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief A VariadicDynCastAllOfMatcher<SourceT, TargetT> object is a 14454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// variadic functor that takes a number of Matcher<TargetT> and returns a 14464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// Matcher<SourceT> that matches TargetT nodes that are matched by all of the 14474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// given matchers, if SourceT can be dynamically casted into TargetT. 14484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// 14494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// For example: 14504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// const VariadicDynCastAllOfMatcher< 1451e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper/// Decl, CXXRecordDecl> record; 1452e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper/// Creates a functor record(...) that creates a Matcher<Decl> given 1453e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper/// a variable number of arguments of type Matcher<CXXRecordDecl>. 1454e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper/// The returned matcher matches if the given Decl can by dynamically 1455e0e6b9e79a0c4edae92abd3928263875c78e23aaDaniel Jasper/// casted to CXXRecordDecl and all given matchers match. 14564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektemplate <typename SourceT, typename TargetT> 14574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekclass VariadicDynCastAllOfMatcher 14584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek : public llvm::VariadicFunction< 14599f17408d50c1d76c5eab435e4ceb924cc10757abManuel Klimek BindableMatcher<SourceT>, Matcher<TargetT>, 14604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek makeDynCastAllOfComposite<SourceT, TargetT> > { 14614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekpublic: 14624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek VariadicDynCastAllOfMatcher() {} 14634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}; 14644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 1465a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper/// \brief A \c VariadicAllOfMatcher<T> object is a variadic functor that takes 1466a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper/// a number of \c Matcher<T> and returns a \c Matcher<T> that matches \c T 1467a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper/// nodes that are matched by all of the given matchers. 1468a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper/// 1469a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper/// For example: 1470a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper/// const VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier; 1471a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper/// Creates a functor nestedNameSpecifier(...) that creates a 1472a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper/// \c Matcher<NestedNameSpecifier> given a variable number of arguments of type 1473a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper/// \c Matcher<NestedNameSpecifier>. 1474a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper/// The returned matcher matches if all given matchers match. 1475a7564433191601cb8851196b8dde39392c9c05eeDaniel Jaspertemplate <typename T> 1476a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasperclass VariadicAllOfMatcher : public llvm::VariadicFunction< 1477a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper BindableMatcher<T>, Matcher<T>, 1478a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper makeAllOfComposite<T> > { 1479a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasperpublic: 1480a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper VariadicAllOfMatcher() {} 1481a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}; 1482a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper 1483a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper/// \brief Matches nodes of type \c TLoc for which the inner 1484a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper/// \c Matcher<T> matches. 1485a7564433191601cb8851196b8dde39392c9c05eeDaniel Jaspertemplate <typename TLoc, typename T> 1486a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasperclass LocMatcher : public MatcherInterface<TLoc> { 1487a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasperpublic: 1488a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper explicit LocMatcher(const Matcher<T> &InnerMatcher) 1489ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper : InnerMatcher(InnerMatcher) {} 1490a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper 1491651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool matches(const TLoc &Node, ASTMatchFinder *Finder, 1492651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BoundNodesTreeBuilder *Builder) const override { 1493a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper if (!Node) 1494a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper return false; 1495a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper return InnerMatcher.matches(*extract(Node), Finder, Builder); 1496a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper } 1497a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper 1498a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasperprivate: 1499a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper const NestedNameSpecifier *extract(const NestedNameSpecifierLoc &Loc) const { 1500a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper return Loc.getNestedNameSpecifier(); 1501a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper } 1502a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper 1503a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper const Matcher<T> InnerMatcher; 1504a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}; 1505a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper 1506ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper/// \brief Matches \c TypeLocs based on an inner matcher matching a certain 1507ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper/// \c QualType. 1508ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper/// 1509ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper/// Used to implement the \c loc() matcher. 1510ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasperclass TypeLocTypeMatcher : public MatcherInterface<TypeLoc> { 1511ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasperpublic: 1512ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper explicit TypeLocTypeMatcher(const Matcher<QualType> &InnerMatcher) 1513ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper : InnerMatcher(InnerMatcher) {} 1514ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper 1515651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool matches(const TypeLoc &Node, ASTMatchFinder *Finder, 1516651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BoundNodesTreeBuilder *Builder) const override { 1517ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper if (!Node) 1518ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper return false; 1519ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper return InnerMatcher.matches(Node.getType(), Finder, Builder); 1520ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper } 1521ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper 1522ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasperprivate: 1523ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper const Matcher<QualType> InnerMatcher; 1524ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper}; 1525ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper 1526a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper/// \brief Matches nodes of type \c T for which the inner matcher matches on a 1527a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper/// another node of type \c T that can be reached using a given traverse 1528a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper/// function. 1529a7564433191601cb8851196b8dde39392c9c05eeDaniel Jaspertemplate <typename T> 1530ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasperclass TypeTraverseMatcher : public MatcherInterface<T> { 1531a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasperpublic: 1532ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper explicit TypeTraverseMatcher(const Matcher<QualType> &InnerMatcher, 1533ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper QualType (T::*TraverseFunction)() const) 1534a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {} 1535a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper 1536651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool matches(const T &Node, ASTMatchFinder *Finder, 1537651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BoundNodesTreeBuilder *Builder) const override { 1538ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper QualType NextNode = (Node.*TraverseFunction)(); 1539ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper if (NextNode.isNull()) 1540a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper return false; 1541ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper return InnerMatcher.matches(NextNode, Finder, Builder); 1542a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper } 1543a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper 1544a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasperprivate: 1545ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper const Matcher<QualType> InnerMatcher; 1546ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper QualType (T::*TraverseFunction)() const; 1547a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}; 1548a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper 1549a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper/// \brief Matches nodes of type \c T in a ..Loc hierarchy, for which the inner 1550a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper/// matcher matches on a another node of type \c T that can be reached using a 1551a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper/// given traverse function. 1552a7564433191601cb8851196b8dde39392c9c05eeDaniel Jaspertemplate <typename T> 1553ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasperclass TypeLocTraverseMatcher : public MatcherInterface<T> { 1554a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasperpublic: 1555ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper explicit TypeLocTraverseMatcher(const Matcher<TypeLoc> &InnerMatcher, 1556ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper TypeLoc (T::*TraverseFunction)() const) 1557a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {} 1558a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper 1559651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool matches(const T &Node, ASTMatchFinder *Finder, 1560651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BoundNodesTreeBuilder *Builder) const override { 1561ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper TypeLoc NextNode = (Node.*TraverseFunction)(); 1562a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper if (!NextNode) 1563a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper return false; 1564a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper return InnerMatcher.matches(NextNode, Finder, Builder); 1565a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper } 1566a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper 1567a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasperprivate: 1568ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper const Matcher<TypeLoc> InnerMatcher; 1569ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper TypeLoc (T::*TraverseFunction)() const; 1570a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper}; 1571a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper 15723f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen/// \brief Converts a \c Matcher<InnerT> to a \c Matcher<OuterT>, where 15733f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen/// \c OuterT is any type that is supported by \c Getter. 15743f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen/// 15753f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen/// \code Getter<OuterT>::value() \endcode returns a 15763f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen/// \code InnerTBase (OuterT::*)() \endcode, which is used to adapt a \c OuterT 15773f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen/// object into a \c InnerT 15783f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquentemplate <typename InnerTBase, 15793f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen template <typename OuterT> class Getter, 15803f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen template <typename OuterT> class MatcherImpl, 15813f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen typename ReturnTypesF> 15823f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquenclass TypeTraversePolymorphicMatcher { 15833f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquenprivate: 15843f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen typedef TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl, 15853f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen ReturnTypesF> Self; 15863f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen static Self create(ArrayRef<const Matcher<InnerTBase> *> InnerMatchers); 15873f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen 15883f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquenpublic: 15893f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes; 15903f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen 15913f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen explicit TypeTraversePolymorphicMatcher( 15923f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen ArrayRef<const Matcher<InnerTBase> *> InnerMatchers) 15933f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen : InnerMatcher(makeAllOfComposite(InnerMatchers)) {} 15943f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen 15953f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen template <typename OuterT> operator Matcher<OuterT>() const { 15963f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen return Matcher<OuterT>( 15973f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen new MatcherImpl<OuterT>(InnerMatcher, Getter<OuterT>::value())); 15983f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen } 15993f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen 16003f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen struct Func : public llvm::VariadicFunction<Self, Matcher<InnerTBase>, 16013f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen &Self::create> { 16023f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen Func() {} 16033f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen }; 16043f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen 16053f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquenprivate: 16063f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen const Matcher<InnerTBase> InnerMatcher; 16073f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen}; 16083f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen 16093f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen// Define the create() method out of line to silence a GCC warning about 16103f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen// the struct "Func" having greater visibility than its base, which comes from 16113f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen// using the flag -fvisibility-inlines-hidden. 16123f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquentemplate <typename InnerTBase, template <typename OuterT> class Getter, 16133f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen template <typename OuterT> class MatcherImpl, typename ReturnTypesF> 16143f84bb341bfb1312842b09db71d76bc3898ba247Samuel BenzaquenTypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl, ReturnTypesF> 16153f84bb341bfb1312842b09db71d76bc3898ba247Samuel BenzaquenTypeTraversePolymorphicMatcher< 16163f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen InnerTBase, Getter, MatcherImpl, 16173f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen ReturnTypesF>::create(ArrayRef<const Matcher<InnerTBase> *> InnerMatchers) { 16183f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen return Self(InnerMatchers); 1619ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper} 1620ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper 1621651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// FIXME: unify ClassTemplateSpecializationDecl and TemplateSpecializationType's 1622651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// APIs for accessing the template argument list. 1623ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesinline ArrayRef<TemplateArgument> 1624651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesgetTemplateSpecializationArgs(const ClassTemplateSpecializationDecl &D) { 1625651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return D.getTemplateArgs().asArray(); 1626651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 1627651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1628ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesinline ArrayRef<TemplateArgument> 1629651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesgetTemplateSpecializationArgs(const TemplateSpecializationType &T) { 1630ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return ArrayRef<TemplateArgument>(T.getArgs(), T.getNumArgs()); 1631651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 1632651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1633651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct NotEqualsBoundNodePredicate { 1634651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool operator()(const internal::BoundNodesMap &Nodes) const { 1635651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return Nodes.getNode(ID) != Node; 1636651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1637651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::string ID; 1638651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ast_type_traits::DynTypedNode Node; 1639651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 1640651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 16414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek} // end namespace internal 16424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek} // end namespace ast_matchers 16434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek} // end namespace clang 16444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 16454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#endif // LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_INTERNAL_H 1646