blob: 5351ffee54c3c7d9cd9bcabfa28a57b8d30a753d [file] [log] [blame]
Eugene Zelenko06becf82017-11-01 23:09:49 +00001//===- ASTMatchersInternal.cpp - Structural query framework ---------------===//
Manuel Klimek04616e42012-07-06 05:48:52 +00002//
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 Klimek04616e42012-07-06 05:48:52 +000014#include "clang/ASTMatchers/ASTMatchersInternal.h"
Eugene Zelenko06becf82017-11-01 23:09:49 +000015#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 Benzaquen8513d622014-10-15 14:58:46 +000025#include "llvm/ADT/SmallString.h"
Samuel Benzaquen922bef42016-02-22 21:13:02 +000026#include "llvm/ADT/SmallVector.h"
Eugene Zelenko06becf82017-11-01 23:09:49 +000027#include "llvm/ADT/StringRef.h"
28#include "llvm/Support/Casting.h"
29#include "llvm/Support/ErrorHandling.h"
Samuel Benzaquen96039d72014-10-09 19:28:18 +000030#include "llvm/Support/ManagedStatic.h"
Eugene Zelenko06becf82017-11-01 23:09:49 +000031#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 Klimek04616e42012-07-06 05:48:52 +000038
39namespace clang {
40namespace ast_matchers {
41namespace internal {
42
Hans Wennborgb27f2492015-07-14 16:50:14 +000043bool NotUnaryOperator(const ast_type_traits::DynTypedNode &DynNode,
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +000044 ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
45 ArrayRef<DynTypedMatcher> InnerMatchers);
46
Hans Wennborgb27f2492015-07-14 16:50:14 +000047bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +000048 ASTMatchFinder *Finder,
49 BoundNodesTreeBuilder *Builder,
50 ArrayRef<DynTypedMatcher> InnerMatchers);
51
Hans Wennborgb27f2492015-07-14 16:50:14 +000052bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +000053 ASTMatchFinder *Finder,
54 BoundNodesTreeBuilder *Builder,
55 ArrayRef<DynTypedMatcher> InnerMatchers);
56
Hans Wennborgb27f2492015-07-14 16:50:14 +000057bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +000058 ASTMatchFinder *Finder,
59 BoundNodesTreeBuilder *Builder,
60 ArrayRef<DynTypedMatcher> InnerMatchers);
61
Manuel Klimeka0c025f2013-06-19 15:42:45 +000062void BoundNodesTreeBuilder::visitMatches(Visitor *ResultVisitor) {
63 if (Bindings.empty())
64 Bindings.push_back(BoundNodesMap());
Benjamin Kramer79f15902014-10-24 13:29:15 +000065 for (BoundNodesMap &Binding : Bindings) {
66 ResultVisitor->visitMatch(BoundNodes(Binding));
Manuel Klimek021d56f2012-08-28 23:26:39 +000067 }
68}
69
Samuel Benzaquenf28d9972014-10-01 15:08:07 +000070namespace {
71
Eugene Zelenko06becf82017-11-01 23:09:49 +000072using VariadicOperatorFunction = bool (*)(
Hans Wennborgb27f2492015-07-14 16:50:14 +000073 const ast_type_traits::DynTypedNode &DynNode, ASTMatchFinder *Finder,
Samuel Benzaquen95636e52014-12-01 14:46:14 +000074 BoundNodesTreeBuilder *Builder, ArrayRef<DynTypedMatcher> InnerMatchers);
75
76template <VariadicOperatorFunction Func>
Samuel Benzaquenf28d9972014-10-01 15:08:07 +000077class VariadicMatcher : public DynMatcherInterface {
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +000078public:
Samuel Benzaquen95636e52014-12-01 14:46:14 +000079 VariadicMatcher(std::vector<DynTypedMatcher> InnerMatchers)
80 : InnerMatchers(std::move(InnerMatchers)) {}
Samuel Benzaquenf28d9972014-10-01 15:08:07 +000081
82 bool dynMatches(const ast_type_traits::DynTypedNode &DynNode,
83 ASTMatchFinder *Finder,
84 BoundNodesTreeBuilder *Builder) const override {
85 return Func(DynNode, Finder, Builder, InnerMatchers);
86 }
87
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +000088private:
Samuel Benzaquenf28d9972014-10-01 15:08:07 +000089 std::vector<DynTypedMatcher> InnerMatchers;
90};
91
92class IdDynMatcher : public DynMatcherInterface {
Benjamin Kramer018b6d42016-07-21 15:06:51 +000093public:
Samuel Benzaquenf28d9972014-10-01 15:08:07 +000094 IdDynMatcher(StringRef ID,
Benjamin Kramer018b6d42016-07-21 15:06:51 +000095 IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher)
96 : ID(ID), InnerMatcher(std::move(InnerMatcher)) {}
Samuel Benzaquenf28d9972014-10-01 15:08:07 +000097
98 bool dynMatches(const ast_type_traits::DynTypedNode &DynNode,
99 ASTMatchFinder *Finder,
100 BoundNodesTreeBuilder *Builder) const override {
101 bool Result = InnerMatcher->dynMatches(DynNode, Finder, Builder);
102 if (Result) Builder->setBinding(ID, DynNode);
103 return Result;
104 }
105
Benjamin Kramer018b6d42016-07-21 15:06:51 +0000106private:
Samuel Benzaquenf28d9972014-10-01 15:08:07 +0000107 const std::string ID;
108 const IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher;
109};
110
Samuel Benzaquen96039d72014-10-09 19:28:18 +0000111/// \brief A matcher that always returns true.
112///
113/// We only ever need one instance of this matcher, so we create a global one
114/// and reuse it to reduce the overhead of the matcher and increase the chance
115/// of cache hits.
Benjamin Kramer967c0792014-10-24 13:29:21 +0000116class TrueMatcherImpl : public DynMatcherInterface {
117public:
118 TrueMatcherImpl() {
119 Retain(); // Reference count will never become zero.
120 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000121
Benjamin Kramer967c0792014-10-24 13:29:21 +0000122 bool dynMatches(const ast_type_traits::DynTypedNode &, ASTMatchFinder *,
123 BoundNodesTreeBuilder *) const override {
124 return true;
125 }
Samuel Benzaquen96039d72014-10-09 19:28:18 +0000126};
Samuel Benzaquen96039d72014-10-09 19:28:18 +0000127
Eugene Zelenko06becf82017-11-01 23:09:49 +0000128} // namespace
129
130static llvm::ManagedStatic<TrueMatcherImpl> TrueMatcherInstance;
Samuel Benzaquenf28d9972014-10-01 15:08:07 +0000131
132DynTypedMatcher DynTypedMatcher::constructVariadic(
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000133 DynTypedMatcher::VariadicOperator Op,
Samuel Benzaquenb063f5c2015-07-17 16:05:27 +0000134 ast_type_traits::ASTNodeKind SupportedKind,
Samuel Benzaquen9743c9d2014-11-17 14:55:49 +0000135 std::vector<DynTypedMatcher> InnerMatchers) {
Eugene Zelenko06becf82017-11-01 23:09:49 +0000136 assert(!InnerMatchers.empty() && "Array must not be empty.");
Samuel Benzaquen20099602014-10-13 17:38:12 +0000137 assert(std::all_of(InnerMatchers.begin(), InnerMatchers.end(),
Samuel Benzaquenb063f5c2015-07-17 16:05:27 +0000138 [SupportedKind](const DynTypedMatcher &M) {
139 return M.canConvertTo(SupportedKind);
140 }) &&
141 "InnerMatchers must be convertible to SupportedKind!");
Samuel Benzaquen20099602014-10-13 17:38:12 +0000142
143 // We must relax the restrict kind here.
144 // The different operators might deal differently with a mismatch.
145 // Make it the same as SupportedKind, since that is the broadest type we are
146 // allowed to accept.
Samuel Benzaquen95636e52014-12-01 14:46:14 +0000147 auto RestrictKind = SupportedKind;
148
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000149 switch (Op) {
150 case VO_AllOf:
Samuel Benzaquen95636e52014-12-01 14:46:14 +0000151 // In the case of allOf() we must pass all the checks, so making
152 // RestrictKind the most restrictive can save us time. This way we reject
153 // invalid types earlier and we can elide the kind checks inside the
154 // matcher.
155 for (auto &IM : InnerMatchers) {
156 RestrictKind = ast_type_traits::ASTNodeKind::getMostDerivedType(
157 RestrictKind, IM.RestrictKind);
158 }
159 return DynTypedMatcher(
160 SupportedKind, RestrictKind,
161 new VariadicMatcher<AllOfVariadicOperator>(std::move(InnerMatchers)));
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000162
Samuel Benzaquen95636e52014-12-01 14:46:14 +0000163 case VO_AnyOf:
164 return DynTypedMatcher(
165 SupportedKind, RestrictKind,
166 new VariadicMatcher<AnyOfVariadicOperator>(std::move(InnerMatchers)));
167
168 case VO_EachOf:
169 return DynTypedMatcher(
170 SupportedKind, RestrictKind,
171 new VariadicMatcher<EachOfVariadicOperator>(std::move(InnerMatchers)));
172
173 case VO_UnaryNot:
174 // FIXME: Implement the Not operator to take a single matcher instead of a
175 // vector.
176 return DynTypedMatcher(
177 SupportedKind, RestrictKind,
178 new VariadicMatcher<NotUnaryOperator>(std::move(InnerMatchers)));
179 }
180 llvm_unreachable("Invalid Op value.");
Samuel Benzaquenf28d9972014-10-01 15:08:07 +0000181}
182
Samuel Benzaquen96039d72014-10-09 19:28:18 +0000183DynTypedMatcher DynTypedMatcher::trueMatcher(
184 ast_type_traits::ASTNodeKind NodeKind) {
Benjamin Kramer967c0792014-10-24 13:29:21 +0000185 return DynTypedMatcher(NodeKind, NodeKind, &*TrueMatcherInstance);
Samuel Benzaquen96039d72014-10-09 19:28:18 +0000186}
187
Samuel Benzaquen074bbb62014-11-24 21:21:09 +0000188bool DynTypedMatcher::canMatchNodesOfKind(
189 ast_type_traits::ASTNodeKind Kind) const {
190 return RestrictKind.isBaseOf(Kind);
191}
192
Samuel Benzaquenf28d9972014-10-01 15:08:07 +0000193DynTypedMatcher DynTypedMatcher::dynCastTo(
194 const ast_type_traits::ASTNodeKind Kind) const {
195 auto Copy = *this;
196 Copy.SupportedKind = Kind;
Samuel Benzaquena1170022014-10-06 13:14:30 +0000197 Copy.RestrictKind =
198 ast_type_traits::ASTNodeKind::getMostDerivedType(Kind, RestrictKind);
Samuel Benzaquenf28d9972014-10-01 15:08:07 +0000199 return Copy;
200}
201
202bool DynTypedMatcher::matches(const ast_type_traits::DynTypedNode &DynNode,
203 ASTMatchFinder *Finder,
204 BoundNodesTreeBuilder *Builder) const {
205 if (RestrictKind.isBaseOf(DynNode.getNodeKind()) &&
206 Implementation->dynMatches(DynNode, Finder, Builder)) {
207 return true;
208 }
209 // Delete all bindings when a matcher does not match.
210 // This prevents unexpected exposure of bound nodes in unmatches
211 // branches of the match tree.
212 Builder->removeBindings([](const BoundNodesMap &) { return true; });
213 return false;
214}
215
Samuel Benzaquen074bbb62014-11-24 21:21:09 +0000216bool DynTypedMatcher::matchesNoKindCheck(
217 const ast_type_traits::DynTypedNode &DynNode, ASTMatchFinder *Finder,
218 BoundNodesTreeBuilder *Builder) const {
219 assert(RestrictKind.isBaseOf(DynNode.getNodeKind()));
220 if (Implementation->dynMatches(DynNode, Finder, Builder)) {
221 return true;
222 }
223 // Delete all bindings when a matcher does not match.
224 // This prevents unexpected exposure of bound nodes in unmatches
225 // branches of the match tree.
226 Builder->removeBindings([](const BoundNodesMap &) { return true; });
227 return false;
228}
229
Samuel Benzaquenf28d9972014-10-01 15:08:07 +0000230llvm::Optional<DynTypedMatcher> DynTypedMatcher::tryBind(StringRef ID) const {
231 if (!AllowBind) return llvm::None;
232 auto Result = *this;
Benjamin Kramer018b6d42016-07-21 15:06:51 +0000233 Result.Implementation =
234 new IdDynMatcher(ID, std::move(Result.Implementation));
235 return std::move(Result);
Samuel Benzaquenf28d9972014-10-01 15:08:07 +0000236}
237
Samuel Benzaquenab005ed2014-09-04 14:13:58 +0000238bool DynTypedMatcher::canConvertTo(ast_type_traits::ASTNodeKind To) const {
239 const auto From = getSupportedKind();
240 auto QualKind = ast_type_traits::ASTNodeKind::getFromNodeKind<QualType>();
241 auto TypeKind = ast_type_traits::ASTNodeKind::getFromNodeKind<Type>();
242 /// Mimic the implicit conversions of Matcher<>.
243 /// - From Matcher<Type> to Matcher<QualType>
244 if (From.isSame(TypeKind) && To.isSame(QualKind)) return true;
245 /// - From Matcher<Base> to Matcher<Derived>
246 return From.isBaseOf(To);
247}
248
Manuel Klimeka0c025f2013-06-19 15:42:45 +0000249void BoundNodesTreeBuilder::addMatch(const BoundNodesTreeBuilder &Other) {
Benjamin Kramer79f15902014-10-24 13:29:15 +0000250 Bindings.append(Other.Bindings.begin(), Other.Bindings.end());
Manuel Klimek021d56f2012-08-28 23:26:39 +0000251}
252
Hans Wennborgb27f2492015-07-14 16:50:14 +0000253bool NotUnaryOperator(const ast_type_traits::DynTypedNode &DynNode,
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000254 ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
255 ArrayRef<DynTypedMatcher> InnerMatchers) {
256 if (InnerMatchers.size() != 1)
257 return false;
258
259 // The 'unless' matcher will always discard the result:
260 // If the inner matcher doesn't match, unless returns true,
261 // but the inner matcher cannot have bound anything.
262 // If the inner matcher matches, the result is false, and
263 // any possible binding will be discarded.
264 // We still need to hand in all the bound nodes up to this
265 // point so the inner matcher can depend on bound nodes,
266 // and we need to actively discard the bound nodes, otherwise
267 // the inner matcher will reset the bound nodes if it doesn't
268 // match, but this would be inversed by 'unless'.
269 BoundNodesTreeBuilder Discard(*Builder);
270 return !InnerMatchers[0].matches(DynNode, Finder, &Discard);
271}
272
Hans Wennborgb27f2492015-07-14 16:50:14 +0000273bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000274 ASTMatchFinder *Finder,
275 BoundNodesTreeBuilder *Builder,
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000276 ArrayRef<DynTypedMatcher> InnerMatchers) {
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000277 // allOf leads to one matcher for each alternative in the first
278 // matcher combined with each alternative in the second matcher.
279 // Thus, we can reuse the same Builder.
Benjamin Kramer79f15902014-10-24 13:29:15 +0000280 for (const DynTypedMatcher &InnerMatcher : InnerMatchers) {
Samuel Benzaquen95636e52014-12-01 14:46:14 +0000281 if (!InnerMatcher.matchesNoKindCheck(DynNode, Finder, Builder))
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000282 return false;
283 }
284 return true;
285}
286
Hans Wennborgb27f2492015-07-14 16:50:14 +0000287bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000288 ASTMatchFinder *Finder,
289 BoundNodesTreeBuilder *Builder,
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000290 ArrayRef<DynTypedMatcher> InnerMatchers) {
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000291 BoundNodesTreeBuilder Result;
292 bool Matched = false;
Benjamin Kramer79f15902014-10-24 13:29:15 +0000293 for (const DynTypedMatcher &InnerMatcher : InnerMatchers) {
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000294 BoundNodesTreeBuilder BuilderInner(*Builder);
Benjamin Kramer79f15902014-10-24 13:29:15 +0000295 if (InnerMatcher.matches(DynNode, Finder, &BuilderInner)) {
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000296 Matched = true;
297 Result.addMatch(BuilderInner);
298 }
299 }
Benjamin Kramerd9c91622014-08-29 11:22:47 +0000300 *Builder = std::move(Result);
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000301 return Matched;
302}
303
Hans Wennborgb27f2492015-07-14 16:50:14 +0000304bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000305 ASTMatchFinder *Finder,
306 BoundNodesTreeBuilder *Builder,
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000307 ArrayRef<DynTypedMatcher> InnerMatchers) {
Benjamin Kramer79f15902014-10-24 13:29:15 +0000308 for (const DynTypedMatcher &InnerMatcher : InnerMatchers) {
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000309 BoundNodesTreeBuilder Result = *Builder;
Benjamin Kramer79f15902014-10-24 13:29:15 +0000310 if (InnerMatcher.matches(DynNode, Finder, &Result)) {
Benjamin Kramerd9c91622014-08-29 11:22:47 +0000311 *Builder = std::move(Result);
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000312 return true;
313 }
314 }
315 return false;
316}
317
George Karpenkov88a16a02018-03-29 00:51:12 +0000318inline static
319std::vector<std::string> vectorFromRefs(ArrayRef<const StringRef *> NameRefs) {
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000320 std::vector<std::string> Names;
321 for (auto *Name : NameRefs)
322 Names.emplace_back(*Name);
George Karpenkov88a16a02018-03-29 00:51:12 +0000323 return Names;
324}
325
326Matcher<NamedDecl> hasAnyNameFunc(ArrayRef<const StringRef *> NameRefs) {
327 std::vector<std::string> Names = vectorFromRefs(NameRefs);
328 return internal::Matcher<NamedDecl>(new internal::HasNameMatcher(Names));
329}
330
331AST_MATCHER_P(ObjCMessageExpr, hasAnySelectorMatcher, std::vector<std::string>,
332 Matches) {
333 std::string SelString = Node.getSelector().getAsString();
334 for (const std::string &S : Matches)
335 if (S == SelString)
336 return true;
337 return false;
338}
339
340Matcher<ObjCMessageExpr> hasAnySelectorFunc(
341 ArrayRef<const StringRef *> NameRefs) {
342 return hasAnySelectorMatcher(vectorFromRefs(NameRefs));
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000343}
344
345HasNameMatcher::HasNameMatcher(std::vector<std::string> N)
346 : UseUnqualifiedMatch(std::all_of(
347 N.begin(), N.end(),
348 [](StringRef Name) { return Name.find("::") == Name.npos; })),
349 Names(std::move(N)) {
Alexander Kornienko1eeac192016-02-23 10:29:04 +0000350#ifndef NDEBUG
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000351 for (StringRef Name : Names)
352 assert(!Name.empty());
Alexander Kornienko1eeac192016-02-23 10:29:04 +0000353#endif
Samuel Benzaquen8513d622014-10-15 14:58:46 +0000354}
355
Eugene Zelenko06becf82017-11-01 23:09:49 +0000356static bool consumeNameSuffix(StringRef &FullName, StringRef Suffix) {
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000357 StringRef Name = FullName;
358 if (!Name.endswith(Suffix))
359 return false;
360 Name = Name.drop_back(Suffix.size());
361 if (!Name.empty()) {
362 if (!Name.endswith("::"))
363 return false;
364 Name = Name.drop_back(2);
Samuel Benzaquenb6f73bc2014-10-16 17:50:19 +0000365 }
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000366 FullName = Name;
367 return true;
368}
369
Eugene Zelenko06becf82017-11-01 23:09:49 +0000370static StringRef getNodeName(const NamedDecl &Node,
371 llvm::SmallString<128> &Scratch) {
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000372 // Simple name.
373 if (Node.getIdentifier())
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000374 return Node.getName();
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000375
Samuel Benzaquenb6f73bc2014-10-16 17:50:19 +0000376 if (Node.getDeclName()) {
Samuel Benzaquen8513d622014-10-15 14:58:46 +0000377 // Name needs to be constructed.
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000378 Scratch.clear();
379 llvm::raw_svector_ostream OS(Scratch);
Samuel Benzaquen8513d622014-10-15 14:58:46 +0000380 Node.printName(OS);
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000381 return OS.str();
Samuel Benzaquen8513d622014-10-15 14:58:46 +0000382 }
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000383
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000384 return "(anonymous)";
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000385}
386
Eugene Zelenko06becf82017-11-01 23:09:49 +0000387static StringRef getNodeName(const RecordDecl &Node,
388 llvm::SmallString<128> &Scratch) {
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000389 if (Node.getIdentifier()) {
390 return Node.getName();
391 }
392 Scratch.clear();
393 return ("(anonymous " + Node.getKindName() + ")").toStringRef(Scratch);
394}
395
Eugene Zelenko06becf82017-11-01 23:09:49 +0000396static StringRef getNodeName(const NamespaceDecl &Node,
397 llvm::SmallString<128> &Scratch) {
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000398 return Node.isAnonymousNamespace() ? "(anonymous namespace)" : Node.getName();
399}
400
Eugene Zelenko06becf82017-11-01 23:09:49 +0000401namespace {
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000402
403class PatternSet {
404public:
405 PatternSet(ArrayRef<std::string> Names) {
406 for (StringRef Name : Names)
407 Patterns.push_back({Name, Name.startswith("::")});
408 }
409
410 /// Consumes the name suffix from each pattern in the set and removes the ones
411 /// that didn't match.
412 /// Return true if there are still any patterns left.
413 bool consumeNameSuffix(StringRef NodeName, bool CanSkip) {
414 for (size_t I = 0; I < Patterns.size();) {
George Karpenkov88a16a02018-03-29 00:51:12 +0000415 if (::clang::ast_matchers::internal::consumeNameSuffix(Patterns[I].P,
416 NodeName) ||
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000417 CanSkip) {
418 ++I;
419 } else {
420 Patterns.erase(Patterns.begin() + I);
421 }
422 }
423 return !Patterns.empty();
424 }
425
426 /// Check if any of the patterns are a match.
427 /// A match will be a pattern that was fully consumed, that also matches the
428 /// 'fully qualified' requirement.
429 bool foundMatch(bool AllowFullyQualified) const {
430 for (auto& P: Patterns)
Hans Wennborg157a5d52016-02-22 22:21:58 +0000431 if (P.P.empty() && (AllowFullyQualified || !P.IsFullyQualified))
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000432 return true;
433 return false;
434 }
435
436private:
437 struct Pattern {
Hans Wennborg157a5d52016-02-22 22:21:58 +0000438 StringRef P;
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000439 bool IsFullyQualified;
440 };
Eugene Zelenko06becf82017-11-01 23:09:49 +0000441
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000442 llvm::SmallVector<Pattern, 8> Patterns;
443};
444
Eugene Zelenko06becf82017-11-01 23:09:49 +0000445} // namespace
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000446
447bool HasNameMatcher::matchesNodeUnqualified(const NamedDecl &Node) const {
448 assert(UseUnqualifiedMatch);
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000449 llvm::SmallString<128> Scratch;
450 StringRef NodeName = getNodeName(Node, Scratch);
451 return std::any_of(Names.begin(), Names.end(), [&](StringRef Name) {
452 return consumeNameSuffix(Name, NodeName) && Name.empty();
453 });
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000454}
455
456bool HasNameMatcher::matchesNodeFullFast(const NamedDecl &Node) const {
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000457 PatternSet Patterns(Names);
458 llvm::SmallString<128> Scratch;
459
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000460 // This function is copied and adapted from NamedDecl::printQualifiedName()
461 // By matching each part individually we optimize in a couple of ways:
462 // - We can exit early on the first failure.
463 // - We can skip inline/anonymous namespaces without another pass.
464 // - We print one name at a time, reducing the chance of overflowing the
465 // inlined space of the SmallString.
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000466
467 // First, match the name.
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000468 if (!Patterns.consumeNameSuffix(getNodeName(Node, Scratch),
469 /*CanSkip=*/false))
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000470 return false;
471
472 // Try to match each declaration context.
473 // We are allowed to skip anonymous and inline namespaces if they don't match.
474 const DeclContext *Ctx = Node.getDeclContext();
475
476 if (Ctx->isFunctionOrMethod())
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000477 return Patterns.foundMatch(/*AllowFullyQualified=*/false);
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000478
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000479 for (; Ctx && isa<NamedDecl>(Ctx); Ctx = Ctx->getParent()) {
480 if (Patterns.foundMatch(/*AllowFullyQualified=*/false))
481 return true;
482
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000483 if (const auto *ND = dyn_cast<NamespaceDecl>(Ctx)) {
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000484 // If it matches (or we can skip it), continue.
485 if (Patterns.consumeNameSuffix(getNodeName(*ND, Scratch),
486 /*CanSkip=*/ND->isAnonymousNamespace() ||
487 ND->isInline()))
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000488 continue;
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000489 return false;
490 }
491 if (const auto *RD = dyn_cast<RecordDecl>(Ctx)) {
492 if (!isa<ClassTemplateSpecializationDecl>(Ctx)) {
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000493 if (Patterns.consumeNameSuffix(getNodeName(*RD, Scratch),
494 /*CanSkip=*/false))
495 continue;
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000496
497 return false;
498 }
499 }
500
501 // We don't know how to deal with this DeclContext.
502 // Fallback to the slow version of the code.
503 return matchesNodeFullSlow(Node);
504 }
505
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000506 return Patterns.foundMatch(/*AllowFullyQualified=*/true);
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000507}
508
509bool HasNameMatcher::matchesNodeFullSlow(const NamedDecl &Node) const {
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000510 const bool SkipUnwrittenCases[] = {false, true};
511 for (bool SkipUnwritten : SkipUnwrittenCases) {
512 llvm::SmallString<128> NodeName = StringRef("::");
513 llvm::raw_svector_ostream OS(NodeName);
514
515 if (SkipUnwritten) {
516 PrintingPolicy Policy = Node.getASTContext().getPrintingPolicy();
517 Policy.SuppressUnwrittenScope = true;
518 Node.printQualifiedName(OS, Policy);
519 } else {
520 Node.printQualifiedName(OS);
521 }
522
523 const StringRef FullName = OS.str();
524
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000525 for (const StringRef Pattern : Names) {
526 if (Pattern.startswith("::")) {
527 if (FullName == Pattern)
528 return true;
529 } else if (FullName.endswith(Pattern) &&
530 FullName.drop_back(Pattern.size()).endswith("::")) {
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000531 return true;
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000532 }
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000533 }
534 }
535
Samuel Benzaquenb6f73bc2014-10-16 17:50:19 +0000536 return false;
Samuel Benzaquen8513d622014-10-15 14:58:46 +0000537}
538
Samuel Benzaquen8513d622014-10-15 14:58:46 +0000539bool HasNameMatcher::matchesNode(const NamedDecl &Node) const {
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000540 assert(matchesNodeFullFast(Node) == matchesNodeFullSlow(Node));
Samuel Benzaquen8513d622014-10-15 14:58:46 +0000541 if (UseUnqualifiedMatch) {
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000542 assert(matchesNodeUnqualified(Node) == matchesNodeFullFast(Node));
Samuel Benzaquen8513d622014-10-15 14:58:46 +0000543 return matchesNodeUnqualified(Node);
544 }
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000545 return matchesNodeFullFast(Node);
Samuel Benzaquen8513d622014-10-15 14:58:46 +0000546}
547
Manuel Klimek04616e42012-07-06 05:48:52 +0000548} // end namespace internal
David Blaikieac7e3d62017-11-15 16:52:12 +0000549
550const internal::VariadicDynCastAllOfMatcher<Decl, TranslationUnitDecl>
551 translationUnitDecl;
552const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl> typedefDecl;
553const internal::VariadicDynCastAllOfMatcher<Decl, TypedefNameDecl>
554 typedefNameDecl;
555const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasDecl> typeAliasDecl;
556const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasTemplateDecl>
557 typeAliasTemplateDecl;
558const internal::VariadicAllOfMatcher<Decl> decl;
559const internal::VariadicDynCastAllOfMatcher<Decl, LinkageSpecDecl>
560 linkageSpecDecl;
561const internal::VariadicDynCastAllOfMatcher<Decl, NamedDecl> namedDecl;
562const internal::VariadicDynCastAllOfMatcher<Decl, LabelDecl> labelDecl;
563const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceDecl> namespaceDecl;
564const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceAliasDecl>
565 namespaceAliasDecl;
566const internal::VariadicDynCastAllOfMatcher<Decl, RecordDecl> recordDecl;
567const internal::VariadicDynCastAllOfMatcher<Decl, CXXRecordDecl> cxxRecordDecl;
568const internal::VariadicDynCastAllOfMatcher<Decl, ClassTemplateDecl>
569 classTemplateDecl;
570const internal::VariadicDynCastAllOfMatcher<Decl,
571 ClassTemplateSpecializationDecl>
572 classTemplateSpecializationDecl;
573const internal::VariadicDynCastAllOfMatcher<Decl, DeclaratorDecl>
574 declaratorDecl;
575const internal::VariadicDynCastAllOfMatcher<Decl, ParmVarDecl> parmVarDecl;
576const internal::VariadicDynCastAllOfMatcher<Decl, AccessSpecDecl>
577 accessSpecDecl;
578const internal::VariadicAllOfMatcher<CXXCtorInitializer> cxxCtorInitializer;
579const internal::VariadicAllOfMatcher<TemplateArgument> templateArgument;
580const internal::VariadicAllOfMatcher<TemplateName> templateName;
581const internal::VariadicDynCastAllOfMatcher<Decl, NonTypeTemplateParmDecl>
582 nonTypeTemplateParmDecl;
583const internal::VariadicDynCastAllOfMatcher<Decl, TemplateTypeParmDecl>
584 templateTypeParmDecl;
585const internal::VariadicAllOfMatcher<QualType> qualType;
586const internal::VariadicAllOfMatcher<Type> type;
587const internal::VariadicAllOfMatcher<TypeLoc> typeLoc;
588const internal::VariadicDynCastAllOfMatcher<Stmt, UnaryExprOrTypeTraitExpr>
589 unaryExprOrTypeTraitExpr;
590const internal::VariadicDynCastAllOfMatcher<Decl, ValueDecl> valueDecl;
591const internal::VariadicDynCastAllOfMatcher<Decl, CXXConstructorDecl>
592 cxxConstructorDecl;
593const internal::VariadicDynCastAllOfMatcher<Decl, CXXDestructorDecl>
594 cxxDestructorDecl;
595const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl;
596const internal::VariadicDynCastAllOfMatcher<Decl, EnumConstantDecl>
597 enumConstantDecl;
598const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> cxxMethodDecl;
599const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl>
600 cxxConversionDecl;
601const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> varDecl;
602const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> fieldDecl;
603const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl> functionDecl;
604const internal::VariadicDynCastAllOfMatcher<Decl, FunctionTemplateDecl>
605 functionTemplateDecl;
606const internal::VariadicDynCastAllOfMatcher<Decl, FriendDecl> friendDecl;
607const internal::VariadicAllOfMatcher<Stmt> stmt;
608const internal::VariadicDynCastAllOfMatcher<Stmt, DeclStmt> declStmt;
609const internal::VariadicDynCastAllOfMatcher<Stmt, MemberExpr> memberExpr;
610const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> callExpr;
611const internal::VariadicDynCastAllOfMatcher<Stmt, LambdaExpr> lambdaExpr;
612const internal::VariadicDynCastAllOfMatcher<Stmt, CXXMemberCallExpr>
613 cxxMemberCallExpr;
614const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCMessageExpr>
615 objcMessageExpr;
616const internal::VariadicDynCastAllOfMatcher<Decl, ObjCInterfaceDecl>
617 objcInterfaceDecl;
618const internal::VariadicDynCastAllOfMatcher<Decl, ObjCImplementationDecl>
619 objcImplementationDecl;
620const internal::VariadicDynCastAllOfMatcher<Decl, ObjCProtocolDecl>
621 objcProtocolDecl;
622const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryDecl>
623 objcCategoryDecl;
624const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryImplDecl>
625 objcCategoryImplDecl;
626const internal::VariadicDynCastAllOfMatcher<Decl, ObjCMethodDecl>
627 objcMethodDecl;
628const internal::VariadicDynCastAllOfMatcher<Decl, ObjCIvarDecl> objcIvarDecl;
629const internal::VariadicDynCastAllOfMatcher<Decl, ObjCPropertyDecl>
630 objcPropertyDecl;
631const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtThrowStmt>
632 objcThrowStmt;
633const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtTryStmt> objcTryStmt;
634const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtCatchStmt>
635 objcCatchStmt;
636const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtFinallyStmt>
637 objcFinallyStmt;
638const internal::VariadicDynCastAllOfMatcher<Stmt, ExprWithCleanups>
639 exprWithCleanups;
640const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr> initListExpr;
641const internal::VariadicDynCastAllOfMatcher<Stmt, CXXStdInitializerListExpr>
642 cxxStdInitializerListExpr;
643const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitValueInitExpr>
644 implicitValueInitExpr;
645const internal::VariadicDynCastAllOfMatcher<Stmt, ParenListExpr> parenListExpr;
646const internal::VariadicDynCastAllOfMatcher<Stmt, SubstNonTypeTemplateParmExpr>
647 substNonTypeTemplateParmExpr;
648const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl;
649const internal::VariadicDynCastAllOfMatcher<Decl, UsingDirectiveDecl>
650 usingDirectiveDecl;
651const internal::VariadicDynCastAllOfMatcher<Stmt, UnresolvedLookupExpr>
652 unresolvedLookupExpr;
653const internal::VariadicDynCastAllOfMatcher<Decl, UnresolvedUsingValueDecl>
654 unresolvedUsingValueDecl;
655const internal::VariadicDynCastAllOfMatcher<Decl, UnresolvedUsingTypenameDecl>
656 unresolvedUsingTypenameDecl;
657const internal::VariadicDynCastAllOfMatcher<Stmt, ParenExpr> parenExpr;
658const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstructExpr>
659 cxxConstructExpr;
660const internal::VariadicDynCastAllOfMatcher<Stmt, CXXUnresolvedConstructExpr>
661 cxxUnresolvedConstructExpr;
662const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThisExpr> cxxThisExpr;
663const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBindTemporaryExpr>
664 cxxBindTemporaryExpr;
665const internal::VariadicDynCastAllOfMatcher<Stmt, MaterializeTemporaryExpr>
666 materializeTemporaryExpr;
667const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> cxxNewExpr;
668const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDeleteExpr> cxxDeleteExpr;
669const internal::VariadicDynCastAllOfMatcher<Stmt, ArraySubscriptExpr>
670 arraySubscriptExpr;
671const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDefaultArgExpr>
672 cxxDefaultArgExpr;
673const internal::VariadicDynCastAllOfMatcher<Stmt, CXXOperatorCallExpr>
674 cxxOperatorCallExpr;
675const internal::VariadicDynCastAllOfMatcher<Stmt, Expr> expr;
676const internal::VariadicDynCastAllOfMatcher<Stmt, DeclRefExpr> declRefExpr;
677const internal::VariadicDynCastAllOfMatcher<Stmt, IfStmt> ifStmt;
678const internal::VariadicDynCastAllOfMatcher<Stmt, ForStmt> forStmt;
679const internal::VariadicDynCastAllOfMatcher<Stmt, CXXForRangeStmt>
680 cxxForRangeStmt;
681const internal::VariadicDynCastAllOfMatcher<Stmt, WhileStmt> whileStmt;
682const internal::VariadicDynCastAllOfMatcher<Stmt, DoStmt> doStmt;
683const internal::VariadicDynCastAllOfMatcher<Stmt, BreakStmt> breakStmt;
684const internal::VariadicDynCastAllOfMatcher<Stmt, ContinueStmt> continueStmt;
685const internal::VariadicDynCastAllOfMatcher<Stmt, ReturnStmt> returnStmt;
686const internal::VariadicDynCastAllOfMatcher<Stmt, GotoStmt> gotoStmt;
687const internal::VariadicDynCastAllOfMatcher<Stmt, LabelStmt> labelStmt;
688const internal::VariadicDynCastAllOfMatcher<Stmt, AddrLabelExpr> addrLabelExpr;
689const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchStmt> switchStmt;
690const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchCase> switchCase;
691const internal::VariadicDynCastAllOfMatcher<Stmt, CaseStmt> caseStmt;
692const internal::VariadicDynCastAllOfMatcher<Stmt, DefaultStmt> defaultStmt;
693const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundStmt> compoundStmt;
694const internal::VariadicDynCastAllOfMatcher<Stmt, CXXCatchStmt> cxxCatchStmt;
695const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTryStmt> cxxTryStmt;
696const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThrowExpr> cxxThrowExpr;
697const internal::VariadicDynCastAllOfMatcher<Stmt, NullStmt> nullStmt;
698const internal::VariadicDynCastAllOfMatcher<Stmt, AsmStmt> asmStmt;
699const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBoolLiteralExpr>
700 cxxBoolLiteral;
701const internal::VariadicDynCastAllOfMatcher<Stmt, StringLiteral> stringLiteral;
702const internal::VariadicDynCastAllOfMatcher<Stmt, CharacterLiteral>
703 characterLiteral;
704const internal::VariadicDynCastAllOfMatcher<Stmt, IntegerLiteral>
705 integerLiteral;
706const internal::VariadicDynCastAllOfMatcher<Stmt, FloatingLiteral> floatLiteral;
707const internal::VariadicDynCastAllOfMatcher<Stmt, UserDefinedLiteral>
708 userDefinedLiteral;
709const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundLiteralExpr>
710 compoundLiteralExpr;
711const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNullPtrLiteralExpr>
712 cxxNullPtrLiteralExpr;
713const internal::VariadicDynCastAllOfMatcher<Stmt, GNUNullExpr> gnuNullExpr;
714const internal::VariadicDynCastAllOfMatcher<Stmt, AtomicExpr> atomicExpr;
715const internal::VariadicDynCastAllOfMatcher<Stmt, StmtExpr> stmtExpr;
716const internal::VariadicDynCastAllOfMatcher<Stmt, BinaryOperator>
717 binaryOperator;
718const internal::VariadicDynCastAllOfMatcher<Stmt, UnaryOperator> unaryOperator;
719const internal::VariadicDynCastAllOfMatcher<Stmt, ConditionalOperator>
720 conditionalOperator;
721const internal::VariadicDynCastAllOfMatcher<Stmt, BinaryConditionalOperator>
722 binaryConditionalOperator;
723const internal::VariadicDynCastAllOfMatcher<Stmt, OpaqueValueExpr>
724 opaqueValueExpr;
725const internal::VariadicDynCastAllOfMatcher<Decl, StaticAssertDecl>
726 staticAssertDecl;
727const internal::VariadicDynCastAllOfMatcher<Stmt, CXXReinterpretCastExpr>
728 cxxReinterpretCastExpr;
729const internal::VariadicDynCastAllOfMatcher<Stmt, CXXStaticCastExpr>
730 cxxStaticCastExpr;
731const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDynamicCastExpr>
732 cxxDynamicCastExpr;
733const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstCastExpr>
734 cxxConstCastExpr;
735const internal::VariadicDynCastAllOfMatcher<Stmt, CStyleCastExpr>
736 cStyleCastExpr;
737const internal::VariadicDynCastAllOfMatcher<Stmt, ExplicitCastExpr>
738 explicitCastExpr;
739const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitCastExpr>
740 implicitCastExpr;
741const internal::VariadicDynCastAllOfMatcher<Stmt, CastExpr> castExpr;
742const internal::VariadicDynCastAllOfMatcher<Stmt, CXXFunctionalCastExpr>
743 cxxFunctionalCastExpr;
744const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTemporaryObjectExpr>
745 cxxTemporaryObjectExpr;
746const internal::VariadicDynCastAllOfMatcher<Stmt, PredefinedExpr>
747 predefinedExpr;
748const internal::VariadicDynCastAllOfMatcher<Stmt, DesignatedInitExpr>
749 designatedInitExpr;
750const internal::VariadicOperatorMatcherFunc<
751 2, std::numeric_limits<unsigned>::max()>
752 eachOf = {internal::DynTypedMatcher::VO_EachOf};
753const internal::VariadicOperatorMatcherFunc<
754 2, std::numeric_limits<unsigned>::max()>
755 anyOf = {internal::DynTypedMatcher::VO_AnyOf};
756const internal::VariadicOperatorMatcherFunc<
757 2, std::numeric_limits<unsigned>::max()>
758 allOf = {internal::DynTypedMatcher::VO_AllOf};
759const internal::VariadicFunction<internal::Matcher<NamedDecl>, StringRef,
760 internal::hasAnyNameFunc>
761 hasAnyName = {};
762const internal::ArgumentAdaptingMatcherFunc<internal::HasMatcher> has = {};
763const internal::ArgumentAdaptingMatcherFunc<internal::HasDescendantMatcher>
764 hasDescendant = {};
765const internal::ArgumentAdaptingMatcherFunc<internal::ForEachMatcher> forEach =
766 {};
767const internal::ArgumentAdaptingMatcherFunc<internal::ForEachDescendantMatcher>
768 forEachDescendant = {};
769const internal::ArgumentAdaptingMatcherFunc<
770 internal::HasParentMatcher,
771 internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>,
772 internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>>
773 hasParent = {};
774const internal::ArgumentAdaptingMatcherFunc<
775 internal::HasAncestorMatcher,
776 internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>,
777 internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>>
778 hasAncestor = {};
779const internal::VariadicOperatorMatcherFunc<1, 1> unless = {
780 internal::DynTypedMatcher::VO_UnaryNot};
781const internal::VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier;
782const internal::VariadicAllOfMatcher<NestedNameSpecifierLoc>
783 nestedNameSpecifierLoc;
784const internal::VariadicDynCastAllOfMatcher<Stmt, CUDAKernelCallExpr>
785 cudaKernelCallExpr;
786const AstTypeMatcher<BuiltinType> builtinType;
787const AstTypeMatcher<ArrayType> arrayType;
788const AstTypeMatcher<ComplexType> complexType;
789const AstTypeMatcher<ConstantArrayType> constantArrayType;
790const AstTypeMatcher<DependentSizedArrayType> dependentSizedArrayType;
791const AstTypeMatcher<IncompleteArrayType> incompleteArrayType;
792const AstTypeMatcher<VariableArrayType> variableArrayType;
793const AstTypeMatcher<AtomicType> atomicType;
794const AstTypeMatcher<AutoType> autoType;
795const AstTypeMatcher<FunctionType> functionType;
796const AstTypeMatcher<FunctionProtoType> functionProtoType;
797const AstTypeMatcher<ParenType> parenType;
798const AstTypeMatcher<BlockPointerType> blockPointerType;
799const AstTypeMatcher<MemberPointerType> memberPointerType;
800const AstTypeMatcher<PointerType> pointerType;
801const AstTypeMatcher<ObjCObjectPointerType> objcObjectPointerType;
802const AstTypeMatcher<ReferenceType> referenceType;
803const AstTypeMatcher<LValueReferenceType> lValueReferenceType;
804const AstTypeMatcher<RValueReferenceType> rValueReferenceType;
805const AstTypeMatcher<TypedefType> typedefType;
806const AstTypeMatcher<EnumType> enumType;
807const AstTypeMatcher<TemplateSpecializationType> templateSpecializationType;
808const AstTypeMatcher<UnaryTransformType> unaryTransformType;
809const AstTypeMatcher<RecordType> recordType;
810const AstTypeMatcher<TagType> tagType;
811const AstTypeMatcher<ElaboratedType> elaboratedType;
812const AstTypeMatcher<SubstTemplateTypeParmType> substTemplateTypeParmType;
813const AstTypeMatcher<TemplateTypeParmType> templateTypeParmType;
814const AstTypeMatcher<InjectedClassNameType> injectedClassNameType;
815const AstTypeMatcher<DecayedType> decayedType;
David Blaikie1de35432017-11-21 01:09:18 +0000816AST_TYPELOC_TRAVERSE_MATCHER_DEF(hasElementType,
817 AST_POLYMORPHIC_SUPPORTED_TYPES(ArrayType,
818 ComplexType));
819AST_TYPELOC_TRAVERSE_MATCHER_DEF(hasValueType,
820 AST_POLYMORPHIC_SUPPORTED_TYPES(AtomicType));
821AST_TYPELOC_TRAVERSE_MATCHER_DEF(
822 pointee,
823 AST_POLYMORPHIC_SUPPORTED_TYPES(BlockPointerType, MemberPointerType,
824 PointerType, ReferenceType));
David Blaikieac7e3d62017-11-15 16:52:12 +0000825
Manuel Klimek04616e42012-07-06 05:48:52 +0000826} // end namespace ast_matchers
827} // end namespace clang