1e5dd7070Spatrick //===- ASTMatchersInternal.cpp - Structural query framework ---------------===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // Implements the base layer of the matcher framework.
10e5dd7070Spatrick //
11e5dd7070Spatrick //===----------------------------------------------------------------------===//
12e5dd7070Spatrick
13e5dd7070Spatrick #include "clang/ASTMatchers/ASTMatchersInternal.h"
14e5dd7070Spatrick #include "clang/AST/ASTContext.h"
15e5dd7070Spatrick #include "clang/AST/ASTTypeTraits.h"
16e5dd7070Spatrick #include "clang/AST/Decl.h"
17e5dd7070Spatrick #include "clang/AST/DeclTemplate.h"
18ec727ea7Spatrick #include "clang/AST/ParentMapContext.h"
19e5dd7070Spatrick #include "clang/AST/PrettyPrinter.h"
20e5dd7070Spatrick #include "clang/ASTMatchers/ASTMatchers.h"
21e5dd7070Spatrick #include "clang/Basic/LLVM.h"
22ec727ea7Spatrick #include "clang/Lex/Lexer.h"
23e5dd7070Spatrick #include "llvm/ADT/ArrayRef.h"
24e5dd7070Spatrick #include "llvm/ADT/IntrusiveRefCntPtr.h"
25e5dd7070Spatrick #include "llvm/ADT/SmallString.h"
26e5dd7070Spatrick #include "llvm/ADT/SmallVector.h"
27e5dd7070Spatrick #include "llvm/ADT/StringRef.h"
28e5dd7070Spatrick #include "llvm/Support/Casting.h"
29e5dd7070Spatrick #include "llvm/Support/ErrorHandling.h"
30e5dd7070Spatrick #include "llvm/Support/ManagedStatic.h"
31ec727ea7Spatrick #include "llvm/Support/Regex.h"
32ec727ea7Spatrick #include "llvm/Support/WithColor.h"
33e5dd7070Spatrick #include "llvm/Support/raw_ostream.h"
34e5dd7070Spatrick #include <algorithm>
35e5dd7070Spatrick #include <cassert>
36e5dd7070Spatrick #include <cstddef>
37*12c85518Srobert #include <optional>
38e5dd7070Spatrick #include <string>
39e5dd7070Spatrick #include <utility>
40e5dd7070Spatrick #include <vector>
41e5dd7070Spatrick
42e5dd7070Spatrick namespace clang {
43e5dd7070Spatrick namespace ast_matchers {
44e5dd7070Spatrick
AST_MATCHER_P(ObjCMessageExpr,hasAnySelectorMatcher,std::vector<std::string>,Matches)45e5dd7070Spatrick AST_MATCHER_P(ObjCMessageExpr, hasAnySelectorMatcher, std::vector<std::string>,
46e5dd7070Spatrick Matches) {
47ec727ea7Spatrick return llvm::is_contained(Matches, Node.getSelector().getAsString());
48e5dd7070Spatrick }
49e5dd7070Spatrick
50e5dd7070Spatrick namespace internal {
51e5dd7070Spatrick
52a9ac8606Spatrick static bool notUnaryOperator(const DynTypedNode &DynNode,
53a9ac8606Spatrick ASTMatchFinder *Finder,
54ec727ea7Spatrick BoundNodesTreeBuilder *Builder,
55e5dd7070Spatrick ArrayRef<DynTypedMatcher> InnerMatchers);
56e5dd7070Spatrick
57a9ac8606Spatrick static bool allOfVariadicOperator(const DynTypedNode &DynNode,
58a9ac8606Spatrick ASTMatchFinder *Finder,
59ec727ea7Spatrick BoundNodesTreeBuilder *Builder,
60ec727ea7Spatrick ArrayRef<DynTypedMatcher> InnerMatchers);
61ec727ea7Spatrick
62a9ac8606Spatrick static bool eachOfVariadicOperator(const DynTypedNode &DynNode,
63a9ac8606Spatrick ASTMatchFinder *Finder,
64ec727ea7Spatrick BoundNodesTreeBuilder *Builder,
65ec727ea7Spatrick ArrayRef<DynTypedMatcher> InnerMatchers);
66ec727ea7Spatrick
67a9ac8606Spatrick static bool anyOfVariadicOperator(const DynTypedNode &DynNode,
68a9ac8606Spatrick ASTMatchFinder *Finder,
69ec727ea7Spatrick BoundNodesTreeBuilder *Builder,
70ec727ea7Spatrick ArrayRef<DynTypedMatcher> InnerMatchers);
71ec727ea7Spatrick
72a9ac8606Spatrick static bool optionallyVariadicOperator(const DynTypedNode &DynNode,
73e5dd7070Spatrick ASTMatchFinder *Finder,
74e5dd7070Spatrick BoundNodesTreeBuilder *Builder,
75e5dd7070Spatrick ArrayRef<DynTypedMatcher> InnerMatchers);
76e5dd7070Spatrick
matchesAnyBase(const CXXRecordDecl & Node,const Matcher<CXXBaseSpecifier> & BaseSpecMatcher,ASTMatchFinder * Finder,BoundNodesTreeBuilder * Builder)77ec727ea7Spatrick bool matchesAnyBase(const CXXRecordDecl &Node,
78ec727ea7Spatrick const Matcher<CXXBaseSpecifier> &BaseSpecMatcher,
79ec727ea7Spatrick ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) {
80ec727ea7Spatrick if (!Node.hasDefinition())
81ec727ea7Spatrick return false;
82e5dd7070Spatrick
83ec727ea7Spatrick CXXBasePaths Paths;
84ec727ea7Spatrick Paths.setOrigin(&Node);
85e5dd7070Spatrick
86ec727ea7Spatrick const auto basePredicate =
87ec727ea7Spatrick [Finder, Builder, &BaseSpecMatcher](const CXXBaseSpecifier *BaseSpec,
88ec727ea7Spatrick CXXBasePath &IgnoredParam) {
89ec727ea7Spatrick BoundNodesTreeBuilder Result(*Builder);
90ec727ea7Spatrick if (BaseSpecMatcher.matches(*BaseSpec, Finder, Builder)) {
91ec727ea7Spatrick *Builder = std::move(Result);
92ec727ea7Spatrick return true;
93ec727ea7Spatrick }
94ec727ea7Spatrick return false;
95ec727ea7Spatrick };
96ec727ea7Spatrick
97ec727ea7Spatrick return Node.lookupInBases(basePredicate, Paths,
98ec727ea7Spatrick /*LookupInDependent =*/true);
99ec727ea7Spatrick }
100e5dd7070Spatrick
visitMatches(Visitor * ResultVisitor)101e5dd7070Spatrick void BoundNodesTreeBuilder::visitMatches(Visitor *ResultVisitor) {
102e5dd7070Spatrick if (Bindings.empty())
103e5dd7070Spatrick Bindings.push_back(BoundNodesMap());
104e5dd7070Spatrick for (BoundNodesMap &Binding : Bindings) {
105e5dd7070Spatrick ResultVisitor->visitMatch(BoundNodes(Binding));
106e5dd7070Spatrick }
107e5dd7070Spatrick }
108e5dd7070Spatrick
109e5dd7070Spatrick namespace {
110e5dd7070Spatrick
111e5dd7070Spatrick using VariadicOperatorFunction = bool (*)(
112ec727ea7Spatrick const DynTypedNode &DynNode, ASTMatchFinder *Finder,
113e5dd7070Spatrick BoundNodesTreeBuilder *Builder, ArrayRef<DynTypedMatcher> InnerMatchers);
114e5dd7070Spatrick
115e5dd7070Spatrick template <VariadicOperatorFunction Func>
116e5dd7070Spatrick class VariadicMatcher : public DynMatcherInterface {
117e5dd7070Spatrick public:
VariadicMatcher(std::vector<DynTypedMatcher> InnerMatchers)118e5dd7070Spatrick VariadicMatcher(std::vector<DynTypedMatcher> InnerMatchers)
119e5dd7070Spatrick : InnerMatchers(std::move(InnerMatchers)) {}
120e5dd7070Spatrick
dynMatches(const DynTypedNode & DynNode,ASTMatchFinder * Finder,BoundNodesTreeBuilder * Builder) const121ec727ea7Spatrick bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
122e5dd7070Spatrick BoundNodesTreeBuilder *Builder) const override {
123e5dd7070Spatrick return Func(DynNode, Finder, Builder, InnerMatchers);
124e5dd7070Spatrick }
125e5dd7070Spatrick
126e5dd7070Spatrick private:
127e5dd7070Spatrick std::vector<DynTypedMatcher> InnerMatchers;
128e5dd7070Spatrick };
129e5dd7070Spatrick
130e5dd7070Spatrick class IdDynMatcher : public DynMatcherInterface {
131e5dd7070Spatrick public:
IdDynMatcher(StringRef ID,IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher)132e5dd7070Spatrick IdDynMatcher(StringRef ID,
133e5dd7070Spatrick IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher)
134e5dd7070Spatrick : ID(ID), InnerMatcher(std::move(InnerMatcher)) {}
135e5dd7070Spatrick
dynMatches(const DynTypedNode & DynNode,ASTMatchFinder * Finder,BoundNodesTreeBuilder * Builder) const136ec727ea7Spatrick bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
137e5dd7070Spatrick BoundNodesTreeBuilder *Builder) const override {
138e5dd7070Spatrick bool Result = InnerMatcher->dynMatches(DynNode, Finder, Builder);
139e5dd7070Spatrick if (Result) Builder->setBinding(ID, DynNode);
140e5dd7070Spatrick return Result;
141e5dd7070Spatrick }
142e5dd7070Spatrick
TraversalKind() const143*12c85518Srobert std::optional<clang::TraversalKind> TraversalKind() const override {
144e5dd7070Spatrick return InnerMatcher->TraversalKind();
145e5dd7070Spatrick }
146e5dd7070Spatrick
147e5dd7070Spatrick private:
148e5dd7070Spatrick const std::string ID;
149e5dd7070Spatrick const IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher;
150e5dd7070Spatrick };
151e5dd7070Spatrick
152e5dd7070Spatrick /// A matcher that always returns true.
153e5dd7070Spatrick class TrueMatcherImpl : public DynMatcherInterface {
154e5dd7070Spatrick public:
155a9ac8606Spatrick TrueMatcherImpl() = default;
156e5dd7070Spatrick
dynMatches(const DynTypedNode &,ASTMatchFinder *,BoundNodesTreeBuilder *) const157ec727ea7Spatrick bool dynMatches(const DynTypedNode &, ASTMatchFinder *,
158e5dd7070Spatrick BoundNodesTreeBuilder *) const override {
159e5dd7070Spatrick return true;
160e5dd7070Spatrick }
161e5dd7070Spatrick };
162e5dd7070Spatrick
163ec727ea7Spatrick /// A matcher that specifies a particular \c TraversalKind.
164ec727ea7Spatrick ///
165ec727ea7Spatrick /// The kind provided to the constructor overrides any kind that may be
166ec727ea7Spatrick /// specified by the `InnerMatcher`.
167ec727ea7Spatrick class DynTraversalMatcherImpl : public DynMatcherInterface {
168ec727ea7Spatrick public:
DynTraversalMatcherImpl(clang::TraversalKind TK,IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher)169ec727ea7Spatrick explicit DynTraversalMatcherImpl(
170ec727ea7Spatrick clang::TraversalKind TK,
171ec727ea7Spatrick IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher)
172ec727ea7Spatrick : TK(TK), InnerMatcher(std::move(InnerMatcher)) {}
173ec727ea7Spatrick
dynMatches(const DynTypedNode & DynNode,ASTMatchFinder * Finder,BoundNodesTreeBuilder * Builder) const174ec727ea7Spatrick bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
175ec727ea7Spatrick BoundNodesTreeBuilder *Builder) const override {
176ec727ea7Spatrick return this->InnerMatcher->dynMatches(DynNode, Finder, Builder);
177ec727ea7Spatrick }
178ec727ea7Spatrick
TraversalKind() const179*12c85518Srobert std::optional<clang::TraversalKind> TraversalKind() const override {
180ec727ea7Spatrick return TK;
181ec727ea7Spatrick }
182ec727ea7Spatrick
183ec727ea7Spatrick private:
184ec727ea7Spatrick clang::TraversalKind TK;
185ec727ea7Spatrick IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher;
186ec727ea7Spatrick };
187ec727ea7Spatrick
188e5dd7070Spatrick } // namespace
189e5dd7070Spatrick
isTraversalIgnoringImplicitNodes() const190a9ac8606Spatrick bool ASTMatchFinder::isTraversalIgnoringImplicitNodes() const {
191a9ac8606Spatrick return getASTContext().getParentMapContext().getTraversalKind() ==
192a9ac8606Spatrick TK_IgnoreUnlessSpelledInSource;
193a9ac8606Spatrick }
194e5dd7070Spatrick
195ec727ea7Spatrick DynTypedMatcher
constructVariadic(DynTypedMatcher::VariadicOperator Op,ASTNodeKind SupportedKind,std::vector<DynTypedMatcher> InnerMatchers)196ec727ea7Spatrick DynTypedMatcher::constructVariadic(DynTypedMatcher::VariadicOperator Op,
197ec727ea7Spatrick ASTNodeKind SupportedKind,
198e5dd7070Spatrick std::vector<DynTypedMatcher> InnerMatchers) {
199e5dd7070Spatrick assert(!InnerMatchers.empty() && "Array must not be empty.");
200e5dd7070Spatrick assert(llvm::all_of(InnerMatchers,
201e5dd7070Spatrick [SupportedKind](const DynTypedMatcher &M) {
202e5dd7070Spatrick return M.canConvertTo(SupportedKind);
203e5dd7070Spatrick }) &&
204e5dd7070Spatrick "InnerMatchers must be convertible to SupportedKind!");
205e5dd7070Spatrick
206e5dd7070Spatrick // We must relax the restrict kind here.
207e5dd7070Spatrick // The different operators might deal differently with a mismatch.
208e5dd7070Spatrick // Make it the same as SupportedKind, since that is the broadest type we are
209e5dd7070Spatrick // allowed to accept.
210e5dd7070Spatrick auto RestrictKind = SupportedKind;
211e5dd7070Spatrick
212e5dd7070Spatrick switch (Op) {
213e5dd7070Spatrick case VO_AllOf:
214e5dd7070Spatrick // In the case of allOf() we must pass all the checks, so making
215e5dd7070Spatrick // RestrictKind the most restrictive can save us time. This way we reject
216e5dd7070Spatrick // invalid types earlier and we can elide the kind checks inside the
217e5dd7070Spatrick // matcher.
218e5dd7070Spatrick for (auto &IM : InnerMatchers) {
219ec727ea7Spatrick RestrictKind =
220ec727ea7Spatrick ASTNodeKind::getMostDerivedType(RestrictKind, IM.RestrictKind);
221e5dd7070Spatrick }
222e5dd7070Spatrick return DynTypedMatcher(
223e5dd7070Spatrick SupportedKind, RestrictKind,
224a9ac8606Spatrick new VariadicMatcher<allOfVariadicOperator>(std::move(InnerMatchers)));
225e5dd7070Spatrick
226e5dd7070Spatrick case VO_AnyOf:
227e5dd7070Spatrick return DynTypedMatcher(
228e5dd7070Spatrick SupportedKind, RestrictKind,
229a9ac8606Spatrick new VariadicMatcher<anyOfVariadicOperator>(std::move(InnerMatchers)));
230e5dd7070Spatrick
231e5dd7070Spatrick case VO_EachOf:
232e5dd7070Spatrick return DynTypedMatcher(
233e5dd7070Spatrick SupportedKind, RestrictKind,
234a9ac8606Spatrick new VariadicMatcher<eachOfVariadicOperator>(std::move(InnerMatchers)));
235e5dd7070Spatrick
236e5dd7070Spatrick case VO_Optionally:
237e5dd7070Spatrick return DynTypedMatcher(SupportedKind, RestrictKind,
238a9ac8606Spatrick new VariadicMatcher<optionallyVariadicOperator>(
239e5dd7070Spatrick std::move(InnerMatchers)));
240e5dd7070Spatrick
241e5dd7070Spatrick case VO_UnaryNot:
242e5dd7070Spatrick // FIXME: Implement the Not operator to take a single matcher instead of a
243e5dd7070Spatrick // vector.
244e5dd7070Spatrick return DynTypedMatcher(
245e5dd7070Spatrick SupportedKind, RestrictKind,
246a9ac8606Spatrick new VariadicMatcher<notUnaryOperator>(std::move(InnerMatchers)));
247e5dd7070Spatrick }
248e5dd7070Spatrick llvm_unreachable("Invalid Op value.");
249e5dd7070Spatrick }
250e5dd7070Spatrick
251ec727ea7Spatrick DynTypedMatcher
constructRestrictedWrapper(const DynTypedMatcher & InnerMatcher,ASTNodeKind RestrictKind)252ec727ea7Spatrick DynTypedMatcher::constructRestrictedWrapper(const DynTypedMatcher &InnerMatcher,
253ec727ea7Spatrick ASTNodeKind RestrictKind) {
254e5dd7070Spatrick DynTypedMatcher Copy = InnerMatcher;
255e5dd7070Spatrick Copy.RestrictKind = RestrictKind;
256e5dd7070Spatrick return Copy;
257e5dd7070Spatrick }
258e5dd7070Spatrick
withTraversalKind(TraversalKind TK)259a9ac8606Spatrick DynTypedMatcher DynTypedMatcher::withTraversalKind(TraversalKind TK) {
260e5dd7070Spatrick auto Copy = *this;
261ec727ea7Spatrick Copy.Implementation =
262ec727ea7Spatrick new DynTraversalMatcherImpl(TK, std::move(Copy.Implementation));
263e5dd7070Spatrick return Copy;
264e5dd7070Spatrick }
265e5dd7070Spatrick
trueMatcher(ASTNodeKind NodeKind)266ec727ea7Spatrick DynTypedMatcher DynTypedMatcher::trueMatcher(ASTNodeKind NodeKind) {
267a9ac8606Spatrick // We only ever need one instance of TrueMatcherImpl, so we create a static
268a9ac8606Spatrick // instance and reuse it to reduce the overhead of the matcher and increase
269a9ac8606Spatrick // the chance of cache hits.
270a9ac8606Spatrick static const llvm::IntrusiveRefCntPtr<TrueMatcherImpl> Instance =
271a9ac8606Spatrick new TrueMatcherImpl();
272a9ac8606Spatrick return DynTypedMatcher(NodeKind, NodeKind, Instance);
273ec727ea7Spatrick }
274ec727ea7Spatrick
canMatchNodesOfKind(ASTNodeKind Kind) const275ec727ea7Spatrick bool DynTypedMatcher::canMatchNodesOfKind(ASTNodeKind Kind) const {
276ec727ea7Spatrick return RestrictKind.isBaseOf(Kind);
277ec727ea7Spatrick }
278ec727ea7Spatrick
dynCastTo(const ASTNodeKind Kind) const279ec727ea7Spatrick DynTypedMatcher DynTypedMatcher::dynCastTo(const ASTNodeKind Kind) const {
280ec727ea7Spatrick auto Copy = *this;
281ec727ea7Spatrick Copy.SupportedKind = Kind;
282ec727ea7Spatrick Copy.RestrictKind = ASTNodeKind::getMostDerivedType(Kind, RestrictKind);
283ec727ea7Spatrick return Copy;
284ec727ea7Spatrick }
285ec727ea7Spatrick
matches(const DynTypedNode & DynNode,ASTMatchFinder * Finder,BoundNodesTreeBuilder * Builder) const286ec727ea7Spatrick bool DynTypedMatcher::matches(const DynTypedNode &DynNode,
287e5dd7070Spatrick ASTMatchFinder *Finder,
288e5dd7070Spatrick BoundNodesTreeBuilder *Builder) const {
289e5dd7070Spatrick TraversalKindScope RAII(Finder->getASTContext(),
290e5dd7070Spatrick Implementation->TraversalKind());
291e5dd7070Spatrick
292a9ac8606Spatrick if (Finder->isTraversalIgnoringImplicitNodes() &&
293a9ac8606Spatrick Finder->IsMatchingInASTNodeNotSpelledInSource())
294a9ac8606Spatrick return false;
295a9ac8606Spatrick
296a9ac8606Spatrick if (!Finder->isTraversalIgnoringImplicitNodes() &&
297a9ac8606Spatrick Finder->IsMatchingInASTNodeNotAsIs())
298a9ac8606Spatrick return false;
299a9ac8606Spatrick
300ec727ea7Spatrick auto N =
301ec727ea7Spatrick Finder->getASTContext().getParentMapContext().traverseIgnored(DynNode);
302e5dd7070Spatrick
303e5dd7070Spatrick if (RestrictKind.isBaseOf(N.getNodeKind()) &&
304e5dd7070Spatrick Implementation->dynMatches(N, Finder, Builder)) {
305e5dd7070Spatrick return true;
306e5dd7070Spatrick }
307e5dd7070Spatrick // Delete all bindings when a matcher does not match.
308e5dd7070Spatrick // This prevents unexpected exposure of bound nodes in unmatches
309e5dd7070Spatrick // branches of the match tree.
310e5dd7070Spatrick Builder->removeBindings([](const BoundNodesMap &) { return true; });
311e5dd7070Spatrick return false;
312e5dd7070Spatrick }
313e5dd7070Spatrick
matchesNoKindCheck(const DynTypedNode & DynNode,ASTMatchFinder * Finder,BoundNodesTreeBuilder * Builder) const314ec727ea7Spatrick bool DynTypedMatcher::matchesNoKindCheck(const DynTypedNode &DynNode,
315ec727ea7Spatrick ASTMatchFinder *Finder,
316e5dd7070Spatrick BoundNodesTreeBuilder *Builder) const {
317e5dd7070Spatrick TraversalKindScope raii(Finder->getASTContext(),
318e5dd7070Spatrick Implementation->TraversalKind());
319e5dd7070Spatrick
320a9ac8606Spatrick if (Finder->isTraversalIgnoringImplicitNodes() &&
321a9ac8606Spatrick Finder->IsMatchingInASTNodeNotSpelledInSource())
322a9ac8606Spatrick return false;
323a9ac8606Spatrick
324a9ac8606Spatrick if (!Finder->isTraversalIgnoringImplicitNodes() &&
325a9ac8606Spatrick Finder->IsMatchingInASTNodeNotAsIs())
326a9ac8606Spatrick return false;
327a9ac8606Spatrick
328ec727ea7Spatrick auto N =
329ec727ea7Spatrick Finder->getASTContext().getParentMapContext().traverseIgnored(DynNode);
330e5dd7070Spatrick
331e5dd7070Spatrick assert(RestrictKind.isBaseOf(N.getNodeKind()));
332e5dd7070Spatrick if (Implementation->dynMatches(N, Finder, Builder)) {
333e5dd7070Spatrick return true;
334e5dd7070Spatrick }
335e5dd7070Spatrick // Delete all bindings when a matcher does not match.
336e5dd7070Spatrick // This prevents unexpected exposure of bound nodes in unmatches
337e5dd7070Spatrick // branches of the match tree.
338e5dd7070Spatrick Builder->removeBindings([](const BoundNodesMap &) { return true; });
339e5dd7070Spatrick return false;
340e5dd7070Spatrick }
341e5dd7070Spatrick
tryBind(StringRef ID) const342*12c85518Srobert std::optional<DynTypedMatcher> DynTypedMatcher::tryBind(StringRef ID) const {
343*12c85518Srobert if (!AllowBind)
344*12c85518Srobert return std::nullopt;
345e5dd7070Spatrick auto Result = *this;
346e5dd7070Spatrick Result.Implementation =
347e5dd7070Spatrick new IdDynMatcher(ID, std::move(Result.Implementation));
348e5dd7070Spatrick return std::move(Result);
349e5dd7070Spatrick }
350e5dd7070Spatrick
canConvertTo(ASTNodeKind To) const351ec727ea7Spatrick bool DynTypedMatcher::canConvertTo(ASTNodeKind To) const {
352e5dd7070Spatrick const auto From = getSupportedKind();
353ec727ea7Spatrick auto QualKind = ASTNodeKind::getFromNodeKind<QualType>();
354ec727ea7Spatrick auto TypeKind = ASTNodeKind::getFromNodeKind<Type>();
355e5dd7070Spatrick /// Mimic the implicit conversions of Matcher<>.
356e5dd7070Spatrick /// - From Matcher<Type> to Matcher<QualType>
357e5dd7070Spatrick if (From.isSame(TypeKind) && To.isSame(QualKind)) return true;
358e5dd7070Spatrick /// - From Matcher<Base> to Matcher<Derived>
359e5dd7070Spatrick return From.isBaseOf(To);
360e5dd7070Spatrick }
361e5dd7070Spatrick
addMatch(const BoundNodesTreeBuilder & Other)362e5dd7070Spatrick void BoundNodesTreeBuilder::addMatch(const BoundNodesTreeBuilder &Other) {
363e5dd7070Spatrick Bindings.append(Other.Bindings.begin(), Other.Bindings.end());
364e5dd7070Spatrick }
365e5dd7070Spatrick
notUnaryOperator(const DynTypedNode & DynNode,ASTMatchFinder * Finder,BoundNodesTreeBuilder * Builder,ArrayRef<DynTypedMatcher> InnerMatchers)366a9ac8606Spatrick static bool notUnaryOperator(const DynTypedNode &DynNode,
367a9ac8606Spatrick ASTMatchFinder *Finder,
368ec727ea7Spatrick BoundNodesTreeBuilder *Builder,
369e5dd7070Spatrick ArrayRef<DynTypedMatcher> InnerMatchers) {
370e5dd7070Spatrick if (InnerMatchers.size() != 1)
371e5dd7070Spatrick return false;
372e5dd7070Spatrick
373e5dd7070Spatrick // The 'unless' matcher will always discard the result:
374e5dd7070Spatrick // If the inner matcher doesn't match, unless returns true,
375e5dd7070Spatrick // but the inner matcher cannot have bound anything.
376e5dd7070Spatrick // If the inner matcher matches, the result is false, and
377e5dd7070Spatrick // any possible binding will be discarded.
378e5dd7070Spatrick // We still need to hand in all the bound nodes up to this
379e5dd7070Spatrick // point so the inner matcher can depend on bound nodes,
380e5dd7070Spatrick // and we need to actively discard the bound nodes, otherwise
381e5dd7070Spatrick // the inner matcher will reset the bound nodes if it doesn't
382e5dd7070Spatrick // match, but this would be inversed by 'unless'.
383e5dd7070Spatrick BoundNodesTreeBuilder Discard(*Builder);
384e5dd7070Spatrick return !InnerMatchers[0].matches(DynNode, Finder, &Discard);
385e5dd7070Spatrick }
386e5dd7070Spatrick
allOfVariadicOperator(const DynTypedNode & DynNode,ASTMatchFinder * Finder,BoundNodesTreeBuilder * Builder,ArrayRef<DynTypedMatcher> InnerMatchers)387a9ac8606Spatrick static bool allOfVariadicOperator(const DynTypedNode &DynNode,
388a9ac8606Spatrick ASTMatchFinder *Finder,
389e5dd7070Spatrick BoundNodesTreeBuilder *Builder,
390e5dd7070Spatrick ArrayRef<DynTypedMatcher> InnerMatchers) {
391e5dd7070Spatrick // allOf leads to one matcher for each alternative in the first
392e5dd7070Spatrick // matcher combined with each alternative in the second matcher.
393e5dd7070Spatrick // Thus, we can reuse the same Builder.
394ec727ea7Spatrick return llvm::all_of(InnerMatchers, [&](const DynTypedMatcher &InnerMatcher) {
395ec727ea7Spatrick return InnerMatcher.matchesNoKindCheck(DynNode, Finder, Builder);
396ec727ea7Spatrick });
397e5dd7070Spatrick }
398e5dd7070Spatrick
eachOfVariadicOperator(const DynTypedNode & DynNode,ASTMatchFinder * Finder,BoundNodesTreeBuilder * Builder,ArrayRef<DynTypedMatcher> InnerMatchers)399a9ac8606Spatrick static bool eachOfVariadicOperator(const DynTypedNode &DynNode,
400a9ac8606Spatrick ASTMatchFinder *Finder,
401e5dd7070Spatrick BoundNodesTreeBuilder *Builder,
402e5dd7070Spatrick ArrayRef<DynTypedMatcher> InnerMatchers) {
403e5dd7070Spatrick BoundNodesTreeBuilder Result;
404e5dd7070Spatrick bool Matched = false;
405e5dd7070Spatrick for (const DynTypedMatcher &InnerMatcher : InnerMatchers) {
406e5dd7070Spatrick BoundNodesTreeBuilder BuilderInner(*Builder);
407e5dd7070Spatrick if (InnerMatcher.matches(DynNode, Finder, &BuilderInner)) {
408e5dd7070Spatrick Matched = true;
409e5dd7070Spatrick Result.addMatch(BuilderInner);
410e5dd7070Spatrick }
411e5dd7070Spatrick }
412e5dd7070Spatrick *Builder = std::move(Result);
413e5dd7070Spatrick return Matched;
414e5dd7070Spatrick }
415e5dd7070Spatrick
anyOfVariadicOperator(const DynTypedNode & DynNode,ASTMatchFinder * Finder,BoundNodesTreeBuilder * Builder,ArrayRef<DynTypedMatcher> InnerMatchers)416a9ac8606Spatrick static bool anyOfVariadicOperator(const DynTypedNode &DynNode,
417a9ac8606Spatrick ASTMatchFinder *Finder,
418e5dd7070Spatrick BoundNodesTreeBuilder *Builder,
419e5dd7070Spatrick ArrayRef<DynTypedMatcher> InnerMatchers) {
420e5dd7070Spatrick for (const DynTypedMatcher &InnerMatcher : InnerMatchers) {
421e5dd7070Spatrick BoundNodesTreeBuilder Result = *Builder;
422e5dd7070Spatrick if (InnerMatcher.matches(DynNode, Finder, &Result)) {
423e5dd7070Spatrick *Builder = std::move(Result);
424e5dd7070Spatrick return true;
425e5dd7070Spatrick }
426e5dd7070Spatrick }
427e5dd7070Spatrick return false;
428e5dd7070Spatrick }
429e5dd7070Spatrick
430a9ac8606Spatrick static bool
optionallyVariadicOperator(const DynTypedNode & DynNode,ASTMatchFinder * Finder,BoundNodesTreeBuilder * Builder,ArrayRef<DynTypedMatcher> InnerMatchers)431a9ac8606Spatrick optionallyVariadicOperator(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
432e5dd7070Spatrick BoundNodesTreeBuilder *Builder,
433e5dd7070Spatrick ArrayRef<DynTypedMatcher> InnerMatchers) {
434ec727ea7Spatrick if (InnerMatchers.size() != 1)
435ec727ea7Spatrick return false;
436ec727ea7Spatrick
437ec727ea7Spatrick BoundNodesTreeBuilder Result(*Builder);
438ec727ea7Spatrick if (InnerMatchers[0].matches(DynNode, Finder, &Result))
439e5dd7070Spatrick *Builder = std::move(Result);
440e5dd7070Spatrick return true;
441e5dd7070Spatrick }
442e5dd7070Spatrick
443e5dd7070Spatrick inline static
vectorFromRefs(ArrayRef<const StringRef * > NameRefs)444e5dd7070Spatrick std::vector<std::string> vectorFromRefs(ArrayRef<const StringRef *> NameRefs) {
445e5dd7070Spatrick std::vector<std::string> Names;
446ec727ea7Spatrick Names.reserve(NameRefs.size());
447e5dd7070Spatrick for (auto *Name : NameRefs)
448e5dd7070Spatrick Names.emplace_back(*Name);
449e5dd7070Spatrick return Names;
450e5dd7070Spatrick }
451e5dd7070Spatrick
hasAnyNameFunc(ArrayRef<const StringRef * > NameRefs)452e5dd7070Spatrick Matcher<NamedDecl> hasAnyNameFunc(ArrayRef<const StringRef *> NameRefs) {
453ec727ea7Spatrick return internal::Matcher<NamedDecl>(
454ec727ea7Spatrick new internal::HasNameMatcher(vectorFromRefs(NameRefs)));
455e5dd7070Spatrick }
456e5dd7070Spatrick
hasAnySelectorFunc(ArrayRef<const StringRef * > NameRefs)457e5dd7070Spatrick Matcher<ObjCMessageExpr> hasAnySelectorFunc(
458e5dd7070Spatrick ArrayRef<const StringRef *> NameRefs) {
459e5dd7070Spatrick return hasAnySelectorMatcher(vectorFromRefs(NameRefs));
460e5dd7070Spatrick }
461e5dd7070Spatrick
hasAnyOperatorNameFunc(ArrayRef<const StringRef * > NameRefs)462ec727ea7Spatrick HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef<const StringRef *> NameRefs) {
463ec727ea7Spatrick return HasOpNameMatcher(vectorFromRefs(NameRefs));
464ec727ea7Spatrick }
465ec727ea7Spatrick
466ec727ea7Spatrick HasOverloadOpNameMatcher
hasAnyOverloadedOperatorNameFunc(ArrayRef<const StringRef * > NameRefs)467ec727ea7Spatrick hasAnyOverloadedOperatorNameFunc(ArrayRef<const StringRef *> NameRefs) {
468ec727ea7Spatrick return HasOverloadOpNameMatcher(vectorFromRefs(NameRefs));
469ec727ea7Spatrick }
470ec727ea7Spatrick
HasNameMatcher(std::vector<std::string> N)471e5dd7070Spatrick HasNameMatcher::HasNameMatcher(std::vector<std::string> N)
472*12c85518Srobert : UseUnqualifiedMatch(
473*12c85518Srobert llvm::all_of(N, [](StringRef Name) { return !Name.contains("::"); })),
474e5dd7070Spatrick Names(std::move(N)) {
475e5dd7070Spatrick #ifndef NDEBUG
476e5dd7070Spatrick for (StringRef Name : Names)
477e5dd7070Spatrick assert(!Name.empty());
478e5dd7070Spatrick #endif
479e5dd7070Spatrick }
480e5dd7070Spatrick
consumeNameSuffix(StringRef & FullName,StringRef Suffix)481e5dd7070Spatrick static bool consumeNameSuffix(StringRef &FullName, StringRef Suffix) {
482e5dd7070Spatrick StringRef Name = FullName;
483e5dd7070Spatrick if (!Name.endswith(Suffix))
484e5dd7070Spatrick return false;
485e5dd7070Spatrick Name = Name.drop_back(Suffix.size());
486e5dd7070Spatrick if (!Name.empty()) {
487e5dd7070Spatrick if (!Name.endswith("::"))
488e5dd7070Spatrick return false;
489e5dd7070Spatrick Name = Name.drop_back(2);
490e5dd7070Spatrick }
491e5dd7070Spatrick FullName = Name;
492e5dd7070Spatrick return true;
493e5dd7070Spatrick }
494e5dd7070Spatrick
getNodeName(const NamedDecl & Node,llvm::SmallString<128> & Scratch)495e5dd7070Spatrick static StringRef getNodeName(const NamedDecl &Node,
496e5dd7070Spatrick llvm::SmallString<128> &Scratch) {
497e5dd7070Spatrick // Simple name.
498e5dd7070Spatrick if (Node.getIdentifier())
499e5dd7070Spatrick return Node.getName();
500e5dd7070Spatrick
501e5dd7070Spatrick if (Node.getDeclName()) {
502e5dd7070Spatrick // Name needs to be constructed.
503e5dd7070Spatrick Scratch.clear();
504e5dd7070Spatrick llvm::raw_svector_ostream OS(Scratch);
505e5dd7070Spatrick Node.printName(OS);
506e5dd7070Spatrick return OS.str();
507e5dd7070Spatrick }
508e5dd7070Spatrick
509e5dd7070Spatrick return "(anonymous)";
510e5dd7070Spatrick }
511e5dd7070Spatrick
getNodeName(const RecordDecl & Node,llvm::SmallString<128> & Scratch)512e5dd7070Spatrick static StringRef getNodeName(const RecordDecl &Node,
513e5dd7070Spatrick llvm::SmallString<128> &Scratch) {
514e5dd7070Spatrick if (Node.getIdentifier()) {
515e5dd7070Spatrick return Node.getName();
516e5dd7070Spatrick }
517e5dd7070Spatrick Scratch.clear();
518e5dd7070Spatrick return ("(anonymous " + Node.getKindName() + ")").toStringRef(Scratch);
519e5dd7070Spatrick }
520e5dd7070Spatrick
getNodeName(const NamespaceDecl & Node,llvm::SmallString<128> & Scratch)521e5dd7070Spatrick static StringRef getNodeName(const NamespaceDecl &Node,
522e5dd7070Spatrick llvm::SmallString<128> &Scratch) {
523e5dd7070Spatrick return Node.isAnonymousNamespace() ? "(anonymous namespace)" : Node.getName();
524e5dd7070Spatrick }
525e5dd7070Spatrick
526e5dd7070Spatrick namespace {
527e5dd7070Spatrick
528e5dd7070Spatrick class PatternSet {
529e5dd7070Spatrick public:
PatternSet(ArrayRef<std::string> Names)530e5dd7070Spatrick PatternSet(ArrayRef<std::string> Names) {
531ec727ea7Spatrick Patterns.reserve(Names.size());
532e5dd7070Spatrick for (StringRef Name : Names)
533e5dd7070Spatrick Patterns.push_back({Name, Name.startswith("::")});
534e5dd7070Spatrick }
535e5dd7070Spatrick
536e5dd7070Spatrick /// Consumes the name suffix from each pattern in the set and removes the ones
537e5dd7070Spatrick /// that didn't match.
538e5dd7070Spatrick /// Return true if there are still any patterns left.
consumeNameSuffix(StringRef NodeName,bool CanSkip)539e5dd7070Spatrick bool consumeNameSuffix(StringRef NodeName, bool CanSkip) {
540e5dd7070Spatrick for (size_t I = 0; I < Patterns.size();) {
541e5dd7070Spatrick if (::clang::ast_matchers::internal::consumeNameSuffix(Patterns[I].P,
542e5dd7070Spatrick NodeName) ||
543e5dd7070Spatrick CanSkip) {
544e5dd7070Spatrick ++I;
545e5dd7070Spatrick } else {
546e5dd7070Spatrick Patterns.erase(Patterns.begin() + I);
547e5dd7070Spatrick }
548e5dd7070Spatrick }
549e5dd7070Spatrick return !Patterns.empty();
550e5dd7070Spatrick }
551e5dd7070Spatrick
552e5dd7070Spatrick /// Check if any of the patterns are a match.
553e5dd7070Spatrick /// A match will be a pattern that was fully consumed, that also matches the
554e5dd7070Spatrick /// 'fully qualified' requirement.
foundMatch(bool AllowFullyQualified) const555e5dd7070Spatrick bool foundMatch(bool AllowFullyQualified) const {
556ec727ea7Spatrick return llvm::any_of(Patterns, [&](const Pattern &Pattern) {
557ec727ea7Spatrick return Pattern.P.empty() &&
558ec727ea7Spatrick (AllowFullyQualified || !Pattern.IsFullyQualified);
559ec727ea7Spatrick });
560e5dd7070Spatrick }
561e5dd7070Spatrick
562e5dd7070Spatrick private:
563e5dd7070Spatrick struct Pattern {
564e5dd7070Spatrick StringRef P;
565e5dd7070Spatrick bool IsFullyQualified;
566e5dd7070Spatrick };
567e5dd7070Spatrick
568e5dd7070Spatrick llvm::SmallVector<Pattern, 8> Patterns;
569e5dd7070Spatrick };
570e5dd7070Spatrick
571e5dd7070Spatrick } // namespace
572e5dd7070Spatrick
matchesNodeUnqualified(const NamedDecl & Node) const573e5dd7070Spatrick bool HasNameMatcher::matchesNodeUnqualified(const NamedDecl &Node) const {
574e5dd7070Spatrick assert(UseUnqualifiedMatch);
575e5dd7070Spatrick llvm::SmallString<128> Scratch;
576e5dd7070Spatrick StringRef NodeName = getNodeName(Node, Scratch);
577e5dd7070Spatrick return llvm::any_of(Names, [&](StringRef Name) {
578e5dd7070Spatrick return consumeNameSuffix(Name, NodeName) && Name.empty();
579e5dd7070Spatrick });
580e5dd7070Spatrick }
581e5dd7070Spatrick
matchesNodeFullFast(const NamedDecl & Node) const582e5dd7070Spatrick bool HasNameMatcher::matchesNodeFullFast(const NamedDecl &Node) const {
583e5dd7070Spatrick PatternSet Patterns(Names);
584e5dd7070Spatrick llvm::SmallString<128> Scratch;
585e5dd7070Spatrick
586e5dd7070Spatrick // This function is copied and adapted from NamedDecl::printQualifiedName()
587e5dd7070Spatrick // By matching each part individually we optimize in a couple of ways:
588e5dd7070Spatrick // - We can exit early on the first failure.
589e5dd7070Spatrick // - We can skip inline/anonymous namespaces without another pass.
590e5dd7070Spatrick // - We print one name at a time, reducing the chance of overflowing the
591e5dd7070Spatrick // inlined space of the SmallString.
592e5dd7070Spatrick
593e5dd7070Spatrick // First, match the name.
594e5dd7070Spatrick if (!Patterns.consumeNameSuffix(getNodeName(Node, Scratch),
595e5dd7070Spatrick /*CanSkip=*/false))
596e5dd7070Spatrick return false;
597e5dd7070Spatrick
598e5dd7070Spatrick // Try to match each declaration context.
599e5dd7070Spatrick // We are allowed to skip anonymous and inline namespaces if they don't match.
600e5dd7070Spatrick const DeclContext *Ctx = Node.getDeclContext();
601e5dd7070Spatrick
602e5dd7070Spatrick if (Ctx->isFunctionOrMethod())
603e5dd7070Spatrick return Patterns.foundMatch(/*AllowFullyQualified=*/false);
604e5dd7070Spatrick
605e5dd7070Spatrick for (; Ctx; Ctx = Ctx->getParent()) {
606e5dd7070Spatrick // Linkage Spec can just be ignored
607e5dd7070Spatrick // FIXME: Any other DeclContext kinds that can be safely disregarded
608e5dd7070Spatrick if (isa<LinkageSpecDecl>(Ctx))
609e5dd7070Spatrick continue;
610e5dd7070Spatrick if (!isa<NamedDecl>(Ctx))
611e5dd7070Spatrick break;
612e5dd7070Spatrick if (Patterns.foundMatch(/*AllowFullyQualified=*/false))
613e5dd7070Spatrick return true;
614e5dd7070Spatrick
615e5dd7070Spatrick if (const auto *ND = dyn_cast<NamespaceDecl>(Ctx)) {
616e5dd7070Spatrick // If it matches (or we can skip it), continue.
617e5dd7070Spatrick if (Patterns.consumeNameSuffix(getNodeName(*ND, Scratch),
618e5dd7070Spatrick /*CanSkip=*/ND->isAnonymousNamespace() ||
619e5dd7070Spatrick ND->isInline()))
620e5dd7070Spatrick continue;
621e5dd7070Spatrick return false;
622e5dd7070Spatrick }
623e5dd7070Spatrick if (const auto *RD = dyn_cast<RecordDecl>(Ctx)) {
624e5dd7070Spatrick if (!isa<ClassTemplateSpecializationDecl>(Ctx)) {
625e5dd7070Spatrick if (Patterns.consumeNameSuffix(getNodeName(*RD, Scratch),
626e5dd7070Spatrick /*CanSkip=*/false))
627e5dd7070Spatrick continue;
628e5dd7070Spatrick
629e5dd7070Spatrick return false;
630e5dd7070Spatrick }
631e5dd7070Spatrick }
632e5dd7070Spatrick
633e5dd7070Spatrick // We don't know how to deal with this DeclContext.
634e5dd7070Spatrick // Fallback to the slow version of the code.
635e5dd7070Spatrick return matchesNodeFullSlow(Node);
636e5dd7070Spatrick }
637e5dd7070Spatrick
638e5dd7070Spatrick return Patterns.foundMatch(/*AllowFullyQualified=*/true);
639e5dd7070Spatrick }
640e5dd7070Spatrick
matchesNodeFullSlow(const NamedDecl & Node) const641e5dd7070Spatrick bool HasNameMatcher::matchesNodeFullSlow(const NamedDecl &Node) const {
642e5dd7070Spatrick const bool SkipUnwrittenCases[] = {false, true};
643e5dd7070Spatrick for (bool SkipUnwritten : SkipUnwrittenCases) {
644e5dd7070Spatrick llvm::SmallString<128> NodeName = StringRef("::");
645e5dd7070Spatrick llvm::raw_svector_ostream OS(NodeName);
646e5dd7070Spatrick
647e5dd7070Spatrick PrintingPolicy Policy = Node.getASTContext().getPrintingPolicy();
648a9ac8606Spatrick Policy.SuppressUnwrittenScope = SkipUnwritten;
649a9ac8606Spatrick Policy.SuppressInlineNamespace = SkipUnwritten;
650e5dd7070Spatrick Node.printQualifiedName(OS, Policy);
651e5dd7070Spatrick
652e5dd7070Spatrick const StringRef FullName = OS.str();
653e5dd7070Spatrick
654e5dd7070Spatrick for (const StringRef Pattern : Names) {
655e5dd7070Spatrick if (Pattern.startswith("::")) {
656e5dd7070Spatrick if (FullName == Pattern)
657e5dd7070Spatrick return true;
658e5dd7070Spatrick } else if (FullName.endswith(Pattern) &&
659e5dd7070Spatrick FullName.drop_back(Pattern.size()).endswith("::")) {
660e5dd7070Spatrick return true;
661e5dd7070Spatrick }
662e5dd7070Spatrick }
663e5dd7070Spatrick }
664e5dd7070Spatrick
665e5dd7070Spatrick return false;
666e5dd7070Spatrick }
667e5dd7070Spatrick
matchesNode(const NamedDecl & Node) const668e5dd7070Spatrick bool HasNameMatcher::matchesNode(const NamedDecl &Node) const {
669e5dd7070Spatrick assert(matchesNodeFullFast(Node) == matchesNodeFullSlow(Node));
670e5dd7070Spatrick if (UseUnqualifiedMatch) {
671e5dd7070Spatrick assert(matchesNodeUnqualified(Node) == matchesNodeFullFast(Node));
672e5dd7070Spatrick return matchesNodeUnqualified(Node);
673e5dd7070Spatrick }
674e5dd7070Spatrick return matchesNodeFullFast(Node);
675e5dd7070Spatrick }
676e5dd7070Spatrick
677ec727ea7Spatrick // Checks whether \p Loc points to a token with source text of \p TokenText.
isTokenAtLoc(const SourceManager & SM,const LangOptions & LangOpts,StringRef Text,SourceLocation Loc)678ec727ea7Spatrick static bool isTokenAtLoc(const SourceManager &SM, const LangOptions &LangOpts,
679ec727ea7Spatrick StringRef Text, SourceLocation Loc) {
680ec727ea7Spatrick llvm::SmallString<16> Buffer;
681ec727ea7Spatrick bool Invalid = false;
682ec727ea7Spatrick // Since `Loc` may point into an expansion buffer, which has no corresponding
683ec727ea7Spatrick // source, we need to look at the spelling location to read the actual source.
684ec727ea7Spatrick StringRef TokenText = Lexer::getSpelling(SM.getSpellingLoc(Loc), Buffer, SM,
685ec727ea7Spatrick LangOpts, &Invalid);
686ec727ea7Spatrick return !Invalid && Text == TokenText;
687ec727ea7Spatrick }
688ec727ea7Spatrick
689*12c85518Srobert std::optional<SourceLocation>
getExpansionLocOfMacro(StringRef MacroName,SourceLocation Loc,const ASTContext & Context)690ec727ea7Spatrick getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc,
691ec727ea7Spatrick const ASTContext &Context) {
692ec727ea7Spatrick auto &SM = Context.getSourceManager();
693ec727ea7Spatrick const LangOptions &LangOpts = Context.getLangOpts();
694ec727ea7Spatrick while (Loc.isMacroID()) {
695ec727ea7Spatrick SrcMgr::ExpansionInfo Expansion =
696ec727ea7Spatrick SM.getSLocEntry(SM.getFileID(Loc)).getExpansion();
697ec727ea7Spatrick if (Expansion.isMacroArgExpansion())
698ec727ea7Spatrick // Check macro argument for an expansion of the given macro. For example,
699ec727ea7Spatrick // `F(G(3))`, where `MacroName` is `G`.
700*12c85518Srobert if (std::optional<SourceLocation> ArgLoc = getExpansionLocOfMacro(
701ec727ea7Spatrick MacroName, Expansion.getSpellingLoc(), Context))
702ec727ea7Spatrick return ArgLoc;
703ec727ea7Spatrick Loc = Expansion.getExpansionLocStart();
704ec727ea7Spatrick if (isTokenAtLoc(SM, LangOpts, MacroName, Loc))
705ec727ea7Spatrick return Loc;
706ec727ea7Spatrick }
707*12c85518Srobert return std::nullopt;
708ec727ea7Spatrick }
709ec727ea7Spatrick
createAndVerifyRegex(StringRef Regex,llvm::Regex::RegexFlags Flags,StringRef MatcherID)710ec727ea7Spatrick std::shared_ptr<llvm::Regex> createAndVerifyRegex(StringRef Regex,
711ec727ea7Spatrick llvm::Regex::RegexFlags Flags,
712ec727ea7Spatrick StringRef MatcherID) {
713ec727ea7Spatrick assert(!Regex.empty() && "Empty regex string");
714ec727ea7Spatrick auto SharedRegex = std::make_shared<llvm::Regex>(Regex, Flags);
715ec727ea7Spatrick std::string Error;
716ec727ea7Spatrick if (!SharedRegex->isValid(Error)) {
717ec727ea7Spatrick llvm::WithColor::error()
718ec727ea7Spatrick << "building matcher '" << MatcherID << "': " << Error << "\n";
719ec727ea7Spatrick llvm::WithColor::note() << " input was '" << Regex << "'\n";
720ec727ea7Spatrick }
721ec727ea7Spatrick return SharedRegex;
722ec727ea7Spatrick }
723e5dd7070Spatrick } // end namespace internal
724e5dd7070Spatrick
725e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAutoreleasePoolStmt>
726e5dd7070Spatrick autoreleasePoolStmt;
727e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, TranslationUnitDecl>
728e5dd7070Spatrick translationUnitDecl;
729e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl> typedefDecl;
730e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, TypedefNameDecl>
731e5dd7070Spatrick typedefNameDecl;
732e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasDecl> typeAliasDecl;
733e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasTemplateDecl>
734e5dd7070Spatrick typeAliasTemplateDecl;
735e5dd7070Spatrick const internal::VariadicAllOfMatcher<Decl> decl;
736a9ac8606Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, DecompositionDecl> decompositionDecl;
737a9ac8606Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, BindingDecl> bindingDecl;
738e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, LinkageSpecDecl>
739e5dd7070Spatrick linkageSpecDecl;
740e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, NamedDecl> namedDecl;
741e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, LabelDecl> labelDecl;
742e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceDecl> namespaceDecl;
743e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceAliasDecl>
744e5dd7070Spatrick namespaceAliasDecl;
745e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, RecordDecl> recordDecl;
746e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, CXXRecordDecl> cxxRecordDecl;
747e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, ClassTemplateDecl>
748e5dd7070Spatrick classTemplateDecl;
749e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl,
750e5dd7070Spatrick ClassTemplateSpecializationDecl>
751e5dd7070Spatrick classTemplateSpecializationDecl;
752e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<
753e5dd7070Spatrick Decl, ClassTemplatePartialSpecializationDecl>
754e5dd7070Spatrick classTemplatePartialSpecializationDecl;
755e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, DeclaratorDecl>
756e5dd7070Spatrick declaratorDecl;
757e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, ParmVarDecl> parmVarDecl;
758e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, AccessSpecDecl>
759e5dd7070Spatrick accessSpecDecl;
760a9ac8606Spatrick const internal::VariadicAllOfMatcher<CXXBaseSpecifier> cxxBaseSpecifier;
761e5dd7070Spatrick const internal::VariadicAllOfMatcher<CXXCtorInitializer> cxxCtorInitializer;
762e5dd7070Spatrick const internal::VariadicAllOfMatcher<TemplateArgument> templateArgument;
763a9ac8606Spatrick const internal::VariadicAllOfMatcher<TemplateArgumentLoc> templateArgumentLoc;
764e5dd7070Spatrick const internal::VariadicAllOfMatcher<TemplateName> templateName;
765e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, NonTypeTemplateParmDecl>
766e5dd7070Spatrick nonTypeTemplateParmDecl;
767e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, TemplateTypeParmDecl>
768e5dd7070Spatrick templateTypeParmDecl;
769a9ac8606Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, TemplateTemplateParmDecl>
770a9ac8606Spatrick templateTemplateParmDecl;
771a9ac8606Spatrick
772*12c85518Srobert const internal::VariadicAllOfMatcher<LambdaCapture> lambdaCapture;
773e5dd7070Spatrick const internal::VariadicAllOfMatcher<QualType> qualType;
774e5dd7070Spatrick const internal::VariadicAllOfMatcher<Type> type;
775e5dd7070Spatrick const internal::VariadicAllOfMatcher<TypeLoc> typeLoc;
776*12c85518Srobert
777*12c85518Srobert const internal::VariadicDynCastAllOfMatcher<TypeLoc, QualifiedTypeLoc>
778*12c85518Srobert qualifiedTypeLoc;
779*12c85518Srobert const internal::VariadicDynCastAllOfMatcher<TypeLoc, PointerTypeLoc>
780*12c85518Srobert pointerTypeLoc;
781*12c85518Srobert const internal::VariadicDynCastAllOfMatcher<TypeLoc, ReferenceTypeLoc>
782*12c85518Srobert referenceTypeLoc;
783*12c85518Srobert const internal::VariadicDynCastAllOfMatcher<TypeLoc,
784*12c85518Srobert TemplateSpecializationTypeLoc>
785*12c85518Srobert templateSpecializationTypeLoc;
786*12c85518Srobert const internal::VariadicDynCastAllOfMatcher<TypeLoc, ElaboratedTypeLoc>
787*12c85518Srobert elaboratedTypeLoc;
788*12c85518Srobert
789e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, UnaryExprOrTypeTraitExpr>
790e5dd7070Spatrick unaryExprOrTypeTraitExpr;
791e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, ValueDecl> valueDecl;
792e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, CXXConstructorDecl>
793e5dd7070Spatrick cxxConstructorDecl;
794e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, CXXDestructorDecl>
795e5dd7070Spatrick cxxDestructorDecl;
796e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl;
797e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, EnumConstantDecl>
798e5dd7070Spatrick enumConstantDecl;
799ec727ea7Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, TagDecl> tagDecl;
800e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> cxxMethodDecl;
801e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl>
802e5dd7070Spatrick cxxConversionDecl;
803e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> varDecl;
804e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> fieldDecl;
805e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, IndirectFieldDecl>
806e5dd7070Spatrick indirectFieldDecl;
807e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl> functionDecl;
808e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, FunctionTemplateDecl>
809e5dd7070Spatrick functionTemplateDecl;
810e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, FriendDecl> friendDecl;
811e5dd7070Spatrick const internal::VariadicAllOfMatcher<Stmt> stmt;
812e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, DeclStmt> declStmt;
813e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, MemberExpr> memberExpr;
814e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, UnresolvedMemberExpr>
815e5dd7070Spatrick unresolvedMemberExpr;
816e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDependentScopeMemberExpr>
817e5dd7070Spatrick cxxDependentScopeMemberExpr;
818e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> callExpr;
819e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, LambdaExpr> lambdaExpr;
820e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CXXMemberCallExpr>
821e5dd7070Spatrick cxxMemberCallExpr;
822e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCMessageExpr>
823e5dd7070Spatrick objcMessageExpr;
824e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, ObjCInterfaceDecl>
825e5dd7070Spatrick objcInterfaceDecl;
826e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, ObjCImplementationDecl>
827e5dd7070Spatrick objcImplementationDecl;
828e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, ObjCProtocolDecl>
829e5dd7070Spatrick objcProtocolDecl;
830e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryDecl>
831e5dd7070Spatrick objcCategoryDecl;
832e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryImplDecl>
833e5dd7070Spatrick objcCategoryImplDecl;
834e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, ObjCMethodDecl>
835e5dd7070Spatrick objcMethodDecl;
836e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, BlockDecl>
837e5dd7070Spatrick blockDecl;
838e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, ObjCIvarDecl> objcIvarDecl;
839e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, ObjCPropertyDecl>
840e5dd7070Spatrick objcPropertyDecl;
841e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtThrowStmt>
842e5dd7070Spatrick objcThrowStmt;
843e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtTryStmt> objcTryStmt;
844e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtCatchStmt>
845e5dd7070Spatrick objcCatchStmt;
846e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtFinallyStmt>
847e5dd7070Spatrick objcFinallyStmt;
848e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, ExprWithCleanups>
849e5dd7070Spatrick exprWithCleanups;
850e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr> initListExpr;
851e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CXXStdInitializerListExpr>
852e5dd7070Spatrick cxxStdInitializerListExpr;
853e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitValueInitExpr>
854e5dd7070Spatrick implicitValueInitExpr;
855e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, ParenListExpr> parenListExpr;
856e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, SubstNonTypeTemplateParmExpr>
857e5dd7070Spatrick substNonTypeTemplateParmExpr;
858e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl;
859a9ac8606Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, UsingEnumDecl> usingEnumDecl;
860e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, UsingDirectiveDecl>
861e5dd7070Spatrick usingDirectiveDecl;
862e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, UnresolvedLookupExpr>
863e5dd7070Spatrick unresolvedLookupExpr;
864e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, UnresolvedUsingValueDecl>
865e5dd7070Spatrick unresolvedUsingValueDecl;
866e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, UnresolvedUsingTypenameDecl>
867e5dd7070Spatrick unresolvedUsingTypenameDecl;
868e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, ConstantExpr> constantExpr;
869e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, ParenExpr> parenExpr;
870e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstructExpr>
871e5dd7070Spatrick cxxConstructExpr;
872e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CXXUnresolvedConstructExpr>
873e5dd7070Spatrick cxxUnresolvedConstructExpr;
874e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThisExpr> cxxThisExpr;
875e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBindTemporaryExpr>
876e5dd7070Spatrick cxxBindTemporaryExpr;
877e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, MaterializeTemporaryExpr>
878e5dd7070Spatrick materializeTemporaryExpr;
879e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> cxxNewExpr;
880e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDeleteExpr> cxxDeleteExpr;
881ec727ea7Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNoexceptExpr>
882ec727ea7Spatrick cxxNoexceptExpr;
883e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, ArraySubscriptExpr>
884e5dd7070Spatrick arraySubscriptExpr;
885e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDefaultArgExpr>
886e5dd7070Spatrick cxxDefaultArgExpr;
887e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CXXOperatorCallExpr>
888e5dd7070Spatrick cxxOperatorCallExpr;
889a9ac8606Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CXXRewrittenBinaryOperator>
890a9ac8606Spatrick cxxRewrittenBinaryOperator;
891e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, Expr> expr;
892e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, DeclRefExpr> declRefExpr;
893e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCIvarRefExpr> objcIvarRefExpr;
894e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, BlockExpr> blockExpr;
895e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, IfStmt> ifStmt;
896e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, ForStmt> forStmt;
897e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CXXForRangeStmt>
898e5dd7070Spatrick cxxForRangeStmt;
899e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, WhileStmt> whileStmt;
900e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, DoStmt> doStmt;
901e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, BreakStmt> breakStmt;
902e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, ContinueStmt> continueStmt;
903a9ac8606Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CoreturnStmt> coreturnStmt;
904e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, ReturnStmt> returnStmt;
905e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, GotoStmt> gotoStmt;
906e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, LabelStmt> labelStmt;
907e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, AddrLabelExpr> addrLabelExpr;
908e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchStmt> switchStmt;
909e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchCase> switchCase;
910e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CaseStmt> caseStmt;
911e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, DefaultStmt> defaultStmt;
912e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundStmt> compoundStmt;
913e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CXXCatchStmt> cxxCatchStmt;
914e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTryStmt> cxxTryStmt;
915e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThrowExpr> cxxThrowExpr;
916e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, NullStmt> nullStmt;
917e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, AsmStmt> asmStmt;
918e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBoolLiteralExpr>
919e5dd7070Spatrick cxxBoolLiteral;
920e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, StringLiteral> stringLiteral;
921*12c85518Srobert const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCStringLiteral> objcStringLiteral;
922e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CharacterLiteral>
923e5dd7070Spatrick characterLiteral;
924e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, IntegerLiteral>
925e5dd7070Spatrick integerLiteral;
926e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, FloatingLiteral> floatLiteral;
927e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, ImaginaryLiteral> imaginaryLiteral;
928ec727ea7Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, FixedPointLiteral>
929ec727ea7Spatrick fixedPointLiteral;
930e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, UserDefinedLiteral>
931e5dd7070Spatrick userDefinedLiteral;
932e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundLiteralExpr>
933e5dd7070Spatrick compoundLiteralExpr;
934e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNullPtrLiteralExpr>
935e5dd7070Spatrick cxxNullPtrLiteralExpr;
936e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, ChooseExpr> chooseExpr;
937a9ac8606Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CoawaitExpr>
938a9ac8606Spatrick coawaitExpr;
939a9ac8606Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, DependentCoawaitExpr>
940a9ac8606Spatrick dependentCoawaitExpr;
941a9ac8606Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CoyieldExpr>
942a9ac8606Spatrick coyieldExpr;
943e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, GNUNullExpr> gnuNullExpr;
944a9ac8606Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, GenericSelectionExpr>
945a9ac8606Spatrick genericSelectionExpr;
946e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, AtomicExpr> atomicExpr;
947e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, StmtExpr> stmtExpr;
948e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, BinaryOperator>
949e5dd7070Spatrick binaryOperator;
950a9ac8606Spatrick const internal::MapAnyOfMatcher<BinaryOperator, CXXOperatorCallExpr,
951a9ac8606Spatrick CXXRewrittenBinaryOperator>
952a9ac8606Spatrick binaryOperation;
953a9ac8606Spatrick const internal::MapAnyOfMatcher<CallExpr, CXXConstructExpr> invocation;
954e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, UnaryOperator> unaryOperator;
955e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, ConditionalOperator>
956e5dd7070Spatrick conditionalOperator;
957e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, BinaryConditionalOperator>
958e5dd7070Spatrick binaryConditionalOperator;
959e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, OpaqueValueExpr>
960e5dd7070Spatrick opaqueValueExpr;
961e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, StaticAssertDecl>
962e5dd7070Spatrick staticAssertDecl;
963e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CXXReinterpretCastExpr>
964e5dd7070Spatrick cxxReinterpretCastExpr;
965e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CXXStaticCastExpr>
966e5dd7070Spatrick cxxStaticCastExpr;
967e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDynamicCastExpr>
968e5dd7070Spatrick cxxDynamicCastExpr;
969e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstCastExpr>
970e5dd7070Spatrick cxxConstCastExpr;
971e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CStyleCastExpr>
972e5dd7070Spatrick cStyleCastExpr;
973e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, ExplicitCastExpr>
974e5dd7070Spatrick explicitCastExpr;
975e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitCastExpr>
976e5dd7070Spatrick implicitCastExpr;
977e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CastExpr> castExpr;
978e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CXXFunctionalCastExpr>
979e5dd7070Spatrick cxxFunctionalCastExpr;
980e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTemporaryObjectExpr>
981e5dd7070Spatrick cxxTemporaryObjectExpr;
982e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, PredefinedExpr>
983e5dd7070Spatrick predefinedExpr;
984e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, DesignatedInitExpr>
985e5dd7070Spatrick designatedInitExpr;
986e5dd7070Spatrick const internal::VariadicOperatorMatcherFunc<
987e5dd7070Spatrick 2, std::numeric_limits<unsigned>::max()>
988e5dd7070Spatrick eachOf = {internal::DynTypedMatcher::VO_EachOf};
989e5dd7070Spatrick const internal::VariadicOperatorMatcherFunc<
990e5dd7070Spatrick 2, std::numeric_limits<unsigned>::max()>
991e5dd7070Spatrick anyOf = {internal::DynTypedMatcher::VO_AnyOf};
992e5dd7070Spatrick const internal::VariadicOperatorMatcherFunc<
993e5dd7070Spatrick 2, std::numeric_limits<unsigned>::max()>
994e5dd7070Spatrick allOf = {internal::DynTypedMatcher::VO_AllOf};
995ec727ea7Spatrick const internal::VariadicOperatorMatcherFunc<1, 1> optionally = {
996ec727ea7Spatrick internal::DynTypedMatcher::VO_Optionally};
997e5dd7070Spatrick const internal::VariadicFunction<internal::Matcher<NamedDecl>, StringRef,
998e5dd7070Spatrick internal::hasAnyNameFunc>
999e5dd7070Spatrick hasAnyName = {};
1000ec727ea7Spatrick
1001ec727ea7Spatrick const internal::VariadicFunction<internal::HasOpNameMatcher, StringRef,
1002ec727ea7Spatrick internal::hasAnyOperatorNameFunc>
1003ec727ea7Spatrick hasAnyOperatorName = {};
1004ec727ea7Spatrick const internal::VariadicFunction<internal::HasOverloadOpNameMatcher, StringRef,
1005ec727ea7Spatrick internal::hasAnyOverloadedOperatorNameFunc>
1006ec727ea7Spatrick hasAnyOverloadedOperatorName = {};
1007e5dd7070Spatrick const internal::VariadicFunction<internal::Matcher<ObjCMessageExpr>, StringRef,
1008e5dd7070Spatrick internal::hasAnySelectorFunc>
1009e5dd7070Spatrick hasAnySelector = {};
1010e5dd7070Spatrick const internal::ArgumentAdaptingMatcherFunc<internal::HasMatcher> has = {};
1011e5dd7070Spatrick const internal::ArgumentAdaptingMatcherFunc<internal::HasDescendantMatcher>
1012e5dd7070Spatrick hasDescendant = {};
1013e5dd7070Spatrick const internal::ArgumentAdaptingMatcherFunc<internal::ForEachMatcher> forEach =
1014e5dd7070Spatrick {};
1015e5dd7070Spatrick const internal::ArgumentAdaptingMatcherFunc<internal::ForEachDescendantMatcher>
1016e5dd7070Spatrick forEachDescendant = {};
1017e5dd7070Spatrick const internal::ArgumentAdaptingMatcherFunc<
1018e5dd7070Spatrick internal::HasParentMatcher,
1019*12c85518Srobert internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>,
1020*12c85518Srobert internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>>
1021e5dd7070Spatrick hasParent = {};
1022e5dd7070Spatrick const internal::ArgumentAdaptingMatcherFunc<
1023e5dd7070Spatrick internal::HasAncestorMatcher,
1024*12c85518Srobert internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>,
1025*12c85518Srobert internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>>
1026e5dd7070Spatrick hasAncestor = {};
1027e5dd7070Spatrick const internal::VariadicOperatorMatcherFunc<1, 1> unless = {
1028e5dd7070Spatrick internal::DynTypedMatcher::VO_UnaryNot};
1029e5dd7070Spatrick const internal::VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier;
1030e5dd7070Spatrick const internal::VariadicAllOfMatcher<NestedNameSpecifierLoc>
1031e5dd7070Spatrick nestedNameSpecifierLoc;
1032*12c85518Srobert const internal::VariadicAllOfMatcher<Attr> attr;
1033e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, CUDAKernelCallExpr>
1034e5dd7070Spatrick cudaKernelCallExpr;
1035e5dd7070Spatrick const AstTypeMatcher<BuiltinType> builtinType;
1036e5dd7070Spatrick const AstTypeMatcher<ArrayType> arrayType;
1037e5dd7070Spatrick const AstTypeMatcher<ComplexType> complexType;
1038e5dd7070Spatrick const AstTypeMatcher<ConstantArrayType> constantArrayType;
1039ec727ea7Spatrick const AstTypeMatcher<DeducedTemplateSpecializationType>
1040ec727ea7Spatrick deducedTemplateSpecializationType;
1041e5dd7070Spatrick const AstTypeMatcher<DependentSizedArrayType> dependentSizedArrayType;
1042e5dd7070Spatrick const AstTypeMatcher<IncompleteArrayType> incompleteArrayType;
1043e5dd7070Spatrick const AstTypeMatcher<VariableArrayType> variableArrayType;
1044e5dd7070Spatrick const AstTypeMatcher<AtomicType> atomicType;
1045e5dd7070Spatrick const AstTypeMatcher<AutoType> autoType;
1046e5dd7070Spatrick const AstTypeMatcher<DecltypeType> decltypeType;
1047e5dd7070Spatrick const AstTypeMatcher<FunctionType> functionType;
1048e5dd7070Spatrick const AstTypeMatcher<FunctionProtoType> functionProtoType;
1049e5dd7070Spatrick const AstTypeMatcher<ParenType> parenType;
1050e5dd7070Spatrick const AstTypeMatcher<BlockPointerType> blockPointerType;
1051e5dd7070Spatrick const AstTypeMatcher<MemberPointerType> memberPointerType;
1052e5dd7070Spatrick const AstTypeMatcher<PointerType> pointerType;
1053e5dd7070Spatrick const AstTypeMatcher<ObjCObjectPointerType> objcObjectPointerType;
1054e5dd7070Spatrick const AstTypeMatcher<ReferenceType> referenceType;
1055e5dd7070Spatrick const AstTypeMatcher<LValueReferenceType> lValueReferenceType;
1056e5dd7070Spatrick const AstTypeMatcher<RValueReferenceType> rValueReferenceType;
1057e5dd7070Spatrick const AstTypeMatcher<TypedefType> typedefType;
1058e5dd7070Spatrick const AstTypeMatcher<EnumType> enumType;
1059e5dd7070Spatrick const AstTypeMatcher<TemplateSpecializationType> templateSpecializationType;
1060e5dd7070Spatrick const AstTypeMatcher<UnaryTransformType> unaryTransformType;
1061e5dd7070Spatrick const AstTypeMatcher<RecordType> recordType;
1062e5dd7070Spatrick const AstTypeMatcher<TagType> tagType;
1063e5dd7070Spatrick const AstTypeMatcher<ElaboratedType> elaboratedType;
1064*12c85518Srobert const AstTypeMatcher<UsingType> usingType;
1065e5dd7070Spatrick const AstTypeMatcher<SubstTemplateTypeParmType> substTemplateTypeParmType;
1066e5dd7070Spatrick const AstTypeMatcher<TemplateTypeParmType> templateTypeParmType;
1067e5dd7070Spatrick const AstTypeMatcher<InjectedClassNameType> injectedClassNameType;
1068e5dd7070Spatrick const AstTypeMatcher<DecayedType> decayedType;
1069e5dd7070Spatrick AST_TYPELOC_TRAVERSE_MATCHER_DEF(hasElementType,
1070e5dd7070Spatrick AST_POLYMORPHIC_SUPPORTED_TYPES(ArrayType,
1071e5dd7070Spatrick ComplexType));
1072e5dd7070Spatrick AST_TYPELOC_TRAVERSE_MATCHER_DEF(hasValueType,
1073e5dd7070Spatrick AST_POLYMORPHIC_SUPPORTED_TYPES(AtomicType));
1074e5dd7070Spatrick AST_TYPELOC_TRAVERSE_MATCHER_DEF(
1075e5dd7070Spatrick pointee,
1076e5dd7070Spatrick AST_POLYMORPHIC_SUPPORTED_TYPES(BlockPointerType, MemberPointerType,
1077e5dd7070Spatrick PointerType, ReferenceType));
1078e5dd7070Spatrick
1079e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Stmt, OMPExecutableDirective>
1080e5dd7070Spatrick ompExecutableDirective;
1081e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<OMPClause, OMPDefaultClause>
1082e5dd7070Spatrick ompDefaultClause;
1083e5dd7070Spatrick const internal::VariadicDynCastAllOfMatcher<Decl, CXXDeductionGuideDecl>
1084e5dd7070Spatrick cxxDeductionGuideDecl;
1085e5dd7070Spatrick
1086e5dd7070Spatrick } // end namespace ast_matchers
1087e5dd7070Spatrick } // end namespace clang
1088