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