clang 22.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// Deduction guide for Matcher.
676template <typename T> Matcher(MatcherInterface<T> *) -> Matcher<T>;
677
678// TODO: Remove in LLVM 23.
679template <typename T>
680[[deprecated(
681 "Use CTAD constructor instead, 'makeMatcher' will be removed in LLVM 23.")]]
682inline Matcher<T> makeMatcher(MatcherInterface<T> *Implementation) {
683 return Matcher<T>(Implementation);
684}
685
686/// Interface that allows matchers to traverse the AST.
687/// FIXME: Find a better name.
688///
689/// This provides three entry methods for each base node type in the AST:
690/// - \c matchesChildOf:
691/// Matches a matcher on every child node of the given node. Returns true
692/// if at least one child node could be matched.
693/// - \c matchesDescendantOf:
694/// Matches a matcher on all descendant nodes of the given node. Returns true
695/// if at least one descendant matched.
696/// - \c matchesAncestorOf:
697/// Matches a matcher on all ancestors of the given node. Returns true if
698/// at least one ancestor matched.
699///
700/// FIXME: Currently we only allow Stmt and Decl nodes to start a traversal.
701/// In the future, we want to implement this for all nodes for which it makes
702/// sense. In the case of matchesAncestorOf, we'll want to implement it for
703/// all nodes, as all nodes have ancestors.
704class ASTMatchFinder {
705public:
706 /// Defines how bindings are processed on recursive matches.
707 enum BindKind {
708 /// Stop at the first match and only bind the first match.
709 BK_First,
710
711 /// Create results for all combinations of bindings that match.
712 BK_All
713 };
714
715 /// Defines which ancestors are considered for a match.
716 enum AncestorMatchMode {
717 /// All ancestors.
718 AMM_All,
719
720 /// Direct parent only.
721 AMM_ParentOnly
722 };
723
724 virtual ~ASTMatchFinder() = default;
725
726 /// Returns true if the given C++ class is directly or indirectly derived
727 /// from a base type matching \c base.
728 ///
729 /// A class is not considered to be derived from itself.
730 virtual bool classIsDerivedFrom(const CXXRecordDecl *Declaration,
731 const Matcher<NamedDecl> &Base,
732 BoundNodesTreeBuilder *Builder,
733 bool Directly) = 0;
734
735 /// Returns true if the given Objective-C class is directly or indirectly
736 /// derived from a base class matching \c base.
737 ///
738 /// A class is not considered to be derived from itself.
739 virtual bool objcClassIsDerivedFrom(const ObjCInterfaceDecl *Declaration,
740 const Matcher<NamedDecl> &Base,
741 BoundNodesTreeBuilder *Builder,
742 bool Directly) = 0;
743
744 template <typename T>
745 bool matchesChildOf(const T &Node, const DynTypedMatcher &Matcher,
746 BoundNodesTreeBuilder *Builder, BindKind Bind) {
747 static_assert(std::is_base_of<Decl, T>::value ||
748 std::is_base_of<Stmt, T>::value ||
749 std::is_base_of<NestedNameSpecifier, T>::value ||
750 std::is_base_of<NestedNameSpecifierLoc, T>::value ||
751 std::is_base_of<TypeLoc, T>::value ||
752 std::is_base_of<QualType, T>::value ||
753 std::is_base_of<Attr, T>::value,
754 "unsupported type for recursive matching");
755 return matchesChildOf(DynTypedNode::create(Node), getASTContext(), Matcher,
756 Builder, Bind);
757 }
758
759 template <typename T>
760 bool matchesDescendantOf(const T &Node, const DynTypedMatcher &Matcher,
761 BoundNodesTreeBuilder *Builder, BindKind Bind) {
762 static_assert(std::is_base_of<Decl, T>::value ||
763 std::is_base_of<Stmt, T>::value ||
764 std::is_base_of<NestedNameSpecifier, T>::value ||
765 std::is_base_of<NestedNameSpecifierLoc, T>::value ||
766 std::is_base_of<TypeLoc, T>::value ||
767 std::is_base_of<QualType, T>::value ||
768 std::is_base_of<Attr, T>::value,
769 "unsupported type for recursive matching");
770 return matchesDescendantOf(DynTypedNode::create(Node), getASTContext(),
771 Matcher, Builder, Bind);
772 }
773
774 // FIXME: Implement support for BindKind.
775 template <typename T>
776 bool matchesAncestorOf(const T &Node, const DynTypedMatcher &Matcher,
777 BoundNodesTreeBuilder *Builder,
778 AncestorMatchMode MatchMode) {
779 static_assert(std::is_base_of<Decl, T>::value ||
780 std::is_base_of<NestedNameSpecifierLoc, T>::value ||
781 std::is_base_of<Stmt, T>::value ||
782 std::is_base_of<TypeLoc, T>::value ||
783 std::is_base_of<Attr, T>::value,
784 "type not allowed for recursive matching");
785 return matchesAncestorOf(DynTypedNode::create(Node), getASTContext(),
786 Matcher, Builder, MatchMode);
787 }
788
789 virtual ASTContext &getASTContext() const = 0;
790
791 virtual bool IsMatchingInASTNodeNotSpelledInSource() const = 0;
792
793 virtual bool IsMatchingInASTNodeNotAsIs() const = 0;
794
795 bool isTraversalIgnoringImplicitNodes() const;
796
797protected:
798 virtual bool matchesChildOf(const DynTypedNode &Node, ASTContext &Ctx,
799 const DynTypedMatcher &Matcher,
800 BoundNodesTreeBuilder *Builder,
801 BindKind Bind) = 0;
802
803 virtual bool matchesDescendantOf(const DynTypedNode &Node, ASTContext &Ctx,
804 const DynTypedMatcher &Matcher,
805 BoundNodesTreeBuilder *Builder,
806 BindKind Bind) = 0;
807
808 virtual bool matchesAncestorOf(const DynTypedNode &Node, ASTContext &Ctx,
809 const DynTypedMatcher &Matcher,
810 BoundNodesTreeBuilder *Builder,
811 AncestorMatchMode MatchMode) = 0;
812private:
813 friend struct ASTChildrenNotSpelledInSourceScope;
814 virtual bool isMatchingChildrenNotSpelledInSource() const = 0;
815 virtual void setMatchingChildrenNotSpelledInSource(bool Set) = 0;
816};
817
818struct ASTChildrenNotSpelledInSourceScope {
819 ASTChildrenNotSpelledInSourceScope(ASTMatchFinder *V, bool B)
820 : MV(V), MB(V->isMatchingChildrenNotSpelledInSource()) {
821 V->setMatchingChildrenNotSpelledInSource(B);
822 }
823 ~ASTChildrenNotSpelledInSourceScope() {
824 MV->setMatchingChildrenNotSpelledInSource(MB);
825 }
826
827private:
828 ASTMatchFinder *MV;
829 bool MB;
830};
831
832/// Specialization of the conversion functions for QualType.
833///
834/// This specialization provides the Matcher<Type>->Matcher<QualType>
835/// conversion that the static API does.
836template <>
837inline Matcher<QualType> DynTypedMatcher::convertTo<QualType>() const {
838 assert(canConvertTo<QualType>());
839 const ASTNodeKind SourceKind = getSupportedKind();
840 if (SourceKind.isSame(ASTNodeKind::getFromNodeKind<Type>())) {
841 // We support implicit conversion from Matcher<Type> to Matcher<QualType>
842 return unconditionalConvertTo<Type>();
843 }
844 return unconditionalConvertTo<QualType>();
845}
846
847/// Finds the first node in a range that matches the given matcher.
848template <typename MatcherT, typename IteratorT>
849IteratorT matchesFirstInRange(const MatcherT &Matcher, IteratorT Start,
850 IteratorT End, ASTMatchFinder *Finder,
851 BoundNodesTreeBuilder *Builder) {
852 for (IteratorT I = Start; I != End; ++I) {
853 BoundNodesTreeBuilder Result(*Builder);
854 if (Matcher.matches(*I, Finder, &Result)) {
855 *Builder = std::move(Result);
856 return I;
857 }
858 }
859 return End;
860}
861
862/// Finds the first node in a pointer range that matches the given
863/// matcher.
864template <typename MatcherT, typename IteratorT>
865IteratorT matchesFirstInPointerRange(const MatcherT &Matcher, IteratorT Start,
866 IteratorT End, ASTMatchFinder *Finder,
867 BoundNodesTreeBuilder *Builder) {
868 for (IteratorT I = Start; I != End; ++I) {
869 BoundNodesTreeBuilder Result(*Builder);
870 if (Matcher.matches(**I, Finder, &Result)) {
871 *Builder = std::move(Result);
872 return I;
873 }
874 }
875 return End;
876}
877
878template <typename T> inline bool isDefaultedHelper(const T *FD) {
879 if constexpr (std::is_base_of_v<FunctionDecl, T>)
880 return FD->isDefaulted();
881 return false;
882}
883
884// Metafunction to determine if type T has a member called getDecl.
885template <typename T>
886using check_has_getDecl = decltype(std::declval<T &>().getDecl());
887
888template <typename T>
889static constexpr bool has_getDecl =
890 llvm::is_detected<check_has_getDecl, T>::value;
891
892/// Matches overloaded operators with a specific name.
893///
894/// The type argument ArgT is not used by this matcher but is used by
895/// PolymorphicMatcher and should be StringRef.
896template <typename T, typename ArgT>
897class HasOverloadedOperatorNameMatcher : public SingleNodeMatcherInterface<T> {
898 static_assert(std::is_same<T, CXXOperatorCallExpr>::value ||
899 std::is_base_of<FunctionDecl, T>::value,
900 "unsupported class for matcher");
901 static_assert(std::is_same<ArgT, std::vector<std::string>>::value,
902 "argument type must be std::vector<std::string>");
903
904public:
905 explicit HasOverloadedOperatorNameMatcher(std::vector<std::string> Names)
906 : SingleNodeMatcherInterface<T>(), Names(std::move(Names)) {}
907
908 bool matchesNode(const T &Node) const override {
909 return matchesSpecialized(Node);
910 }
911
912private:
913
914 /// CXXOperatorCallExpr exist only for calls to overloaded operators
915 /// so this function returns true if the call is to an operator of the given
916 /// name.
917 bool matchesSpecialized(const CXXOperatorCallExpr &Node) const {
918 return llvm::is_contained(Names, getOperatorSpelling(Node.getOperator()));
919 }
920
921 /// Returns true only if CXXMethodDecl represents an overloaded
922 /// operator and has the given operator name.
923 bool matchesSpecialized(const FunctionDecl &Node) const {
924 return Node.isOverloadedOperator() &&
925 llvm::is_contained(
926 Names, getOperatorSpelling(Node.getOverloadedOperator()));
927 }
928
929 std::vector<std::string> Names;
930};
931
932/// Matches named declarations with a specific name.
933///
934/// See \c hasName() and \c hasAnyName() in ASTMatchers.h for details.
935class HasNameMatcher : public SingleNodeMatcherInterface<NamedDecl> {
936 public:
937 explicit HasNameMatcher(std::vector<std::string> Names);
938
939 bool matchesNode(const NamedDecl &Node) const override;
940
941private:
942 /// Unqualified match routine.
943 ///
944 /// It is much faster than the full match, but it only works for unqualified
945 /// matches.
946 bool matchesNodeUnqualified(const NamedDecl &Node) const;
947
948 /// Full match routine
949 ///
950 /// Fast implementation for the simple case of a named declaration at
951 /// namespace or RecordDecl scope.
952 /// It is slower than matchesNodeUnqualified, but faster than
953 /// matchesNodeFullSlow.
954 bool matchesNodeFullFast(const NamedDecl &Node) const;
955
956 /// Full match routine
957 ///
958 /// It generates the fully qualified name of the declaration (which is
959 /// expensive) before trying to match.
960 /// It is slower but simple and works on all cases.
961 bool matchesNodeFullSlow(const NamedDecl &Node) const;
962
963 bool UseUnqualifiedMatch;
964 std::vector<std::string> Names;
965};
966
967/// Trampoline function to use VariadicFunction<> to construct a
968/// HasNameMatcher.
969Matcher<NamedDecl> hasAnyNameFunc(ArrayRef<const StringRef *> NameRefs);
970
971/// Trampoline function to use VariadicFunction<> to construct a
972/// hasAnySelector matcher.
973Matcher<ObjCMessageExpr> hasAnySelectorFunc(
974 ArrayRef<const StringRef *> NameRefs);
975
976/// Matches declarations for QualType and CallExpr.
977///
978/// Type argument DeclMatcherT is required by PolymorphicMatcher but
979/// not actually used.
980template <typename T, typename DeclMatcherT>
981class HasDeclarationMatcher : public MatcherInterface<T> {
982 static_assert(std::is_same<DeclMatcherT, Matcher<Decl>>::value,
983 "instantiated with wrong types");
984
985 DynTypedMatcher InnerMatcher;
986
987public:
988 explicit HasDeclarationMatcher(const Matcher<Decl> &InnerMatcher)
989 : InnerMatcher(InnerMatcher) {}
990
991 bool matches(const T &Node, ASTMatchFinder *Finder,
992 BoundNodesTreeBuilder *Builder) const override {
993 return matchesSpecialized(Node, Finder, Builder);
994 }
995
996private:
997 /// Forwards to matching on the underlying type of the QualType.
998 bool matchesSpecialized(const QualType &Node, ASTMatchFinder *Finder,
999 BoundNodesTreeBuilder *Builder) const {
1000 if (Node.isNull())
1001 return false;
1002
1003 return matchesSpecialized(*Node, Finder, Builder);
1004 }
1005
1006 /// Finds the best declaration for a type and returns whether the inner
1007 /// matcher matches on it.
1008 bool matchesSpecialized(const Type &Node, ASTMatchFinder *Finder,
1009 BoundNodesTreeBuilder *Builder) const {
1010 // DeducedType does not have declarations of its own, so
1011 // match the deduced type instead.
1012 if (const auto *S = dyn_cast<DeducedType>(&Node)) {
1013 QualType DT = S->getDeducedType();
1014 return !DT.isNull() ? matchesSpecialized(*DT, Finder, Builder) : false;
1015 }
1016
1017 // First, for any types that have a declaration, extract the declaration and
1018 // match on it.
1019 if (const auto *S = dyn_cast<TagType>(&Node)) {
1020 return matchesDecl(S->getOriginalDecl(), Finder, Builder);
1021 }
1022 if (const auto *S = dyn_cast<TemplateTypeParmType>(&Node)) {
1023 return matchesDecl(S->getDecl(), Finder, Builder);
1024 }
1025 if (const auto *S = dyn_cast<TypedefType>(&Node)) {
1026 return matchesDecl(S->getDecl(), Finder, Builder);
1027 }
1028 if (const auto *S = dyn_cast<UnresolvedUsingType>(&Node)) {
1029 return matchesDecl(S->getDecl(), Finder, Builder);
1030 }
1031 if (const auto *S = dyn_cast<UsingType>(&Node)) {
1032 return matchesDecl(S->getDecl(), Finder, Builder);
1033 }
1034 if (const auto *S = dyn_cast<ObjCObjectType>(&Node)) {
1035 return matchesDecl(S->getInterface(), Finder, Builder);
1036 }
1037
1038 // A SubstTemplateTypeParmType exists solely to mark a type substitution
1039 // on the instantiated template. As users usually want to match the
1040 // template parameter on the uninitialized template, we can always desugar
1041 // one level without loss of expressiveness.
1042 // For example, given:
1043 // template<typename T> struct X { T t; } class A {}; X<A> a;
1044 // The following matcher will match, which otherwise would not:
1045 // fieldDecl(hasType(pointerType())).
1046 if (const auto *S = dyn_cast<SubstTemplateTypeParmType>(&Node)) {
1047 return matchesSpecialized(S->getReplacementType(), Finder, Builder);
1048 }
1049
1050 // For template specialization types, we want to match the template
1051 // declaration, as long as the type is still dependent, and otherwise the
1052 // declaration of the instantiated tag type.
1053 if (const auto *S = dyn_cast<TemplateSpecializationType>(&Node)) {
1054 if (!S->isTypeAlias() && S->isSugared()) {
1055 // If the template is non-dependent, we want to match the instantiated
1056 // tag type.
1057 // For example, given:
1058 // template<typename T> struct X {}; X<int> a;
1059 // The following matcher will match, which otherwise would not:
1060 // templateSpecializationType(hasDeclaration(cxxRecordDecl())).
1061 return matchesSpecialized(*S->desugar(), Finder, Builder);
1062 }
1063 // If the template is dependent or an alias, match the template
1064 // declaration.
1065 return matchesDecl(S->getTemplateName().getAsTemplateDecl(), Finder,
1066 Builder);
1067 }
1068
1069 // Similarly types found via using declarations.
1070 // These are *usually* meaningless sugar, and this matches the historical
1071 // behavior prior to the introduction of UsingType.
1072 if (const auto *S = dyn_cast<UsingType>(&Node)) {
1073 return matchesSpecialized(S->desugar(), Finder, Builder);
1074 }
1075 return false;
1076 }
1077
1078 /// Extracts the Decl the DeclRefExpr references and returns whether
1079 /// the inner matcher matches on it.
1080 bool matchesSpecialized(const DeclRefExpr &Node, ASTMatchFinder *Finder,
1081 BoundNodesTreeBuilder *Builder) const {
1082 return matchesDecl(Node.getDecl(), Finder, Builder);
1083 }
1084
1085 /// Extracts the Decl of the callee of a CallExpr and returns whether
1086 /// the inner matcher matches on it.
1087 bool matchesSpecialized(const CallExpr &Node, ASTMatchFinder *Finder,
1088 BoundNodesTreeBuilder *Builder) const {
1089 return matchesDecl(Node.getCalleeDecl(), Finder, Builder);
1090 }
1091
1092 /// Extracts the Decl of the constructor call and returns whether the
1093 /// inner matcher matches on it.
1094 bool matchesSpecialized(const CXXConstructExpr &Node,
1095 ASTMatchFinder *Finder,
1096 BoundNodesTreeBuilder *Builder) const {
1097 return matchesDecl(Node.getConstructor(), Finder, Builder);
1098 }
1099
1100 bool matchesSpecialized(const ObjCIvarRefExpr &Node,
1101 ASTMatchFinder *Finder,
1102 BoundNodesTreeBuilder *Builder) const {
1103 return matchesDecl(Node.getDecl(), Finder, Builder);
1104 }
1105
1106 bool matchesSpecialized(const ObjCInterfaceDecl &Node, ASTMatchFinder *Finder,
1107 BoundNodesTreeBuilder *Builder) const {
1108 return matchesDecl(Node.getCanonicalDecl(), Finder, Builder);
1109 }
1110
1111 /// Extracts the operator new of the new call and returns whether the
1112 /// inner matcher matches on it.
1113 bool matchesSpecialized(const CXXNewExpr &Node,
1114 ASTMatchFinder *Finder,
1115 BoundNodesTreeBuilder *Builder) const {
1116 return matchesDecl(Node.getOperatorNew(), Finder, Builder);
1117 }
1118
1119 /// Extracts the \c ValueDecl a \c MemberExpr refers to and returns
1120 /// whether the inner matcher matches on it.
1121 bool matchesSpecialized(const MemberExpr &Node,
1122 ASTMatchFinder *Finder,
1123 BoundNodesTreeBuilder *Builder) const {
1124 return matchesDecl(Node.getMemberDecl(), Finder, Builder);
1125 }
1126
1127 /// Extracts the \c LabelDecl a \c AddrLabelExpr refers to and returns
1128 /// whether the inner matcher matches on it.
1129 bool matchesSpecialized(const AddrLabelExpr &Node,
1130 ASTMatchFinder *Finder,
1131 BoundNodesTreeBuilder *Builder) const {
1132 return matchesDecl(Node.getLabel(), Finder, Builder);
1133 }
1134
1135 /// Extracts the declaration of a LabelStmt and returns whether the
1136 /// inner matcher matches on it.
1137 bool matchesSpecialized(const LabelStmt &Node, ASTMatchFinder *Finder,
1138 BoundNodesTreeBuilder *Builder) const {
1139 return matchesDecl(Node.getDecl(), Finder, Builder);
1140 }
1141
1142 /// Returns whether the inner matcher \c Node. Returns false if \c Node
1143 /// is \c NULL.
1144 bool matchesDecl(const Decl *Node, ASTMatchFinder *Finder,
1145 BoundNodesTreeBuilder *Builder) const {
1146 return Node != nullptr &&
1147 !(Finder->isTraversalIgnoringImplicitNodes() &&
1148 Node->isImplicit()) &&
1149 this->InnerMatcher.matches(DynTypedNode::create(*Node), Finder,
1150 Builder);
1151 }
1152};
1153
1154/// IsBaseType<T>::value is true if T is a "base" type in the AST
1155/// node class hierarchies.
1156template <typename T>
1157struct IsBaseType {
1158 static const bool value =
1159 std::is_same<T, Decl>::value || std::is_same<T, Stmt>::value ||
1160 std::is_same<T, QualType>::value || std::is_same<T, Type>::value ||
1161 std::is_same<T, TypeLoc>::value ||
1162 std::is_same<T, NestedNameSpecifier>::value ||
1163 std::is_same<T, NestedNameSpecifierLoc>::value ||
1164 std::is_same<T, CXXCtorInitializer>::value ||
1165 std::is_same<T, TemplateArgumentLoc>::value ||
1166 std::is_same<T, Attr>::value;
1167};
1168template <typename T>
1169const bool IsBaseType<T>::value;
1170
1171/// A "type list" that contains all types.
1172///
1173/// Useful for matchers like \c anything and \c unless.
1174using AllNodeBaseTypes =
1175 TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, QualType,
1176 Type, TypeLoc, CXXCtorInitializer, Attr>;
1177
1178/// Helper meta-function to extract the argument out of a function of
1179/// type void(Arg).
1180///
1181/// See AST_POLYMORPHIC_SUPPORTED_TYPES for details.
1182template <class T> struct ExtractFunctionArgMeta;
1183template <class T> struct ExtractFunctionArgMeta<void(T)> {
1184 using type = T;
1185};
1186
1187template <class T, class Tuple, std::size_t... I>
1188constexpr T *new_from_tuple_impl(Tuple &&t, std::index_sequence<I...>) {
1189 return new T(std::get<I>(std::forward<Tuple>(t))...);
1190}
1191
1192template <class T, class Tuple> constexpr T *new_from_tuple(Tuple &&t) {
1193 return new_from_tuple_impl<T>(
1194 std::forward<Tuple>(t),
1195 std::make_index_sequence<
1196 std::tuple_size<std::remove_reference_t<Tuple>>::value>{});
1197}
1198
1199/// Default type lists for ArgumentAdaptingMatcher matchers.
1200using AdaptativeDefaultFromTypes = AllNodeBaseTypes;
1201using AdaptativeDefaultToTypes =
1202 TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, TypeLoc,
1203 QualType, Attr>;
1204
1205/// All types that are supported by HasDeclarationMatcher above.
1206using HasDeclarationSupportedTypes =
1207 TypeList<CallExpr, CXXConstructExpr, CXXNewExpr, DeclRefExpr, EnumType,
1208 InjectedClassNameType, LabelStmt, AddrLabelExpr, MemberExpr,
1209 QualType, RecordType, TagType, UsingType,
1210 TemplateSpecializationType, TemplateTypeParmType, TypedefType,
1211 UnresolvedUsingType, ObjCIvarRefExpr, ObjCInterfaceDecl>;
1212
1213/// A Matcher that allows binding the node it matches to an id.
1214///
1215/// BindableMatcher provides a \a bind() method that allows binding the
1216/// matched node to an id if the match was successful.
1217template <typename T> class BindableMatcher : public Matcher<T> {
1218public:
1219 explicit BindableMatcher(const Matcher<T> &M) : Matcher<T>(M) {}
1220 explicit BindableMatcher(MatcherInterface<T> *Implementation)
1221 : Matcher<T>(Implementation) {}
1222
1223 /// Returns a matcher that will bind the matched node on a match.
1224 ///
1225 /// The returned matcher is equivalent to this matcher, but will
1226 /// bind the matched node on a match.
1227 Matcher<T> bind(StringRef ID) const {
1228 return DynTypedMatcher(*this)
1229 .tryBind(ID)
1230 ->template unconditionalConvertTo<T>();
1231 }
1232
1233 /// Same as Matcher<T>'s conversion operator, but enables binding on
1234 /// the returned matcher.
1235 operator DynTypedMatcher() const {
1236 DynTypedMatcher Result = static_cast<const Matcher<T> &>(*this);
1237 Result.setAllowBind(true);
1238 return Result;
1239 }
1240};
1241
1242/// Matches any instance of the given NodeType.
1243///
1244/// This is useful when a matcher syntactically requires a child matcher,
1245/// but the context doesn't care. See for example: anything().
1246class TrueMatcher {
1247public:
1248 using ReturnTypes = AllNodeBaseTypes;
1249
1250 template <typename T> operator Matcher<T>() const {
1251 return DynTypedMatcher::trueMatcher(ASTNodeKind::getFromNodeKind<T>())
1252 .template unconditionalConvertTo<T>();
1253 }
1254};
1255
1256/// Creates a Matcher<T> that matches if all inner matchers match.
1257template <typename T>
1258BindableMatcher<T>
1259makeAllOfComposite(ArrayRef<const Matcher<T> *> InnerMatchers) {
1260 // For the size() == 0 case, we return a "true" matcher.
1261 if (InnerMatchers.empty()) {
1262 return BindableMatcher<T>(TrueMatcher());
1263 }
1264 // For the size() == 1 case, we simply return that one matcher.
1265 // No need to wrap it in a variadic operation.
1266 if (InnerMatchers.size() == 1) {
1267 return BindableMatcher<T>(*InnerMatchers[0]);
1268 }
1269
1270 using PI = llvm::pointee_iterator<const Matcher<T> *const *>;
1271
1272 std::vector<DynTypedMatcher> DynMatchers(PI(InnerMatchers.begin()),
1273 PI(InnerMatchers.end()));
1274 return BindableMatcher<T>(
1275 DynTypedMatcher::constructVariadic(DynTypedMatcher::VO_AllOf,
1277 std::move(DynMatchers))
1278 .template unconditionalConvertTo<T>());
1279}
1280
1281/// Creates a Matcher<T> that matches if
1282/// T is dyn_cast'able into InnerT and all inner matchers match.
1283///
1284/// Returns BindableMatcher, as matchers that use dyn_cast have
1285/// the same object both to match on and to run submatchers on,
1286/// so there is no ambiguity with what gets bound.
1287template <typename T, typename InnerT>
1288BindableMatcher<T>
1289makeDynCastAllOfComposite(ArrayRef<const Matcher<InnerT> *> InnerMatchers) {
1290 return BindableMatcher<T>(
1291 makeAllOfComposite(InnerMatchers).template dynCastTo<T>());
1292}
1293
1294/// A VariadicDynCastAllOfMatcher<SourceT, TargetT> object is a
1295/// variadic functor that takes a number of Matcher<TargetT> and returns a
1296/// Matcher<SourceT> that matches TargetT nodes that are matched by all of the
1297/// given matchers, if SourceT can be dynamically casted into TargetT.
1298///
1299/// For example:
1300/// const VariadicDynCastAllOfMatcher<Decl, CXXRecordDecl> record;
1301/// Creates a functor record(...) that creates a Matcher<Decl> given
1302/// a variable number of arguments of type Matcher<CXXRecordDecl>.
1303/// The returned matcher matches if the given Decl can by dynamically
1304/// casted to CXXRecordDecl and all given matchers match.
1305template <typename SourceT, typename TargetT>
1306class VariadicDynCastAllOfMatcher
1307 : public VariadicFunction<BindableMatcher<SourceT>, Matcher<TargetT>,
1308 makeDynCastAllOfComposite<SourceT, TargetT>> {
1309public:
1310 VariadicDynCastAllOfMatcher() {}
1311};
1312
1313/// A \c VariadicAllOfMatcher<T> object is a variadic functor that takes
1314/// a number of \c Matcher<T> and returns a \c Matcher<T> that matches \c T
1315/// nodes that are matched by all of the given matchers.
1316///
1317/// For example:
1318/// const VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier;
1319/// Creates a functor nestedNameSpecifier(...) that creates a
1320/// \c Matcher<NestedNameSpecifier> given a variable number of arguments of type
1321/// \c Matcher<NestedNameSpecifier>.
1322/// The returned matcher matches if all given matchers match.
1323template <typename T>
1324class VariadicAllOfMatcher
1325 : public VariadicFunction<BindableMatcher<T>, Matcher<T>,
1326 makeAllOfComposite<T>> {
1327public:
1328 VariadicAllOfMatcher() {}
1329};
1330
1331/// VariadicOperatorMatcher related types.
1332/// @{
1333
1334/// Polymorphic matcher object that uses a \c
1335/// DynTypedMatcher::VariadicOperator operator.
1336///
1337/// Input matchers can have any type (including other polymorphic matcher
1338/// types), and the actual Matcher<T> is generated on demand with an implicit
1339/// conversion operator.
1340template <typename... Ps> class VariadicOperatorMatcher {
1341public:
1342 VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, Ps &&... Params)
1343 : Op(Op), Params(std::forward<Ps>(Params)...) {}
1344
1345 template <typename T> operator Matcher<T>() const & {
1346 return DynTypedMatcher::constructVariadic(
1347 Op, ASTNodeKind::getFromNodeKind<T>(),
1348 getMatchers<T>(std::index_sequence_for<Ps...>()))
1349 .template unconditionalConvertTo<T>();
1350 }
1351
1352 template <typename T> operator Matcher<T>() && {
1353 return DynTypedMatcher::constructVariadic(
1354 Op, ASTNodeKind::getFromNodeKind<T>(),
1355 getMatchers<T>(std::index_sequence_for<Ps...>()))
1356 .template unconditionalConvertTo<T>();
1357 }
1358
1359private:
1360 // Helper method to unpack the tuple into a vector.
1361 template <typename T, std::size_t... Is>
1362 std::vector<DynTypedMatcher> getMatchers(std::index_sequence<Is...>) const & {
1363 return {Matcher<T>(std::get<Is>(Params))...};
1364 }
1365
1366 template <typename T, std::size_t... Is>
1367 std::vector<DynTypedMatcher> getMatchers(std::index_sequence<Is...>) && {
1368 return {Matcher<T>(std::get<Is>(std::move(Params)))...};
1369 }
1370
1371 const DynTypedMatcher::VariadicOperator Op;
1372 std::tuple<Ps...> Params;
1373};
1374
1375/// Overloaded function object to generate VariadicOperatorMatcher
1376/// objects from arbitrary matchers.
1377template <unsigned MinCount, unsigned MaxCount>
1378struct VariadicOperatorMatcherFunc {
1379 DynTypedMatcher::VariadicOperator Op;
1380
1381 template <typename... Ms>
1382 VariadicOperatorMatcher<Ms...> operator()(Ms &&... Ps) const {
1383 static_assert(MinCount <= sizeof...(Ms) && sizeof...(Ms) <= MaxCount,
1384 "invalid number of parameters for variadic matcher");
1385 return VariadicOperatorMatcher<Ms...>(Op, std::forward<Ms>(Ps)...);
1386 }
1387};
1388
1389template <typename T, bool IsBaseOf, typename Head, typename Tail>
1390struct GetCladeImpl {
1391 using Type = Head;
1392};
1393template <typename T, typename Head, typename Tail>
1394struct GetCladeImpl<T, false, Head, Tail>
1395 : GetCladeImpl<T, std::is_base_of<typename Tail::head, T>::value,
1396 typename Tail::head, typename Tail::tail> {};
1397
1398template <typename T, typename... U>
1399struct GetClade : GetCladeImpl<T, false, T, AllNodeBaseTypes> {};
1400
1401template <typename CladeType, typename... MatcherTypes>
1402struct MapAnyOfMatcherImpl {
1403
1404 template <typename... InnerMatchers>
1405 BindableMatcher<CladeType>
1406 operator()(InnerMatchers &&... InnerMatcher) const {
1407 return VariadicAllOfMatcher<CladeType>()(std::apply(
1408 internal::VariadicOperatorMatcherFunc<
1409 0, std::numeric_limits<unsigned>::max()>{
1410 internal::DynTypedMatcher::VO_AnyOf},
1411 std::apply(
1412 [&](auto... Matcher) {
1413 return std::make_tuple(Matcher(InnerMatcher...)...);
1414 },
1415 std::tuple<
1416 VariadicDynCastAllOfMatcher<CladeType, MatcherTypes>...>())));
1417 }
1418};
1419
1420template <typename... MatcherTypes>
1421using MapAnyOfMatcher =
1422 MapAnyOfMatcherImpl<typename GetClade<MatcherTypes...>::Type,
1423 MatcherTypes...>;
1424
1425template <typename... MatcherTypes> struct MapAnyOfHelper {
1426 using CladeType = typename GetClade<MatcherTypes...>::Type;
1427
1428 MapAnyOfMatcher<MatcherTypes...> with;
1429
1430 operator BindableMatcher<CladeType>() const { return with(); }
1431
1432 Matcher<CladeType> bind(StringRef ID) const { return with().bind(ID); }
1433};
1434
1435template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
1436 typename T, typename ToTypes>
1437class ArgumentAdaptingMatcherFuncAdaptor {
1438public:
1439 explicit ArgumentAdaptingMatcherFuncAdaptor(const Matcher<T> &InnerMatcher)
1440 : InnerMatcher(InnerMatcher) {}
1441
1442 using ReturnTypes = ToTypes;
1443
1444 template <typename To> operator Matcher<To>() const & {
1445 return Matcher<To>(new ArgumentAdapterT<To, T>(InnerMatcher));
1446 }
1447
1448 template <typename To> operator Matcher<To>() && {
1449 return Matcher<To>(new ArgumentAdapterT<To, T>(std::move(InnerMatcher)));
1450 }
1451
1452private:
1453 Matcher<T> InnerMatcher;
1454};
1455
1456/// Converts a \c Matcher<T> to a matcher of desired type \c To by
1457/// "adapting" a \c To into a \c T.
1458///
1459/// The \c ArgumentAdapterT argument specifies how the adaptation is done.
1460///
1461/// For example:
1462/// \c ArgumentAdaptingMatcher<HasMatcher, T>(InnerMatcher);
1463/// Given that \c InnerMatcher is of type \c Matcher<T>, this returns a matcher
1464/// that is convertible into any matcher of type \c To by constructing
1465/// \c HasMatcher<To, T>(InnerMatcher).
1466///
1467/// If a matcher does not need knowledge about the inner type, prefer to use
1468/// PolymorphicMatcher.
1469template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
1470 typename FromTypes = AdaptativeDefaultFromTypes,
1471 typename ToTypes = AdaptativeDefaultToTypes>
1472struct ArgumentAdaptingMatcherFunc {
1473 template <typename T>
1474 static ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>
1475 create(const Matcher<T> &InnerMatcher) {
1476 return ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>(
1477 InnerMatcher);
1478 }
1479
1480 template <typename T>
1481 ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>
1482 operator()(const Matcher<T> &InnerMatcher) const {
1483 return create(InnerMatcher);
1484 }
1485
1486 template <typename... T>
1487 ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT,
1488 typename GetClade<T...>::Type, ToTypes>
1489 operator()(const MapAnyOfHelper<T...> &InnerMatcher) const {
1490 return create(InnerMatcher.with());
1491 }
1492};
1493
1494template <typename T> class TraversalMatcher : public MatcherInterface<T> {
1495 DynTypedMatcher InnerMatcher;
1496 clang::TraversalKind Traversal;
1497
1498public:
1499 explicit TraversalMatcher(clang::TraversalKind TK,
1500 const Matcher<T> &InnerMatcher)
1501 : InnerMatcher(InnerMatcher), Traversal(TK) {}
1502
1503 bool matches(const T &Node, ASTMatchFinder *Finder,
1504 BoundNodesTreeBuilder *Builder) const override {
1505 return this->InnerMatcher.matches(DynTypedNode::create(Node), Finder,
1506 Builder);
1507 }
1508
1509 std::optional<clang::TraversalKind> TraversalKind() const override {
1510 if (auto NestedKind = this->InnerMatcher.getTraversalKind())
1511 return NestedKind;
1512 return Traversal;
1513 }
1514};
1515
1516template <typename MatcherType> class TraversalWrapper {
1517public:
1518 TraversalWrapper(TraversalKind TK, const MatcherType &InnerMatcher)
1519 : TK(TK), InnerMatcher(InnerMatcher) {}
1520
1521 template <typename T> operator Matcher<T>() const & {
1522 return internal::DynTypedMatcher::constructRestrictedWrapper(
1523 new internal::TraversalMatcher<T>(TK, InnerMatcher),
1524 ASTNodeKind::getFromNodeKind<T>())
1525 .template unconditionalConvertTo<T>();
1526 }
1527
1528 template <typename T> operator Matcher<T>() && {
1529 return internal::DynTypedMatcher::constructRestrictedWrapper(
1530 new internal::TraversalMatcher<T>(TK, std::move(InnerMatcher)),
1531 ASTNodeKind::getFromNodeKind<T>())
1532 .template unconditionalConvertTo<T>();
1533 }
1534
1535private:
1536 TraversalKind TK;
1537 MatcherType InnerMatcher;
1538};
1539
1540/// A PolymorphicMatcher<MatcherT, P1, ..., PN> object can be
1541/// created from N parameters p1, ..., pN (of type P1, ..., PN) and
1542/// used as a Matcher<T> where a MatcherT<T, P1, ..., PN>(p1, ..., pN)
1543/// can be constructed.
1544///
1545/// For example:
1546/// - PolymorphicMatcher<IsDefinitionMatcher>()
1547/// creates an object that can be used as a Matcher<T> for any type T
1548/// where an IsDefinitionMatcher<T>() can be constructed.
1549/// - PolymorphicMatcher<ValueEqualsMatcher, int>(42)
1550/// creates an object that can be used as a Matcher<T> for any type T
1551/// where a ValueEqualsMatcher<T, int>(42) can be constructed.
1552template <template <typename T, typename... Params> class MatcherT,
1553 typename ReturnTypesF, typename... ParamTypes>
1554class PolymorphicMatcher {
1555public:
1556 PolymorphicMatcher(const ParamTypes &... Params) : Params(Params...) {}
1557
1558 using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
1559
1560 template <typename T> operator Matcher<T>() const & {
1561 static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
1562 "right polymorphic conversion");
1563 return Matcher<T>(new_from_tuple<MatcherT<T, ParamTypes...>>(Params));
1564 }
1565
1566 template <typename T> operator Matcher<T>() && {
1567 static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
1568 "right polymorphic conversion");
1569 return Matcher<T>(
1570 new_from_tuple<MatcherT<T, ParamTypes...>>(std::move(Params)));
1571 }
1572
1573private:
1574 std::tuple<ParamTypes...> Params;
1575};
1576
1577/// Matches nodes of type T that have child nodes of type ChildT for
1578/// which a specified child matcher matches.
1579///
1580/// ChildT must be an AST base type.
1581template <typename T, typename ChildT>
1582class HasMatcher : public MatcherInterface<T> {
1583 DynTypedMatcher InnerMatcher;
1584
1585public:
1586 explicit HasMatcher(const Matcher<ChildT> &InnerMatcher)
1587 : InnerMatcher(InnerMatcher) {}
1588
1589 bool matches(const T &Node, ASTMatchFinder *Finder,
1590 BoundNodesTreeBuilder *Builder) const override {
1591 return Finder->matchesChildOf(Node, this->InnerMatcher, Builder,
1592 ASTMatchFinder::BK_First);
1593 }
1594};
1595
1596/// Matches nodes of type T that have child nodes of type ChildT for
1597/// which a specified child matcher matches. ChildT must be an AST base
1598/// type.
1599/// As opposed to the HasMatcher, the ForEachMatcher will produce a match
1600/// for each child that matches.
1601template <typename T, typename ChildT>
1602class ForEachMatcher : public MatcherInterface<T> {
1603 static_assert(IsBaseType<ChildT>::value,
1604 "for each only accepts base type matcher");
1605
1606 DynTypedMatcher InnerMatcher;
1607
1608public:
1609 explicit ForEachMatcher(const Matcher<ChildT> &InnerMatcher)
1610 : InnerMatcher(InnerMatcher) {}
1611
1612 bool matches(const T &Node, ASTMatchFinder *Finder,
1613 BoundNodesTreeBuilder *Builder) const override {
1614 return Finder->matchesChildOf(
1615 Node, this->InnerMatcher, Builder,
1616 ASTMatchFinder::BK_All);
1617 }
1618};
1619
1620/// @}
1621
1622template <typename T>
1623inline Matcher<T> DynTypedMatcher::unconditionalConvertTo() const {
1624 return Matcher<T>(*this);
1625}
1626
1627/// Matches nodes of type T that have at least one descendant node of
1628/// type DescendantT for which the given inner matcher matches.
1629///
1630/// DescendantT must be an AST base type.
1631template <typename T, typename DescendantT>
1632class HasDescendantMatcher : public MatcherInterface<T> {
1633 static_assert(IsBaseType<DescendantT>::value,
1634 "has descendant only accepts base type matcher");
1635
1636 DynTypedMatcher DescendantMatcher;
1637
1638public:
1639 explicit HasDescendantMatcher(const Matcher<DescendantT> &DescendantMatcher)
1640 : DescendantMatcher(DescendantMatcher) {}
1641
1642 bool matches(const T &Node, ASTMatchFinder *Finder,
1643 BoundNodesTreeBuilder *Builder) const override {
1644 return Finder->matchesDescendantOf(Node, this->DescendantMatcher, Builder,
1645 ASTMatchFinder::BK_First);
1646 }
1647};
1648
1649/// Matches nodes of type \c T that have a parent node of type \c ParentT
1650/// for which the given inner matcher matches.
1651///
1652/// \c ParentT must be an AST base type.
1653template <typename T, typename ParentT>
1654class HasParentMatcher : public MatcherInterface<T> {
1655 static_assert(IsBaseType<ParentT>::value,
1656 "has parent only accepts base type matcher");
1657
1658 DynTypedMatcher ParentMatcher;
1659
1660public:
1661 explicit HasParentMatcher(const Matcher<ParentT> &ParentMatcher)
1662 : ParentMatcher(ParentMatcher) {}
1663
1664 bool matches(const T &Node, ASTMatchFinder *Finder,
1665 BoundNodesTreeBuilder *Builder) const override {
1666 return Finder->matchesAncestorOf(Node, this->ParentMatcher, Builder,
1667 ASTMatchFinder::AMM_ParentOnly);
1668 }
1669};
1670
1671/// Matches nodes of type \c T that have at least one ancestor node of
1672/// type \c AncestorT for which the given inner matcher matches.
1673///
1674/// \c AncestorT must be an AST base type.
1675template <typename T, typename AncestorT>
1676class HasAncestorMatcher : public MatcherInterface<T> {
1677 static_assert(IsBaseType<AncestorT>::value,
1678 "has ancestor only accepts base type matcher");
1679
1680 DynTypedMatcher AncestorMatcher;
1681
1682public:
1683 explicit HasAncestorMatcher(const Matcher<AncestorT> &AncestorMatcher)
1684 : AncestorMatcher(AncestorMatcher) {}
1685
1686 bool matches(const T &Node, ASTMatchFinder *Finder,
1687 BoundNodesTreeBuilder *Builder) const override {
1688 return Finder->matchesAncestorOf(Node, this->AncestorMatcher, Builder,
1689 ASTMatchFinder::AMM_All);
1690 }
1691};
1692
1693/// Matches nodes of type T that have at least one descendant node of
1694/// type DescendantT for which the given inner matcher matches.
1695///
1696/// DescendantT must be an AST base type.
1697/// As opposed to HasDescendantMatcher, ForEachDescendantMatcher will match
1698/// for each descendant node that matches instead of only for the first.
1699template <typename T, typename DescendantT>
1700class ForEachDescendantMatcher : public MatcherInterface<T> {
1701 static_assert(IsBaseType<DescendantT>::value,
1702 "for each descendant only accepts base type matcher");
1703
1704 DynTypedMatcher DescendantMatcher;
1705
1706public:
1707 explicit ForEachDescendantMatcher(
1708 const Matcher<DescendantT> &DescendantMatcher)
1709 : DescendantMatcher(DescendantMatcher) {}
1710
1711 bool matches(const T &Node, ASTMatchFinder *Finder,
1712 BoundNodesTreeBuilder *Builder) const override {
1713 return Finder->matchesDescendantOf(Node, this->DescendantMatcher, Builder,
1714 ASTMatchFinder::BK_All);
1715 }
1716};
1717
1718/// Matches on nodes that have a getValue() method if getValue() equals
1719/// the value the ValueEqualsMatcher was constructed with.
1720template <typename T, typename ValueT>
1721class ValueEqualsMatcher : public SingleNodeMatcherInterface<T> {
1722 static_assert(std::is_base_of<CharacterLiteral, T>::value ||
1723 std::is_base_of<CXXBoolLiteralExpr, T>::value ||
1724 std::is_base_of<FloatingLiteral, T>::value ||
1725 std::is_base_of<IntegerLiteral, T>::value ||
1726 std::is_base_of<FixedPointLiteral, T>::value,
1727 "the node must have a getValue method");
1728
1729public:
1730 explicit ValueEqualsMatcher(const ValueT &ExpectedValue)
1731 : ExpectedValue(ExpectedValue) {}
1732
1733 bool matchesNode(const T &Node) const override {
1734 return Node.getValue() == ExpectedValue;
1735 }
1736
1737private:
1738 ValueT ExpectedValue;
1739};
1740
1741/// Template specializations to easily write matchers for floating point
1742/// literals.
1743template <>
1744inline bool ValueEqualsMatcher<FloatingLiteral, double>::matchesNode(
1745 const FloatingLiteral &Node) const {
1746 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle())
1747 return Node.getValue().convertToFloat() == ExpectedValue;
1748 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble())
1749 return Node.getValue().convertToDouble() == ExpectedValue;
1750 return false;
1751}
1752template <>
1753inline bool ValueEqualsMatcher<FloatingLiteral, float>::matchesNode(
1754 const FloatingLiteral &Node) const {
1755 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle())
1756 return Node.getValue().convertToFloat() == ExpectedValue;
1757 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble())
1758 return Node.getValue().convertToDouble() == ExpectedValue;
1759 return false;
1760}
1761template <>
1762inline bool ValueEqualsMatcher<FloatingLiteral, llvm::APFloat>::matchesNode(
1763 const FloatingLiteral &Node) const {
1764 return ExpectedValue.compare(Node.getValue()) == llvm::APFloat::cmpEqual;
1765}
1766
1767/// Matches nodes of type \c TLoc for which the inner
1768/// \c Matcher<T> matches.
1769template <typename TLoc, typename T>
1770class LocMatcher : public MatcherInterface<TLoc> {
1771 DynTypedMatcher InnerMatcher;
1772
1773public:
1774 explicit LocMatcher(const Matcher<T> &InnerMatcher)
1775 : InnerMatcher(InnerMatcher) {}
1776
1777 bool matches(const TLoc &Node, ASTMatchFinder *Finder,
1778 BoundNodesTreeBuilder *Builder) const override {
1779 if (!Node)
1780 return false;
1781 return this->InnerMatcher.matches(extract(Node), Finder, Builder);
1782 }
1783
1784private:
1785 static DynTypedNode extract(const NestedNameSpecifierLoc &Loc) {
1786 return DynTypedNode::create(Loc.getNestedNameSpecifier());
1787 }
1788};
1789
1790/// Matches \c TypeLocs based on an inner matcher matching a certain
1791/// \c QualType.
1792///
1793/// Used to implement the \c loc() matcher.
1794class TypeLocTypeMatcher : public MatcherInterface<TypeLoc> {
1795 Matcher<QualType> InnerMatcher;
1796
1797public:
1798 explicit TypeLocTypeMatcher(const Matcher<QualType> &InnerMatcher)
1799 : InnerMatcher(InnerMatcher) {}
1800
1801 bool matches(const TypeLoc &Node, ASTMatchFinder *Finder,
1802 BoundNodesTreeBuilder *Builder) const override {
1803 if (!Node)
1804 return false;
1805 return this->InnerMatcher.matches(Node.getType(), Finder, Builder);
1806 }
1807};
1808
1809/// Matches nodes of type \c T for which the inner matcher matches on a
1810/// another node of type \c T that can be reached using a given traverse
1811/// function.
1812template <typename T> class TypeTraverseMatcher : public MatcherInterface<T> {
1813 DynTypedMatcher InnerMatcher;
1814
1815public:
1816 explicit TypeTraverseMatcher(const Matcher<QualType> &InnerMatcher,
1817 QualType (T::*TraverseFunction)() const)
1818 : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {}
1819
1820 bool matches(const T &Node, ASTMatchFinder *Finder,
1821 BoundNodesTreeBuilder *Builder) const override {
1822 QualType NextNode = (Node.*TraverseFunction)();
1823 if (NextNode.isNull())
1824 return false;
1825 return this->InnerMatcher.matches(DynTypedNode::create(NextNode), Finder,
1826 Builder);
1827 }
1828
1829private:
1830 QualType (T::*TraverseFunction)() const;
1831};
1832
1833/// Matches nodes of type \c T in a ..Loc hierarchy, for which the inner
1834/// matcher matches on a another node of type \c T that can be reached using a
1835/// given traverse function.
1836template <typename T>
1837class TypeLocTraverseMatcher : public MatcherInterface<T> {
1838 DynTypedMatcher InnerMatcher;
1839
1840public:
1841 explicit TypeLocTraverseMatcher(const Matcher<TypeLoc> &InnerMatcher,
1842 TypeLoc (T::*TraverseFunction)() const)
1843 : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {}
1844
1845 bool matches(const T &Node, ASTMatchFinder *Finder,
1846 BoundNodesTreeBuilder *Builder) const override {
1847 TypeLoc NextNode = (Node.*TraverseFunction)();
1848 if (!NextNode)
1849 return false;
1850 return this->InnerMatcher.matches(DynTypedNode::create(NextNode), Finder,
1851 Builder);
1852 }
1853
1854private:
1855 TypeLoc (T::*TraverseFunction)() const;
1856};
1857
1858/// Converts a \c Matcher<InnerT> to a \c Matcher<OuterT>, where
1859/// \c OuterT is any type that is supported by \c Getter.
1860///
1861/// \code Getter<OuterT>::value() \endcode returns a
1862/// \code InnerTBase (OuterT::*)() \endcode, which is used to adapt a \c OuterT
1863/// object into a \c InnerT
1864template <typename InnerTBase,
1865 template <typename OuterT> class Getter,
1866 template <typename OuterT> class MatcherImpl,
1867 typename ReturnTypesF>
1868class TypeTraversePolymorphicMatcher {
1869private:
1870 using Self = TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl,
1871 ReturnTypesF>;
1872
1873 static Self create(ArrayRef<const Matcher<InnerTBase> *> InnerMatchers);
1874
1875public:
1876 using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
1877
1878 explicit TypeTraversePolymorphicMatcher(
1879 ArrayRef<const Matcher<InnerTBase> *> InnerMatchers)
1880 : InnerMatcher(makeAllOfComposite(InnerMatchers)) {}
1881
1882 template <typename OuterT> operator Matcher<OuterT>() const {
1883 return Matcher<OuterT>(
1884 new MatcherImpl<OuterT>(InnerMatcher, Getter<OuterT>::value()));
1885 }
1886
1887 struct Func
1888 : public VariadicFunction<Self, Matcher<InnerTBase>, &Self::create> {
1889 Func() {}
1890 };
1891
1892private:
1893 Matcher<InnerTBase> InnerMatcher;
1894};
1895
1896/// A simple memoizer of T(*)() functions.
1897///
1898/// It will call the passed 'Func' template parameter at most once.
1899/// Used to support AST_MATCHER_FUNCTION() macro.
1900template <typename Matcher, Matcher (*Func)()> class MemoizedMatcher {
1901 struct Wrapper {
1902 Wrapper() : M(Func()) {}
1903
1904 Matcher M;
1905 };
1906
1907public:
1908 static const Matcher &getInstance() {
1909 static llvm::ManagedStatic<Wrapper> Instance;
1910 return Instance->M;
1911 }
1912};
1913
1914// Define the create() method out of line to silence a GCC warning about
1915// the struct "Func" having greater visibility than its base, which comes from
1916// using the flag -fvisibility-inlines-hidden.
1917template <typename InnerTBase, template <typename OuterT> class Getter,
1918 template <typename OuterT> class MatcherImpl, typename ReturnTypesF>
1919TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl, ReturnTypesF>
1920TypeTraversePolymorphicMatcher<
1921 InnerTBase, Getter, MatcherImpl,
1922 ReturnTypesF>::create(ArrayRef<const Matcher<InnerTBase> *> InnerMatchers) {
1923 return Self(InnerMatchers);
1924}
1925
1926// FIXME: unify ClassTemplateSpecializationDecl and TemplateSpecializationType's
1927// APIs for accessing the template argument list.
1928inline ArrayRef<TemplateArgument>
1929getTemplateSpecializationArgs(const ClassTemplateSpecializationDecl &D) {
1930 return D.getTemplateArgs().asArray();
1931}
1932
1933inline ArrayRef<TemplateArgument>
1934getTemplateSpecializationArgs(const VarTemplateSpecializationDecl &D) {
1935 return D.getTemplateArgs().asArray();
1936}
1937
1938inline ArrayRef<TemplateArgument>
1939getTemplateSpecializationArgs(const TemplateSpecializationType &T) {
1940 return T.template_arguments();
1941}
1942
1943inline ArrayRef<TemplateArgument>
1944getTemplateSpecializationArgs(const FunctionDecl &FD) {
1945 if (const auto* TemplateArgs = FD.getTemplateSpecializationArgs())
1946 return TemplateArgs->asArray();
1947 return {};
1948}
1949
1950inline ArrayRef<TemplateArgumentLoc>
1951getTemplateArgsWritten(const ClassTemplateSpecializationDecl &D) {
1952 if (const ASTTemplateArgumentListInfo *Args = D.getTemplateArgsAsWritten())
1953 return Args->arguments();
1954 return {};
1955}
1956
1957inline ArrayRef<TemplateArgumentLoc>
1958getTemplateArgsWritten(const VarTemplateSpecializationDecl &D) {
1959 if (const ASTTemplateArgumentListInfo *Args = D.getTemplateArgsAsWritten())
1960 return Args->arguments();
1961 return {};
1962}
1963
1964inline ArrayRef<TemplateArgumentLoc>
1965getTemplateArgsWritten(const FunctionDecl &FD) {
1966 if (const auto *Args = FD.getTemplateSpecializationArgsAsWritten())
1967 return Args->arguments();
1968 return {};
1969}
1970
1971inline ArrayRef<TemplateArgumentLoc>
1972getTemplateArgsWritten(const DeclRefExpr &DRE) {
1973 if (const auto *Args = DRE.getTemplateArgs())
1974 return {Args, DRE.getNumTemplateArgs()};
1975 return {};
1976}
1977
1978inline SmallVector<TemplateArgumentLoc>
1979getTemplateArgsWritten(const TemplateSpecializationTypeLoc &T) {
1980 SmallVector<TemplateArgumentLoc> Args;
1981 if (!T.isNull()) {
1982 Args.reserve(T.getNumArgs());
1983 for (unsigned I = 0; I < T.getNumArgs(); ++I)
1984 Args.emplace_back(T.getArgLoc(I));
1985 }
1986 return Args;
1987}
1988
1989struct NotEqualsBoundNodePredicate {
1990 bool operator()(const internal::BoundNodesMap &Nodes) const {
1991 return Nodes.getNode(ID) != Node;
1992 }
1993
1994 std::string ID;
1995 DynTypedNode Node;
1996};
1997
1998template <typename Ty, typename Enable = void> struct GetBodyMatcher {
1999 static const Stmt *get(const Ty &Node) { return Node.getBody(); }
2000};
2001
2002template <typename Ty>
2003struct GetBodyMatcher<
2004 Ty, std::enable_if_t<std::is_base_of<FunctionDecl, Ty>::value>> {
2005 static const Stmt *get(const Ty &Node) {
2006 return Node.doesThisDeclarationHaveABody() ? Node.getBody() : nullptr;
2007 }
2008};
2009
2010template <typename NodeType>
2011inline std::optional<BinaryOperatorKind>
2012equivalentBinaryOperator(const NodeType &Node) {
2013 return Node.getOpcode();
2014}
2015
2016template <>
2017inline std::optional<BinaryOperatorKind>
2018equivalentBinaryOperator<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
2019 if (Node.getNumArgs() != 2)
2020 return std::nullopt;
2021 switch (Node.getOperator()) {
2022 default:
2023 return std::nullopt;
2024 case OO_ArrowStar:
2025 return BO_PtrMemI;
2026 case OO_Star:
2027 return BO_Mul;
2028 case OO_Slash:
2029 return BO_Div;
2030 case OO_Percent:
2031 return BO_Rem;
2032 case OO_Plus:
2033 return BO_Add;
2034 case OO_Minus:
2035 return BO_Sub;
2036 case OO_LessLess:
2037 return BO_Shl;
2038 case OO_GreaterGreater:
2039 return BO_Shr;
2040 case OO_Spaceship:
2041 return BO_Cmp;
2042 case OO_Less:
2043 return BO_LT;
2044 case OO_Greater:
2045 return BO_GT;
2046 case OO_LessEqual:
2047 return BO_LE;
2048 case OO_GreaterEqual:
2049 return BO_GE;
2050 case OO_EqualEqual:
2051 return BO_EQ;
2052 case OO_ExclaimEqual:
2053 return BO_NE;
2054 case OO_Amp:
2055 return BO_And;
2056 case OO_Caret:
2057 return BO_Xor;
2058 case OO_Pipe:
2059 return BO_Or;
2060 case OO_AmpAmp:
2061 return BO_LAnd;
2062 case OO_PipePipe:
2063 return BO_LOr;
2064 case OO_Equal:
2065 return BO_Assign;
2066 case OO_StarEqual:
2067 return BO_MulAssign;
2068 case OO_SlashEqual:
2069 return BO_DivAssign;
2070 case OO_PercentEqual:
2071 return BO_RemAssign;
2072 case OO_PlusEqual:
2073 return BO_AddAssign;
2074 case OO_MinusEqual:
2075 return BO_SubAssign;
2076 case OO_LessLessEqual:
2077 return BO_ShlAssign;
2078 case OO_GreaterGreaterEqual:
2079 return BO_ShrAssign;
2080 case OO_AmpEqual:
2081 return BO_AndAssign;
2082 case OO_CaretEqual:
2083 return BO_XorAssign;
2084 case OO_PipeEqual:
2085 return BO_OrAssign;
2086 case OO_Comma:
2087 return BO_Comma;
2088 }
2089}
2090
2091template <typename NodeType>
2092inline std::optional<UnaryOperatorKind>
2093equivalentUnaryOperator(const NodeType &Node) {
2094 return Node.getOpcode();
2095}
2096
2097template <>
2098inline std::optional<UnaryOperatorKind>
2099equivalentUnaryOperator<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
2100 if (Node.getNumArgs() != 1 && Node.getOperator() != OO_PlusPlus &&
2101 Node.getOperator() != OO_MinusMinus)
2102 return std::nullopt;
2103 switch (Node.getOperator()) {
2104 default:
2105 return std::nullopt;
2106 case OO_Plus:
2107 return UO_Plus;
2108 case OO_Minus:
2109 return UO_Minus;
2110 case OO_Amp:
2111 return UO_AddrOf;
2112 case OO_Star:
2113 return UO_Deref;
2114 case OO_Tilde:
2115 return UO_Not;
2116 case OO_Exclaim:
2117 return UO_LNot;
2118 case OO_PlusPlus: {
2119 const auto *FD = Node.getDirectCallee();
2120 if (!FD)
2121 return std::nullopt;
2122 return FD->getNumParams() > 0 ? UO_PostInc : UO_PreInc;
2123 }
2124 case OO_MinusMinus: {
2125 const auto *FD = Node.getDirectCallee();
2126 if (!FD)
2127 return std::nullopt;
2128 return FD->getNumParams() > 0 ? UO_PostDec : UO_PreDec;
2129 }
2130 case OO_Coawait:
2131 return UO_Coawait;
2132 }
2133}
2134
2135template <typename NodeType> inline const Expr *getLHS(const NodeType &Node) {
2136 return Node.getLHS();
2137}
2138template <>
2139inline const Expr *
2140getLHS<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
2141 if (!internal::equivalentBinaryOperator(Node))
2142 return nullptr;
2143 return Node.getArg(0);
2144}
2145template <typename NodeType> inline const Expr *getRHS(const NodeType &Node) {
2146 return Node.getRHS();
2147}
2148template <>
2149inline const Expr *
2150getRHS<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
2151 if (!internal::equivalentBinaryOperator(Node))
2152 return nullptr;
2153 return Node.getArg(1);
2154}
2155template <typename NodeType>
2156inline const Expr *getSubExpr(const NodeType &Node) {
2157 return Node.getSubExpr();
2158}
2159template <>
2160inline const Expr *
2161getSubExpr<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
2162 if (!internal::equivalentUnaryOperator(Node) &&
2163 Node.getOperator() != OO_Arrow) {
2164 return nullptr;
2165 }
2166 return Node.getArg(0);
2167}
2168
2169template <typename Ty>
2170struct HasSizeMatcher {
2171 static bool hasSize(const Ty &Node, unsigned int N) {
2172 return Node.getSize() == N;
2173 }
2174};
2175
2176template <>
2177inline bool HasSizeMatcher<StringLiteral>::hasSize(
2178 const StringLiteral &Node, unsigned int N) {
2179 return Node.getLength() == N;
2180}
2181
2182template <typename Ty>
2183struct GetSourceExpressionMatcher {
2184 static const Expr *get(const Ty &Node) {
2185 return Node.getSubExpr();
2186 }
2187};
2188
2189template <>
2190inline const Expr *GetSourceExpressionMatcher<OpaqueValueExpr>::get(
2191 const OpaqueValueExpr &Node) {
2192 return Node.getSourceExpr();
2193}
2194
2195template <typename Ty>
2196struct CompoundStmtMatcher {
2197 static const CompoundStmt *get(const Ty &Node) {
2198 return &Node;
2199 }
2200};
2201
2202template <>
2203inline const CompoundStmt *
2204CompoundStmtMatcher<StmtExpr>::get(const StmtExpr &Node) {
2205 return Node.getSubStmt();
2206}
2207
2208/// If \p Loc is (transitively) expanded from macro \p MacroName, returns the
2209/// location (in the chain of expansions) at which \p MacroName was
2210/// expanded. Since the macro may have been expanded inside a series of
2211/// expansions, that location may itself be a MacroID.
2212std::optional<SourceLocation> getExpansionLocOfMacro(StringRef MacroName,
2213 SourceLocation Loc,
2214 const ASTContext &Context);
2215
2216inline std::optional<StringRef> getOpName(const UnaryOperator &Node) {
2217 return Node.getOpcodeStr(Node.getOpcode());
2218}
2219inline std::optional<StringRef> getOpName(const BinaryOperator &Node) {
2220 return Node.getOpcodeStr();
2221}
2222inline StringRef getOpName(const CXXRewrittenBinaryOperator &Node) {
2223 return Node.getOpcodeStr();
2224}
2225inline std::optional<StringRef> getOpName(const CXXOperatorCallExpr &Node) {
2226 if (const char *Str = getOperatorSpelling(Node.getOperator()))
2227 return Str;
2228 return std::nullopt;
2229}
2230inline StringRef getOpName(const CXXFoldExpr &Node) {
2231 return BinaryOperator::getOpcodeStr(Node.getOperator());
2232}
2233
2234/// Matches overloaded operators with a specific name.
2235///
2236/// The type argument ArgT is not used by this matcher but is used by
2237/// PolymorphicMatcher and should be std::vector<std::string>>.
2238template <typename T, typename ArgT = std::vector<std::string>>
2239class HasAnyOperatorNameMatcher : public SingleNodeMatcherInterface<T> {
2240 static_assert(std::is_same<T, BinaryOperator>::value ||
2241 std::is_same<T, CXXOperatorCallExpr>::value ||
2242 std::is_same<T, CXXRewrittenBinaryOperator>::value ||
2243 std::is_same<T, UnaryOperator>::value,
2244 "Matcher only supports `BinaryOperator`, `UnaryOperator`, "
2245 "`CXXOperatorCallExpr` and `CXXRewrittenBinaryOperator`");
2246 static_assert(std::is_same<ArgT, std::vector<std::string>>::value,
2247 "Matcher ArgT must be std::vector<std::string>");
2248
2249public:
2250 explicit HasAnyOperatorNameMatcher(std::vector<std::string> Names)
2251 : SingleNodeMatcherInterface<T>(), Names(std::move(Names)) {}
2252
2253 bool matchesNode(const T &Node) const override {
2254 std::optional<StringRef> OptOpName = getOpName(Node);
2255 return OptOpName && llvm::is_contained(Names, *OptOpName);
2256 }
2257
2258private:
2259 static std::optional<StringRef> getOpName(const UnaryOperator &Node) {
2260 return Node.getOpcodeStr(Node.getOpcode());
2261 }
2262 static std::optional<StringRef> getOpName(const BinaryOperator &Node) {
2263 return Node.getOpcodeStr();
2264 }
2265 static StringRef getOpName(const CXXRewrittenBinaryOperator &Node) {
2266 return Node.getOpcodeStr();
2267 }
2268 static std::optional<StringRef> getOpName(const CXXOperatorCallExpr &Node) {
2269 if (const char *Str = getOperatorSpelling(Node.getOperator()))
2270 return Str;
2271 return std::nullopt;
2272 }
2273
2274 std::vector<std::string> Names;
2275};
2276
2277using HasOpNameMatcher =
2278 PolymorphicMatcher<HasAnyOperatorNameMatcher,
2279 void(
2280 TypeList<BinaryOperator, CXXOperatorCallExpr,
2281 CXXRewrittenBinaryOperator, UnaryOperator>),
2282 std::vector<std::string>>;
2283
2284HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef<const StringRef *> NameRefs);
2285
2286using HasOverloadOpNameMatcher =
2287 PolymorphicMatcher<HasOverloadedOperatorNameMatcher,
2288 void(TypeList<CXXOperatorCallExpr, FunctionDecl>),
2289 std::vector<std::string>>;
2290
2291HasOverloadOpNameMatcher
2292hasAnyOverloadedOperatorNameFunc(ArrayRef<const StringRef *> NameRefs);
2293
2294/// Returns true if \p Node has a base specifier matching \p BaseSpec.
2295///
2296/// A class is not considered to be derived from itself.
2297bool matchesAnyBase(const CXXRecordDecl &Node,
2298 const Matcher<CXXBaseSpecifier> &BaseSpecMatcher,
2299 ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder);
2300
2301std::shared_ptr<llvm::Regex> createAndVerifyRegex(StringRef Regex,
2302 llvm::Regex::RegexFlags Flags,
2303 StringRef MatcherID);
2304
2305inline bool
2306MatchTemplateArgLocAt(const DeclRefExpr &Node, unsigned int Index,
2307 internal::Matcher<TemplateArgumentLoc> InnerMatcher,
2308 internal::ASTMatchFinder *Finder,
2309 internal::BoundNodesTreeBuilder *Builder) {
2310 llvm::ArrayRef<TemplateArgumentLoc> ArgLocs = Node.template_arguments();
2311 return Index < ArgLocs.size() &&
2312 InnerMatcher.matches(ArgLocs[Index], Finder, Builder);
2313}
2314
2315inline bool
2316MatchTemplateArgLocAt(const TemplateSpecializationTypeLoc &Node,
2317 unsigned int Index,
2318 internal::Matcher<TemplateArgumentLoc> InnerMatcher,
2319 internal::ASTMatchFinder *Finder,
2320 internal::BoundNodesTreeBuilder *Builder) {
2321 return !Node.isNull() && Index < Node.getNumArgs() &&
2322 InnerMatcher.matches(Node.getArgLoc(Index), Finder, Builder);
2323}
2324
2325inline std::string getDependentName(const DependentScopeDeclRefExpr &node) {
2326 return node.getDeclName().getAsString();
2327}
2328
2329inline std::string getDependentName(const DependentNameType &node) {
2330 return node.getIdentifier()->getName().str();
2331}
2332
2333} // namespace internal
2334
2335} // namespace ast_matchers
2336
2337} // namespace clang
2338
2339#endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H
#define V(N, I)
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
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:188
static constexpr ASTNodeKind getFromNodeKind()
Construct an identifier for T.
StringRef getOpcodeStr() const
Definition Expr.h:4040
Maps string IDs to AST nodes matched by parts of a matcher.
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::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions &DiagOpts, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
bool matches(const til::SExpr *E1, const til::SExpr *E2)
RangeSelector node(std::string ID)
Selects a node, including trailing semicolon, if any (for declarations and non-expression statements)...
The JSON file list parser is used to communicate input to InstallAPI.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Definition Specifiers.h:123
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.
@ Result
The result type of a method or function.
Definition TypeBase.h:905
const FunctionProtoType * T
@ Type
The name was classified as a type.
Definition Sema.h:562
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword.
@ Other
Other implicit parameter.
Definition Decl.h:1745
typename enable_if< B, T >::Type enable_if_t
Definition hlsl_detail.h:31
unsigned long uint64_t
#define false
Definition stdbool.h:26