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