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