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