clang 20.0.0git
ASTMatchersInternal.h
Go to the documentation of this file.
1//===- ASTMatchersInternal.h - Structural query framework -------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Implements the base layer of the matcher framework.
10//
11// Matchers are methods that return a Matcher<T> which provides a method
12// Matches(...) which is a predicate on an AST node. The Matches method's
13// parameters define the context of the match, which allows matchers to recurse
14// or store the current node as bound to a specific string, so that it can be
15// retrieved later.
16//
17// In general, matchers have two parts:
18// 1. A function Matcher<T> MatcherName(<arguments>) which returns a Matcher<T>
19// based on the arguments and optionally on template type deduction based
20// on the arguments. Matcher<T>s form an implicit reverse hierarchy
21// to clang's AST class hierarchy, meaning that you can use a Matcher<Base>
22// everywhere a Matcher<Derived> is required.
23// 2. An implementation of a class derived from MatcherInterface<T>.
24//
25// The matcher functions are defined in ASTMatchers.h. To make it possible
26// to implement both the matcher function and the implementation of the matcher
27// interface in one place, ASTMatcherMacros.h defines macros that allow
28// implementing a matcher in a single place.
29//
30// This file contains the base classes needed to construct the actual matchers.
31//
32//===----------------------------------------------------------------------===//
33
34#ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H
35#define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H
36
38#include "clang/AST/Decl.h"
39#include "clang/AST/DeclCXX.h"
42#include "clang/AST/Expr.h"
43#include "clang/AST/ExprCXX.h"
44#include "clang/AST/ExprObjC.h"
46#include "clang/AST/Stmt.h"
48#include "clang/AST/Type.h"
49#include "clang/AST/TypeLoc.h"
50#include "clang/Basic/LLVM.h"
52#include "llvm/ADT/APFloat.h"
53#include "llvm/ADT/ArrayRef.h"
54#include "llvm/ADT/IntrusiveRefCntPtr.h"
55#include "llvm/ADT/STLExtras.h"
56#include "llvm/ADT/SmallVector.h"
57#include "llvm/ADT/StringRef.h"
58#include "llvm/ADT/iterator.h"
59#include "llvm/Support/Casting.h"
60#include "llvm/Support/ManagedStatic.h"
61#include "llvm/Support/Regex.h"
62#include <algorithm>
63#include <cassert>
64#include <cstddef>
65#include <cstdint>
66#include <map>
67#include <memory>
68#include <optional>
69#include <string>
70#include <tuple>
71#include <type_traits>
72#include <utility>
73#include <vector>
74
75namespace clang {
76
77class ASTContext;
78
79namespace ast_matchers {
80
81class BoundNodes;
82
83namespace internal {
84
85/// A type-list implementation.
86///
87/// A "linked list" of types, accessible by using the ::head and ::tail
88/// typedefs.
89template <typename... Ts> struct TypeList {}; // Empty sentinel type list.
90
91template <typename T1, typename... Ts> struct TypeList<T1, Ts...> {
92 /// The first type on the list.
93 using head = T1;
94
95 /// A sublist with the tail. ie everything but the head.
96 ///
97 /// This type is used to do recursion. TypeList<>/EmptyTypeList indicates the
98 /// end of the list.
99 using tail = TypeList<Ts...>;
100};
101
102/// The empty type list.
103using EmptyTypeList = TypeList<>;
104
105/// Helper meta-function to determine if some type \c T is present or
106/// a parent type in the list.
107template <typename AnyTypeList, typename T> struct TypeListContainsSuperOf {
108 static const bool value =
109 std::is_base_of<typename AnyTypeList::head, T>::value ||
110 TypeListContainsSuperOf<typename AnyTypeList::tail, T>::value;
111};
112template <typename T> struct TypeListContainsSuperOf<EmptyTypeList, T> {
113 static const bool value = false;
114};
115
116/// Variadic function object.
117///
118/// Most of the functions below that use VariadicFunction could be implemented
119/// using plain C++11 variadic functions, but the function object allows us to
120/// capture it on the dynamic matcher registry.
121template <typename ResultT, typename ArgT,
122 ResultT (*Func)(ArrayRef<const ArgT *>)>
123struct VariadicFunction {
124 ResultT operator()() const { return Func({}); }
125
126 template <typename... ArgsT>
127 ResultT operator()(const ArgT &Arg1, const ArgsT &... Args) const {
128 return Execute(Arg1, static_cast<const ArgT &>(Args)...);
129 }
130
131 // We also allow calls with an already created array, in case the caller
132 // already had it.
133 ResultT operator()(ArrayRef<ArgT> Args) const {
134 return Func(llvm::to_vector<8>(llvm::make_pointer_range(Args)));
135 }
136
137private:
138 // Trampoline function to allow for implicit conversions to take place
139 // before we make the array.
140 template <typename... ArgsT> ResultT Execute(const ArgsT &... Args) const {
141 const ArgT *const ArgsArray[] = {&Args...};
142 return Func(ArrayRef<const ArgT *>(ArgsArray, sizeof...(ArgsT)));
143 }
144};
145
146/// Unifies obtaining the underlying type of a regular node through
147/// `getType` and a TypedefNameDecl node through `getUnderlyingType`.
148inline QualType getUnderlyingType(const Expr &Node) { return Node.getType(); }
149
150inline QualType getUnderlyingType(const ValueDecl &Node) {
151 return Node.getType();
152}
153inline QualType getUnderlyingType(const TypedefNameDecl &Node) {
154 return Node.getUnderlyingType();
155}
156inline QualType getUnderlyingType(const FriendDecl &Node) {
157 if (const TypeSourceInfo *TSI = Node.getFriendType())
158 return TSI->getType();
159 return QualType();
160}
161inline QualType getUnderlyingType(const CXXBaseSpecifier &Node) {
162 return Node.getType();
163}
164inline QualType getUnderlyingType(const ObjCInterfaceDecl &Node) {
165 return Node.getTypeForDecl()->getPointeeType();
166}
167
168/// Unifies obtaining a `TypeSourceInfo` from different node types.
169template <typename T,
170 std::enable_if_t<TypeListContainsSuperOf<
171 TypeList<CXXBaseSpecifier, CXXCtorInitializer,
172 CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr,
173 CompoundLiteralExpr, DeclaratorDecl, ObjCPropertyDecl,
174 TemplateArgumentLoc, TypedefNameDecl>,
175 T>::value> * = nullptr>
176inline TypeSourceInfo *GetTypeSourceInfo(const T &Node) {
177 return Node.getTypeSourceInfo();
178}
179template <typename T,
180 std::enable_if_t<TypeListContainsSuperOf<
181 TypeList<CXXFunctionalCastExpr, ExplicitCastExpr>, T>::value> * =
182 nullptr>
183inline TypeSourceInfo *GetTypeSourceInfo(const T &Node) {
184 return Node.getTypeInfoAsWritten();
185}
186inline TypeSourceInfo *GetTypeSourceInfo(const BlockDecl &Node) {
187 return Node.getSignatureAsWritten();
188}
189inline TypeSourceInfo *GetTypeSourceInfo(const CXXNewExpr &Node) {
190 return Node.getAllocatedTypeSourceInfo();
191}
192
193/// Unifies obtaining the FunctionProtoType pointer from both
194/// FunctionProtoType and FunctionDecl nodes..
195inline const FunctionProtoType *
196getFunctionProtoType(const FunctionProtoType &Node) {
197 return &Node;
198}
199
200inline const FunctionProtoType *getFunctionProtoType(const FunctionDecl &Node) {
201 return Node.getType()->getAs<FunctionProtoType>();
202}
203
204/// Unifies obtaining the access specifier from Decl and CXXBaseSpecifier nodes.
205inline clang::AccessSpecifier getAccessSpecifier(const Decl &Node) {
206 return Node.getAccess();
207}
208
209inline clang::AccessSpecifier getAccessSpecifier(const CXXBaseSpecifier &Node) {
210 return Node.getAccessSpecifier();
211}
212
213/// Internal version of BoundNodes. Holds all the bound nodes.
214class BoundNodesMap {
215public:
216 /// Adds \c Node to the map with key \c ID.
217 ///
218 /// The node's base type should be in NodeBaseType or it will be unaccessible.
219 void addNode(StringRef ID, const DynTypedNode &DynNode) {
220 NodeMap[std::string(ID)] = DynNode;
221 }
222
223 /// Returns the AST node bound to \c ID.
224 ///
225 /// Returns NULL if there was no node bound to \c ID or if there is a node but
226 /// it cannot be converted to the specified type.
227 template <typename T>
228 const T *getNodeAs(StringRef ID) const {
229 IDToNodeMap::const_iterator It = NodeMap.find(ID);
230 if (It == NodeMap.end()) {
231 return nullptr;
232 }
233 return It->second.get<T>();
234 }
235
236 DynTypedNode getNode(StringRef ID) const {
237 IDToNodeMap::const_iterator It = NodeMap.find(ID);
238 if (It == NodeMap.end()) {
239 return DynTypedNode();
240 }
241 return It->second;
242 }
243
244 /// Imposes an order on BoundNodesMaps.
245 bool operator<(const BoundNodesMap &Other) const {
246 return NodeMap < Other.NodeMap;
247 }
248
249 /// A map from IDs to the bound nodes.
250 ///
251 /// Note that we're using std::map here, as for memoization:
252 /// - we need a comparison operator
253 /// - we need an assignment operator
254 using IDToNodeMap = std::map<std::string, DynTypedNode, std::less<>>;
255
256 const IDToNodeMap &getMap() const {
257 return NodeMap;
258 }
259
260 /// Returns \c true if this \c BoundNodesMap can be compared, i.e. all
261 /// stored nodes have memoization data.
262 bool isComparable() const {
263 for (const auto &IDAndNode : NodeMap) {
264 if (!IDAndNode.second.getMemoizationData())
265 return false;
266 }
267 return true;
268 }
269
270private:
271 IDToNodeMap NodeMap;
272};
273
274/// Creates BoundNodesTree objects.
275///
276/// The tree builder is used during the matching process to insert the bound
277/// nodes from the Id matcher.
278class BoundNodesTreeBuilder {
279public:
280 /// A visitor interface to visit all BoundNodes results for a
281 /// BoundNodesTree.
282 class Visitor {
283 public:
284 virtual ~Visitor() = default;
285
286 /// Called multiple times during a single call to VisitMatches(...).
287 ///
288 /// 'BoundNodesView' contains the bound nodes for a single match.
289 virtual void visitMatch(const BoundNodes& BoundNodesView) = 0;
290 };
291
292 /// Add a binding from an id to a node.
293 void setBinding(StringRef Id, const DynTypedNode &DynNode) {
294 if (Bindings.empty())
295 Bindings.emplace_back();
296 for (BoundNodesMap &Binding : Bindings)
297 Binding.addNode(Id, DynNode);
298 }
299
300 /// Adds a branch in the tree.
301 void addMatch(const BoundNodesTreeBuilder &Bindings);
302
303 /// Visits all matches that this BoundNodesTree represents.
304 ///
305 /// The ownership of 'ResultVisitor' remains at the caller.
306 void visitMatches(Visitor* ResultVisitor);
307
308 template <typename ExcludePredicate>
309 bool removeBindings(const ExcludePredicate &Predicate) {
310 llvm::erase_if(Bindings, Predicate);
311 return !Bindings.empty();
312 }
313
314 /// Imposes an order on BoundNodesTreeBuilders.
315 bool operator<(const BoundNodesTreeBuilder &Other) const {
316 return Bindings < Other.Bindings;
317 }
318
319 /// Returns \c true if this \c BoundNodesTreeBuilder can be compared,
320 /// i.e. all stored node maps have memoization data.
321 bool isComparable() const {
322 for (const BoundNodesMap &NodesMap : Bindings) {
323 if (!NodesMap.isComparable())
324 return false;
325 }
326 return true;
327 }
328
329private:
330 SmallVector<BoundNodesMap, 1> Bindings;
331};
332
333class ASTMatchFinder;
334
335/// Generic interface for all matchers.
336///
337/// Used by the implementation of Matcher<T> and DynTypedMatcher.
338/// In general, implement MatcherInterface<T> or SingleNodeMatcherInterface<T>
339/// instead.
340class DynMatcherInterface
341 : public llvm::ThreadSafeRefCountedBase<DynMatcherInterface> {
342public:
343 virtual ~DynMatcherInterface() = default;
344
345 /// Returns true if \p DynNode can be matched.
346 ///
347 /// May bind \p DynNode to an ID via \p Builder, or recurse into
348 /// the AST via \p Finder.
349 virtual bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
350 BoundNodesTreeBuilder *Builder) const = 0;
351
352 virtual std::optional<clang::TraversalKind> TraversalKind() const {
353 return std::nullopt;
354 }
355};
356
357/// Generic interface for matchers on an AST node of type T.
358///
359/// Implement this if your matcher may need to inspect the children or
360/// descendants of the node or bind matched nodes to names. If you are
361/// writing a simple matcher that only inspects properties of the
362/// current node and doesn't care about its children or descendants,
363/// implement SingleNodeMatcherInterface instead.
364template <typename T>
365class MatcherInterface : public DynMatcherInterface {
366public:
367 /// Returns true if 'Node' can be matched.
368 ///
369 /// May bind 'Node' to an ID via 'Builder', or recurse into
370 /// the AST via 'Finder'.
371 virtual bool matches(const T &Node,
372 ASTMatchFinder *Finder,
373 BoundNodesTreeBuilder *Builder) const = 0;
374
375 bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
376 BoundNodesTreeBuilder *Builder) const override {
377 return matches(DynNode.getUnchecked<T>(), Finder, Builder);
378 }
379};
380
381/// Interface for matchers that only evaluate properties on a single
382/// node.
383template <typename T>
384class SingleNodeMatcherInterface : public MatcherInterface<T> {
385public:
386 /// Returns true if the matcher matches the provided node.
387 ///
388 /// A subclass must implement this instead of Matches().
389 virtual bool matchesNode(const T &Node) const = 0;
390
391private:
392 /// Implements MatcherInterface::Matches.
393 bool matches(const T &Node,
394 ASTMatchFinder * /* Finder */,
395 BoundNodesTreeBuilder * /* Builder */) const override {
396 return matchesNode(Node);
397 }
398};
399
400template <typename> class Matcher;
401
402/// Matcher that works on a \c DynTypedNode.
403///
404/// It is constructed from a \c Matcher<T> object and redirects most calls to
405/// underlying matcher.
406/// It checks whether the \c DynTypedNode is convertible into the type of the
407/// underlying matcher and then do the actual match on the actual node, or
408/// return false if it is not convertible.
409class DynTypedMatcher {
410public:
411 /// Takes ownership of the provided implementation pointer.
412 template <typename T>
413 DynTypedMatcher(MatcherInterface<T> *Implementation)
414 : SupportedKind(ASTNodeKind::getFromNodeKind<T>()),
415 RestrictKind(SupportedKind), Implementation(Implementation) {}
416
417 /// Construct from a variadic function.
418 enum VariadicOperator {
419 /// Matches nodes for which all provided matchers match.
420 VO_AllOf,
421
422 /// Matches nodes for which at least one of the provided matchers
423 /// matches.
424 VO_AnyOf,
425
426 /// Matches nodes for which at least one of the provided matchers
427 /// matches, but doesn't stop at the first match.
428 VO_EachOf,
429
430 /// Matches any node but executes all inner matchers to find result
431 /// bindings.
432 VO_Optionally,
433
434 /// Matches nodes that do not match the provided matcher.
435 ///
436 /// Uses the variadic matcher interface, but fails if
437 /// InnerMatchers.size() != 1.
438 VO_UnaryNot
439 };
440
441 static DynTypedMatcher
442 constructVariadic(VariadicOperator Op, ASTNodeKind SupportedKind,
443 std::vector<DynTypedMatcher> InnerMatchers);
444
445 static DynTypedMatcher
446 constructRestrictedWrapper(const DynTypedMatcher &InnerMatcher,
447 ASTNodeKind RestrictKind);
448
449 /// Get a "true" matcher for \p NodeKind.
450 ///
451 /// It only checks that the node is of the right kind.
452 static DynTypedMatcher trueMatcher(ASTNodeKind NodeKind);
453
454 void setAllowBind(bool AB) { AllowBind = AB; }
455
456 /// Check whether this matcher could ever match a node of kind \p Kind.
457 /// \return \c false if this matcher will never match such a node. Otherwise,
458 /// return \c true.
459 bool canMatchNodesOfKind(ASTNodeKind Kind) const;
460
461 /// Return a matcher that points to the same implementation, but
462 /// restricts the node types for \p Kind.
463 DynTypedMatcher dynCastTo(const ASTNodeKind Kind) const;
464
465 /// Return a matcher that points to the same implementation, but sets the
466 /// traversal kind.
467 ///
468 /// If the traversal kind is already set, then \c TK overrides it.
469 DynTypedMatcher withTraversalKind(TraversalKind TK);
470
471 /// Returns true if the matcher matches the given \c DynNode.
472 bool matches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
473 BoundNodesTreeBuilder *Builder) const;
474
475 /// Same as matches(), but skips the kind check.
476 ///
477 /// It is faster, but the caller must ensure the node is valid for the
478 /// kind of this matcher.
479 bool matchesNoKindCheck(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
480 BoundNodesTreeBuilder *Builder) const;
481
482 /// Bind the specified \p ID to the matcher.
483 /// \return A new matcher with the \p ID bound to it if this matcher supports
484 /// binding. Otherwise, returns an empty \c std::optional<>.
485 std::optional<DynTypedMatcher> tryBind(StringRef ID) const;
486
487 /// Returns a unique \p ID for the matcher.
488 ///
489 /// Casting a Matcher<T> to Matcher<U> creates a matcher that has the
490 /// same \c Implementation pointer, but different \c RestrictKind. We need to
491 /// include both in the ID to make it unique.
492 ///
493 /// \c MatcherIDType supports operator< and provides strict weak ordering.
494 using MatcherIDType = std::pair<ASTNodeKind, uint64_t>;
495 MatcherIDType getID() const {
496 /// FIXME: Document the requirements this imposes on matcher
497 /// implementations (no new() implementation_ during a Matches()).
498 return std::make_pair(RestrictKind,
499 reinterpret_cast<uint64_t>(Implementation.get()));
500 }
501
502 /// Returns the type this matcher works on.
503 ///
504 /// \c matches() will always return false unless the node passed is of this
505 /// or a derived type.
506 ASTNodeKind getSupportedKind() const { return SupportedKind; }
507
508 /// Returns \c true if the passed \c DynTypedMatcher can be converted
509 /// to a \c Matcher<T>.
510 ///
511 /// This method verifies that the underlying matcher in \c Other can process
512 /// nodes of types T.
513 template <typename T> bool canConvertTo() const {
514 return canConvertTo(ASTNodeKind::getFromNodeKind<T>());
515 }
516 bool canConvertTo(ASTNodeKind To) const;
517
518 /// Construct a \c Matcher<T> interface around the dynamic matcher.
519 ///
520 /// This method asserts that \c canConvertTo() is \c true. Callers
521 /// should call \c canConvertTo() first to make sure that \c this is
522 /// compatible with T.
523 template <typename T> Matcher<T> convertTo() const {
524 assert(canConvertTo<T>());
525 return unconditionalConvertTo<T>();
526 }
527
528 /// Same as \c convertTo(), but does not check that the underlying
529 /// matcher can handle a value of T.
530 ///
531 /// If it is not compatible, then this matcher will never match anything.
532 template <typename T> Matcher<T> unconditionalConvertTo() const;
533
534 /// Returns the \c TraversalKind respected by calls to `match()`, if any.
535 ///
536 /// Most matchers will not have a traversal kind set, instead relying on the
537 /// surrounding context. For those, \c std::nullopt is returned.
538 std::optional<clang::TraversalKind> getTraversalKind() const {
539 return Implementation->TraversalKind();
540 }
541
542private:
543 DynTypedMatcher(ASTNodeKind SupportedKind, ASTNodeKind RestrictKind,
544 IntrusiveRefCntPtr<DynMatcherInterface> Implementation)
545 : SupportedKind(SupportedKind), RestrictKind(RestrictKind),
546 Implementation(std::move(Implementation)) {}
547
548 bool AllowBind = false;
549 ASTNodeKind SupportedKind;
550
551 /// A potentially stricter node kind.
552 ///
553 /// It allows to perform implicit and dynamic cast of matchers without
554 /// needing to change \c Implementation.
555 ASTNodeKind RestrictKind;
556 IntrusiveRefCntPtr<DynMatcherInterface> Implementation;
557};
558
559/// Wrapper of a MatcherInterface<T> *that allows copying.
560///
561/// A Matcher<Base> can be used anywhere a Matcher<Derived> is
562/// required. This establishes an is-a relationship which is reverse
563/// to the AST hierarchy. In other words, Matcher<T> is contravariant
564/// with respect to T. The relationship is built via a type conversion
565/// operator rather than a type hierarchy to be able to templatize the
566/// type hierarchy instead of spelling it out.
567template <typename T>
568class Matcher {
569public:
570 /// Takes ownership of the provided implementation pointer.
571 explicit Matcher(MatcherInterface<T> *Implementation)
572 : Implementation(Implementation) {}
573
574 /// Implicitly converts \c Other to a Matcher<T>.
575 ///
576 /// Requires \c T to be derived from \c From.
577 template <typename From>
578 Matcher(const Matcher<From> &Other,
579 std::enable_if_t<std::is_base_of<From, T>::value &&
580 !std::is_same<From, T>::value> * = nullptr)
581 : Implementation(restrictMatcher(Other.Implementation)) {
582 assert(Implementation.getSupportedKind().isSame(
583 ASTNodeKind::getFromNodeKind<T>()));
584 }
585
586 /// Implicitly converts \c Matcher<Type> to \c Matcher<QualType>.
587 ///
588 /// The resulting matcher is not strict, i.e. ignores qualifiers.
589 template <typename TypeT>
590 Matcher(const Matcher<TypeT> &Other,
591 std::enable_if_t<std::is_same<T, QualType>::value &&
592 std::is_same<TypeT, Type>::value> * = nullptr)
593 : Implementation(new TypeToQualType<TypeT>(Other)) {}
594
595 /// Convert \c this into a \c Matcher<T> by applying dyn_cast<> to the
596 /// argument.
597 /// \c To must be a base class of \c T.
598 template <typename To> Matcher<To> dynCastTo() const & {
599 static_assert(std::is_base_of<To, T>::value, "Invalid dynCast call.");
600 return Matcher<To>(Implementation);
601 }
602
603 template <typename To> Matcher<To> dynCastTo() && {
604 static_assert(std::is_base_of<To, T>::value, "Invalid dynCast call.");
605 return Matcher<To>(std::move(Implementation));
606 }
607
608 /// Forwards the call to the underlying MatcherInterface<T> pointer.
609 bool matches(const T &Node,
610 ASTMatchFinder *Finder,
611 BoundNodesTreeBuilder *Builder) const {
612 return Implementation.matches(DynTypedNode::create(Node), Finder, Builder);
613 }
614
615 /// Returns an ID that uniquely identifies the matcher.
616 DynTypedMatcher::MatcherIDType getID() const {
617 return Implementation.getID();
618 }
619
620 /// Extract the dynamic matcher.
621 ///
622 /// The returned matcher keeps the same restrictions as \c this and remembers
623 /// that it is meant to support nodes of type \c T.
624 operator DynTypedMatcher() const & { return Implementation; }
625
626 operator DynTypedMatcher() && { return std::move(Implementation); }
627
628 /// Allows the conversion of a \c Matcher<Type> to a \c
629 /// Matcher<QualType>.
630 ///
631 /// Depending on the constructor argument, the matcher is either strict, i.e.
632 /// does only matches in the absence of qualifiers, or not, i.e. simply
633 /// ignores any qualifiers.
634 template <typename TypeT>
635 class TypeToQualType : public MatcherInterface<QualType> {
636 const DynTypedMatcher InnerMatcher;
637
638 public:
639 TypeToQualType(const Matcher<TypeT> &InnerMatcher)
640 : InnerMatcher(InnerMatcher) {}
641
642 bool matches(const QualType &Node, ASTMatchFinder *Finder,
643 BoundNodesTreeBuilder *Builder) const override {
644 if (Node.isNull())
645 return false;
646 return this->InnerMatcher.matches(DynTypedNode::create(*Node), Finder,
647 Builder);
648 }
649
650 std::optional<clang::TraversalKind> TraversalKind() const override {
651 return this->InnerMatcher.getTraversalKind();
652 }
653 };
654
655private:
656 // For Matcher<T> <=> Matcher<U> conversions.
657 template <typename U> friend class Matcher;
658
659 // For DynTypedMatcher::unconditionalConvertTo<T>.
660 friend class DynTypedMatcher;
661
662 static DynTypedMatcher restrictMatcher(const DynTypedMatcher &Other) {
663 return Other.dynCastTo(ASTNodeKind::getFromNodeKind<T>());
664 }
665
666 explicit Matcher(const DynTypedMatcher &Implementation)
667 : Implementation(restrictMatcher(Implementation)) {
668 assert(this->Implementation.getSupportedKind().isSame(
669 ASTNodeKind::getFromNodeKind<T>()));
670 }
671
672 DynTypedMatcher Implementation;
673}; // class Matcher
674
675/// A convenient helper for creating a Matcher<T> without specifying
676/// the template type argument.
677template <typename T>
678inline Matcher<T> makeMatcher(MatcherInterface<T> *Implementation) {
679 return Matcher<T>(Implementation);
680}
681
682/// Interface that allows matchers to traverse the AST.
683/// FIXME: Find a better name.
684///
685/// This provides three entry methods for each base node type in the AST:
686/// - \c matchesChildOf:
687/// Matches a matcher on every child node of the given node. Returns true
688/// if at least one child node could be matched.
689/// - \c matchesDescendantOf:
690/// Matches a matcher on all descendant nodes of the given node. Returns true
691/// if at least one descendant matched.
692/// - \c matchesAncestorOf:
693/// Matches a matcher on all ancestors of the given node. Returns true if
694/// at least one ancestor matched.
695///
696/// FIXME: Currently we only allow Stmt and Decl nodes to start a traversal.
697/// In the future, we want to implement this for all nodes for which it makes
698/// sense. In the case of matchesAncestorOf, we'll want to implement it for
699/// all nodes, as all nodes have ancestors.
700class ASTMatchFinder {
701public:
702 /// Defines how bindings are processed on recursive matches.
703 enum BindKind {
704 /// Stop at the first match and only bind the first match.
705 BK_First,
706
707 /// Create results for all combinations of bindings that match.
708 BK_All
709 };
710
711 /// Defines which ancestors are considered for a match.
712 enum AncestorMatchMode {
713 /// All ancestors.
714 AMM_All,
715
716 /// Direct parent only.
717 AMM_ParentOnly
718 };
719
720 virtual ~ASTMatchFinder() = default;
721
722 /// Returns true if the given C++ class is directly or indirectly derived
723 /// from a base type matching \c base.
724 ///
725 /// A class is not considered to be derived from itself.
726 virtual bool classIsDerivedFrom(const CXXRecordDecl *Declaration,
727 const Matcher<NamedDecl> &Base,
728 BoundNodesTreeBuilder *Builder,
729 bool Directly) = 0;
730
731 /// Returns true if the given Objective-C class is directly or indirectly
732 /// derived from a base class matching \c base.
733 ///
734 /// A class is not considered to be derived from itself.
735 virtual bool objcClassIsDerivedFrom(const ObjCInterfaceDecl *Declaration,
736 const Matcher<NamedDecl> &Base,
737 BoundNodesTreeBuilder *Builder,
738 bool Directly) = 0;
739
740 template <typename T>
741 bool matchesChildOf(const T &Node, const DynTypedMatcher &Matcher,
742 BoundNodesTreeBuilder *Builder, BindKind Bind) {
743 static_assert(std::is_base_of<Decl, T>::value ||
744 std::is_base_of<Stmt, T>::value ||
745 std::is_base_of<NestedNameSpecifier, T>::value ||
746 std::is_base_of<NestedNameSpecifierLoc, T>::value ||
747 std::is_base_of<TypeLoc, T>::value ||
748 std::is_base_of<QualType, T>::value ||
749 std::is_base_of<Attr, T>::value,
750 "unsupported type for recursive matching");
751 return matchesChildOf(DynTypedNode::create(Node), getASTContext(), Matcher,
752 Builder, Bind);
753 }
754
755 template <typename T>
756 bool matchesDescendantOf(const T &Node, const DynTypedMatcher &Matcher,
757 BoundNodesTreeBuilder *Builder, BindKind Bind) {
758 static_assert(std::is_base_of<Decl, T>::value ||
759 std::is_base_of<Stmt, T>::value ||
760 std::is_base_of<NestedNameSpecifier, T>::value ||
761 std::is_base_of<NestedNameSpecifierLoc, T>::value ||
762 std::is_base_of<TypeLoc, T>::value ||
763 std::is_base_of<QualType, T>::value ||
764 std::is_base_of<Attr, T>::value,
765 "unsupported type for recursive matching");
766 return matchesDescendantOf(DynTypedNode::create(Node), getASTContext(),
767 Matcher, Builder, Bind);
768 }
769
770 // FIXME: Implement support for BindKind.
771 template <typename T>
772 bool matchesAncestorOf(const T &Node, const DynTypedMatcher &Matcher,
773 BoundNodesTreeBuilder *Builder,
774 AncestorMatchMode MatchMode) {
775 static_assert(std::is_base_of<Decl, T>::value ||
776 std::is_base_of<NestedNameSpecifierLoc, T>::value ||
777 std::is_base_of<Stmt, T>::value ||
778 std::is_base_of<TypeLoc, T>::value ||
779 std::is_base_of<Attr, T>::value,
780 "type not allowed for recursive matching");
781 return matchesAncestorOf(DynTypedNode::create(Node), getASTContext(),
782 Matcher, Builder, MatchMode);
783 }
784
785 virtual ASTContext &getASTContext() const = 0;
786
787 virtual bool IsMatchingInASTNodeNotSpelledInSource() const = 0;
788
789 virtual bool IsMatchingInASTNodeNotAsIs() const = 0;
790
791 bool isTraversalIgnoringImplicitNodes() const;
792
793protected:
794 virtual bool matchesChildOf(const DynTypedNode &Node, ASTContext &Ctx,
795 const DynTypedMatcher &Matcher,
796 BoundNodesTreeBuilder *Builder,
797 BindKind Bind) = 0;
798
799 virtual bool matchesDescendantOf(const DynTypedNode &Node, ASTContext &Ctx,
800 const DynTypedMatcher &Matcher,
801 BoundNodesTreeBuilder *Builder,
802 BindKind Bind) = 0;
803
804 virtual bool matchesAncestorOf(const DynTypedNode &Node, ASTContext &Ctx,
805 const DynTypedMatcher &Matcher,
806 BoundNodesTreeBuilder *Builder,
807 AncestorMatchMode MatchMode) = 0;
808private:
809 friend struct ASTChildrenNotSpelledInSourceScope;
810 virtual bool isMatchingChildrenNotSpelledInSource() const = 0;
811 virtual void setMatchingChildrenNotSpelledInSource(bool Set) = 0;
812};
813
814struct ASTChildrenNotSpelledInSourceScope {
815 ASTChildrenNotSpelledInSourceScope(ASTMatchFinder *V, bool B)
816 : MV(V), MB(V->isMatchingChildrenNotSpelledInSource()) {
817 V->setMatchingChildrenNotSpelledInSource(B);
818 }
819 ~ASTChildrenNotSpelledInSourceScope() {
820 MV->setMatchingChildrenNotSpelledInSource(MB);
821 }
822
823private:
824 ASTMatchFinder *MV;
825 bool MB;
826};
827
828/// Specialization of the conversion functions for QualType.
829///
830/// This specialization provides the Matcher<Type>->Matcher<QualType>
831/// conversion that the static API does.
832template <>
833inline Matcher<QualType> DynTypedMatcher::convertTo<QualType>() const {
834 assert(canConvertTo<QualType>());
835 const ASTNodeKind SourceKind = getSupportedKind();
836 if (SourceKind.isSame(ASTNodeKind::getFromNodeKind<Type>())) {
837 // We support implicit conversion from Matcher<Type> to Matcher<QualType>
838 return unconditionalConvertTo<Type>();
839 }
840 return unconditionalConvertTo<QualType>();
841}
842
843/// Finds the first node in a range that matches the given matcher.
844template <typename MatcherT, typename IteratorT>
845IteratorT matchesFirstInRange(const MatcherT &Matcher, IteratorT Start,
846 IteratorT End, ASTMatchFinder *Finder,
847 BoundNodesTreeBuilder *Builder) {
848 for (IteratorT I = Start; I != End; ++I) {
849 BoundNodesTreeBuilder Result(*Builder);
850 if (Matcher.matches(*I, Finder, &Result)) {
851 *Builder = std::move(Result);
852 return I;
853 }
854 }
855 return End;
856}
857
858/// Finds the first node in a pointer range that matches the given
859/// matcher.
860template <typename MatcherT, typename IteratorT>
861IteratorT matchesFirstInPointerRange(const MatcherT &Matcher, IteratorT Start,
862 IteratorT End, ASTMatchFinder *Finder,
863 BoundNodesTreeBuilder *Builder) {
864 for (IteratorT I = Start; I != End; ++I) {
865 BoundNodesTreeBuilder Result(*Builder);
866 if (Matcher.matches(**I, Finder, &Result)) {
867 *Builder = std::move(Result);
868 return I;
869 }
870 }
871 return End;
872}
873
874template <typename T, std::enable_if_t<!std::is_base_of<FunctionDecl, T>::value>
875 * = nullptr>
876inline bool isDefaultedHelper(const T *) {
877 return false;
878}
879inline bool isDefaultedHelper(const FunctionDecl *FD) {
880 return FD->isDefaulted();
881}
882
883// Metafunction to determine if type T has a member called getDecl.
884template <typename Ty>
885class has_getDecl {
886 using yes = char[1];
887 using no = char[2];
888
889 template <typename Inner>
890 static yes& test(Inner *I, decltype(I->getDecl()) * = nullptr);
891
892 template <typename>
893 static no& test(...);
894
895public:
896 static const bool value = sizeof(test<Ty>(nullptr)) == sizeof(yes);
897};
898
899/// Matches overloaded operators with a specific name.
900///
901/// The type argument ArgT is not used by this matcher but is used by
902/// PolymorphicMatcher and should be StringRef.
903template <typename T, typename ArgT>
904class HasOverloadedOperatorNameMatcher : public SingleNodeMatcherInterface<T> {
905 static_assert(std::is_same<T, CXXOperatorCallExpr>::value ||
906 std::is_base_of<FunctionDecl, T>::value,
907 "unsupported class for matcher");
908 static_assert(std::is_same<ArgT, std::vector<std::string>>::value,
909 "argument type must be std::vector<std::string>");
910
911public:
912 explicit HasOverloadedOperatorNameMatcher(std::vector<std::string> Names)
913 : SingleNodeMatcherInterface<T>(), Names(std::move(Names)) {}
914
915 bool matchesNode(const T &Node) const override {
916 return matchesSpecialized(Node);
917 }
918
919private:
920
921 /// CXXOperatorCallExpr exist only for calls to overloaded operators
922 /// so this function returns true if the call is to an operator of the given
923 /// name.
924 bool matchesSpecialized(const CXXOperatorCallExpr &Node) const {
925 return llvm::is_contained(Names, getOperatorSpelling(Node.getOperator()));
926 }
927
928 /// Returns true only if CXXMethodDecl represents an overloaded
929 /// operator and has the given operator name.
930 bool matchesSpecialized(const FunctionDecl &Node) const {
931 return Node.isOverloadedOperator() &&
932 llvm::is_contained(
933 Names, getOperatorSpelling(Node.getOverloadedOperator()));
934 }
935
936 std::vector<std::string> Names;
937};
938
939/// Matches named declarations with a specific name.
940///
941/// See \c hasName() and \c hasAnyName() in ASTMatchers.h for details.
942class HasNameMatcher : public SingleNodeMatcherInterface<NamedDecl> {
943 public:
944 explicit HasNameMatcher(std::vector<std::string> Names);
945
946 bool matchesNode(const NamedDecl &Node) const override;
947
948private:
949 /// Unqualified match routine.
950 ///
951 /// It is much faster than the full match, but it only works for unqualified
952 /// matches.
953 bool matchesNodeUnqualified(const NamedDecl &Node) const;
954
955 /// Full match routine
956 ///
957 /// Fast implementation for the simple case of a named declaration at
958 /// namespace or RecordDecl scope.
959 /// It is slower than matchesNodeUnqualified, but faster than
960 /// matchesNodeFullSlow.
961 bool matchesNodeFullFast(const NamedDecl &Node) const;
962
963 /// Full match routine
964 ///
965 /// It generates the fully qualified name of the declaration (which is
966 /// expensive) before trying to match.
967 /// It is slower but simple and works on all cases.
968 bool matchesNodeFullSlow(const NamedDecl &Node) const;
969
970 bool UseUnqualifiedMatch;
971 std::vector<std::string> Names;
972};
973
974/// Trampoline function to use VariadicFunction<> to construct a
975/// HasNameMatcher.
976Matcher<NamedDecl> hasAnyNameFunc(ArrayRef<const StringRef *> NameRefs);
977
978/// Trampoline function to use VariadicFunction<> to construct a
979/// hasAnySelector matcher.
980Matcher<ObjCMessageExpr> hasAnySelectorFunc(
981 ArrayRef<const StringRef *> NameRefs);
982
983/// Matches declarations for QualType and CallExpr.
984///
985/// Type argument DeclMatcherT is required by PolymorphicMatcher but
986/// not actually used.
987template <typename T, typename DeclMatcherT>
988class HasDeclarationMatcher : public MatcherInterface<T> {
989 static_assert(std::is_same<DeclMatcherT, Matcher<Decl>>::value,
990 "instantiated with wrong types");
991
992 DynTypedMatcher InnerMatcher;
993
994public:
995 explicit HasDeclarationMatcher(const Matcher<Decl> &InnerMatcher)
996 : InnerMatcher(InnerMatcher) {}
997
998 bool matches(const T &Node, ASTMatchFinder *Finder,
999 BoundNodesTreeBuilder *Builder) const override {
1000 return matchesSpecialized(Node, Finder, Builder);
1001 }
1002
1003private:
1004 /// Forwards to matching on the underlying type of the QualType.
1005 bool matchesSpecialized(const QualType &Node, ASTMatchFinder *Finder,
1006 BoundNodesTreeBuilder *Builder) const {
1007 if (Node.isNull())
1008 return false;
1009
1010 return matchesSpecialized(*Node, Finder, Builder);
1011 }
1012
1013 /// Finds the best declaration for a type and returns whether the inner
1014 /// matcher matches on it.
1015 bool matchesSpecialized(const Type &Node, ASTMatchFinder *Finder,
1016 BoundNodesTreeBuilder *Builder) const {
1017 // DeducedType does not have declarations of its own, so
1018 // match the deduced type instead.
1019 if (const auto *S = dyn_cast<DeducedType>(&Node)) {
1020 QualType DT = S->getDeducedType();
1021 return !DT.isNull() ? matchesSpecialized(*DT, Finder, Builder) : false;
1022 }
1023
1024 // First, for any types that have a declaration, extract the declaration and
1025 // match on it.
1026 if (const auto *S = dyn_cast<TagType>(&Node)) {
1027 return matchesDecl(S->getDecl(), Finder, Builder);
1028 }
1029 if (const auto *S = dyn_cast<InjectedClassNameType>(&Node)) {
1030 return matchesDecl(S->getDecl(), Finder, Builder);
1031 }
1032 if (const auto *S = dyn_cast<TemplateTypeParmType>(&Node)) {
1033 return matchesDecl(S->getDecl(), Finder, Builder);
1034 }
1035 if (const auto *S = dyn_cast<TypedefType>(&Node)) {
1036 return matchesDecl(S->getDecl(), Finder, Builder);
1037 }
1038 if (const auto *S = dyn_cast<UnresolvedUsingType>(&Node)) {
1039 return matchesDecl(S->getDecl(), Finder, Builder);
1040 }
1041 if (const auto *S = dyn_cast<ObjCObjectType>(&Node)) {
1042 return matchesDecl(S->getInterface(), Finder, Builder);
1043 }
1044
1045 // A SubstTemplateTypeParmType exists solely to mark a type substitution
1046 // on the instantiated template. As users usually want to match the
1047 // template parameter on the uninitialized template, we can always desugar
1048 // one level without loss of expressivness.
1049 // For example, given:
1050 // template<typename T> struct X { T t; } class A {}; X<A> a;
1051 // The following matcher will match, which otherwise would not:
1052 // fieldDecl(hasType(pointerType())).
1053 if (const auto *S = dyn_cast<SubstTemplateTypeParmType>(&Node)) {
1054 return matchesSpecialized(S->getReplacementType(), Finder, Builder);
1055 }
1056
1057 // For template specialization types, we want to match the template
1058 // declaration, as long as the type is still dependent, and otherwise the
1059 // declaration of the instantiated tag type.
1060 if (const auto *S = dyn_cast<TemplateSpecializationType>(&Node)) {
1061 if (!S->isTypeAlias() && S->isSugared()) {
1062 // If the template is non-dependent, we want to match the instantiated
1063 // tag type.
1064 // For example, given:
1065 // template<typename T> struct X {}; X<int> a;
1066 // The following matcher will match, which otherwise would not:
1067 // templateSpecializationType(hasDeclaration(cxxRecordDecl())).
1068 return matchesSpecialized(*S->desugar(), Finder, Builder);
1069 }
1070 // If the template is dependent or an alias, match the template
1071 // declaration.
1072 return matchesDecl(S->getTemplateName().getAsTemplateDecl(), Finder,
1073 Builder);
1074 }
1075
1076 // FIXME: We desugar elaborated types. This makes the assumption that users
1077 // do never want to match on whether a type is elaborated - there are
1078 // arguments for both sides; for now, continue desugaring.
1079 if (const auto *S = dyn_cast<ElaboratedType>(&Node)) {
1080 return matchesSpecialized(S->desugar(), Finder, Builder);
1081 }
1082 // Similarly types found via using declarations.
1083 // These are *usually* meaningless sugar, and this matches the historical
1084 // behavior prior to the introduction of UsingType.
1085 if (const auto *S = dyn_cast<UsingType>(&Node)) {
1086 return matchesSpecialized(S->desugar(), Finder, Builder);
1087 }
1088 return false;
1089 }
1090
1091 /// Extracts the Decl the DeclRefExpr references and returns whether
1092 /// the inner matcher matches on it.
1093 bool matchesSpecialized(const DeclRefExpr &Node, ASTMatchFinder *Finder,
1094 BoundNodesTreeBuilder *Builder) const {
1095 return matchesDecl(Node.getDecl(), Finder, Builder);
1096 }
1097
1098 /// Extracts the Decl of the callee of a CallExpr and returns whether
1099 /// the inner matcher matches on it.
1100 bool matchesSpecialized(const CallExpr &Node, ASTMatchFinder *Finder,
1101 BoundNodesTreeBuilder *Builder) const {
1102 return matchesDecl(Node.getCalleeDecl(), Finder, Builder);
1103 }
1104
1105 /// Extracts the Decl of the constructor call and returns whether the
1106 /// inner matcher matches on it.
1107 bool matchesSpecialized(const CXXConstructExpr &Node,
1108 ASTMatchFinder *Finder,
1109 BoundNodesTreeBuilder *Builder) const {
1110 return matchesDecl(Node.getConstructor(), Finder, Builder);
1111 }
1112
1113 bool matchesSpecialized(const ObjCIvarRefExpr &Node,
1114 ASTMatchFinder *Finder,
1115 BoundNodesTreeBuilder *Builder) const {
1116 return matchesDecl(Node.getDecl(), Finder, Builder);
1117 }
1118
1119 bool matchesSpecialized(const ObjCInterfaceDecl &Node, ASTMatchFinder *Finder,
1120 BoundNodesTreeBuilder *Builder) const {
1121 return matchesDecl(Node.getCanonicalDecl(), Finder, Builder);
1122 }
1123
1124 /// Extracts the operator new of the new call and returns whether the
1125 /// inner matcher matches on it.
1126 bool matchesSpecialized(const CXXNewExpr &Node,
1127 ASTMatchFinder *Finder,
1128 BoundNodesTreeBuilder *Builder) const {
1129 return matchesDecl(Node.getOperatorNew(), Finder, Builder);
1130 }
1131
1132 /// Extracts the \c ValueDecl a \c MemberExpr refers to and returns
1133 /// whether the inner matcher matches on it.
1134 bool matchesSpecialized(const MemberExpr &Node,
1135 ASTMatchFinder *Finder,
1136 BoundNodesTreeBuilder *Builder) const {
1137 return matchesDecl(Node.getMemberDecl(), Finder, Builder);
1138 }
1139
1140 /// Extracts the \c LabelDecl a \c AddrLabelExpr refers to and returns
1141 /// whether the inner matcher matches on it.
1142 bool matchesSpecialized(const AddrLabelExpr &Node,
1143 ASTMatchFinder *Finder,
1144 BoundNodesTreeBuilder *Builder) const {
1145 return matchesDecl(Node.getLabel(), Finder, Builder);
1146 }
1147
1148 /// Extracts the declaration of a LabelStmt and returns whether the
1149 /// inner matcher matches on it.
1150 bool matchesSpecialized(const LabelStmt &Node, ASTMatchFinder *Finder,
1151 BoundNodesTreeBuilder *Builder) const {
1152 return matchesDecl(Node.getDecl(), Finder, Builder);
1153 }
1154
1155 /// Returns whether the inner matcher \c Node. Returns false if \c Node
1156 /// is \c NULL.
1157 bool matchesDecl(const Decl *Node, ASTMatchFinder *Finder,
1158 BoundNodesTreeBuilder *Builder) const {
1159 return Node != nullptr &&
1160 !(Finder->isTraversalIgnoringImplicitNodes() &&
1161 Node->isImplicit()) &&
1162 this->InnerMatcher.matches(DynTypedNode::create(*Node), Finder,
1163 Builder);
1164 }
1165};
1166
1167/// IsBaseType<T>::value is true if T is a "base" type in the AST
1168/// node class hierarchies.
1169template <typename T>
1170struct IsBaseType {
1171 static const bool value =
1172 std::is_same<T, Decl>::value || std::is_same<T, Stmt>::value ||
1173 std::is_same<T, QualType>::value || std::is_same<T, Type>::value ||
1174 std::is_same<T, TypeLoc>::value ||
1175 std::is_same<T, NestedNameSpecifier>::value ||
1176 std::is_same<T, NestedNameSpecifierLoc>::value ||
1177 std::is_same<T, CXXCtorInitializer>::value ||
1178 std::is_same<T, TemplateArgumentLoc>::value ||
1179 std::is_same<T, Attr>::value;
1180};
1181template <typename T>
1182const bool IsBaseType<T>::value;
1183
1184/// A "type list" that contains all types.
1185///
1186/// Useful for matchers like \c anything and \c unless.
1187using AllNodeBaseTypes =
1188 TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, QualType,
1189 Type, TypeLoc, CXXCtorInitializer, Attr>;
1190
1191/// Helper meta-function to extract the argument out of a function of
1192/// type void(Arg).
1193///
1194/// See AST_POLYMORPHIC_SUPPORTED_TYPES for details.
1195template <class T> struct ExtractFunctionArgMeta;
1196template <class T> struct ExtractFunctionArgMeta<void(T)> {
1197 using type = T;
1198};
1199
1200template <class T, class Tuple, std::size_t... I>
1201constexpr T *new_from_tuple_impl(Tuple &&t, std::index_sequence<I...>) {
1202 return new T(std::get<I>(std::forward<Tuple>(t))...);
1203}
1204
1205template <class T, class Tuple> constexpr T *new_from_tuple(Tuple &&t) {
1206 return new_from_tuple_impl<T>(
1207 std::forward<Tuple>(t),
1208 std::make_index_sequence<
1209 std::tuple_size<std::remove_reference_t<Tuple>>::value>{});
1210}
1211
1212/// Default type lists for ArgumentAdaptingMatcher matchers.
1213using AdaptativeDefaultFromTypes = AllNodeBaseTypes;
1214using AdaptativeDefaultToTypes =
1215 TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, TypeLoc,
1216 QualType, Attr>;
1217
1218/// All types that are supported by HasDeclarationMatcher above.
1219using HasDeclarationSupportedTypes =
1220 TypeList<CallExpr, CXXConstructExpr, CXXNewExpr, DeclRefExpr, EnumType,
1221 ElaboratedType, InjectedClassNameType, LabelStmt, AddrLabelExpr,
1222 MemberExpr, QualType, RecordType, TagType,
1223 TemplateSpecializationType, TemplateTypeParmType, TypedefType,
1224 UnresolvedUsingType, ObjCIvarRefExpr, ObjCInterfaceDecl>;
1225
1226/// A Matcher that allows binding the node it matches to an id.
1227///
1228/// BindableMatcher provides a \a bind() method that allows binding the
1229/// matched node to an id if the match was successful.
1230template <typename T> class BindableMatcher : public Matcher<T> {
1231public:
1232 explicit BindableMatcher(const Matcher<T> &M) : Matcher<T>(M) {}
1233 explicit BindableMatcher(MatcherInterface<T> *Implementation)
1234 : Matcher<T>(Implementation) {}
1235
1236 /// Returns a matcher that will bind the matched node on a match.
1237 ///
1238 /// The returned matcher is equivalent to this matcher, but will
1239 /// bind the matched node on a match.
1240 Matcher<T> bind(StringRef ID) const {
1241 return DynTypedMatcher(*this)
1242 .tryBind(ID)
1243 ->template unconditionalConvertTo<T>();
1244 }
1245
1246 /// Same as Matcher<T>'s conversion operator, but enables binding on
1247 /// the returned matcher.
1248 operator DynTypedMatcher() const {
1249 DynTypedMatcher Result = static_cast<const Matcher<T> &>(*this);
1250 Result.setAllowBind(true);
1251 return Result;
1252 }
1253};
1254
1255/// Matches any instance of the given NodeType.
1256///
1257/// This is useful when a matcher syntactically requires a child matcher,
1258/// but the context doesn't care. See for example: anything().
1259class TrueMatcher {
1260public:
1261 using ReturnTypes = AllNodeBaseTypes;
1262
1263 template <typename T> operator Matcher<T>() const {
1264 return DynTypedMatcher::trueMatcher(ASTNodeKind::getFromNodeKind<T>())
1265 .template unconditionalConvertTo<T>();
1266 }
1267};
1268
1269/// Creates a Matcher<T> that matches if all inner matchers match.
1270template <typename T>
1271BindableMatcher<T>
1272makeAllOfComposite(ArrayRef<const Matcher<T> *> InnerMatchers) {
1273 // For the size() == 0 case, we return a "true" matcher.
1274 if (InnerMatchers.empty()) {
1275 return BindableMatcher<T>(TrueMatcher());
1276 }
1277 // For the size() == 1 case, we simply return that one matcher.
1278 // No need to wrap it in a variadic operation.
1279 if (InnerMatchers.size() == 1) {
1280 return BindableMatcher<T>(*InnerMatchers[0]);
1281 }
1282
1283 using PI = llvm::pointee_iterator<const Matcher<T> *const *>;
1284
1285 std::vector<DynTypedMatcher> DynMatchers(PI(InnerMatchers.begin()),
1286 PI(InnerMatchers.end()));
1287 return BindableMatcher<T>(
1288 DynTypedMatcher::constructVariadic(DynTypedMatcher::VO_AllOf,
1289 ASTNodeKind::getFromNodeKind<T>(),
1290 std::move(DynMatchers))
1291 .template unconditionalConvertTo<T>());
1292}
1293
1294/// Creates a Matcher<T> that matches if
1295/// T is dyn_cast'able into InnerT and all inner matchers match.
1296///
1297/// Returns BindableMatcher, as matchers that use dyn_cast have
1298/// the same object both to match on and to run submatchers on,
1299/// so there is no ambiguity with what gets bound.
1300template <typename T, typename InnerT>
1301BindableMatcher<T>
1302makeDynCastAllOfComposite(ArrayRef<const Matcher<InnerT> *> InnerMatchers) {
1303 return BindableMatcher<T>(
1304 makeAllOfComposite(InnerMatchers).template dynCastTo<T>());
1305}
1306
1307/// A VariadicDynCastAllOfMatcher<SourceT, TargetT> object is a
1308/// variadic functor that takes a number of Matcher<TargetT> and returns a
1309/// Matcher<SourceT> that matches TargetT nodes that are matched by all of the
1310/// given matchers, if SourceT can be dynamically casted into TargetT.
1311///
1312/// For example:
1313/// const VariadicDynCastAllOfMatcher<Decl, CXXRecordDecl> record;
1314/// Creates a functor record(...) that creates a Matcher<Decl> given
1315/// a variable number of arguments of type Matcher<CXXRecordDecl>.
1316/// The returned matcher matches if the given Decl can by dynamically
1317/// casted to CXXRecordDecl and all given matchers match.
1318template <typename SourceT, typename TargetT>
1319class VariadicDynCastAllOfMatcher
1320 : public VariadicFunction<BindableMatcher<SourceT>, Matcher<TargetT>,
1321 makeDynCastAllOfComposite<SourceT, TargetT>> {
1322public:
1323 VariadicDynCastAllOfMatcher() {}
1324};
1325
1326/// A \c VariadicAllOfMatcher<T> object is a variadic functor that takes
1327/// a number of \c Matcher<T> and returns a \c Matcher<T> that matches \c T
1328/// nodes that are matched by all of the given matchers.
1329///
1330/// For example:
1331/// const VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier;
1332/// Creates a functor nestedNameSpecifier(...) that creates a
1333/// \c Matcher<NestedNameSpecifier> given a variable number of arguments of type
1334/// \c Matcher<NestedNameSpecifier>.
1335/// The returned matcher matches if all given matchers match.
1336template <typename T>
1337class VariadicAllOfMatcher
1338 : public VariadicFunction<BindableMatcher<T>, Matcher<T>,
1339 makeAllOfComposite<T>> {
1340public:
1341 VariadicAllOfMatcher() {}
1342};
1343
1344/// VariadicOperatorMatcher related types.
1345/// @{
1346
1347/// Polymorphic matcher object that uses a \c
1348/// DynTypedMatcher::VariadicOperator operator.
1349///
1350/// Input matchers can have any type (including other polymorphic matcher
1351/// types), and the actual Matcher<T> is generated on demand with an implicit
1352/// conversion operator.
1353template <typename... Ps> class VariadicOperatorMatcher {
1354public:
1355 VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, Ps &&... Params)
1356 : Op(Op), Params(std::forward<Ps>(Params)...) {}
1357
1358 template <typename T> operator Matcher<T>() const & {
1359 return DynTypedMatcher::constructVariadic(
1360 Op, ASTNodeKind::getFromNodeKind<T>(),
1361 getMatchers<T>(std::index_sequence_for<Ps...>()))
1362 .template unconditionalConvertTo<T>();
1363 }
1364
1365 template <typename T> operator Matcher<T>() && {
1366 return DynTypedMatcher::constructVariadic(
1367 Op, ASTNodeKind::getFromNodeKind<T>(),
1368 getMatchers<T>(std::index_sequence_for<Ps...>()))
1369 .template unconditionalConvertTo<T>();
1370 }
1371
1372private:
1373 // Helper method to unpack the tuple into a vector.
1374 template <typename T, std::size_t... Is>
1375 std::vector<DynTypedMatcher> getMatchers(std::index_sequence<Is...>) const & {
1376 return {Matcher<T>(std::get<Is>(Params))...};
1377 }
1378
1379 template <typename T, std::size_t... Is>
1380 std::vector<DynTypedMatcher> getMatchers(std::index_sequence<Is...>) && {
1381 return {Matcher<T>(std::get<Is>(std::move(Params)))...};
1382 }
1383
1384 const DynTypedMatcher::VariadicOperator Op;
1385 std::tuple<Ps...> Params;
1386};
1387
1388/// Overloaded function object to generate VariadicOperatorMatcher
1389/// objects from arbitrary matchers.
1390template <unsigned MinCount, unsigned MaxCount>
1391struct VariadicOperatorMatcherFunc {
1392 DynTypedMatcher::VariadicOperator Op;
1393
1394 template <typename... Ms>
1395 VariadicOperatorMatcher<Ms...> operator()(Ms &&... Ps) const {
1396 static_assert(MinCount <= sizeof...(Ms) && sizeof...(Ms) <= MaxCount,
1397 "invalid number of parameters for variadic matcher");
1398 return VariadicOperatorMatcher<Ms...>(Op, std::forward<Ms>(Ps)...);
1399 }
1400};
1401
1402template <typename T, bool IsBaseOf, typename Head, typename Tail>
1403struct GetCladeImpl {
1404 using Type = Head;
1405};
1406template <typename T, typename Head, typename Tail>
1407struct GetCladeImpl<T, false, Head, Tail>
1408 : GetCladeImpl<T, std::is_base_of<typename Tail::head, T>::value,
1409 typename Tail::head, typename Tail::tail> {};
1410
1411template <typename T, typename... U>
1412struct GetClade : GetCladeImpl<T, false, T, AllNodeBaseTypes> {};
1413
1414template <typename CladeType, typename... MatcherTypes>
1415struct MapAnyOfMatcherImpl {
1416
1417 template <typename... InnerMatchers>
1418 BindableMatcher<CladeType>
1419 operator()(InnerMatchers &&... InnerMatcher) const {
1420 return VariadicAllOfMatcher<CladeType>()(std::apply(
1421 internal::VariadicOperatorMatcherFunc<
1422 0, std::numeric_limits<unsigned>::max()>{
1423 internal::DynTypedMatcher::VO_AnyOf},
1424 std::apply(
1425 [&](auto... Matcher) {
1426 return std::make_tuple(Matcher(InnerMatcher...)...);
1427 },
1428 std::tuple<
1429 VariadicDynCastAllOfMatcher<CladeType, MatcherTypes>...>())));
1430 }
1431};
1432
1433template <typename... MatcherTypes>
1434using MapAnyOfMatcher =
1435 MapAnyOfMatcherImpl<typename GetClade<MatcherTypes...>::Type,
1436 MatcherTypes...>;
1437
1438template <typename... MatcherTypes> struct MapAnyOfHelper {
1439 using CladeType = typename GetClade<MatcherTypes...>::Type;
1440
1441 MapAnyOfMatcher<MatcherTypes...> with;
1442
1443 operator BindableMatcher<CladeType>() const { return with(); }
1444
1445 Matcher<CladeType> bind(StringRef ID) const { return with().bind(ID); }
1446};
1447
1448template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
1449 typename T, typename ToTypes>
1450class ArgumentAdaptingMatcherFuncAdaptor {
1451public:
1452 explicit ArgumentAdaptingMatcherFuncAdaptor(const Matcher<T> &InnerMatcher)
1453 : InnerMatcher(InnerMatcher) {}
1454
1455 using ReturnTypes = ToTypes;
1456
1457 template <typename To> operator Matcher<To>() const & {
1458 return Matcher<To>(new ArgumentAdapterT<To, T>(InnerMatcher));
1459 }
1460
1461 template <typename To> operator Matcher<To>() && {
1462 return Matcher<To>(new ArgumentAdapterT<To, T>(std::move(InnerMatcher)));
1463 }
1464
1465private:
1466 Matcher<T> InnerMatcher;
1467};
1468
1469/// Converts a \c Matcher<T> to a matcher of desired type \c To by
1470/// "adapting" a \c To into a \c T.
1471///
1472/// The \c ArgumentAdapterT argument specifies how the adaptation is done.
1473///
1474/// For example:
1475/// \c ArgumentAdaptingMatcher<HasMatcher, T>(InnerMatcher);
1476/// Given that \c InnerMatcher is of type \c Matcher<T>, this returns a matcher
1477/// that is convertible into any matcher of type \c To by constructing
1478/// \c HasMatcher<To, T>(InnerMatcher).
1479///
1480/// If a matcher does not need knowledge about the inner type, prefer to use
1481/// PolymorphicMatcher.
1482template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
1483 typename FromTypes = AdaptativeDefaultFromTypes,
1484 typename ToTypes = AdaptativeDefaultToTypes>
1485struct ArgumentAdaptingMatcherFunc {
1486 template <typename T>
1487 static ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>
1488 create(const Matcher<T> &InnerMatcher) {
1489 return ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>(
1490 InnerMatcher);
1491 }
1492
1493 template <typename T>
1494 ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>
1495 operator()(const Matcher<T> &InnerMatcher) const {
1496 return create(InnerMatcher);
1497 }
1498
1499 template <typename... T>
1500 ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT,
1501 typename GetClade<T...>::Type, ToTypes>
1502 operator()(const MapAnyOfHelper<T...> &InnerMatcher) const {
1503 return create(InnerMatcher.with());
1504 }
1505};
1506
1507template <typename T> class TraversalMatcher : public MatcherInterface<T> {
1508 DynTypedMatcher InnerMatcher;
1510
1511public:
1512 explicit TraversalMatcher(clang::TraversalKind TK,
1513 const Matcher<T> &InnerMatcher)
1514 : InnerMatcher(InnerMatcher), Traversal(TK) {}
1515
1516 bool matches(const T &Node, ASTMatchFinder *Finder,
1517 BoundNodesTreeBuilder *Builder) const override {
1518 return this->InnerMatcher.matches(DynTypedNode::create(Node), Finder,
1519 Builder);
1520 }
1521
1522 std::optional<clang::TraversalKind> TraversalKind() const override {
1523 if (auto NestedKind = this->InnerMatcher.getTraversalKind())
1524 return NestedKind;
1525 return Traversal;
1526 }
1527};
1528
1529template <typename MatcherType> class TraversalWrapper {
1530public:
1531 TraversalWrapper(TraversalKind TK, const MatcherType &InnerMatcher)
1532 : TK(TK), InnerMatcher(InnerMatcher) {}
1533
1534 template <typename T> operator Matcher<T>() const & {
1535 return internal::DynTypedMatcher::constructRestrictedWrapper(
1536 new internal::TraversalMatcher<T>(TK, InnerMatcher),
1537 ASTNodeKind::getFromNodeKind<T>())
1538 .template unconditionalConvertTo<T>();
1539 }
1540
1541 template <typename T> operator Matcher<T>() && {
1542 return internal::DynTypedMatcher::constructRestrictedWrapper(
1543 new internal::TraversalMatcher<T>(TK, std::move(InnerMatcher)),
1544 ASTNodeKind::getFromNodeKind<T>())
1545 .template unconditionalConvertTo<T>();
1546 }
1547
1548private:
1549 TraversalKind TK;
1550 MatcherType InnerMatcher;
1551};
1552
1553/// A PolymorphicMatcher<MatcherT, P1, ..., PN> object can be
1554/// created from N parameters p1, ..., pN (of type P1, ..., PN) and
1555/// used as a Matcher<T> where a MatcherT<T, P1, ..., PN>(p1, ..., pN)
1556/// can be constructed.
1557///
1558/// For example:
1559/// - PolymorphicMatcher<IsDefinitionMatcher>()
1560/// creates an object that can be used as a Matcher<T> for any type T
1561/// where an IsDefinitionMatcher<T>() can be constructed.
1562/// - PolymorphicMatcher<ValueEqualsMatcher, int>(42)
1563/// creates an object that can be used as a Matcher<T> for any type T
1564/// where a ValueEqualsMatcher<T, int>(42) can be constructed.
1565template <template <typename T, typename... Params> class MatcherT,
1566 typename ReturnTypesF, typename... ParamTypes>
1567class PolymorphicMatcher {
1568public:
1569 PolymorphicMatcher(const ParamTypes &... Params) : Params(Params...) {}
1570
1571 using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
1572
1573 template <typename T> operator Matcher<T>() const & {
1574 static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
1575 "right polymorphic conversion");
1576 return Matcher<T>(new_from_tuple<MatcherT<T, ParamTypes...>>(Params));
1577 }
1578
1579 template <typename T> operator Matcher<T>() && {
1580 static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
1581 "right polymorphic conversion");
1582 return Matcher<T>(
1583 new_from_tuple<MatcherT<T, ParamTypes...>>(std::move(Params)));
1584 }
1585
1586private:
1587 std::tuple<ParamTypes...> Params;
1588};
1589
1590/// Matches nodes of type T that have child nodes of type ChildT for
1591/// which a specified child matcher matches.
1592///
1593/// ChildT must be an AST base type.
1594template <typename T, typename ChildT>
1595class HasMatcher : public MatcherInterface<T> {
1596 DynTypedMatcher InnerMatcher;
1597
1598public:
1599 explicit HasMatcher(const Matcher<ChildT> &InnerMatcher)
1600 : InnerMatcher(InnerMatcher) {}
1601
1602 bool matches(const T &Node, ASTMatchFinder *Finder,
1603 BoundNodesTreeBuilder *Builder) const override {
1604 return Finder->matchesChildOf(Node, this->InnerMatcher, Builder,
1605 ASTMatchFinder::BK_First);
1606 }
1607};
1608
1609/// Matches nodes of type T that have child nodes of type ChildT for
1610/// which a specified child matcher matches. ChildT must be an AST base
1611/// type.
1612/// As opposed to the HasMatcher, the ForEachMatcher will produce a match
1613/// for each child that matches.
1614template <typename T, typename ChildT>
1615class ForEachMatcher : public MatcherInterface<T> {
1616 static_assert(IsBaseType<ChildT>::value,
1617 "for each only accepts base type matcher");
1618
1619 DynTypedMatcher InnerMatcher;
1620
1621public:
1622 explicit ForEachMatcher(const Matcher<ChildT> &InnerMatcher)
1623 : InnerMatcher(InnerMatcher) {}
1624
1625 bool matches(const T &Node, ASTMatchFinder *Finder,
1626 BoundNodesTreeBuilder *Builder) const override {
1627 return Finder->matchesChildOf(
1628 Node, this->InnerMatcher, Builder,
1629 ASTMatchFinder::BK_All);
1630 }
1631};
1632
1633/// @}
1634
1635template <typename T>
1636inline Matcher<T> DynTypedMatcher::unconditionalConvertTo() const {
1637 return Matcher<T>(*this);
1638}
1639
1640/// Matches nodes of type T that have at least one descendant node of
1641/// type DescendantT for which the given inner matcher matches.
1642///
1643/// DescendantT must be an AST base type.
1644template <typename T, typename DescendantT>
1645class HasDescendantMatcher : public MatcherInterface<T> {
1646 static_assert(IsBaseType<DescendantT>::value,
1647 "has descendant only accepts base type matcher");
1648
1649 DynTypedMatcher DescendantMatcher;
1650
1651public:
1652 explicit HasDescendantMatcher(const Matcher<DescendantT> &DescendantMatcher)
1653 : DescendantMatcher(DescendantMatcher) {}
1654
1655 bool matches(const T &Node, ASTMatchFinder *Finder,
1656 BoundNodesTreeBuilder *Builder) const override {
1657 return Finder->matchesDescendantOf(Node, this->DescendantMatcher, Builder,
1658 ASTMatchFinder::BK_First);
1659 }
1660};
1661
1662/// Matches nodes of type \c T that have a parent node of type \c ParentT
1663/// for which the given inner matcher matches.
1664///
1665/// \c ParentT must be an AST base type.
1666template <typename T, typename ParentT>
1667class HasParentMatcher : public MatcherInterface<T> {
1668 static_assert(IsBaseType<ParentT>::value,
1669 "has parent only accepts base type matcher");
1670
1671 DynTypedMatcher ParentMatcher;
1672
1673public:
1674 explicit HasParentMatcher(const Matcher<ParentT> &ParentMatcher)
1675 : ParentMatcher(ParentMatcher) {}
1676
1677 bool matches(const T &Node, ASTMatchFinder *Finder,
1678 BoundNodesTreeBuilder *Builder) const override {
1679 return Finder->matchesAncestorOf(Node, this->ParentMatcher, Builder,
1680 ASTMatchFinder::AMM_ParentOnly);
1681 }
1682};
1683
1684/// Matches nodes of type \c T that have at least one ancestor node of
1685/// type \c AncestorT for which the given inner matcher matches.
1686///
1687/// \c AncestorT must be an AST base type.
1688template <typename T, typename AncestorT>
1689class HasAncestorMatcher : public MatcherInterface<T> {
1690 static_assert(IsBaseType<AncestorT>::value,
1691 "has ancestor only accepts base type matcher");
1692
1693 DynTypedMatcher AncestorMatcher;
1694
1695public:
1696 explicit HasAncestorMatcher(const Matcher<AncestorT> &AncestorMatcher)
1697 : AncestorMatcher(AncestorMatcher) {}
1698
1699 bool matches(const T &Node, ASTMatchFinder *Finder,
1700 BoundNodesTreeBuilder *Builder) const override {
1701 return Finder->matchesAncestorOf(Node, this->AncestorMatcher, Builder,
1702 ASTMatchFinder::AMM_All);
1703 }
1704};
1705
1706/// Matches nodes of type T that have at least one descendant node of
1707/// type DescendantT for which the given inner matcher matches.
1708///
1709/// DescendantT must be an AST base type.
1710/// As opposed to HasDescendantMatcher, ForEachDescendantMatcher will match
1711/// for each descendant node that matches instead of only for the first.
1712template <typename T, typename DescendantT>
1713class ForEachDescendantMatcher : public MatcherInterface<T> {
1714 static_assert(IsBaseType<DescendantT>::value,
1715 "for each descendant only accepts base type matcher");
1716
1717 DynTypedMatcher DescendantMatcher;
1718
1719public:
1720 explicit ForEachDescendantMatcher(
1721 const Matcher<DescendantT> &DescendantMatcher)
1722 : DescendantMatcher(DescendantMatcher) {}
1723
1724 bool matches(const T &Node, ASTMatchFinder *Finder,
1725 BoundNodesTreeBuilder *Builder) const override {
1726 return Finder->matchesDescendantOf(Node, this->DescendantMatcher, Builder,
1727 ASTMatchFinder::BK_All);
1728 }
1729};
1730
1731/// Matches on nodes that have a getValue() method if getValue() equals
1732/// the value the ValueEqualsMatcher was constructed with.
1733template <typename T, typename ValueT>
1734class ValueEqualsMatcher : public SingleNodeMatcherInterface<T> {
1735 static_assert(std::is_base_of<CharacterLiteral, T>::value ||
1736 std::is_base_of<CXXBoolLiteralExpr, T>::value ||
1737 std::is_base_of<FloatingLiteral, T>::value ||
1738 std::is_base_of<IntegerLiteral, T>::value,
1739 "the node must have a getValue method");
1740
1741public:
1742 explicit ValueEqualsMatcher(const ValueT &ExpectedValue)
1743 : ExpectedValue(ExpectedValue) {}
1744
1745 bool matchesNode(const T &Node) const override {
1746 return Node.getValue() == ExpectedValue;
1747 }
1748
1749private:
1750 ValueT ExpectedValue;
1751};
1752
1753/// Template specializations to easily write matchers for floating point
1754/// literals.
1755template <>
1756inline bool ValueEqualsMatcher<FloatingLiteral, double>::matchesNode(
1757 const FloatingLiteral &Node) const {
1758 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle())
1759 return Node.getValue().convertToFloat() == ExpectedValue;
1760 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble())
1761 return Node.getValue().convertToDouble() == ExpectedValue;
1762 return false;
1763}
1764template <>
1765inline bool ValueEqualsMatcher<FloatingLiteral, float>::matchesNode(
1766 const FloatingLiteral &Node) const {
1767 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle())
1768 return Node.getValue().convertToFloat() == ExpectedValue;
1769 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble())
1770 return Node.getValue().convertToDouble() == ExpectedValue;
1771 return false;
1772}
1773template <>
1774inline bool ValueEqualsMatcher<FloatingLiteral, llvm::APFloat>::matchesNode(
1775 const FloatingLiteral &Node) const {
1776 return ExpectedValue.compare(Node.getValue()) == llvm::APFloat::cmpEqual;
1777}
1778
1779/// Matches nodes of type \c TLoc for which the inner
1780/// \c Matcher<T> matches.
1781template <typename TLoc, typename T>
1782class LocMatcher : public MatcherInterface<TLoc> {
1783 DynTypedMatcher InnerMatcher;
1784
1785public:
1786 explicit LocMatcher(const Matcher<T> &InnerMatcher)
1787 : InnerMatcher(InnerMatcher) {}
1788
1789 bool matches(const TLoc &Node, ASTMatchFinder *Finder,
1790 BoundNodesTreeBuilder *Builder) const override {
1791 if (!Node)
1792 return false;
1793 return this->InnerMatcher.matches(extract(Node), Finder, Builder);
1794 }
1795
1796private:
1797 static DynTypedNode extract(const NestedNameSpecifierLoc &Loc) {
1798 return DynTypedNode::create(*Loc.getNestedNameSpecifier());
1799 }
1800};
1801
1802/// Matches \c TypeLocs based on an inner matcher matching a certain
1803/// \c QualType.
1804///
1805/// Used to implement the \c loc() matcher.
1806class TypeLocTypeMatcher : public MatcherInterface<TypeLoc> {
1807 DynTypedMatcher InnerMatcher;
1808
1809public:
1810 explicit TypeLocTypeMatcher(const Matcher<QualType> &InnerMatcher)
1811 : InnerMatcher(InnerMatcher) {}
1812
1813 bool matches(const TypeLoc &Node, ASTMatchFinder *Finder,
1814 BoundNodesTreeBuilder *Builder) const override {
1815 if (!Node)
1816 return false;
1817 return this->InnerMatcher.matches(DynTypedNode::create(Node.getType()),
1818 Finder, Builder);
1819 }
1820};
1821
1822/// Matches nodes of type \c T for which the inner matcher matches on a
1823/// another node of type \c T that can be reached using a given traverse
1824/// function.
1825template <typename T> class TypeTraverseMatcher : public MatcherInterface<T> {
1826 DynTypedMatcher InnerMatcher;
1827
1828public:
1829 explicit TypeTraverseMatcher(const Matcher<QualType> &InnerMatcher,
1830 QualType (T::*TraverseFunction)() const)
1831 : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {}
1832
1833 bool matches(const T &Node, ASTMatchFinder *Finder,
1834 BoundNodesTreeBuilder *Builder) const override {
1835 QualType NextNode = (Node.*TraverseFunction)();
1836 if (NextNode.isNull())
1837 return false;
1838 return this->InnerMatcher.matches(DynTypedNode::create(NextNode), Finder,
1839 Builder);
1840 }
1841
1842private:
1843 QualType (T::*TraverseFunction)() const;
1844};
1845
1846/// Matches nodes of type \c T in a ..Loc hierarchy, for which the inner
1847/// matcher matches on a another node of type \c T that can be reached using a
1848/// given traverse function.
1849template <typename T>
1850class TypeLocTraverseMatcher : public MatcherInterface<T> {
1851 DynTypedMatcher InnerMatcher;
1852
1853public:
1854 explicit TypeLocTraverseMatcher(const Matcher<TypeLoc> &InnerMatcher,
1855 TypeLoc (T::*TraverseFunction)() const)
1856 : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {}
1857
1858 bool matches(const T &Node, ASTMatchFinder *Finder,
1859 BoundNodesTreeBuilder *Builder) const override {
1860 TypeLoc NextNode = (Node.*TraverseFunction)();
1861 if (!NextNode)
1862 return false;
1863 return this->InnerMatcher.matches(DynTypedNode::create(NextNode), Finder,
1864 Builder);
1865 }
1866
1867private:
1868 TypeLoc (T::*TraverseFunction)() const;
1869};
1870
1871/// Converts a \c Matcher<InnerT> to a \c Matcher<OuterT>, where
1872/// \c OuterT is any type that is supported by \c Getter.
1873///
1874/// \code Getter<OuterT>::value() \endcode returns a
1875/// \code InnerTBase (OuterT::*)() \endcode, which is used to adapt a \c OuterT
1876/// object into a \c InnerT
1877template <typename InnerTBase,
1878 template <typename OuterT> class Getter,
1879 template <typename OuterT> class MatcherImpl,
1880 typename ReturnTypesF>
1881class TypeTraversePolymorphicMatcher {
1882private:
1883 using Self = TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl,
1884 ReturnTypesF>;
1885
1886 static Self create(ArrayRef<const Matcher<InnerTBase> *> InnerMatchers);
1887
1888public:
1889 using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
1890
1891 explicit TypeTraversePolymorphicMatcher(
1892 ArrayRef<const Matcher<InnerTBase> *> InnerMatchers)
1893 : InnerMatcher(makeAllOfComposite(InnerMatchers)) {}
1894
1895 template <typename OuterT> operator Matcher<OuterT>() const {
1896 return Matcher<OuterT>(
1897 new MatcherImpl<OuterT>(InnerMatcher, Getter<OuterT>::value()));
1898 }
1899
1900 struct Func
1901 : public VariadicFunction<Self, Matcher<InnerTBase>, &Self::create> {
1902 Func() {}
1903 };
1904
1905private:
1906 Matcher<InnerTBase> InnerMatcher;
1907};
1908
1909/// A simple memoizer of T(*)() functions.
1910///
1911/// It will call the passed 'Func' template parameter at most once.
1912/// Used to support AST_MATCHER_FUNCTION() macro.
1913template <typename Matcher, Matcher (*Func)()> class MemoizedMatcher {
1914 struct Wrapper {
1915 Wrapper() : M(Func()) {}
1916
1917 Matcher M;
1918 };
1919
1920public:
1921 static const Matcher &getInstance() {
1922 static llvm::ManagedStatic<Wrapper> Instance;
1923 return Instance->M;
1924 }
1925};
1926
1927// Define the create() method out of line to silence a GCC warning about
1928// the struct "Func" having greater visibility than its base, which comes from
1929// using the flag -fvisibility-inlines-hidden.
1930template <typename InnerTBase, template <typename OuterT> class Getter,
1931 template <typename OuterT> class MatcherImpl, typename ReturnTypesF>
1932TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl, ReturnTypesF>
1933TypeTraversePolymorphicMatcher<
1934 InnerTBase, Getter, MatcherImpl,
1935 ReturnTypesF>::create(ArrayRef<const Matcher<InnerTBase> *> InnerMatchers) {
1936 return Self(InnerMatchers);
1937}
1938
1939// FIXME: unify ClassTemplateSpecializationDecl and TemplateSpecializationType's
1940// APIs for accessing the template argument list.
1941inline ArrayRef<TemplateArgument>
1942getTemplateSpecializationArgs(const ClassTemplateSpecializationDecl &D) {
1943 return D.getTemplateArgs().asArray();
1944}
1945
1946inline ArrayRef<TemplateArgument>
1947getTemplateSpecializationArgs(const VarTemplateSpecializationDecl &D) {
1948 return D.getTemplateArgs().asArray();
1949}
1950
1951inline ArrayRef<TemplateArgument>
1952getTemplateSpecializationArgs(const TemplateSpecializationType &T) {
1953 return T.template_arguments();
1954}
1955
1956inline ArrayRef<TemplateArgument>
1957getTemplateSpecializationArgs(const FunctionDecl &FD) {
1958 if (const auto* TemplateArgs = FD.getTemplateSpecializationArgs())
1959 return TemplateArgs->asArray();
1960 return {};
1961}
1962
1963inline ArrayRef<TemplateArgumentLoc>
1964getTemplateArgsWritten(const ClassTemplateSpecializationDecl &D) {
1965 if (const ASTTemplateArgumentListInfo *Args = D.getTemplateArgsAsWritten())
1966 return Args->arguments();
1967 return {};
1968}
1969
1970inline ArrayRef<TemplateArgumentLoc>
1971getTemplateArgsWritten(const VarTemplateSpecializationDecl &D) {
1972 if (const ASTTemplateArgumentListInfo *Args = D.getTemplateArgsAsWritten())
1973 return Args->arguments();
1974 return {};
1975}
1976
1977inline ArrayRef<TemplateArgumentLoc>
1978getTemplateArgsWritten(const FunctionDecl &FD) {
1979 if (const auto *Args = FD.getTemplateSpecializationArgsAsWritten())
1980 return Args->arguments();
1981 return {};
1982}
1983
1984inline ArrayRef<TemplateArgumentLoc>
1985getTemplateArgsWritten(const DeclRefExpr &DRE) {
1986 if (const auto *Args = DRE.getTemplateArgs())
1987 return {Args, DRE.getNumTemplateArgs()};
1988 return {};
1989}
1990
1991inline SmallVector<TemplateArgumentLoc>
1992getTemplateArgsWritten(const TemplateSpecializationTypeLoc &T) {
1993 SmallVector<TemplateArgumentLoc> Args;
1994 if (!T.isNull()) {
1995 Args.reserve(T.getNumArgs());
1996 for (unsigned I = 0; I < T.getNumArgs(); ++I)
1997 Args.emplace_back(T.getArgLoc(I));
1998 }
1999 return Args;
2000}
2001
2002struct NotEqualsBoundNodePredicate {
2003 bool operator()(const internal::BoundNodesMap &Nodes) const {
2004 return Nodes.getNode(ID) != Node;
2005 }
2006
2007 std::string ID;
2009};
2010
2011template <typename Ty, typename Enable = void> struct GetBodyMatcher {
2012 static const Stmt *get(const Ty &Node) { return Node.getBody(); }
2013};
2014
2015template <typename Ty>
2016struct GetBodyMatcher<
2017 Ty, std::enable_if_t<std::is_base_of<FunctionDecl, Ty>::value>> {
2018 static const Stmt *get(const Ty &Node) {
2019 return Node.doesThisDeclarationHaveABody() ? Node.getBody() : nullptr;
2020 }
2021};
2022
2023template <typename NodeType>
2024inline std::optional<BinaryOperatorKind>
2025equivalentBinaryOperator(const NodeType &Node) {
2026 return Node.getOpcode();
2027}
2028
2029template <>
2030inline std::optional<BinaryOperatorKind>
2031equivalentBinaryOperator<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
2032 if (Node.getNumArgs() != 2)
2033 return std::nullopt;
2034 switch (Node.getOperator()) {
2035 default:
2036 return std::nullopt;
2037 case OO_ArrowStar:
2038 return BO_PtrMemI;
2039 case OO_Star:
2040 return BO_Mul;
2041 case OO_Slash:
2042 return BO_Div;
2043 case OO_Percent:
2044 return BO_Rem;
2045 case OO_Plus:
2046 return BO_Add;
2047 case OO_Minus:
2048 return BO_Sub;
2049 case OO_LessLess:
2050 return BO_Shl;
2051 case OO_GreaterGreater:
2052 return BO_Shr;
2053 case OO_Spaceship:
2054 return BO_Cmp;
2055 case OO_Less:
2056 return BO_LT;
2057 case OO_Greater:
2058 return BO_GT;
2059 case OO_LessEqual:
2060 return BO_LE;
2061 case OO_GreaterEqual:
2062 return BO_GE;
2063 case OO_EqualEqual:
2064 return BO_EQ;
2065 case OO_ExclaimEqual:
2066 return BO_NE;
2067 case OO_Amp:
2068 return BO_And;
2069 case OO_Caret:
2070 return BO_Xor;
2071 case OO_Pipe:
2072 return BO_Or;
2073 case OO_AmpAmp:
2074 return BO_LAnd;
2075 case OO_PipePipe:
2076 return BO_LOr;
2077 case OO_Equal:
2078 return BO_Assign;
2079 case OO_StarEqual:
2080 return BO_MulAssign;
2081 case OO_SlashEqual:
2082 return BO_DivAssign;
2083 case OO_PercentEqual:
2084 return BO_RemAssign;
2085 case OO_PlusEqual:
2086 return BO_AddAssign;
2087 case OO_MinusEqual:
2088 return BO_SubAssign;
2089 case OO_LessLessEqual:
2090 return BO_ShlAssign;
2091 case OO_GreaterGreaterEqual:
2092 return BO_ShrAssign;
2093 case OO_AmpEqual:
2094 return BO_AndAssign;
2095 case OO_CaretEqual:
2096 return BO_XorAssign;
2097 case OO_PipeEqual:
2098 return BO_OrAssign;
2099 case OO_Comma:
2100 return BO_Comma;
2101 }
2102}
2103
2104template <typename NodeType>
2105inline std::optional<UnaryOperatorKind>
2106equivalentUnaryOperator(const NodeType &Node) {
2107 return Node.getOpcode();
2108}
2109
2110template <>
2111inline std::optional<UnaryOperatorKind>
2112equivalentUnaryOperator<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
2113 if (Node.getNumArgs() != 1 && Node.getOperator() != OO_PlusPlus &&
2114 Node.getOperator() != OO_MinusMinus)
2115 return std::nullopt;
2116 switch (Node.getOperator()) {
2117 default:
2118 return std::nullopt;
2119 case OO_Plus:
2120 return UO_Plus;
2121 case OO_Minus:
2122 return UO_Minus;
2123 case OO_Amp:
2124 return UO_AddrOf;
2125 case OO_Star:
2126 return UO_Deref;
2127 case OO_Tilde:
2128 return UO_Not;
2129 case OO_Exclaim:
2130 return UO_LNot;
2131 case OO_PlusPlus: {
2132 const auto *FD = Node.getDirectCallee();
2133 if (!FD)
2134 return std::nullopt;
2135 return FD->getNumParams() > 0 ? UO_PostInc : UO_PreInc;
2136 }
2137 case OO_MinusMinus: {
2138 const auto *FD = Node.getDirectCallee();
2139 if (!FD)
2140 return std::nullopt;
2141 return FD->getNumParams() > 0 ? UO_PostDec : UO_PreDec;
2142 }
2143 case OO_Coawait:
2144 return UO_Coawait;
2145 }
2146}
2147
2148template <typename NodeType> inline const Expr *getLHS(const NodeType &Node) {
2149 return Node.getLHS();
2150}
2151template <>
2152inline const Expr *
2153getLHS<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
2154 if (!internal::equivalentBinaryOperator(Node))
2155 return nullptr;
2156 return Node.getArg(0);
2157}
2158template <typename NodeType> inline const Expr *getRHS(const NodeType &Node) {
2159 return Node.getRHS();
2160}
2161template <>
2162inline const Expr *
2163getRHS<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
2164 if (!internal::equivalentBinaryOperator(Node))
2165 return nullptr;
2166 return Node.getArg(1);
2167}
2168template <typename NodeType>
2169inline const Expr *getSubExpr(const NodeType &Node) {
2170 return Node.getSubExpr();
2171}
2172template <>
2173inline const Expr *
2174getSubExpr<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
2175 if (!internal::equivalentUnaryOperator(Node))
2176 return nullptr;
2177 return Node.getArg(0);
2178}
2179
2180template <typename Ty>
2181struct HasSizeMatcher {
2182 static bool hasSize(const Ty &Node, unsigned int N) {
2183 return Node.getSize() == N;
2184 }
2185};
2186
2187template <>
2188inline bool HasSizeMatcher<StringLiteral>::hasSize(
2189 const StringLiteral &Node, unsigned int N) {
2190 return Node.getLength() == N;
2191}
2192
2193template <typename Ty>
2194struct GetSourceExpressionMatcher {
2195 static const Expr *get(const Ty &Node) {
2196 return Node.getSubExpr();
2197 }
2198};
2199
2200template <>
2201inline const Expr *GetSourceExpressionMatcher<OpaqueValueExpr>::get(
2202 const OpaqueValueExpr &Node) {
2203 return Node.getSourceExpr();
2204}
2205
2206template <typename Ty>
2207struct CompoundStmtMatcher {
2208 static const CompoundStmt *get(const Ty &Node) {
2209 return &Node;
2210 }
2211};
2212
2213template <>
2214inline const CompoundStmt *
2215CompoundStmtMatcher<StmtExpr>::get(const StmtExpr &Node) {
2216 return Node.getSubStmt();
2217}
2218
2219/// If \p Loc is (transitively) expanded from macro \p MacroName, returns the
2220/// location (in the chain of expansions) at which \p MacroName was
2221/// expanded. Since the macro may have been expanded inside a series of
2222/// expansions, that location may itself be a MacroID.
2223std::optional<SourceLocation> getExpansionLocOfMacro(StringRef MacroName,
2224 SourceLocation Loc,
2225 const ASTContext &Context);
2226
2227inline std::optional<StringRef> getOpName(const UnaryOperator &Node) {
2228 return Node.getOpcodeStr(Node.getOpcode());
2229}
2230inline std::optional<StringRef> getOpName(const BinaryOperator &Node) {
2231 return Node.getOpcodeStr();
2232}
2233inline StringRef getOpName(const CXXRewrittenBinaryOperator &Node) {
2234 return Node.getOpcodeStr();
2235}
2236inline std::optional<StringRef> getOpName(const CXXOperatorCallExpr &Node) {
2237 auto optBinaryOpcode = equivalentBinaryOperator(Node);
2238 if (!optBinaryOpcode) {
2239 auto optUnaryOpcode = equivalentUnaryOperator(Node);
2240 if (!optUnaryOpcode)
2241 return std::nullopt;
2242 return UnaryOperator::getOpcodeStr(*optUnaryOpcode);
2243 }
2244 return BinaryOperator::getOpcodeStr(*optBinaryOpcode);
2245}
2246inline StringRef getOpName(const CXXFoldExpr &Node) {
2247 return BinaryOperator::getOpcodeStr(Node.getOperator());
2248}
2249
2250/// Matches overloaded operators with a specific name.
2251///
2252/// The type argument ArgT is not used by this matcher but is used by
2253/// PolymorphicMatcher and should be std::vector<std::string>>.
2254template <typename T, typename ArgT = std::vector<std::string>>
2255class HasAnyOperatorNameMatcher : public SingleNodeMatcherInterface<T> {
2256 static_assert(std::is_same<T, BinaryOperator>::value ||
2257 std::is_same<T, CXXOperatorCallExpr>::value ||
2258 std::is_same<T, CXXRewrittenBinaryOperator>::value ||
2259 std::is_same<T, UnaryOperator>::value,
2260 "Matcher only supports `BinaryOperator`, `UnaryOperator`, "
2261 "`CXXOperatorCallExpr` and `CXXRewrittenBinaryOperator`");
2262 static_assert(std::is_same<ArgT, std::vector<std::string>>::value,
2263 "Matcher ArgT must be std::vector<std::string>");
2264
2265public:
2266 explicit HasAnyOperatorNameMatcher(std::vector<std::string> Names)
2267 : SingleNodeMatcherInterface<T>(), Names(std::move(Names)) {}
2268
2269 bool matchesNode(const T &Node) const override {
2270 std::optional<StringRef> OptOpName = getOpName(Node);
2271 return OptOpName && llvm::is_contained(Names, *OptOpName);
2272 }
2273
2274private:
2275 static std::optional<StringRef> getOpName(const UnaryOperator &Node) {
2276 return Node.getOpcodeStr(Node.getOpcode());
2277 }
2278 static std::optional<StringRef> getOpName(const BinaryOperator &Node) {
2279 return Node.getOpcodeStr();
2280 }
2281 static StringRef getOpName(const CXXRewrittenBinaryOperator &Node) {
2282 return Node.getOpcodeStr();
2283 }
2284 static std::optional<StringRef> getOpName(const CXXOperatorCallExpr &Node) {
2285 auto optBinaryOpcode = equivalentBinaryOperator(Node);
2286 if (!optBinaryOpcode) {
2287 auto optUnaryOpcode = equivalentUnaryOperator(Node);
2288 if (!optUnaryOpcode)
2289 return std::nullopt;
2290 return UnaryOperator::getOpcodeStr(*optUnaryOpcode);
2291 }
2292 return BinaryOperator::getOpcodeStr(*optBinaryOpcode);
2293 }
2294
2295 std::vector<std::string> Names;
2296};
2297
2298using HasOpNameMatcher =
2299 PolymorphicMatcher<HasAnyOperatorNameMatcher,
2300 void(
2301 TypeList<BinaryOperator, CXXOperatorCallExpr,
2302 CXXRewrittenBinaryOperator, UnaryOperator>),
2303 std::vector<std::string>>;
2304
2305HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef<const StringRef *> NameRefs);
2306
2307using HasOverloadOpNameMatcher =
2308 PolymorphicMatcher<HasOverloadedOperatorNameMatcher,
2309 void(TypeList<CXXOperatorCallExpr, FunctionDecl>),
2310 std::vector<std::string>>;
2311
2312HasOverloadOpNameMatcher
2313hasAnyOverloadedOperatorNameFunc(ArrayRef<const StringRef *> NameRefs);
2314
2315/// Returns true if \p Node has a base specifier matching \p BaseSpec.
2316///
2317/// A class is not considered to be derived from itself.
2318bool matchesAnyBase(const CXXRecordDecl &Node,
2319 const Matcher<CXXBaseSpecifier> &BaseSpecMatcher,
2320 ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder);
2321
2322std::shared_ptr<llvm::Regex> createAndVerifyRegex(StringRef Regex,
2323 llvm::Regex::RegexFlags Flags,
2324 StringRef MatcherID);
2325
2326inline bool
2327MatchTemplateArgLocAt(const DeclRefExpr &Node, unsigned int Index,
2328 internal::Matcher<TemplateArgumentLoc> InnerMatcher,
2329 internal::ASTMatchFinder *Finder,
2330 internal::BoundNodesTreeBuilder *Builder) {
2331 llvm::ArrayRef<TemplateArgumentLoc> ArgLocs = Node.template_arguments();
2332 return Index < ArgLocs.size() &&
2333 InnerMatcher.matches(ArgLocs[Index], Finder, Builder);
2334}
2335
2336inline bool
2337MatchTemplateArgLocAt(const TemplateSpecializationTypeLoc &Node,
2338 unsigned int Index,
2339 internal::Matcher<TemplateArgumentLoc> InnerMatcher,
2340 internal::ASTMatchFinder *Finder,
2341 internal::BoundNodesTreeBuilder *Builder) {
2342 return !Node.isNull() && Index < Node.getNumArgs() &&
2343 InnerMatcher.matches(Node.getArgLoc(Index), Finder, Builder);
2344}
2345
2346} // namespace internal
2347
2348} // namespace ast_matchers
2349
2350} // namespace clang
2351
2352#endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H
#define V(N, I)
Definition: ASTContext.h:3443
MatchType Type
BoundNodesTreeBuilder BoundNodes
BoundNodesTreeBuilder Nodes
DynTypedNode Node
DynTypedMatcher::MatcherIDType MatcherID
TraversalKind Traversal
static char ID
Definition: Arena.cpp:183
const Decl * D
enum clang::sema::@1718::IndirectLocalPathEntry::EntryKind Kind
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines an enumeration for C++ overloaded operators.
static Expected< DynTypedNode > getNode(const ast_matchers::BoundNodes &Nodes, StringRef ID)
static QualType getUnderlyingType(const SubRegion *R)
llvm::SmallVector< std::pair< const MemRegion *, SVal >, 4 > Bindings
uint32_t Id
Definition: SemaARM.cpp:1134
SourceLocation Loc
Definition: SemaObjC.cpp:759
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
StringRef getOpcodeStr() const
Definition: Expr.h:3975
static StringRef getOpcodeStr(Opcode Op)
getOpcodeStr - Turn an Opcode enum value into the punctuation char it corresponds to,...
Definition: Expr.cpp:1401
Code completion in a.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
HasOverloadOpNameMatcher hasAnyOverloadedOperatorNameFunc(ArrayRef< const StringRef * > NameRefs)
std::shared_ptr< llvm::Regex > createAndVerifyRegex(StringRef Regex, llvm::Regex::RegexFlags Flags, StringRef MatcherID)
Matcher< ObjCMessageExpr > hasAnySelectorFunc(ArrayRef< const StringRef * > NameRefs)
Matcher< NamedDecl > hasAnyNameFunc(ArrayRef< const StringRef * > NameRefs)
HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef< const StringRef * > NameRefs)
std::optional< SourceLocation > getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc, const ASTContext &Context)
bool matchesAnyBase(const CXXRecordDecl &Node, const Matcher< CXXBaseSpecifier > &BaseSpecMatcher, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder)
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
DynTypedNode DynTypedNode
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
bool matches(const til::SExpr *E1, const til::SExpr *E2)
The JSON file list parser is used to communicate input to InstallAPI.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
TraversalKind
Defines how we descend a level in the AST when we pass through expressions.
Definition: ASTTypeTraits.h:38
@ Result
The result type of a method or function.
const FunctionProtoType * T
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword.
@ Other
Other implicit parameter.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Definition: Specifiers.h:123
typename enable_if< B, T >::Type enable_if_t
Definition: hlsl_detail.h:23
unsigned long uint64_t
#define false
Definition: stdbool.h:26