1239313Sdim//===--- ASTMatchersInternal.h - Structural query framework -----*- C++ -*-===// 2239313Sdim// 3239313Sdim// The LLVM Compiler Infrastructure 4239313Sdim// 5239313Sdim// This file is distributed under the University of Illinois Open Source 6239313Sdim// License. See LICENSE.TXT for details. 7239313Sdim// 8239313Sdim//===----------------------------------------------------------------------===// 9239313Sdim// 10239313Sdim// Implements the base layer of the matcher framework. 11239313Sdim// 12239313Sdim// Matchers are methods that return a Matcher<T> which provides a method 13239313Sdim// Matches(...) which is a predicate on an AST node. The Matches method's 14239313Sdim// parameters define the context of the match, which allows matchers to recurse 15239313Sdim// or store the current node as bound to a specific string, so that it can be 16239313Sdim// retrieved later. 17239313Sdim// 18239313Sdim// In general, matchers have two parts: 19239313Sdim// 1. A function Matcher<T> MatcherName(<arguments>) which returns a Matcher<T> 20239313Sdim// based on the arguments and optionally on template type deduction based 21239313Sdim// on the arguments. Matcher<T>s form an implicit reverse hierarchy 22239313Sdim// to clang's AST class hierarchy, meaning that you can use a Matcher<Base> 23239313Sdim// everywhere a Matcher<Derived> is required. 24239313Sdim// 2. An implementation of a class derived from MatcherInterface<T>. 25239313Sdim// 26239313Sdim// The matcher functions are defined in ASTMatchers.h. To make it possible 27239313Sdim// to implement both the matcher function and the implementation of the matcher 28239313Sdim// interface in one place, ASTMatcherMacros.h defines macros that allow 29239313Sdim// implementing a matcher in a single place. 30239313Sdim// 31239313Sdim// This file contains the base classes needed to construct the actual matchers. 32239313Sdim// 33239313Sdim//===----------------------------------------------------------------------===// 34239313Sdim 35239313Sdim#ifndef LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_INTERNAL_H 36239313Sdim#define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_INTERNAL_H 37239313Sdim 38249423Sdim#include "clang/AST/ASTTypeTraits.h" 39263508Sdim#include "clang/AST/Decl.h" 40249423Sdim#include "clang/AST/DeclCXX.h" 41239313Sdim#include "clang/AST/ExprCXX.h" 42263508Sdim#include "clang/AST/Stmt.h" 43249423Sdim#include "clang/AST/StmtCXX.h" 44243830Sdim#include "clang/AST/Type.h" 45263508Sdim#include "llvm/ADT/Optional.h" 46239313Sdim#include "llvm/ADT/VariadicFunction.h" 47243830Sdim#include "llvm/Support/type_traits.h" 48239313Sdim#include <map> 49239313Sdim#include <string> 50239313Sdim#include <vector> 51239313Sdim 52239313Sdimnamespace clang { 53239313Sdimnamespace ast_matchers { 54239313Sdim 55239313Sdim/// FIXME: Move into the llvm support library. 56239313Sdimtemplate <bool> struct CompileAssert {}; 57239313Sdim#define TOOLING_COMPILE_ASSERT(Expr, Msg) \ 58239313Sdim typedef CompileAssert<(bool(Expr))> Msg[bool(Expr) ? 1 : -1] 59239313Sdim 60239313Sdimclass BoundNodes; 61239313Sdim 62239313Sdimnamespace internal { 63239313Sdim 64243830Sdim/// \brief Internal version of BoundNodes. Holds all the bound nodes. 65243830Sdimclass BoundNodesMap { 66243830Sdimpublic: 67243830Sdim /// \brief Adds \c Node to the map with key \c ID. 68243830Sdim /// 69243830Sdim /// The node's base type should be in NodeBaseType or it will be unaccessible. 70243830Sdim template <typename T> 71243830Sdim void addNode(StringRef ID, const T* Node) { 72243830Sdim NodeMap[ID] = ast_type_traits::DynTypedNode::create(*Node); 73243830Sdim } 74239313Sdim 75243830Sdim /// \brief Returns the AST node bound to \c ID. 76243830Sdim /// 77243830Sdim /// Returns NULL if there was no node bound to \c ID or if there is a node but 78243830Sdim /// it cannot be converted to the specified type. 79243830Sdim template <typename T> 80243830Sdim const T *getNodeAs(StringRef ID) const { 81243830Sdim IDToNodeMap::const_iterator It = NodeMap.find(ID); 82243830Sdim if (It == NodeMap.end()) { 83243830Sdim return NULL; 84243830Sdim } 85243830Sdim return It->second.get<T>(); 86243830Sdim } 87243830Sdim 88263508Sdim ast_type_traits::DynTypedNode getNode(StringRef ID) const { 89263508Sdim IDToNodeMap::const_iterator It = NodeMap.find(ID); 90263508Sdim if (It == NodeMap.end()) { 91263508Sdim return ast_type_traits::DynTypedNode(); 92263508Sdim } 93263508Sdim return It->second; 94263508Sdim } 95243830Sdim 96263508Sdim /// \brief Imposes an order on BoundNodesMaps. 97263508Sdim bool operator<(const BoundNodesMap &Other) const { 98263508Sdim return NodeMap < Other.NodeMap; 99263508Sdim } 100243830Sdim 101243830Sdim /// \brief A map from IDs to the bound nodes. 102263508Sdim /// 103263508Sdim /// Note that we're using std::map here, as for memoization: 104263508Sdim /// - we need a comparison operator 105263508Sdim /// - we need an assignment operator 106243830Sdim typedef std::map<std::string, ast_type_traits::DynTypedNode> IDToNodeMap; 107243830Sdim 108263508Sdim const IDToNodeMap &getMap() const { 109263508Sdim return NodeMap; 110263508Sdim } 111263508Sdim 112263508Sdimprivate: 113243830Sdim IDToNodeMap NodeMap; 114243830Sdim}; 115243830Sdim 116263508Sdim/// \brief Creates BoundNodesTree objects. 117239313Sdim/// 118263508Sdim/// The tree builder is used during the matching process to insert the bound 119263508Sdim/// nodes from the Id matcher. 120263508Sdimclass BoundNodesTreeBuilder { 121239313Sdimpublic: 122239313Sdim /// \brief A visitor interface to visit all BoundNodes results for a 123239313Sdim /// BoundNodesTree. 124239313Sdim class Visitor { 125239313Sdim public: 126239313Sdim virtual ~Visitor() {} 127239313Sdim 128239313Sdim /// \brief Called multiple times during a single call to VisitMatches(...). 129239313Sdim /// 130239313Sdim /// 'BoundNodesView' contains the bound nodes for a single match. 131239313Sdim virtual void visitMatch(const BoundNodes& BoundNodesView) = 0; 132239313Sdim }; 133239313Sdim 134263508Sdim /// \brief Add a binding from an id to a node. 135263508Sdim template <typename T> void setBinding(const std::string &Id, const T *Node) { 136263508Sdim if (Bindings.empty()) 137263508Sdim Bindings.push_back(BoundNodesMap()); 138263508Sdim for (unsigned i = 0, e = Bindings.size(); i != e; ++i) 139263508Sdim Bindings[i].addNode(Id, Node); 140263508Sdim } 141239313Sdim 142263508Sdim /// \brief Adds a branch in the tree. 143263508Sdim void addMatch(const BoundNodesTreeBuilder &Bindings); 144239313Sdim 145239313Sdim /// \brief Visits all matches that this BoundNodesTree represents. 146239313Sdim /// 147239313Sdim /// The ownership of 'ResultVisitor' remains at the caller. 148239313Sdim void visitMatches(Visitor* ResultVisitor); 149239313Sdim 150263508Sdim template <typename ExcludePredicate> 151263508Sdim bool removeBindings(const ExcludePredicate &Predicate) { 152263508Sdim Bindings.erase(std::remove_if(Bindings.begin(), Bindings.end(), Predicate), 153263508Sdim Bindings.end()); 154263508Sdim return !Bindings.empty(); 155263508Sdim } 156239313Sdim 157263508Sdim /// \brief Imposes an order on BoundNodesTreeBuilders. 158263508Sdim bool operator<(const BoundNodesTreeBuilder &Other) const { 159263508Sdim return Bindings < Other.Bindings; 160243830Sdim } 161239313Sdim 162239313Sdimprivate: 163263508Sdim SmallVector<BoundNodesMap, 16> Bindings; 164239313Sdim}; 165239313Sdim 166239313Sdimclass ASTMatchFinder; 167239313Sdim 168239313Sdim/// \brief Generic interface for matchers on an AST node of type T. 169239313Sdim/// 170239313Sdim/// Implement this if your matcher may need to inspect the children or 171239313Sdim/// descendants of the node or bind matched nodes to names. If you are 172239313Sdim/// writing a simple matcher that only inspects properties of the 173239313Sdim/// current node and doesn't care about its children or descendants, 174239313Sdim/// implement SingleNodeMatcherInterface instead. 175239313Sdimtemplate <typename T> 176249423Sdimclass MatcherInterface : public RefCountedBaseVPTR { 177239313Sdimpublic: 178239313Sdim virtual ~MatcherInterface() {} 179239313Sdim 180239313Sdim /// \brief Returns true if 'Node' can be matched. 181239313Sdim /// 182239313Sdim /// May bind 'Node' to an ID via 'Builder', or recurse into 183239313Sdim /// the AST via 'Finder'. 184239313Sdim virtual bool matches(const T &Node, 185239313Sdim ASTMatchFinder *Finder, 186239313Sdim BoundNodesTreeBuilder *Builder) const = 0; 187239313Sdim}; 188239313Sdim 189243830Sdim/// \brief Interface for matchers that only evaluate properties on a single 190243830Sdim/// node. 191239313Sdimtemplate <typename T> 192239313Sdimclass SingleNodeMatcherInterface : public MatcherInterface<T> { 193239313Sdimpublic: 194239313Sdim /// \brief Returns true if the matcher matches the provided node. 195239313Sdim /// 196239313Sdim /// A subclass must implement this instead of Matches(). 197239313Sdim virtual bool matchesNode(const T &Node) const = 0; 198239313Sdim 199239313Sdimprivate: 200239313Sdim /// Implements MatcherInterface::Matches. 201239313Sdim virtual bool matches(const T &Node, 202239313Sdim ASTMatchFinder * /* Finder */, 203239313Sdim BoundNodesTreeBuilder * /* Builder */) const { 204239313Sdim return matchesNode(Node); 205239313Sdim } 206239313Sdim}; 207239313Sdim 208239313Sdim/// \brief Wrapper of a MatcherInterface<T> *that allows copying. 209239313Sdim/// 210239313Sdim/// A Matcher<Base> can be used anywhere a Matcher<Derived> is 211239313Sdim/// required. This establishes an is-a relationship which is reverse 212239313Sdim/// to the AST hierarchy. In other words, Matcher<T> is contravariant 213239313Sdim/// with respect to T. The relationship is built via a type conversion 214239313Sdim/// operator rather than a type hierarchy to be able to templatize the 215239313Sdim/// type hierarchy instead of spelling it out. 216239313Sdimtemplate <typename T> 217263508Sdimclass Matcher { 218239313Sdimpublic: 219239313Sdim /// \brief Takes ownership of the provided implementation pointer. 220239313Sdim explicit Matcher(MatcherInterface<T> *Implementation) 221239313Sdim : Implementation(Implementation) {} 222239313Sdim 223243830Sdim /// \brief Implicitly converts \c Other to a Matcher<T>. 224243830Sdim /// 225243830Sdim /// Requires \c T to be derived from \c From. 226243830Sdim template <typename From> 227243830Sdim Matcher(const Matcher<From> &Other, 228243830Sdim typename llvm::enable_if_c< 229243830Sdim llvm::is_base_of<From, T>::value && 230243830Sdim !llvm::is_same<From, T>::value >::type* = 0) 231243830Sdim : Implementation(new ImplicitCastMatcher<From>(Other)) {} 232243830Sdim 233243830Sdim /// \brief Implicitly converts \c Matcher<Type> to \c Matcher<QualType>. 234243830Sdim /// 235243830Sdim /// The resulting matcher is not strict, i.e. ignores qualifiers. 236243830Sdim template <typename TypeT> 237243830Sdim Matcher(const Matcher<TypeT> &Other, 238243830Sdim typename llvm::enable_if_c< 239243830Sdim llvm::is_same<T, QualType>::value && 240243830Sdim llvm::is_same<TypeT, Type>::value >::type* = 0) 241243830Sdim : Implementation(new TypeToQualType<TypeT>(Other)) {} 242243830Sdim 243239313Sdim /// \brief Forwards the call to the underlying MatcherInterface<T> pointer. 244239313Sdim bool matches(const T &Node, 245239313Sdim ASTMatchFinder *Finder, 246239313Sdim BoundNodesTreeBuilder *Builder) const { 247263508Sdim if (Implementation->matches(Node, Finder, Builder)) 248263508Sdim return true; 249263508Sdim // Delete all bindings when a matcher does not match. 250263508Sdim // This prevents unexpected exposure of bound nodes in unmatches 251263508Sdim // branches of the match tree. 252263508Sdim *Builder = BoundNodesTreeBuilder(); 253263508Sdim return false; 254239313Sdim } 255239313Sdim 256239313Sdim /// \brief Returns an ID that uniquely identifies the matcher. 257239313Sdim uint64_t getID() const { 258239313Sdim /// FIXME: Document the requirements this imposes on matcher 259239313Sdim /// implementations (no new() implementation_ during a Matches()). 260239313Sdim return reinterpret_cast<uint64_t>(Implementation.getPtr()); 261239313Sdim } 262239313Sdim 263243830Sdim /// \brief Allows the conversion of a \c Matcher<Type> to a \c 264243830Sdim /// Matcher<QualType>. 265243830Sdim /// 266243830Sdim /// Depending on the constructor argument, the matcher is either strict, i.e. 267243830Sdim /// does only matches in the absence of qualifiers, or not, i.e. simply 268243830Sdim /// ignores any qualifiers. 269243830Sdim template <typename TypeT> 270243830Sdim class TypeToQualType : public MatcherInterface<QualType> { 271243830Sdim public: 272243830Sdim TypeToQualType(const Matcher<TypeT> &InnerMatcher) 273243830Sdim : InnerMatcher(InnerMatcher) {} 274243830Sdim 275243830Sdim virtual bool matches(const QualType &Node, 276243830Sdim ASTMatchFinder *Finder, 277243830Sdim BoundNodesTreeBuilder *Builder) const { 278243830Sdim if (Node.isNull()) 279243830Sdim return false; 280243830Sdim return InnerMatcher.matches(*Node, Finder, Builder); 281243830Sdim } 282243830Sdim private: 283243830Sdim const Matcher<TypeT> InnerMatcher; 284243830Sdim }; 285243830Sdim 286239313Sdimprivate: 287243830Sdim /// \brief Allows conversion from Matcher<Base> to Matcher<T> if T 288243830Sdim /// is derived from Base. 289243830Sdim template <typename Base> 290243830Sdim class ImplicitCastMatcher : public MatcherInterface<T> { 291239313Sdim public: 292243830Sdim explicit ImplicitCastMatcher(const Matcher<Base> &From) 293239313Sdim : From(From) {} 294239313Sdim 295243830Sdim virtual bool matches(const T &Node, 296239313Sdim ASTMatchFinder *Finder, 297239313Sdim BoundNodesTreeBuilder *Builder) const { 298239313Sdim return From.matches(Node, Finder, Builder); 299239313Sdim } 300239313Sdim 301239313Sdim private: 302243830Sdim const Matcher<Base> From; 303239313Sdim }; 304239313Sdim 305249423Sdim IntrusiveRefCntPtr< MatcherInterface<T> > Implementation; 306239313Sdim}; // class Matcher 307239313Sdim 308239313Sdim/// \brief A convenient helper for creating a Matcher<T> without specifying 309239313Sdim/// the template type argument. 310239313Sdimtemplate <typename T> 311239313Sdiminline Matcher<T> makeMatcher(MatcherInterface<T> *Implementation) { 312239313Sdim return Matcher<T>(Implementation); 313239313Sdim} 314239313Sdim 315263508Sdimtemplate <typename T> class BindableMatcher; 316263508Sdim 317263508Sdim/// \brief Matcher that works on a \c DynTypedNode. 318263508Sdim/// 319263508Sdim/// It is constructed from a \c Matcher<T> object and redirects most calls to 320263508Sdim/// underlying matcher. 321263508Sdim/// It checks whether the \c DynTypedNode is convertible into the type of the 322263508Sdim/// underlying matcher and then do the actual match on the actual node, or 323263508Sdim/// return false if it is not convertible. 324263508Sdimclass DynTypedMatcher { 325263508Sdimpublic: 326263508Sdim /// \brief Construct from a \c Matcher<T>. Copies the matcher. 327263508Sdim template <typename T> inline DynTypedMatcher(const Matcher<T> &M); 328263508Sdim 329263508Sdim /// \brief Construct from a bindable \c Matcher<T>. Copies the matcher. 330263508Sdim /// 331263508Sdim /// This version enables \c tryBind() on the \c DynTypedMatcher. 332263508Sdim template <typename T> inline DynTypedMatcher(const BindableMatcher<T> &M); 333263508Sdim 334263508Sdim /// \brief Returns true if the matcher matches the given \c DynNode. 335263508Sdim bool matches(const ast_type_traits::DynTypedNode DynNode, 336263508Sdim ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const { 337263508Sdim return Storage->matches(DynNode, Finder, Builder); 338263508Sdim } 339263508Sdim 340263508Sdim /// \brief Bind the specified \p ID to the matcher. 341263508Sdim /// \return A new matcher with the \p ID bound to it if this matcher supports 342263508Sdim /// binding. Otherwise, returns an empty \c Optional<>. 343263508Sdim llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const { 344263508Sdim return Storage->tryBind(ID); 345263508Sdim } 346263508Sdim 347263508Sdim /// \brief Returns a unique \p ID for the matcher. 348263508Sdim uint64_t getID() const { return Storage->getID(); } 349263508Sdim 350263508Sdim /// \brief Returns the type this matcher works on. 351263508Sdim /// 352263508Sdim /// \c matches() will always return false unless the node passed is of this 353263508Sdim /// or a derived type. 354263508Sdim ast_type_traits::ASTNodeKind getSupportedKind() const { 355263508Sdim return Storage->getSupportedKind(); 356263508Sdim } 357263508Sdim 358263508Sdim /// \brief Returns \c true if the passed \c DynTypedMatcher can be converted 359263508Sdim /// to a \c Matcher<T>. 360263508Sdim /// 361263508Sdim /// This method verifies that the underlying matcher in \c Other can process 362263508Sdim /// nodes of types T. 363263508Sdim template <typename T> bool canConvertTo() const { 364263508Sdim return getSupportedKind().isBaseOf( 365263508Sdim ast_type_traits::ASTNodeKind::getFromNodeKind<T>()); 366263508Sdim } 367263508Sdim 368263508Sdim /// \brief Construct a \c Matcher<T> interface around the dynamic matcher. 369263508Sdim /// 370263508Sdim /// This method asserts that \c canConvertTo() is \c true. Callers 371263508Sdim /// should call \c canConvertTo() first to make sure that \c this is 372263508Sdim /// compatible with T. 373263508Sdim template <typename T> Matcher<T> convertTo() const { 374263508Sdim assert(canConvertTo<T>()); 375263508Sdim return unconditionalConvertTo<T>(); 376263508Sdim } 377263508Sdim 378263508Sdim /// \brief Same as \c convertTo(), but does not check that the underlying 379263508Sdim /// matcher can handle a value of T. 380263508Sdim /// 381263508Sdim /// If it is not compatible, then this matcher will never match anything. 382263508Sdim template <typename T> Matcher<T> unconditionalConvertTo() const { 383263508Sdim return Matcher<T>(new WrappedMatcher<T>(*this)); 384263508Sdim } 385263508Sdim 386263508Sdimprivate: 387263508Sdim class MatcherStorage : public RefCountedBaseVPTR { 388263508Sdim public: 389263508Sdim MatcherStorage(ast_type_traits::ASTNodeKind SupportedKind, uint64_t ID) 390263508Sdim : SupportedKind(SupportedKind), ID(ID) {} 391263508Sdim virtual ~MatcherStorage(); 392263508Sdim 393263508Sdim virtual bool matches(const ast_type_traits::DynTypedNode DynNode, 394263508Sdim ASTMatchFinder *Finder, 395263508Sdim BoundNodesTreeBuilder *Builder) const = 0; 396263508Sdim 397263508Sdim virtual llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const = 0; 398263508Sdim 399263508Sdim ast_type_traits::ASTNodeKind getSupportedKind() const { 400263508Sdim return SupportedKind; 401263508Sdim } 402263508Sdim 403263508Sdim uint64_t getID() const { return ID; } 404263508Sdim 405263508Sdim private: 406263508Sdim const ast_type_traits::ASTNodeKind SupportedKind; 407263508Sdim const uint64_t ID; 408263508Sdim }; 409263508Sdim 410263508Sdim /// \brief Typed implementation of \c MatcherStorage. 411263508Sdim template <typename T> class TypedMatcherStorage; 412263508Sdim 413263508Sdim /// \brief Simple MatcherInterface<T> wrapper around a DynTypedMatcher. 414263508Sdim template <typename T> class WrappedMatcher; 415263508Sdim 416263508Sdim IntrusiveRefCntPtr<const MatcherStorage> Storage; 417263508Sdim}; 418263508Sdim 419263508Sdimtemplate <typename T> 420263508Sdimclass DynTypedMatcher::TypedMatcherStorage : public MatcherStorage { 421263508Sdimpublic: 422263508Sdim TypedMatcherStorage(const Matcher<T> &Other, bool AllowBind) 423263508Sdim : MatcherStorage(ast_type_traits::ASTNodeKind::getFromNodeKind<T>(), 424263508Sdim Other.getID()), 425263508Sdim InnerMatcher(Other), AllowBind(AllowBind) {} 426263508Sdim 427263508Sdim bool matches(const ast_type_traits::DynTypedNode DynNode, 428263508Sdim ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const 429263508Sdim LLVM_OVERRIDE { 430263508Sdim if (const T *Node = DynNode.get<T>()) { 431263508Sdim return InnerMatcher.matches(*Node, Finder, Builder); 432263508Sdim } 433263508Sdim return false; 434263508Sdim } 435263508Sdim 436263508Sdim llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const LLVM_OVERRIDE { 437263508Sdim if (!AllowBind) 438263508Sdim return llvm::Optional<DynTypedMatcher>(); 439263508Sdim return DynTypedMatcher(BindableMatcher<T>(InnerMatcher).bind(ID)); 440263508Sdim } 441263508Sdim 442263508Sdimprivate: 443263508Sdim const Matcher<T> InnerMatcher; 444263508Sdim const bool AllowBind; 445263508Sdim}; 446263508Sdim 447263508Sdimtemplate <typename T> 448263508Sdiminline DynTypedMatcher::DynTypedMatcher(const Matcher<T> &M) 449263508Sdim : Storage(new TypedMatcherStorage<T>(M, false)) {} 450263508Sdim 451263508Sdimtemplate <typename T> 452263508Sdiminline DynTypedMatcher::DynTypedMatcher(const BindableMatcher<T> &M) 453263508Sdim : Storage(new TypedMatcherStorage<T>(M, true)) {} 454263508Sdim 455263508Sdimtemplate <typename T> 456263508Sdimclass DynTypedMatcher::WrappedMatcher : public MatcherInterface<T> { 457263508Sdimpublic: 458263508Sdim explicit WrappedMatcher(const DynTypedMatcher &Matcher) : Inner(Matcher) {} 459263508Sdim virtual ~WrappedMatcher() {} 460263508Sdim 461263508Sdim bool matches(const T &Node, ASTMatchFinder *Finder, 462263508Sdim BoundNodesTreeBuilder *Builder) const { 463263508Sdim return Inner.matches(ast_type_traits::DynTypedNode::create(Node), Finder, 464263508Sdim Builder); 465263508Sdim } 466263508Sdim 467263508Sdimprivate: 468263508Sdim const DynTypedMatcher Inner; 469263508Sdim}; 470263508Sdim 471263508Sdim/// \brief Specialization of the conversion functions for QualType. 472263508Sdim/// 473263508Sdim/// These specializations provide the Matcher<Type>->Matcher<QualType> 474263508Sdim/// conversion that the static API does. 475263508Sdimtemplate <> inline bool DynTypedMatcher::canConvertTo<QualType>() const { 476263508Sdim const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind(); 477263508Sdim return SourceKind.isSame( 478263508Sdim ast_type_traits::ASTNodeKind::getFromNodeKind<Type>()) || 479263508Sdim SourceKind.isSame( 480263508Sdim ast_type_traits::ASTNodeKind::getFromNodeKind<QualType>()); 481263508Sdim} 482263508Sdim 483263508Sdimtemplate <> 484263508Sdiminline Matcher<QualType> DynTypedMatcher::convertTo<QualType>() const { 485263508Sdim assert(canConvertTo<QualType>()); 486263508Sdim const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind(); 487263508Sdim if (SourceKind.isSame( 488263508Sdim ast_type_traits::ASTNodeKind::getFromNodeKind<Type>())) { 489263508Sdim // We support implicit conversion from Matcher<Type> to Matcher<QualType> 490263508Sdim return unconditionalConvertTo<Type>(); 491263508Sdim } 492263508Sdim return unconditionalConvertTo<QualType>(); 493263508Sdim} 494263508Sdim 495263508Sdim/// \brief Finds the first node in a range that matches the given matcher. 496263508Sdimtemplate <typename MatcherT, typename IteratorT> 497263508Sdimbool matchesFirstInRange(const MatcherT &Matcher, IteratorT Start, 498263508Sdim IteratorT End, ASTMatchFinder *Finder, 499263508Sdim BoundNodesTreeBuilder *Builder) { 500263508Sdim for (IteratorT I = Start; I != End; ++I) { 501263508Sdim BoundNodesTreeBuilder Result(*Builder); 502263508Sdim if (Matcher.matches(*I, Finder, &Result)) { 503263508Sdim *Builder = Result; 504263508Sdim return true; 505263508Sdim } 506263508Sdim } 507263508Sdim return false; 508263508Sdim} 509263508Sdim 510263508Sdim/// \brief Finds the first node in a pointer range that matches the given 511263508Sdim/// matcher. 512263508Sdimtemplate <typename MatcherT, typename IteratorT> 513263508Sdimbool matchesFirstInPointerRange(const MatcherT &Matcher, IteratorT Start, 514263508Sdim IteratorT End, ASTMatchFinder *Finder, 515263508Sdim BoundNodesTreeBuilder *Builder) { 516263508Sdim for (IteratorT I = Start; I != End; ++I) { 517263508Sdim BoundNodesTreeBuilder Result(*Builder); 518263508Sdim if (Matcher.matches(**I, Finder, &Result)) { 519263508Sdim *Builder = Result; 520263508Sdim return true; 521263508Sdim } 522263508Sdim } 523263508Sdim return false; 524263508Sdim} 525263508Sdim 526249423Sdim/// \brief Metafunction to determine if type T has a member called getDecl. 527249423Sdimtemplate <typename T> struct has_getDecl { 528249423Sdim struct Default { int getDecl; }; 529249423Sdim struct Derived : T, Default { }; 530249423Sdim 531249423Sdim template<typename C, C> struct CheckT; 532249423Sdim 533249423Sdim // If T::getDecl exists, an ambiguity arises and CheckT will 534249423Sdim // not be instantiable. This makes f(...) the only available 535249423Sdim // overload. 536249423Sdim template<typename C> 537249423Sdim static char (&f(CheckT<int Default::*, &C::getDecl>*))[1]; 538249423Sdim template<typename C> static char (&f(...))[2]; 539249423Sdim 540249423Sdim static bool const value = sizeof(f<Derived>(0)) == 2; 541249423Sdim}; 542249423Sdim 543249423Sdim/// \brief Matches overloaded operators with a specific name. 544249423Sdim/// 545249423Sdim/// The type argument ArgT is not used by this matcher but is used by 546249423Sdim/// PolymorphicMatcherWithParam1 and should be StringRef. 547249423Sdimtemplate <typename T, typename ArgT> 548249423Sdimclass HasOverloadedOperatorNameMatcher : public SingleNodeMatcherInterface<T> { 549249423Sdim TOOLING_COMPILE_ASSERT((llvm::is_same<T, CXXOperatorCallExpr>::value || 550249423Sdim llvm::is_same<T, CXXMethodDecl>::value), 551249423Sdim unsupported_class_for_matcher); 552249423Sdim TOOLING_COMPILE_ASSERT((llvm::is_same<ArgT, StringRef>::value), 553249423Sdim argument_type_must_be_StringRef); 554249423Sdimpublic: 555249423Sdim explicit HasOverloadedOperatorNameMatcher(const StringRef Name) 556249423Sdim : SingleNodeMatcherInterface<T>(), Name(Name) {} 557249423Sdim 558249423Sdim virtual bool matchesNode(const T &Node) const LLVM_OVERRIDE { 559249423Sdim return matchesSpecialized(Node); 560249423Sdim } 561249423Sdim 562249423Sdimprivate: 563249423Sdim 564249423Sdim /// \brief CXXOperatorCallExpr exist only for calls to overloaded operators 565249423Sdim /// so this function returns true if the call is to an operator of the given 566249423Sdim /// name. 567249423Sdim bool matchesSpecialized(const CXXOperatorCallExpr &Node) const { 568249423Sdim return getOperatorSpelling(Node.getOperator()) == Name; 569249423Sdim } 570249423Sdim 571249423Sdim /// \brief Returns true only if CXXMethodDecl represents an overloaded 572249423Sdim /// operator and has the given operator name. 573249423Sdim bool matchesSpecialized(const CXXMethodDecl &Node) const { 574249423Sdim return Node.isOverloadedOperator() && 575249423Sdim getOperatorSpelling(Node.getOverloadedOperator()) == Name; 576249423Sdim } 577249423Sdim 578249423Sdim std::string Name; 579249423Sdim}; 580249423Sdim 581239313Sdim/// \brief Matches declarations for QualType and CallExpr. 582239313Sdim/// 583239313Sdim/// Type argument DeclMatcherT is required by PolymorphicMatcherWithParam1 but 584239313Sdim/// not actually used. 585239313Sdimtemplate <typename T, typename DeclMatcherT> 586239313Sdimclass HasDeclarationMatcher : public MatcherInterface<T> { 587239313Sdim TOOLING_COMPILE_ASSERT((llvm::is_same< DeclMatcherT, 588239313Sdim Matcher<Decl> >::value), 589239313Sdim instantiated_with_wrong_types); 590239313Sdimpublic: 591239313Sdim explicit HasDeclarationMatcher(const Matcher<Decl> &InnerMatcher) 592239313Sdim : InnerMatcher(InnerMatcher) {} 593239313Sdim 594239313Sdim virtual bool matches(const T &Node, 595239313Sdim ASTMatchFinder *Finder, 596239313Sdim BoundNodesTreeBuilder *Builder) const { 597239313Sdim return matchesSpecialized(Node, Finder, Builder); 598239313Sdim } 599239313Sdim 600239313Sdimprivate: 601249423Sdim /// \brief If getDecl exists as a member of U, returns whether the inner 602249423Sdim /// matcher matches Node.getDecl(). 603249423Sdim template <typename U> 604249423Sdim bool matchesSpecialized( 605249423Sdim const U &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder, 606249423Sdim typename llvm::enable_if<has_getDecl<U>, int>::type = 0) const { 607249423Sdim return matchesDecl(Node.getDecl(), Finder, Builder); 608249423Sdim } 609249423Sdim 610249423Sdim /// \brief Extracts the CXXRecordDecl or EnumDecl of a QualType and returns 611249423Sdim /// whether the inner matcher matches on it. 612239313Sdim bool matchesSpecialized(const QualType &Node, ASTMatchFinder *Finder, 613239313Sdim BoundNodesTreeBuilder *Builder) const { 614239313Sdim /// FIXME: Add other ways to convert... 615239313Sdim if (Node.isNull()) 616239313Sdim return false; 617249423Sdim if (const EnumType *AsEnum = dyn_cast<EnumType>(Node.getTypePtr())) 618249423Sdim return matchesDecl(AsEnum->getDecl(), Finder, Builder); 619243830Sdim return matchesDecl(Node->getAsCXXRecordDecl(), Finder, Builder); 620239313Sdim } 621239313Sdim 622249423Sdim /// \brief Gets the TemplateDecl from a TemplateSpecializationType 623249423Sdim /// and returns whether the inner matches on it. 624249423Sdim bool matchesSpecialized(const TemplateSpecializationType &Node, 625249423Sdim ASTMatchFinder *Finder, 626249423Sdim BoundNodesTreeBuilder *Builder) const { 627249423Sdim return matchesDecl(Node.getTemplateName().getAsTemplateDecl(), 628249423Sdim Finder, Builder); 629249423Sdim } 630249423Sdim 631239313Sdim /// \brief Extracts the Decl of the callee of a CallExpr and returns whether 632239313Sdim /// the inner matcher matches on it. 633239313Sdim bool matchesSpecialized(const CallExpr &Node, ASTMatchFinder *Finder, 634239313Sdim BoundNodesTreeBuilder *Builder) const { 635243830Sdim return matchesDecl(Node.getCalleeDecl(), Finder, Builder); 636239313Sdim } 637239313Sdim 638239313Sdim /// \brief Extracts the Decl of the constructor call and returns whether the 639239313Sdim /// inner matcher matches on it. 640239313Sdim bool matchesSpecialized(const CXXConstructExpr &Node, 641239313Sdim ASTMatchFinder *Finder, 642239313Sdim BoundNodesTreeBuilder *Builder) const { 643243830Sdim return matchesDecl(Node.getConstructor(), Finder, Builder); 644239313Sdim } 645239313Sdim 646243830Sdim /// \brief Extracts the \c ValueDecl a \c MemberExpr refers to and returns 647243830Sdim /// whether the inner matcher matches on it. 648243830Sdim bool matchesSpecialized(const MemberExpr &Node, 649243830Sdim ASTMatchFinder *Finder, 650243830Sdim BoundNodesTreeBuilder *Builder) const { 651243830Sdim return matchesDecl(Node.getMemberDecl(), Finder, Builder); 652243830Sdim } 653243830Sdim 654243830Sdim /// \brief Returns whether the inner matcher \c Node. Returns false if \c Node 655243830Sdim /// is \c NULL. 656243830Sdim bool matchesDecl(const Decl *Node, 657243830Sdim ASTMatchFinder *Finder, 658243830Sdim BoundNodesTreeBuilder *Builder) const { 659243830Sdim return Node != NULL && InnerMatcher.matches(*Node, Finder, Builder); 660243830Sdim } 661243830Sdim 662239313Sdim const Matcher<Decl> InnerMatcher; 663239313Sdim}; 664239313Sdim 665239313Sdim/// \brief IsBaseType<T>::value is true if T is a "base" type in the AST 666243830Sdim/// node class hierarchies. 667239313Sdimtemplate <typename T> 668239313Sdimstruct IsBaseType { 669239313Sdim static const bool value = 670239313Sdim (llvm::is_same<T, Decl>::value || 671239313Sdim llvm::is_same<T, Stmt>::value || 672239313Sdim llvm::is_same<T, QualType>::value || 673243830Sdim llvm::is_same<T, Type>::value || 674243830Sdim llvm::is_same<T, TypeLoc>::value || 675243830Sdim llvm::is_same<T, NestedNameSpecifier>::value || 676243830Sdim llvm::is_same<T, NestedNameSpecifierLoc>::value || 677239313Sdim llvm::is_same<T, CXXCtorInitializer>::value); 678239313Sdim}; 679239313Sdimtemplate <typename T> 680239313Sdimconst bool IsBaseType<T>::value; 681239313Sdim 682239313Sdim/// \brief Interface that allows matchers to traverse the AST. 683239313Sdim/// FIXME: Find a better name. 684239313Sdim/// 685243830Sdim/// This provides three entry methods for each base node type in the AST: 686243830Sdim/// - \c matchesChildOf: 687239313Sdim/// Matches a matcher on every child node of the given node. Returns true 688239313Sdim/// if at least one child node could be matched. 689243830Sdim/// - \c matchesDescendantOf: 690239313Sdim/// Matches a matcher on all descendant nodes of the given node. Returns true 691239313Sdim/// if at least one descendant matched. 692243830Sdim/// - \c matchesAncestorOf: 693243830Sdim/// Matches a matcher on all ancestors of the given node. Returns true if 694243830Sdim/// at least one ancestor matched. 695243830Sdim/// 696243830Sdim/// FIXME: Currently we only allow Stmt and Decl nodes to start a traversal. 697243830Sdim/// In the future, we wan to implement this for all nodes for which it makes 698243830Sdim/// sense. In the case of matchesAncestorOf, we'll want to implement it for 699243830Sdim/// all nodes, as all nodes have ancestors. 700239313Sdimclass ASTMatchFinder { 701239313Sdimpublic: 702239313Sdim /// \brief Defines how we descend a level in the AST when we pass 703239313Sdim /// through expressions. 704239313Sdim enum TraversalKind { 705239313Sdim /// Will traverse any child nodes. 706239313Sdim TK_AsIs, 707239313Sdim /// Will not traverse implicit casts and parentheses. 708239313Sdim TK_IgnoreImplicitCastsAndParentheses 709239313Sdim }; 710239313Sdim 711239313Sdim /// \brief Defines how bindings are processed on recursive matches. 712239313Sdim enum BindKind { 713239313Sdim /// Stop at the first match and only bind the first match. 714239313Sdim BK_First, 715239313Sdim /// Create results for all combinations of bindings that match. 716239313Sdim BK_All 717239313Sdim }; 718239313Sdim 719243830Sdim /// \brief Defines which ancestors are considered for a match. 720243830Sdim enum AncestorMatchMode { 721243830Sdim /// All ancestors. 722243830Sdim AMM_All, 723243830Sdim /// Direct parent only. 724243830Sdim AMM_ParentOnly 725243830Sdim }; 726243830Sdim 727239313Sdim virtual ~ASTMatchFinder() {} 728239313Sdim 729239313Sdim /// \brief Returns true if the given class is directly or indirectly derived 730239313Sdim /// from a base type matching \c base. 731239313Sdim /// 732239313Sdim /// A class is considered to be also derived from itself. 733239313Sdim virtual bool classIsDerivedFrom(const CXXRecordDecl *Declaration, 734239313Sdim const Matcher<NamedDecl> &Base, 735239313Sdim BoundNodesTreeBuilder *Builder) = 0; 736239313Sdim 737243830Sdim template <typename T> 738243830Sdim bool matchesChildOf(const T &Node, 739243830Sdim const DynTypedMatcher &Matcher, 740243830Sdim BoundNodesTreeBuilder *Builder, 741243830Sdim TraversalKind Traverse, 742243830Sdim BindKind Bind) { 743243830Sdim TOOLING_COMPILE_ASSERT( 744243830Sdim (llvm::is_base_of<Decl, T>::value || 745243830Sdim llvm::is_base_of<Stmt, T>::value || 746243830Sdim llvm::is_base_of<NestedNameSpecifier, T>::value || 747243830Sdim llvm::is_base_of<NestedNameSpecifierLoc, T>::value || 748243830Sdim llvm::is_base_of<TypeLoc, T>::value || 749243830Sdim llvm::is_base_of<QualType, T>::value), 750243830Sdim unsupported_type_for_recursive_matching); 751243830Sdim return matchesChildOf(ast_type_traits::DynTypedNode::create(Node), 752243830Sdim Matcher, Builder, Traverse, Bind); 753243830Sdim } 754243830Sdim 755243830Sdim template <typename T> 756243830Sdim bool matchesDescendantOf(const T &Node, 757243830Sdim const DynTypedMatcher &Matcher, 758243830Sdim BoundNodesTreeBuilder *Builder, 759243830Sdim BindKind Bind) { 760243830Sdim TOOLING_COMPILE_ASSERT( 761243830Sdim (llvm::is_base_of<Decl, T>::value || 762243830Sdim llvm::is_base_of<Stmt, T>::value || 763243830Sdim llvm::is_base_of<NestedNameSpecifier, T>::value || 764243830Sdim llvm::is_base_of<NestedNameSpecifierLoc, T>::value || 765243830Sdim llvm::is_base_of<TypeLoc, T>::value || 766243830Sdim llvm::is_base_of<QualType, T>::value), 767243830Sdim unsupported_type_for_recursive_matching); 768243830Sdim return matchesDescendantOf(ast_type_traits::DynTypedNode::create(Node), 769243830Sdim Matcher, Builder, Bind); 770243830Sdim } 771243830Sdim 772243830Sdim // FIXME: Implement support for BindKind. 773243830Sdim template <typename T> 774243830Sdim bool matchesAncestorOf(const T &Node, 775243830Sdim const DynTypedMatcher &Matcher, 776243830Sdim BoundNodesTreeBuilder *Builder, 777243830Sdim AncestorMatchMode MatchMode) { 778243830Sdim TOOLING_COMPILE_ASSERT((llvm::is_base_of<Decl, T>::value || 779243830Sdim llvm::is_base_of<Stmt, T>::value), 780243830Sdim only_Decl_or_Stmt_allowed_for_recursive_matching); 781243830Sdim return matchesAncestorOf(ast_type_traits::DynTypedNode::create(Node), 782243830Sdim Matcher, Builder, MatchMode); 783243830Sdim } 784243830Sdim 785249423Sdim virtual ASTContext &getASTContext() const = 0; 786249423Sdim 787243830Sdimprotected: 788243830Sdim virtual bool matchesChildOf(const ast_type_traits::DynTypedNode &Node, 789243830Sdim const DynTypedMatcher &Matcher, 790239313Sdim BoundNodesTreeBuilder *Builder, 791239313Sdim TraversalKind Traverse, 792239313Sdim BindKind Bind) = 0; 793239313Sdim 794243830Sdim virtual bool matchesDescendantOf(const ast_type_traits::DynTypedNode &Node, 795243830Sdim const DynTypedMatcher &Matcher, 796239313Sdim BoundNodesTreeBuilder *Builder, 797239313Sdim BindKind Bind) = 0; 798243830Sdim 799243830Sdim virtual bool matchesAncestorOf(const ast_type_traits::DynTypedNode &Node, 800243830Sdim const DynTypedMatcher &Matcher, 801243830Sdim BoundNodesTreeBuilder *Builder, 802243830Sdim AncestorMatchMode MatchMode) = 0; 803239313Sdim}; 804239313Sdim 805263508Sdim/// \brief A type-list implementation. 806263508Sdim/// 807263508Sdim/// A list is declared as a tree of type list nodes, where the leafs are the 808263508Sdim/// types. 809263508Sdim/// However, it is used as a "linked list" of types, by using the ::head and 810263508Sdim/// ::tail typedefs. 811263508Sdim/// Each node supports up to 4 children (instead of just 2) to reduce the 812263508Sdim/// nesting required by large lists. 813263508Sdimtemplate <typename T1 = void, typename T2 = void, typename T3 = void, 814263508Sdim typename T4 = void> 815263508Sdimstruct TypeList { 816263508Sdim /// \brief Implementation detail. Combined with the specializations below, 817263508Sdim /// this typedef allows for flattening of nested structures. 818263508Sdim typedef TypeList<T1, T2, T3, T4> self; 819263508Sdim 820263508Sdim /// \brief The first type on the list. 821263508Sdim typedef T1 head; 822263508Sdim 823263508Sdim /// \brief A sub list with the tail. ie everything but the head. 824263508Sdim /// 825263508Sdim /// This type is used to do recursion. TypeList<>/EmptyTypeList indicates the 826263508Sdim /// end of the list. 827263508Sdim typedef typename TypeList<T2, T3, T4>::self tail; 828263508Sdim}; 829263508Sdim 830263508Sdim/// \brief Template specialization to allow nested lists. 831263508Sdim/// 832263508Sdim/// First element is a typelist. Pop its first element. 833263508Sdimtemplate <typename Sub1, typename Sub2, typename Sub3, typename Sub4, 834263508Sdim typename T2, typename T3, typename T4> 835263508Sdimstruct TypeList<TypeList<Sub1, Sub2, Sub3, Sub4>, T2, T3, 836263508Sdim T4> : public TypeList<Sub1, 837263508Sdim typename TypeList<Sub2, Sub3, Sub4>::self, 838263508Sdim typename TypeList<T2, T3, T4>::self> {}; 839263508Sdim 840263508Sdim/// \brief Template specialization to allow nested lists. 841263508Sdim/// 842263508Sdim/// First element is an empty typelist. Skip it. 843263508Sdimtemplate <typename T2, typename T3, typename T4> 844263508Sdimstruct TypeList<TypeList<>, T2, T3, T4> : public TypeList<T2, T3, T4> { 845263508Sdim}; 846263508Sdim 847263508Sdim/// \brief The empty type list. 848263508Sdimtypedef TypeList<> EmptyTypeList; 849263508Sdim 850263508Sdim/// \brief Helper meta-function to determine if some type \c T is present or 851263508Sdim/// a parent type in the list. 852263508Sdimtemplate <typename AnyTypeList, typename T> 853263508Sdimstruct TypeListContainsSuperOf { 854263508Sdim static const bool value = 855263508Sdim llvm::is_base_of<typename AnyTypeList::head, T>::value || 856263508Sdim TypeListContainsSuperOf<typename AnyTypeList::tail, T>::value; 857263508Sdim}; 858263508Sdimtemplate <typename T> 859263508Sdimstruct TypeListContainsSuperOf<EmptyTypeList, T> { 860263508Sdim static const bool value = false; 861263508Sdim}; 862263508Sdim 863263508Sdim/// \brief A "type list" that contains all types. 864263508Sdim/// 865263508Sdim/// Useful for matchers like \c anything and \c unless. 866263508Sdimtypedef TypeList< 867263508Sdim TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc>, 868263508Sdim TypeList<QualType, Type, TypeLoc, CXXCtorInitializer> > AllNodeBaseTypes; 869263508Sdim 870263508Sdim/// \brief Helper meta-function to extract the argument out of a function of 871263508Sdim/// type void(Arg). 872263508Sdim/// 873263508Sdim/// See AST_POLYMORPHIC_SUPPORTED_TYPES_* for details. 874263508Sdimtemplate <class T> struct ExtractFunctionArgMeta; 875263508Sdimtemplate <class T> struct ExtractFunctionArgMeta<void(T)> { 876263508Sdim typedef T type; 877263508Sdim}; 878263508Sdim 879263508Sdim/// \brief Default type lists for ArgumentAdaptingMatcher matchers. 880263508Sdimtypedef AllNodeBaseTypes AdaptativeDefaultFromTypes; 881263508Sdimtypedef TypeList<TypeList<Decl, Stmt, NestedNameSpecifier>, 882263508Sdim TypeList<NestedNameSpecifierLoc, TypeLoc, QualType> > 883263508SdimAdaptativeDefaultToTypes; 884263508Sdim 885263508Sdim/// \brief All types that are supported by HasDeclarationMatcher above. 886263508Sdimtypedef TypeList<TypeList<CallExpr, CXXConstructExpr, DeclRefExpr, EnumType>, 887263508Sdim TypeList<InjectedClassNameType, LabelStmt, MemberExpr>, 888263508Sdim TypeList<QualType, RecordType, TagType>, 889263508Sdim TypeList<TemplateSpecializationType, TemplateTypeParmType, 890263508Sdim TypedefType, UnresolvedUsingType> > 891263508SdimHasDeclarationSupportedTypes; 892263508Sdim 893239313Sdim/// \brief Converts a \c Matcher<T> to a matcher of desired type \c To by 894239313Sdim/// "adapting" a \c To into a \c T. 895239313Sdim/// 896239313Sdim/// The \c ArgumentAdapterT argument specifies how the adaptation is done. 897239313Sdim/// 898239313Sdim/// For example: 899239313Sdim/// \c ArgumentAdaptingMatcher<HasMatcher, T>(InnerMatcher); 900239313Sdim/// Given that \c InnerMatcher is of type \c Matcher<T>, this returns a matcher 901239313Sdim/// that is convertible into any matcher of type \c To by constructing 902239313Sdim/// \c HasMatcher<To, T>(InnerMatcher). 903239313Sdim/// 904239313Sdim/// If a matcher does not need knowledge about the inner type, prefer to use 905239313Sdim/// PolymorphicMatcherWithParam1. 906239313Sdimtemplate <template <typename ToArg, typename FromArg> class ArgumentAdapterT, 907263508Sdim typename FromTypes = AdaptativeDefaultFromTypes, 908263508Sdim typename ToTypes = AdaptativeDefaultToTypes> 909263508Sdimstruct ArgumentAdaptingMatcherFunc { 910263508Sdim template <typename T> class Adaptor { 911263508Sdim public: 912263508Sdim explicit Adaptor(const Matcher<T> &InnerMatcher) 913263508Sdim : InnerMatcher(InnerMatcher) {} 914239313Sdim 915263508Sdim typedef ToTypes ReturnTypes; 916263508Sdim 917263508Sdim template <typename To> operator Matcher<To>() const { 918263508Sdim return Matcher<To>(new ArgumentAdapterT<To, T>(InnerMatcher)); 919263508Sdim } 920263508Sdim 921263508Sdim private: 922263508Sdim const Matcher<T> InnerMatcher; 923263508Sdim }; 924263508Sdim 925263508Sdim template <typename T> 926263508Sdim static Adaptor<T> create(const Matcher<T> &InnerMatcher) { 927263508Sdim return Adaptor<T>(InnerMatcher); 928239313Sdim } 929239313Sdim 930263508Sdim template <typename T> 931263508Sdim Adaptor<T> operator()(const Matcher<T> &InnerMatcher) const { 932263508Sdim return create(InnerMatcher); 933263508Sdim } 934239313Sdim}; 935239313Sdim 936239313Sdim/// \brief A PolymorphicMatcherWithParamN<MatcherT, P1, ..., PN> object can be 937239313Sdim/// created from N parameters p1, ..., pN (of type P1, ..., PN) and 938239313Sdim/// used as a Matcher<T> where a MatcherT<T, P1, ..., PN>(p1, ..., pN) 939239313Sdim/// can be constructed. 940239313Sdim/// 941239313Sdim/// For example: 942239313Sdim/// - PolymorphicMatcherWithParam0<IsDefinitionMatcher>() 943239313Sdim/// creates an object that can be used as a Matcher<T> for any type T 944239313Sdim/// where an IsDefinitionMatcher<T>() can be constructed. 945239313Sdim/// - PolymorphicMatcherWithParam1<ValueEqualsMatcher, int>(42) 946239313Sdim/// creates an object that can be used as a Matcher<T> for any type T 947239313Sdim/// where a ValueEqualsMatcher<T, int>(42) can be constructed. 948263508Sdimtemplate <template <typename T> class MatcherT, 949263508Sdim typename ReturnTypesF = void(AllNodeBaseTypes)> 950239313Sdimclass PolymorphicMatcherWithParam0 { 951239313Sdimpublic: 952263508Sdim typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes; 953239313Sdim template <typename T> 954239313Sdim operator Matcher<T>() const { 955263508Sdim TOOLING_COMPILE_ASSERT((TypeListContainsSuperOf<ReturnTypes, T>::value), 956263508Sdim right_polymorphic_conversion); 957239313Sdim return Matcher<T>(new MatcherT<T>()); 958239313Sdim } 959239313Sdim}; 960239313Sdim 961239313Sdimtemplate <template <typename T, typename P1> class MatcherT, 962263508Sdim typename P1, 963263508Sdim typename ReturnTypesF = void(AllNodeBaseTypes)> 964239313Sdimclass PolymorphicMatcherWithParam1 { 965239313Sdimpublic: 966239313Sdim explicit PolymorphicMatcherWithParam1(const P1 &Param1) 967239313Sdim : Param1(Param1) {} 968239313Sdim 969263508Sdim typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes; 970263508Sdim 971239313Sdim template <typename T> 972239313Sdim operator Matcher<T>() const { 973263508Sdim TOOLING_COMPILE_ASSERT((TypeListContainsSuperOf<ReturnTypes, T>::value), 974263508Sdim right_polymorphic_conversion); 975239313Sdim return Matcher<T>(new MatcherT<T, P1>(Param1)); 976239313Sdim } 977239313Sdim 978239313Sdimprivate: 979239313Sdim const P1 Param1; 980239313Sdim}; 981239313Sdim 982239313Sdimtemplate <template <typename T, typename P1, typename P2> class MatcherT, 983263508Sdim typename P1, typename P2, 984263508Sdim typename ReturnTypesF = void(AllNodeBaseTypes)> 985239313Sdimclass PolymorphicMatcherWithParam2 { 986239313Sdimpublic: 987239313Sdim PolymorphicMatcherWithParam2(const P1 &Param1, const P2 &Param2) 988239313Sdim : Param1(Param1), Param2(Param2) {} 989239313Sdim 990263508Sdim typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes; 991263508Sdim 992239313Sdim template <typename T> 993239313Sdim operator Matcher<T>() const { 994263508Sdim TOOLING_COMPILE_ASSERT((TypeListContainsSuperOf<ReturnTypes, T>::value), 995263508Sdim right_polymorphic_conversion); 996239313Sdim return Matcher<T>(new MatcherT<T, P1, P2>(Param1, Param2)); 997239313Sdim } 998239313Sdim 999239313Sdimprivate: 1000239313Sdim const P1 Param1; 1001239313Sdim const P2 Param2; 1002239313Sdim}; 1003239313Sdim 1004239313Sdim/// \brief Matches any instance of the given NodeType. 1005239313Sdim/// 1006239313Sdim/// This is useful when a matcher syntactically requires a child matcher, 1007239313Sdim/// but the context doesn't care. See for example: anything(). 1008239313Sdim/// 1009239313Sdim/// FIXME: Alternatively we could also create a IsAMatcher or something 1010239313Sdim/// that checks that a dyn_cast is possible. This is purely needed for the 1011239313Sdim/// difference between calling for example: 1012239313Sdim/// record() 1013239313Sdim/// and 1014239313Sdim/// record(SomeMatcher) 1015239313Sdim/// In the second case we need the correct type we were dyn_cast'ed to in order 1016239313Sdim/// to get the right type for the inner matcher. In the first case we don't need 1017239313Sdim/// that, but we use the type conversion anyway and insert a TrueMatcher. 1018239313Sdimtemplate <typename T> 1019239313Sdimclass TrueMatcher : public SingleNodeMatcherInterface<T> { 1020239313Sdimpublic: 1021239313Sdim virtual bool matchesNode(const T &Node) const { 1022239313Sdim return true; 1023239313Sdim } 1024239313Sdim}; 1025239313Sdim 1026239313Sdim/// \brief Matcher<T> that wraps an inner Matcher<T> and binds the matched node 1027239313Sdim/// to an ID if the inner matcher matches on the node. 1028239313Sdimtemplate <typename T> 1029239313Sdimclass IdMatcher : public MatcherInterface<T> { 1030239313Sdimpublic: 1031239313Sdim /// \brief Creates an IdMatcher that binds to 'ID' if 'InnerMatcher' matches 1032239313Sdim /// the node. 1033239313Sdim IdMatcher(StringRef ID, const Matcher<T> &InnerMatcher) 1034239313Sdim : ID(ID), InnerMatcher(InnerMatcher) {} 1035239313Sdim 1036239313Sdim virtual bool matches(const T &Node, 1037239313Sdim ASTMatchFinder *Finder, 1038239313Sdim BoundNodesTreeBuilder *Builder) const { 1039239313Sdim bool Result = InnerMatcher.matches(Node, Finder, Builder); 1040239313Sdim if (Result) { 1041239313Sdim Builder->setBinding(ID, &Node); 1042239313Sdim } 1043239313Sdim return Result; 1044239313Sdim } 1045239313Sdim 1046239313Sdimprivate: 1047239313Sdim const std::string ID; 1048239313Sdim const Matcher<T> InnerMatcher; 1049239313Sdim}; 1050239313Sdim 1051239313Sdim/// \brief A Matcher that allows binding the node it matches to an id. 1052239313Sdim/// 1053239313Sdim/// BindableMatcher provides a \a bind() method that allows binding the 1054239313Sdim/// matched node to an id if the match was successful. 1055239313Sdimtemplate <typename T> 1056239313Sdimclass BindableMatcher : public Matcher<T> { 1057239313Sdimpublic: 1058263508Sdim explicit BindableMatcher(const Matcher<T> &M) : Matcher<T>(M) {} 1059263508Sdim explicit BindableMatcher(MatcherInterface<T> *Implementation) 1060239313Sdim : Matcher<T>(Implementation) {} 1061239313Sdim 1062239313Sdim /// \brief Returns a matcher that will bind the matched node on a match. 1063239313Sdim /// 1064239313Sdim /// The returned matcher is equivalent to this matcher, but will 1065239313Sdim /// bind the matched node on a match. 1066239313Sdim Matcher<T> bind(StringRef ID) const { 1067239313Sdim return Matcher<T>(new IdMatcher<T>(ID, *this)); 1068239313Sdim } 1069239313Sdim}; 1070239313Sdim 1071239313Sdim/// \brief Matches nodes of type T that have child nodes of type ChildT for 1072239313Sdim/// which a specified child matcher matches. 1073239313Sdim/// 1074239313Sdim/// ChildT must be an AST base type. 1075239313Sdimtemplate <typename T, typename ChildT> 1076239313Sdimclass HasMatcher : public MatcherInterface<T> { 1077239313Sdim TOOLING_COMPILE_ASSERT(IsBaseType<ChildT>::value, 1078239313Sdim has_only_accepts_base_type_matcher); 1079239313Sdimpublic: 1080239313Sdim explicit HasMatcher(const Matcher<ChildT> &ChildMatcher) 1081239313Sdim : ChildMatcher(ChildMatcher) {} 1082239313Sdim 1083239313Sdim virtual bool matches(const T &Node, 1084239313Sdim ASTMatchFinder *Finder, 1085239313Sdim BoundNodesTreeBuilder *Builder) const { 1086239313Sdim return Finder->matchesChildOf( 1087239313Sdim Node, ChildMatcher, Builder, 1088239313Sdim ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses, 1089239313Sdim ASTMatchFinder::BK_First); 1090239313Sdim } 1091239313Sdim 1092239313Sdim private: 1093243830Sdim const Matcher<ChildT> ChildMatcher; 1094239313Sdim}; 1095239313Sdim 1096239313Sdim/// \brief Matches nodes of type T that have child nodes of type ChildT for 1097239313Sdim/// which a specified child matcher matches. ChildT must be an AST base 1098239313Sdim/// type. 1099239313Sdim/// As opposed to the HasMatcher, the ForEachMatcher will produce a match 1100239313Sdim/// for each child that matches. 1101239313Sdimtemplate <typename T, typename ChildT> 1102239313Sdimclass ForEachMatcher : public MatcherInterface<T> { 1103239313Sdim TOOLING_COMPILE_ASSERT(IsBaseType<ChildT>::value, 1104239313Sdim for_each_only_accepts_base_type_matcher); 1105239313Sdim public: 1106239313Sdim explicit ForEachMatcher(const Matcher<ChildT> &ChildMatcher) 1107239313Sdim : ChildMatcher(ChildMatcher) {} 1108239313Sdim 1109239313Sdim virtual bool matches(const T& Node, 1110239313Sdim ASTMatchFinder* Finder, 1111239313Sdim BoundNodesTreeBuilder* Builder) const { 1112239313Sdim return Finder->matchesChildOf( 1113239313Sdim Node, ChildMatcher, Builder, 1114239313Sdim ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses, 1115239313Sdim ASTMatchFinder::BK_All); 1116239313Sdim } 1117239313Sdim 1118239313Sdimprivate: 1119243830Sdim const Matcher<ChildT> ChildMatcher; 1120239313Sdim}; 1121239313Sdim 1122239313Sdim/// \brief Matches nodes of type T if the given Matcher<T> does not match. 1123239313Sdim/// 1124239313Sdim/// Type argument MatcherT is required by PolymorphicMatcherWithParam1 1125239313Sdim/// but not actually used. It will always be instantiated with a type 1126239313Sdim/// convertible to Matcher<T>. 1127239313Sdimtemplate <typename T, typename MatcherT> 1128239313Sdimclass NotMatcher : public MatcherInterface<T> { 1129239313Sdimpublic: 1130239313Sdim explicit NotMatcher(const Matcher<T> &InnerMatcher) 1131239313Sdim : InnerMatcher(InnerMatcher) {} 1132239313Sdim 1133239313Sdim virtual bool matches(const T &Node, 1134239313Sdim ASTMatchFinder *Finder, 1135239313Sdim BoundNodesTreeBuilder *Builder) const { 1136263508Sdim // The 'unless' matcher will always discard the result: 1137263508Sdim // If the inner matcher doesn't match, unless returns true, 1138263508Sdim // but the inner matcher cannot have bound anything. 1139263508Sdim // If the inner matcher matches, the result is false, and 1140263508Sdim // any possible binding will be discarded. 1141263508Sdim // We still need to hand in all the bound nodes up to this 1142263508Sdim // point so the inner matcher can depend on bound nodes, 1143263508Sdim // and we need to actively discard the bound nodes, otherwise 1144263508Sdim // the inner matcher will reset the bound nodes if it doesn't 1145263508Sdim // match, but this would be inversed by 'unless'. 1146263508Sdim BoundNodesTreeBuilder Discard(*Builder); 1147263508Sdim return !InnerMatcher.matches(Node, Finder, &Discard); 1148239313Sdim } 1149239313Sdim 1150239313Sdimprivate: 1151239313Sdim const Matcher<T> InnerMatcher; 1152239313Sdim}; 1153239313Sdim 1154263508Sdim/// \brief VariadicOperatorMatcher related types. 1155263508Sdim/// @{ 1156263508Sdim 1157263508Sdim/// \brief Function signature for any variadic operator. It takes the inner 1158263508Sdim/// matchers as an array of DynTypedMatcher. 1159263508Sdimtypedef bool (*VariadicOperatorFunction)( 1160263508Sdim const ast_type_traits::DynTypedNode DynNode, ASTMatchFinder *Finder, 1161263508Sdim BoundNodesTreeBuilder *Builder, ArrayRef<DynTypedMatcher> InnerMatchers); 1162263508Sdim 1163263508Sdim/// \brief \c MatcherInterface<T> implementation for an variadic operator. 1164263508Sdimtemplate <typename T> 1165263508Sdimclass VariadicOperatorMatcherInterface : public MatcherInterface<T> { 1166239313Sdimpublic: 1167263508Sdim VariadicOperatorMatcherInterface(VariadicOperatorFunction Func, 1168263508Sdim ArrayRef<const Matcher<T> *> InputMatchers) 1169263508Sdim : Func(Func) { 1170263508Sdim for (size_t i = 0, e = InputMatchers.size(); i != e; ++i) { 1171263508Sdim InnerMatchers.push_back(*InputMatchers[i]); 1172263508Sdim } 1173263508Sdim } 1174239313Sdim 1175263508Sdim virtual bool matches(const T &Node, ASTMatchFinder *Finder, 1176239313Sdim BoundNodesTreeBuilder *Builder) const { 1177263508Sdim return Func(ast_type_traits::DynTypedNode::create(Node), Finder, Builder, 1178263508Sdim InnerMatchers); 1179239313Sdim } 1180239313Sdim 1181239313Sdimprivate: 1182263508Sdim const VariadicOperatorFunction Func; 1183263508Sdim std::vector<DynTypedMatcher> InnerMatchers; 1184239313Sdim}; 1185239313Sdim 1186263508Sdim/// \brief "No argument" placeholder to use as template paratemers. 1187263508Sdimstruct VariadicOperatorNoArg {}; 1188263508Sdim 1189263508Sdim/// \brief Polymorphic matcher object that uses a \c VariadicOperatorFunction 1190263508Sdim/// operator. 1191239313Sdim/// 1192263508Sdim/// Input matchers can have any type (including other polymorphic matcher 1193263508Sdim/// types), and the actual Matcher<T> is generated on demand with an implicit 1194263508Sdim/// coversion operator. 1195263508Sdimtemplate <typename P1, typename P2, 1196263508Sdim typename P3 = VariadicOperatorNoArg, 1197263508Sdim typename P4 = VariadicOperatorNoArg, 1198263508Sdim typename P5 = VariadicOperatorNoArg> 1199263508Sdimclass VariadicOperatorMatcher { 1200249423Sdimpublic: 1201263508Sdim VariadicOperatorMatcher(VariadicOperatorFunction Func, const P1 &Param1, 1202263508Sdim const P2 &Param2, 1203263508Sdim const P3 &Param3 = VariadicOperatorNoArg(), 1204263508Sdim const P4 &Param4 = VariadicOperatorNoArg(), 1205263508Sdim const P5 &Param5 = VariadicOperatorNoArg()) 1206263508Sdim : Func(Func), Param1(Param1), Param2(Param2), Param3(Param3), 1207263508Sdim Param4(Param4), Param5(Param5) {} 1208249423Sdim 1209263508Sdim template <typename T> operator Matcher<T>() const { 1210263508Sdim Matcher<T> *Array[5]; 1211263508Sdim size_t Size = 0; 1212249423Sdim 1213263508Sdim addMatcher<T>(Param1, Array, Size); 1214263508Sdim addMatcher<T>(Param2, Array, Size); 1215263508Sdim addMatcher<T>(Param3, Array, Size); 1216263508Sdim addMatcher<T>(Param4, Array, Size); 1217263508Sdim addMatcher<T>(Param5, Array, Size); 1218263508Sdim Matcher<T> Result(new VariadicOperatorMatcherInterface<T>( 1219263508Sdim Func, ArrayRef<const Matcher<T> *>(Array, Size))); 1220263508Sdim for (size_t i = 0, e = Size; i != e; ++i) delete Array[i]; 1221263508Sdim return Result; 1222263508Sdim } 1223249423Sdim 1224263508Sdimprivate: 1225263508Sdim template <typename T> 1226263508Sdim static void addMatcher(const Matcher<T> &M, Matcher<T> **Array, 1227263508Sdim size_t &Size) { 1228263508Sdim Array[Size++] = new Matcher<T>(M); 1229249423Sdim } 1230249423Sdim 1231263508Sdim /// \brief Overload to ignore \c VariadicOperatorNoArg arguments. 1232263508Sdim template <typename T> 1233263508Sdim static void addMatcher(VariadicOperatorNoArg, Matcher<T> **Array, 1234263508Sdim size_t &Size) {} 1235263508Sdim 1236263508Sdim const VariadicOperatorFunction Func; 1237263508Sdim const P1 Param1; 1238263508Sdim const P2 Param2; 1239263508Sdim const P3 Param3; 1240263508Sdim const P4 Param4; 1241263508Sdim const P5 Param5; 1242249423Sdim}; 1243249423Sdim 1244263508Sdim/// \brief Overloaded function object to generate VariadicOperatorMatcher 1245263508Sdim/// objects from arbitrary matchers. 1246249423Sdim/// 1247263508Sdim/// It supports 2-5 argument overloaded operator(). More can be added if needed. 1248263508Sdimstruct VariadicOperatorMatcherFunc { 1249263508Sdim VariadicOperatorFunction Func; 1250239313Sdim 1251263508Sdim template <typename M1, typename M2> 1252263508Sdim VariadicOperatorMatcher<M1, M2> operator()(const M1 &P1, const M2 &P2) const { 1253263508Sdim return VariadicOperatorMatcher<M1, M2>(Func, P1, P2); 1254239313Sdim } 1255263508Sdim template <typename M1, typename M2, typename M3> 1256263508Sdim VariadicOperatorMatcher<M1, M2, M3> operator()(const M1 &P1, const M2 &P2, 1257263508Sdim const M3 &P3) const { 1258263508Sdim return VariadicOperatorMatcher<M1, M2, M3>(Func, P1, P2, P3); 1259263508Sdim } 1260263508Sdim template <typename M1, typename M2, typename M3, typename M4> 1261263508Sdim VariadicOperatorMatcher<M1, M2, M3, M4> 1262263508Sdim operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4) const { 1263263508Sdim return VariadicOperatorMatcher<M1, M2, M3, M4>(Func, P1, P2, P3, P4); 1264263508Sdim } 1265263508Sdim template <typename M1, typename M2, typename M3, typename M4, typename M5> 1266263508Sdim VariadicOperatorMatcher<M1, M2, M3, M4, M5> 1267263508Sdim operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, 1268263508Sdim const M5 &P5) const { 1269263508Sdim return VariadicOperatorMatcher<M1, M2, M3, M4, M5>(Func, P1, P2, P3, P4, 1270263508Sdim P5); 1271263508Sdim } 1272239313Sdim}; 1273239313Sdim 1274263508Sdim/// @} 1275263508Sdim 1276263508Sdim/// \brief Matches nodes for which all provided matchers match. 1277263508Sdimbool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode, 1278263508Sdim ASTMatchFinder *Finder, 1279263508Sdim BoundNodesTreeBuilder *Builder, 1280263508Sdim ArrayRef<DynTypedMatcher> InnerMatchers); 1281263508Sdim 1282263508Sdim/// \brief Matches nodes for which at least one of the provided matchers 1283263508Sdim/// matches, but doesn't stop at the first match. 1284263508Sdimbool EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode, 1285263508Sdim ASTMatchFinder *Finder, 1286263508Sdim BoundNodesTreeBuilder *Builder, 1287263508Sdim ArrayRef<DynTypedMatcher> InnerMatchers); 1288263508Sdim 1289263508Sdim/// \brief Matches nodes for which at least one of the provided matchers 1290263508Sdim/// matches. 1291263508Sdimbool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode, 1292263508Sdim ASTMatchFinder *Finder, 1293263508Sdim BoundNodesTreeBuilder *Builder, 1294263508Sdim ArrayRef<DynTypedMatcher> InnerMatchers); 1295263508Sdim 1296243830Sdim/// \brief Creates a Matcher<T> that matches if all inner matchers match. 1297243830Sdimtemplate<typename T> 1298243830SdimBindableMatcher<T> makeAllOfComposite( 1299243830Sdim ArrayRef<const Matcher<T> *> InnerMatchers) { 1300263508Sdim return BindableMatcher<T>(new VariadicOperatorMatcherInterface<T>( 1301263508Sdim AllOfVariadicOperator, InnerMatchers)); 1302243830Sdim} 1303243830Sdim 1304239313Sdim/// \brief Creates a Matcher<T> that matches if 1305239313Sdim/// T is dyn_cast'able into InnerT and all inner matchers match. 1306239313Sdim/// 1307239313Sdim/// Returns BindableMatcher, as matchers that use dyn_cast have 1308239313Sdim/// the same object both to match on and to run submatchers on, 1309239313Sdim/// so there is no ambiguity with what gets bound. 1310239313Sdimtemplate<typename T, typename InnerT> 1311239313SdimBindableMatcher<T> makeDynCastAllOfComposite( 1312239313Sdim ArrayRef<const Matcher<InnerT> *> InnerMatchers) { 1313263508Sdim return BindableMatcher<T>(DynTypedMatcher(makeAllOfComposite(InnerMatchers)) 1314263508Sdim .unconditionalConvertTo<T>()); 1315239313Sdim} 1316239313Sdim 1317239313Sdim/// \brief Matches nodes of type T that have at least one descendant node of 1318239313Sdim/// type DescendantT for which the given inner matcher matches. 1319239313Sdim/// 1320239313Sdim/// DescendantT must be an AST base type. 1321239313Sdimtemplate <typename T, typename DescendantT> 1322239313Sdimclass HasDescendantMatcher : public MatcherInterface<T> { 1323239313Sdim TOOLING_COMPILE_ASSERT(IsBaseType<DescendantT>::value, 1324239313Sdim has_descendant_only_accepts_base_type_matcher); 1325239313Sdimpublic: 1326239313Sdim explicit HasDescendantMatcher(const Matcher<DescendantT> &DescendantMatcher) 1327239313Sdim : DescendantMatcher(DescendantMatcher) {} 1328239313Sdim 1329239313Sdim virtual bool matches(const T &Node, 1330239313Sdim ASTMatchFinder *Finder, 1331239313Sdim BoundNodesTreeBuilder *Builder) const { 1332239313Sdim return Finder->matchesDescendantOf( 1333239313Sdim Node, DescendantMatcher, Builder, ASTMatchFinder::BK_First); 1334239313Sdim } 1335239313Sdim 1336239313Sdim private: 1337243830Sdim const Matcher<DescendantT> DescendantMatcher; 1338239313Sdim}; 1339239313Sdim 1340243830Sdim/// \brief Matches nodes of type \c T that have a parent node of type \c ParentT 1341243830Sdim/// for which the given inner matcher matches. 1342243830Sdim/// 1343243830Sdim/// \c ParentT must be an AST base type. 1344243830Sdimtemplate <typename T, typename ParentT> 1345243830Sdimclass HasParentMatcher : public MatcherInterface<T> { 1346243830Sdim TOOLING_COMPILE_ASSERT(IsBaseType<ParentT>::value, 1347243830Sdim has_parent_only_accepts_base_type_matcher); 1348243830Sdimpublic: 1349243830Sdim explicit HasParentMatcher(const Matcher<ParentT> &ParentMatcher) 1350243830Sdim : ParentMatcher(ParentMatcher) {} 1351243830Sdim 1352243830Sdim virtual bool matches(const T &Node, 1353243830Sdim ASTMatchFinder *Finder, 1354243830Sdim BoundNodesTreeBuilder *Builder) const { 1355243830Sdim return Finder->matchesAncestorOf( 1356243830Sdim Node, ParentMatcher, Builder, ASTMatchFinder::AMM_ParentOnly); 1357243830Sdim } 1358243830Sdim 1359243830Sdim private: 1360243830Sdim const Matcher<ParentT> ParentMatcher; 1361243830Sdim}; 1362243830Sdim 1363243830Sdim/// \brief Matches nodes of type \c T that have at least one ancestor node of 1364243830Sdim/// type \c AncestorT for which the given inner matcher matches. 1365243830Sdim/// 1366243830Sdim/// \c AncestorT must be an AST base type. 1367243830Sdimtemplate <typename T, typename AncestorT> 1368243830Sdimclass HasAncestorMatcher : public MatcherInterface<T> { 1369243830Sdim TOOLING_COMPILE_ASSERT(IsBaseType<AncestorT>::value, 1370243830Sdim has_ancestor_only_accepts_base_type_matcher); 1371243830Sdimpublic: 1372243830Sdim explicit HasAncestorMatcher(const Matcher<AncestorT> &AncestorMatcher) 1373243830Sdim : AncestorMatcher(AncestorMatcher) {} 1374243830Sdim 1375243830Sdim virtual bool matches(const T &Node, 1376243830Sdim ASTMatchFinder *Finder, 1377243830Sdim BoundNodesTreeBuilder *Builder) const { 1378243830Sdim return Finder->matchesAncestorOf( 1379243830Sdim Node, AncestorMatcher, Builder, ASTMatchFinder::AMM_All); 1380243830Sdim } 1381243830Sdim 1382243830Sdim private: 1383243830Sdim const Matcher<AncestorT> AncestorMatcher; 1384243830Sdim}; 1385243830Sdim 1386239313Sdim/// \brief Matches nodes of type T that have at least one descendant node of 1387239313Sdim/// type DescendantT for which the given inner matcher matches. 1388239313Sdim/// 1389239313Sdim/// DescendantT must be an AST base type. 1390239313Sdim/// As opposed to HasDescendantMatcher, ForEachDescendantMatcher will match 1391239313Sdim/// for each descendant node that matches instead of only for the first. 1392239313Sdimtemplate <typename T, typename DescendantT> 1393239313Sdimclass ForEachDescendantMatcher : public MatcherInterface<T> { 1394239313Sdim TOOLING_COMPILE_ASSERT(IsBaseType<DescendantT>::value, 1395239313Sdim for_each_descendant_only_accepts_base_type_matcher); 1396239313Sdim public: 1397239313Sdim explicit ForEachDescendantMatcher( 1398239313Sdim const Matcher<DescendantT>& DescendantMatcher) 1399239313Sdim : DescendantMatcher(DescendantMatcher) {} 1400239313Sdim 1401239313Sdim virtual bool matches(const T& Node, 1402239313Sdim ASTMatchFinder* Finder, 1403239313Sdim BoundNodesTreeBuilder* Builder) const { 1404239313Sdim return Finder->matchesDescendantOf(Node, DescendantMatcher, Builder, 1405239313Sdim ASTMatchFinder::BK_All); 1406239313Sdim } 1407239313Sdim 1408239313Sdimprivate: 1409243830Sdim const Matcher<DescendantT> DescendantMatcher; 1410239313Sdim}; 1411239313Sdim 1412239313Sdim/// \brief Matches on nodes that have a getValue() method if getValue() equals 1413239313Sdim/// the value the ValueEqualsMatcher was constructed with. 1414239313Sdimtemplate <typename T, typename ValueT> 1415239313Sdimclass ValueEqualsMatcher : public SingleNodeMatcherInterface<T> { 1416239313Sdim TOOLING_COMPILE_ASSERT((llvm::is_base_of<CharacterLiteral, T>::value || 1417239313Sdim llvm::is_base_of<CXXBoolLiteralExpr, 1418239313Sdim T>::value || 1419239313Sdim llvm::is_base_of<FloatingLiteral, T>::value || 1420239313Sdim llvm::is_base_of<IntegerLiteral, T>::value), 1421239313Sdim the_node_must_have_a_getValue_method); 1422239313Sdimpublic: 1423239313Sdim explicit ValueEqualsMatcher(const ValueT &ExpectedValue) 1424239313Sdim : ExpectedValue(ExpectedValue) {} 1425239313Sdim 1426239313Sdim virtual bool matchesNode(const T &Node) const { 1427239313Sdim return Node.getValue() == ExpectedValue; 1428239313Sdim } 1429239313Sdim 1430239313Sdimprivate: 1431239313Sdim const ValueT ExpectedValue; 1432239313Sdim}; 1433239313Sdim 1434239313Sdim/// \brief A VariadicDynCastAllOfMatcher<SourceT, TargetT> object is a 1435239313Sdim/// variadic functor that takes a number of Matcher<TargetT> and returns a 1436239313Sdim/// Matcher<SourceT> that matches TargetT nodes that are matched by all of the 1437239313Sdim/// given matchers, if SourceT can be dynamically casted into TargetT. 1438239313Sdim/// 1439239313Sdim/// For example: 1440239313Sdim/// const VariadicDynCastAllOfMatcher< 1441239313Sdim/// Decl, CXXRecordDecl> record; 1442239313Sdim/// Creates a functor record(...) that creates a Matcher<Decl> given 1443239313Sdim/// a variable number of arguments of type Matcher<CXXRecordDecl>. 1444239313Sdim/// The returned matcher matches if the given Decl can by dynamically 1445239313Sdim/// casted to CXXRecordDecl and all given matchers match. 1446239313Sdimtemplate <typename SourceT, typename TargetT> 1447239313Sdimclass VariadicDynCastAllOfMatcher 1448239313Sdim : public llvm::VariadicFunction< 1449239313Sdim BindableMatcher<SourceT>, Matcher<TargetT>, 1450239313Sdim makeDynCastAllOfComposite<SourceT, TargetT> > { 1451239313Sdimpublic: 1452239313Sdim VariadicDynCastAllOfMatcher() {} 1453239313Sdim}; 1454239313Sdim 1455243830Sdim/// \brief A \c VariadicAllOfMatcher<T> object is a variadic functor that takes 1456243830Sdim/// a number of \c Matcher<T> and returns a \c Matcher<T> that matches \c T 1457243830Sdim/// nodes that are matched by all of the given matchers. 1458243830Sdim/// 1459243830Sdim/// For example: 1460243830Sdim/// const VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier; 1461243830Sdim/// Creates a functor nestedNameSpecifier(...) that creates a 1462243830Sdim/// \c Matcher<NestedNameSpecifier> given a variable number of arguments of type 1463243830Sdim/// \c Matcher<NestedNameSpecifier>. 1464243830Sdim/// The returned matcher matches if all given matchers match. 1465243830Sdimtemplate <typename T> 1466243830Sdimclass VariadicAllOfMatcher : public llvm::VariadicFunction< 1467243830Sdim BindableMatcher<T>, Matcher<T>, 1468243830Sdim makeAllOfComposite<T> > { 1469243830Sdimpublic: 1470243830Sdim VariadicAllOfMatcher() {} 1471243830Sdim}; 1472243830Sdim 1473243830Sdim/// \brief Matches nodes of type \c TLoc for which the inner 1474243830Sdim/// \c Matcher<T> matches. 1475243830Sdimtemplate <typename TLoc, typename T> 1476243830Sdimclass LocMatcher : public MatcherInterface<TLoc> { 1477243830Sdimpublic: 1478243830Sdim explicit LocMatcher(const Matcher<T> &InnerMatcher) 1479243830Sdim : InnerMatcher(InnerMatcher) {} 1480243830Sdim 1481243830Sdim virtual bool matches(const TLoc &Node, 1482243830Sdim ASTMatchFinder *Finder, 1483243830Sdim BoundNodesTreeBuilder *Builder) const { 1484243830Sdim if (!Node) 1485243830Sdim return false; 1486243830Sdim return InnerMatcher.matches(*extract(Node), Finder, Builder); 1487243830Sdim } 1488243830Sdim 1489243830Sdimprivate: 1490243830Sdim const NestedNameSpecifier *extract(const NestedNameSpecifierLoc &Loc) const { 1491243830Sdim return Loc.getNestedNameSpecifier(); 1492243830Sdim } 1493243830Sdim 1494243830Sdim const Matcher<T> InnerMatcher; 1495243830Sdim}; 1496243830Sdim 1497243830Sdim/// \brief Matches \c TypeLocs based on an inner matcher matching a certain 1498243830Sdim/// \c QualType. 1499243830Sdim/// 1500243830Sdim/// Used to implement the \c loc() matcher. 1501243830Sdimclass TypeLocTypeMatcher : public MatcherInterface<TypeLoc> { 1502243830Sdimpublic: 1503243830Sdim explicit TypeLocTypeMatcher(const Matcher<QualType> &InnerMatcher) 1504243830Sdim : InnerMatcher(InnerMatcher) {} 1505243830Sdim 1506243830Sdim virtual bool matches(const TypeLoc &Node, 1507243830Sdim ASTMatchFinder *Finder, 1508243830Sdim BoundNodesTreeBuilder *Builder) const { 1509243830Sdim if (!Node) 1510243830Sdim return false; 1511243830Sdim return InnerMatcher.matches(Node.getType(), Finder, Builder); 1512243830Sdim } 1513243830Sdim 1514243830Sdimprivate: 1515243830Sdim const Matcher<QualType> InnerMatcher; 1516243830Sdim}; 1517243830Sdim 1518243830Sdim/// \brief Matches nodes of type \c T for which the inner matcher matches on a 1519243830Sdim/// another node of type \c T that can be reached using a given traverse 1520243830Sdim/// function. 1521243830Sdimtemplate <typename T> 1522243830Sdimclass TypeTraverseMatcher : public MatcherInterface<T> { 1523243830Sdimpublic: 1524243830Sdim explicit TypeTraverseMatcher(const Matcher<QualType> &InnerMatcher, 1525243830Sdim QualType (T::*TraverseFunction)() const) 1526243830Sdim : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {} 1527243830Sdim 1528243830Sdim virtual bool matches(const T &Node, 1529243830Sdim ASTMatchFinder *Finder, 1530243830Sdim BoundNodesTreeBuilder *Builder) const { 1531243830Sdim QualType NextNode = (Node.*TraverseFunction)(); 1532243830Sdim if (NextNode.isNull()) 1533243830Sdim return false; 1534243830Sdim return InnerMatcher.matches(NextNode, Finder, Builder); 1535243830Sdim } 1536243830Sdim 1537243830Sdimprivate: 1538243830Sdim const Matcher<QualType> InnerMatcher; 1539243830Sdim QualType (T::*TraverseFunction)() const; 1540243830Sdim}; 1541243830Sdim 1542243830Sdim/// \brief Matches nodes of type \c T in a ..Loc hierarchy, for which the inner 1543243830Sdim/// matcher matches on a another node of type \c T that can be reached using a 1544243830Sdim/// given traverse function. 1545243830Sdimtemplate <typename T> 1546243830Sdimclass TypeLocTraverseMatcher : public MatcherInterface<T> { 1547243830Sdimpublic: 1548243830Sdim explicit TypeLocTraverseMatcher(const Matcher<TypeLoc> &InnerMatcher, 1549243830Sdim TypeLoc (T::*TraverseFunction)() const) 1550243830Sdim : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {} 1551243830Sdim 1552243830Sdim virtual bool matches(const T &Node, 1553243830Sdim ASTMatchFinder *Finder, 1554243830Sdim BoundNodesTreeBuilder *Builder) const { 1555243830Sdim TypeLoc NextNode = (Node.*TraverseFunction)(); 1556243830Sdim if (!NextNode) 1557243830Sdim return false; 1558243830Sdim return InnerMatcher.matches(NextNode, Finder, Builder); 1559243830Sdim } 1560243830Sdim 1561243830Sdimprivate: 1562243830Sdim const Matcher<TypeLoc> InnerMatcher; 1563243830Sdim TypeLoc (T::*TraverseFunction)() const; 1564243830Sdim}; 1565243830Sdim 1566263508Sdim/// \brief Converts a \c Matcher<InnerT> to a \c Matcher<OuterT>, where 1567263508Sdim/// \c OuterT is any type that is supported by \c Getter. 1568263508Sdim/// 1569263508Sdim/// \code Getter<OuterT>::value() \endcode returns a 1570263508Sdim/// \code InnerTBase (OuterT::*)() \endcode, which is used to adapt a \c OuterT 1571263508Sdim/// object into a \c InnerT 1572263508Sdimtemplate <typename InnerTBase, 1573263508Sdim template <typename OuterT> class Getter, 1574263508Sdim template <typename OuterT> class MatcherImpl, 1575263508Sdim typename ReturnTypesF> 1576263508Sdimclass TypeTraversePolymorphicMatcher { 1577263508Sdimprivate: 1578263508Sdim typedef TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl, 1579263508Sdim ReturnTypesF> Self; 1580263508Sdim static Self create(ArrayRef<const Matcher<InnerTBase> *> InnerMatchers); 1581263508Sdim 1582263508Sdimpublic: 1583263508Sdim typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes; 1584263508Sdim 1585263508Sdim explicit TypeTraversePolymorphicMatcher( 1586263508Sdim ArrayRef<const Matcher<InnerTBase> *> InnerMatchers) 1587263508Sdim : InnerMatcher(makeAllOfComposite(InnerMatchers)) {} 1588263508Sdim 1589263508Sdim template <typename OuterT> operator Matcher<OuterT>() const { 1590263508Sdim return Matcher<OuterT>( 1591263508Sdim new MatcherImpl<OuterT>(InnerMatcher, Getter<OuterT>::value())); 1592263508Sdim } 1593263508Sdim 1594263508Sdim struct Func : public llvm::VariadicFunction<Self, Matcher<InnerTBase>, 1595263508Sdim &Self::create> { 1596263508Sdim Func() {} 1597263508Sdim }; 1598263508Sdim 1599263508Sdimprivate: 1600263508Sdim const Matcher<InnerTBase> InnerMatcher; 1601263508Sdim}; 1602263508Sdim 1603263508Sdim// Define the create() method out of line to silence a GCC warning about 1604263508Sdim// the struct "Func" having greater visibility than its base, which comes from 1605263508Sdim// using the flag -fvisibility-inlines-hidden. 1606263508Sdimtemplate <typename InnerTBase, template <typename OuterT> class Getter, 1607263508Sdim template <typename OuterT> class MatcherImpl, typename ReturnTypesF> 1608263508SdimTypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl, ReturnTypesF> 1609263508SdimTypeTraversePolymorphicMatcher< 1610263508Sdim InnerTBase, Getter, MatcherImpl, 1611263508Sdim ReturnTypesF>::create(ArrayRef<const Matcher<InnerTBase> *> InnerMatchers) { 1612263508Sdim return Self(InnerMatchers); 1613243830Sdim} 1614243830Sdim 1615239313Sdim} // end namespace internal 1616239313Sdim} // end namespace ast_matchers 1617239313Sdim} // end namespace clang 1618239313Sdim 1619239313Sdim#endif // LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_INTERNAL_H 1620