blob: 8c75b76156729a5fd2cc219f35d69ce40faa0792 [file] [log] [blame]
Eugene Zelenko06becf82017-11-01 23:09:49 +00001//===- ASTMatchersInternal.cpp - Structural query framework ---------------===//
Manuel Klimek04616e42012-07-06 05:48:52 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Manuel Klimek04616e42012-07-06 05:48:52 +00006//
7//===----------------------------------------------------------------------===//
8//
9// Implements the base layer of the matcher framework.
10//
11//===----------------------------------------------------------------------===//
12
Manuel Klimek04616e42012-07-06 05:48:52 +000013#include "clang/ASTMatchers/ASTMatchersInternal.h"
Eugene Zelenko06becf82017-11-01 23:09:49 +000014#include "clang/AST/ASTContext.h"
15#include "clang/AST/ASTTypeTraits.h"
16#include "clang/AST/Decl.h"
17#include "clang/AST/DeclTemplate.h"
18#include "clang/AST/PrettyPrinter.h"
19#include "clang/ASTMatchers/ASTMatchers.h"
20#include "clang/Basic/LLVM.h"
21#include "llvm/ADT/ArrayRef.h"
22#include "llvm/ADT/IntrusiveRefCntPtr.h"
23#include "llvm/ADT/None.h"
Samuel Benzaquen8513d622014-10-15 14:58:46 +000024#include "llvm/ADT/SmallString.h"
Samuel Benzaquen922bef42016-02-22 21:13:02 +000025#include "llvm/ADT/SmallVector.h"
Eugene Zelenko06becf82017-11-01 23:09:49 +000026#include "llvm/ADT/StringRef.h"
27#include "llvm/Support/Casting.h"
28#include "llvm/Support/ErrorHandling.h"
Samuel Benzaquen96039d72014-10-09 19:28:18 +000029#include "llvm/Support/ManagedStatic.h"
Eugene Zelenko06becf82017-11-01 23:09:49 +000030#include "llvm/Support/raw_ostream.h"
31#include <algorithm>
32#include <cassert>
33#include <cstddef>
34#include <string>
35#include <utility>
36#include <vector>
Manuel Klimek04616e42012-07-06 05:48:52 +000037
38namespace clang {
39namespace ast_matchers {
George Karpenkov446f4982018-03-29 01:15:05 +000040
41AST_MATCHER_P(ObjCMessageExpr, hasAnySelectorMatcher, std::vector<std::string>,
42 Matches) {
43 std::string SelString = Node.getSelector().getAsString();
44 for (const std::string &S : Matches)
45 if (S == SelString)
46 return true;
47 return false;
48}
49
Manuel Klimek04616e42012-07-06 05:48:52 +000050namespace internal {
51
Hans Wennborgb27f2492015-07-14 16:50:14 +000052bool NotUnaryOperator(const ast_type_traits::DynTypedNode &DynNode,
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +000053 ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
54 ArrayRef<DynTypedMatcher> InnerMatchers);
55
Hans Wennborgb27f2492015-07-14 16:50:14 +000056bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +000057 ASTMatchFinder *Finder,
58 BoundNodesTreeBuilder *Builder,
59 ArrayRef<DynTypedMatcher> InnerMatchers);
60
Hans Wennborgb27f2492015-07-14 16:50:14 +000061bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +000062 ASTMatchFinder *Finder,
63 BoundNodesTreeBuilder *Builder,
64 ArrayRef<DynTypedMatcher> InnerMatchers);
65
Hans Wennborgb27f2492015-07-14 16:50:14 +000066bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +000067 ASTMatchFinder *Finder,
68 BoundNodesTreeBuilder *Builder,
69 ArrayRef<DynTypedMatcher> InnerMatchers);
70
Manuel Klimeka0c025f2013-06-19 15:42:45 +000071void BoundNodesTreeBuilder::visitMatches(Visitor *ResultVisitor) {
72 if (Bindings.empty())
73 Bindings.push_back(BoundNodesMap());
Benjamin Kramer79f15902014-10-24 13:29:15 +000074 for (BoundNodesMap &Binding : Bindings) {
75 ResultVisitor->visitMatch(BoundNodes(Binding));
Manuel Klimek021d56f2012-08-28 23:26:39 +000076 }
77}
78
Samuel Benzaquenf28d9972014-10-01 15:08:07 +000079namespace {
80
Eugene Zelenko06becf82017-11-01 23:09:49 +000081using VariadicOperatorFunction = bool (*)(
Hans Wennborgb27f2492015-07-14 16:50:14 +000082 const ast_type_traits::DynTypedNode &DynNode, ASTMatchFinder *Finder,
Samuel Benzaquen95636e52014-12-01 14:46:14 +000083 BoundNodesTreeBuilder *Builder, ArrayRef<DynTypedMatcher> InnerMatchers);
84
85template <VariadicOperatorFunction Func>
Samuel Benzaquenf28d9972014-10-01 15:08:07 +000086class VariadicMatcher : public DynMatcherInterface {
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +000087public:
Samuel Benzaquen95636e52014-12-01 14:46:14 +000088 VariadicMatcher(std::vector<DynTypedMatcher> InnerMatchers)
89 : InnerMatchers(std::move(InnerMatchers)) {}
Samuel Benzaquenf28d9972014-10-01 15:08:07 +000090
91 bool dynMatches(const ast_type_traits::DynTypedNode &DynNode,
92 ASTMatchFinder *Finder,
93 BoundNodesTreeBuilder *Builder) const override {
94 return Func(DynNode, Finder, Builder, InnerMatchers);
95 }
96
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +000097private:
Samuel Benzaquenf28d9972014-10-01 15:08:07 +000098 std::vector<DynTypedMatcher> InnerMatchers;
99};
100
101class IdDynMatcher : public DynMatcherInterface {
Benjamin Kramer018b6d42016-07-21 15:06:51 +0000102public:
Samuel Benzaquenf28d9972014-10-01 15:08:07 +0000103 IdDynMatcher(StringRef ID,
Benjamin Kramer018b6d42016-07-21 15:06:51 +0000104 IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher)
105 : ID(ID), InnerMatcher(std::move(InnerMatcher)) {}
Samuel Benzaquenf28d9972014-10-01 15:08:07 +0000106
107 bool dynMatches(const ast_type_traits::DynTypedNode &DynNode,
108 ASTMatchFinder *Finder,
109 BoundNodesTreeBuilder *Builder) const override {
110 bool Result = InnerMatcher->dynMatches(DynNode, Finder, Builder);
111 if (Result) Builder->setBinding(ID, DynNode);
112 return Result;
113 }
114
Benjamin Kramer018b6d42016-07-21 15:06:51 +0000115private:
Samuel Benzaquenf28d9972014-10-01 15:08:07 +0000116 const std::string ID;
117 const IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher;
118};
119
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000120/// A matcher that always returns true.
Samuel Benzaquen96039d72014-10-09 19:28:18 +0000121///
122/// We only ever need one instance of this matcher, so we create a global one
123/// and reuse it to reduce the overhead of the matcher and increase the chance
124/// of cache hits.
Benjamin Kramer967c0792014-10-24 13:29:21 +0000125class TrueMatcherImpl : public DynMatcherInterface {
126public:
127 TrueMatcherImpl() {
128 Retain(); // Reference count will never become zero.
129 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000130
Benjamin Kramer967c0792014-10-24 13:29:21 +0000131 bool dynMatches(const ast_type_traits::DynTypedNode &, ASTMatchFinder *,
132 BoundNodesTreeBuilder *) const override {
133 return true;
134 }
Samuel Benzaquen96039d72014-10-09 19:28:18 +0000135};
Samuel Benzaquen96039d72014-10-09 19:28:18 +0000136
Eugene Zelenko06becf82017-11-01 23:09:49 +0000137} // namespace
138
139static llvm::ManagedStatic<TrueMatcherImpl> TrueMatcherInstance;
Samuel Benzaquenf28d9972014-10-01 15:08:07 +0000140
141DynTypedMatcher DynTypedMatcher::constructVariadic(
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000142 DynTypedMatcher::VariadicOperator Op,
Samuel Benzaquenb063f5c2015-07-17 16:05:27 +0000143 ast_type_traits::ASTNodeKind SupportedKind,
Samuel Benzaquen9743c9d2014-11-17 14:55:49 +0000144 std::vector<DynTypedMatcher> InnerMatchers) {
Eugene Zelenko06becf82017-11-01 23:09:49 +0000145 assert(!InnerMatchers.empty() && "Array must not be empty.");
Fangrui Song3117b172018-10-20 17:53:42 +0000146 assert(llvm::all_of(InnerMatchers,
147 [SupportedKind](const DynTypedMatcher &M) {
148 return M.canConvertTo(SupportedKind);
149 }) &&
Samuel Benzaquenb063f5c2015-07-17 16:05:27 +0000150 "InnerMatchers must be convertible to SupportedKind!");
Samuel Benzaquen20099602014-10-13 17:38:12 +0000151
152 // We must relax the restrict kind here.
153 // The different operators might deal differently with a mismatch.
154 // Make it the same as SupportedKind, since that is the broadest type we are
155 // allowed to accept.
Samuel Benzaquen95636e52014-12-01 14:46:14 +0000156 auto RestrictKind = SupportedKind;
157
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000158 switch (Op) {
159 case VO_AllOf:
Samuel Benzaquen95636e52014-12-01 14:46:14 +0000160 // In the case of allOf() we must pass all the checks, so making
161 // RestrictKind the most restrictive can save us time. This way we reject
162 // invalid types earlier and we can elide the kind checks inside the
163 // matcher.
164 for (auto &IM : InnerMatchers) {
165 RestrictKind = ast_type_traits::ASTNodeKind::getMostDerivedType(
166 RestrictKind, IM.RestrictKind);
167 }
168 return DynTypedMatcher(
169 SupportedKind, RestrictKind,
170 new VariadicMatcher<AllOfVariadicOperator>(std::move(InnerMatchers)));
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000171
Samuel Benzaquen95636e52014-12-01 14:46:14 +0000172 case VO_AnyOf:
173 return DynTypedMatcher(
174 SupportedKind, RestrictKind,
175 new VariadicMatcher<AnyOfVariadicOperator>(std::move(InnerMatchers)));
176
177 case VO_EachOf:
178 return DynTypedMatcher(
179 SupportedKind, RestrictKind,
180 new VariadicMatcher<EachOfVariadicOperator>(std::move(InnerMatchers)));
181
182 case VO_UnaryNot:
183 // FIXME: Implement the Not operator to take a single matcher instead of a
184 // vector.
185 return DynTypedMatcher(
186 SupportedKind, RestrictKind,
187 new VariadicMatcher<NotUnaryOperator>(std::move(InnerMatchers)));
188 }
189 llvm_unreachable("Invalid Op value.");
Samuel Benzaquenf28d9972014-10-01 15:08:07 +0000190}
191
Samuel Benzaquen96039d72014-10-09 19:28:18 +0000192DynTypedMatcher DynTypedMatcher::trueMatcher(
193 ast_type_traits::ASTNodeKind NodeKind) {
Benjamin Kramer967c0792014-10-24 13:29:21 +0000194 return DynTypedMatcher(NodeKind, NodeKind, &*TrueMatcherInstance);
Samuel Benzaquen96039d72014-10-09 19:28:18 +0000195}
196
Samuel Benzaquen074bbb62014-11-24 21:21:09 +0000197bool DynTypedMatcher::canMatchNodesOfKind(
198 ast_type_traits::ASTNodeKind Kind) const {
199 return RestrictKind.isBaseOf(Kind);
200}
201
Samuel Benzaquenf28d9972014-10-01 15:08:07 +0000202DynTypedMatcher DynTypedMatcher::dynCastTo(
203 const ast_type_traits::ASTNodeKind Kind) const {
204 auto Copy = *this;
205 Copy.SupportedKind = Kind;
Samuel Benzaquena1170022014-10-06 13:14:30 +0000206 Copy.RestrictKind =
207 ast_type_traits::ASTNodeKind::getMostDerivedType(Kind, RestrictKind);
Samuel Benzaquenf28d9972014-10-01 15:08:07 +0000208 return Copy;
209}
210
211bool DynTypedMatcher::matches(const ast_type_traits::DynTypedNode &DynNode,
212 ASTMatchFinder *Finder,
213 BoundNodesTreeBuilder *Builder) const {
214 if (RestrictKind.isBaseOf(DynNode.getNodeKind()) &&
215 Implementation->dynMatches(DynNode, Finder, Builder)) {
216 return true;
217 }
218 // Delete all bindings when a matcher does not match.
219 // This prevents unexpected exposure of bound nodes in unmatches
220 // branches of the match tree.
221 Builder->removeBindings([](const BoundNodesMap &) { return true; });
222 return false;
223}
224
Samuel Benzaquen074bbb62014-11-24 21:21:09 +0000225bool DynTypedMatcher::matchesNoKindCheck(
226 const ast_type_traits::DynTypedNode &DynNode, ASTMatchFinder *Finder,
227 BoundNodesTreeBuilder *Builder) const {
228 assert(RestrictKind.isBaseOf(DynNode.getNodeKind()));
229 if (Implementation->dynMatches(DynNode, Finder, Builder)) {
230 return true;
231 }
232 // Delete all bindings when a matcher does not match.
233 // This prevents unexpected exposure of bound nodes in unmatches
234 // branches of the match tree.
235 Builder->removeBindings([](const BoundNodesMap &) { return true; });
236 return false;
237}
238
Samuel Benzaquenf28d9972014-10-01 15:08:07 +0000239llvm::Optional<DynTypedMatcher> DynTypedMatcher::tryBind(StringRef ID) const {
240 if (!AllowBind) return llvm::None;
241 auto Result = *this;
Benjamin Kramer018b6d42016-07-21 15:06:51 +0000242 Result.Implementation =
243 new IdDynMatcher(ID, std::move(Result.Implementation));
244 return std::move(Result);
Samuel Benzaquenf28d9972014-10-01 15:08:07 +0000245}
246
Samuel Benzaquenab005ed2014-09-04 14:13:58 +0000247bool DynTypedMatcher::canConvertTo(ast_type_traits::ASTNodeKind To) const {
248 const auto From = getSupportedKind();
249 auto QualKind = ast_type_traits::ASTNodeKind::getFromNodeKind<QualType>();
250 auto TypeKind = ast_type_traits::ASTNodeKind::getFromNodeKind<Type>();
251 /// Mimic the implicit conversions of Matcher<>.
252 /// - From Matcher<Type> to Matcher<QualType>
253 if (From.isSame(TypeKind) && To.isSame(QualKind)) return true;
254 /// - From Matcher<Base> to Matcher<Derived>
255 return From.isBaseOf(To);
256}
257
Manuel Klimeka0c025f2013-06-19 15:42:45 +0000258void BoundNodesTreeBuilder::addMatch(const BoundNodesTreeBuilder &Other) {
Benjamin Kramer79f15902014-10-24 13:29:15 +0000259 Bindings.append(Other.Bindings.begin(), Other.Bindings.end());
Manuel Klimek021d56f2012-08-28 23:26:39 +0000260}
261
Hans Wennborgb27f2492015-07-14 16:50:14 +0000262bool NotUnaryOperator(const ast_type_traits::DynTypedNode &DynNode,
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000263 ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
264 ArrayRef<DynTypedMatcher> InnerMatchers) {
265 if (InnerMatchers.size() != 1)
266 return false;
267
268 // The 'unless' matcher will always discard the result:
269 // If the inner matcher doesn't match, unless returns true,
270 // but the inner matcher cannot have bound anything.
271 // If the inner matcher matches, the result is false, and
272 // any possible binding will be discarded.
273 // We still need to hand in all the bound nodes up to this
274 // point so the inner matcher can depend on bound nodes,
275 // and we need to actively discard the bound nodes, otherwise
276 // the inner matcher will reset the bound nodes if it doesn't
277 // match, but this would be inversed by 'unless'.
278 BoundNodesTreeBuilder Discard(*Builder);
279 return !InnerMatchers[0].matches(DynNode, Finder, &Discard);
280}
281
Hans Wennborgb27f2492015-07-14 16:50:14 +0000282bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000283 ASTMatchFinder *Finder,
284 BoundNodesTreeBuilder *Builder,
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000285 ArrayRef<DynTypedMatcher> InnerMatchers) {
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000286 // allOf leads to one matcher for each alternative in the first
287 // matcher combined with each alternative in the second matcher.
288 // Thus, we can reuse the same Builder.
Benjamin Kramer79f15902014-10-24 13:29:15 +0000289 for (const DynTypedMatcher &InnerMatcher : InnerMatchers) {
Samuel Benzaquen95636e52014-12-01 14:46:14 +0000290 if (!InnerMatcher.matchesNoKindCheck(DynNode, Finder, Builder))
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000291 return false;
292 }
293 return true;
294}
295
Hans Wennborgb27f2492015-07-14 16:50:14 +0000296bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000297 ASTMatchFinder *Finder,
298 BoundNodesTreeBuilder *Builder,
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000299 ArrayRef<DynTypedMatcher> InnerMatchers) {
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000300 BoundNodesTreeBuilder Result;
301 bool Matched = false;
Benjamin Kramer79f15902014-10-24 13:29:15 +0000302 for (const DynTypedMatcher &InnerMatcher : InnerMatchers) {
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000303 BoundNodesTreeBuilder BuilderInner(*Builder);
Benjamin Kramer79f15902014-10-24 13:29:15 +0000304 if (InnerMatcher.matches(DynNode, Finder, &BuilderInner)) {
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000305 Matched = true;
306 Result.addMatch(BuilderInner);
307 }
308 }
Benjamin Kramerd9c91622014-08-29 11:22:47 +0000309 *Builder = std::move(Result);
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000310 return Matched;
311}
312
Hans Wennborgb27f2492015-07-14 16:50:14 +0000313bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000314 ASTMatchFinder *Finder,
315 BoundNodesTreeBuilder *Builder,
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000316 ArrayRef<DynTypedMatcher> InnerMatchers) {
Benjamin Kramer79f15902014-10-24 13:29:15 +0000317 for (const DynTypedMatcher &InnerMatcher : InnerMatchers) {
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000318 BoundNodesTreeBuilder Result = *Builder;
Benjamin Kramer79f15902014-10-24 13:29:15 +0000319 if (InnerMatcher.matches(DynNode, Finder, &Result)) {
Benjamin Kramerd9c91622014-08-29 11:22:47 +0000320 *Builder = std::move(Result);
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000321 return true;
322 }
323 }
324 return false;
325}
326
George Karpenkov88a16a02018-03-29 00:51:12 +0000327inline static
328std::vector<std::string> vectorFromRefs(ArrayRef<const StringRef *> NameRefs) {
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000329 std::vector<std::string> Names;
330 for (auto *Name : NameRefs)
331 Names.emplace_back(*Name);
George Karpenkov88a16a02018-03-29 00:51:12 +0000332 return Names;
333}
334
335Matcher<NamedDecl> hasAnyNameFunc(ArrayRef<const StringRef *> NameRefs) {
336 std::vector<std::string> Names = vectorFromRefs(NameRefs);
337 return internal::Matcher<NamedDecl>(new internal::HasNameMatcher(Names));
338}
339
George Karpenkov88a16a02018-03-29 00:51:12 +0000340Matcher<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);
Fangrui Song3117b172018-10-20 17:53:42 +0000451 return llvm::any_of(Names, [&](StringRef Name) {
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000452 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
George Karpenkovba02bc52018-07-06 21:36:04 +0000550const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAutoreleasePoolStmt>
551 autoreleasePoolStmt;
David Blaikieac7e3d62017-11-15 16:52:12 +0000552const internal::VariadicDynCastAllOfMatcher<Decl, TranslationUnitDecl>
553 translationUnitDecl;
554const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl> typedefDecl;
555const internal::VariadicDynCastAllOfMatcher<Decl, TypedefNameDecl>
556 typedefNameDecl;
557const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasDecl> typeAliasDecl;
558const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasTemplateDecl>
559 typeAliasTemplateDecl;
560const internal::VariadicAllOfMatcher<Decl> decl;
561const internal::VariadicDynCastAllOfMatcher<Decl, LinkageSpecDecl>
562 linkageSpecDecl;
563const internal::VariadicDynCastAllOfMatcher<Decl, NamedDecl> namedDecl;
564const internal::VariadicDynCastAllOfMatcher<Decl, LabelDecl> labelDecl;
565const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceDecl> namespaceDecl;
566const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceAliasDecl>
567 namespaceAliasDecl;
568const internal::VariadicDynCastAllOfMatcher<Decl, RecordDecl> recordDecl;
569const internal::VariadicDynCastAllOfMatcher<Decl, CXXRecordDecl> cxxRecordDecl;
570const internal::VariadicDynCastAllOfMatcher<Decl, ClassTemplateDecl>
571 classTemplateDecl;
572const internal::VariadicDynCastAllOfMatcher<Decl,
573 ClassTemplateSpecializationDecl>
574 classTemplateSpecializationDecl;
Gabor Marton42e15de2018-08-22 11:52:14 +0000575const internal::VariadicDynCastAllOfMatcher<
576 Decl, ClassTemplatePartialSpecializationDecl>
577 classTemplatePartialSpecializationDecl;
David Blaikieac7e3d62017-11-15 16:52:12 +0000578const internal::VariadicDynCastAllOfMatcher<Decl, DeclaratorDecl>
579 declaratorDecl;
580const internal::VariadicDynCastAllOfMatcher<Decl, ParmVarDecl> parmVarDecl;
581const internal::VariadicDynCastAllOfMatcher<Decl, AccessSpecDecl>
582 accessSpecDecl;
583const internal::VariadicAllOfMatcher<CXXCtorInitializer> cxxCtorInitializer;
584const internal::VariadicAllOfMatcher<TemplateArgument> templateArgument;
585const internal::VariadicAllOfMatcher<TemplateName> templateName;
586const internal::VariadicDynCastAllOfMatcher<Decl, NonTypeTemplateParmDecl>
587 nonTypeTemplateParmDecl;
588const internal::VariadicDynCastAllOfMatcher<Decl, TemplateTypeParmDecl>
589 templateTypeParmDecl;
590const internal::VariadicAllOfMatcher<QualType> qualType;
591const internal::VariadicAllOfMatcher<Type> type;
592const internal::VariadicAllOfMatcher<TypeLoc> typeLoc;
593const internal::VariadicDynCastAllOfMatcher<Stmt, UnaryExprOrTypeTraitExpr>
594 unaryExprOrTypeTraitExpr;
595const internal::VariadicDynCastAllOfMatcher<Decl, ValueDecl> valueDecl;
596const internal::VariadicDynCastAllOfMatcher<Decl, CXXConstructorDecl>
597 cxxConstructorDecl;
598const internal::VariadicDynCastAllOfMatcher<Decl, CXXDestructorDecl>
599 cxxDestructorDecl;
600const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl;
601const internal::VariadicDynCastAllOfMatcher<Decl, EnumConstantDecl>
602 enumConstantDecl;
603const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> cxxMethodDecl;
604const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl>
605 cxxConversionDecl;
606const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> varDecl;
607const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> fieldDecl;
Gabor Marton7df342a2018-12-17 12:42:12 +0000608const internal::VariadicDynCastAllOfMatcher<Decl, IndirectFieldDecl>
609 indirectFieldDecl;
David Blaikieac7e3d62017-11-15 16:52:12 +0000610const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl> functionDecl;
611const internal::VariadicDynCastAllOfMatcher<Decl, FunctionTemplateDecl>
612 functionTemplateDecl;
613const internal::VariadicDynCastAllOfMatcher<Decl, FriendDecl> friendDecl;
614const internal::VariadicAllOfMatcher<Stmt> stmt;
615const internal::VariadicDynCastAllOfMatcher<Stmt, DeclStmt> declStmt;
616const internal::VariadicDynCastAllOfMatcher<Stmt, MemberExpr> memberExpr;
Shuai Wang72b56ed2018-08-12 17:34:36 +0000617const internal::VariadicDynCastAllOfMatcher<Stmt, UnresolvedMemberExpr>
618 unresolvedMemberExpr;
619const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDependentScopeMemberExpr>
620 cxxDependentScopeMemberExpr;
David Blaikieac7e3d62017-11-15 16:52:12 +0000621const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> callExpr;
622const internal::VariadicDynCastAllOfMatcher<Stmt, LambdaExpr> lambdaExpr;
623const internal::VariadicDynCastAllOfMatcher<Stmt, CXXMemberCallExpr>
624 cxxMemberCallExpr;
625const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCMessageExpr>
626 objcMessageExpr;
627const internal::VariadicDynCastAllOfMatcher<Decl, ObjCInterfaceDecl>
628 objcInterfaceDecl;
629const internal::VariadicDynCastAllOfMatcher<Decl, ObjCImplementationDecl>
630 objcImplementationDecl;
631const internal::VariadicDynCastAllOfMatcher<Decl, ObjCProtocolDecl>
632 objcProtocolDecl;
633const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryDecl>
634 objcCategoryDecl;
635const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryImplDecl>
636 objcCategoryImplDecl;
637const internal::VariadicDynCastAllOfMatcher<Decl, ObjCMethodDecl>
638 objcMethodDecl;
George Karpenkovb4c0cbd2018-05-16 22:47:03 +0000639const internal::VariadicDynCastAllOfMatcher<Decl, BlockDecl>
640 blockDecl;
David Blaikieac7e3d62017-11-15 16:52:12 +0000641const internal::VariadicDynCastAllOfMatcher<Decl, ObjCIvarDecl> objcIvarDecl;
642const internal::VariadicDynCastAllOfMatcher<Decl, ObjCPropertyDecl>
643 objcPropertyDecl;
644const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtThrowStmt>
645 objcThrowStmt;
646const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtTryStmt> objcTryStmt;
647const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtCatchStmt>
648 objcCatchStmt;
649const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtFinallyStmt>
650 objcFinallyStmt;
651const internal::VariadicDynCastAllOfMatcher<Stmt, ExprWithCleanups>
652 exprWithCleanups;
653const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr> initListExpr;
654const internal::VariadicDynCastAllOfMatcher<Stmt, CXXStdInitializerListExpr>
655 cxxStdInitializerListExpr;
656const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitValueInitExpr>
657 implicitValueInitExpr;
658const internal::VariadicDynCastAllOfMatcher<Stmt, ParenListExpr> parenListExpr;
659const internal::VariadicDynCastAllOfMatcher<Stmt, SubstNonTypeTemplateParmExpr>
660 substNonTypeTemplateParmExpr;
661const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl;
662const internal::VariadicDynCastAllOfMatcher<Decl, UsingDirectiveDecl>
663 usingDirectiveDecl;
664const internal::VariadicDynCastAllOfMatcher<Stmt, UnresolvedLookupExpr>
665 unresolvedLookupExpr;
666const internal::VariadicDynCastAllOfMatcher<Decl, UnresolvedUsingValueDecl>
667 unresolvedUsingValueDecl;
668const internal::VariadicDynCastAllOfMatcher<Decl, UnresolvedUsingTypenameDecl>
669 unresolvedUsingTypenameDecl;
Bill Wendling8003edc2018-11-09 00:41:36 +0000670const internal::VariadicDynCastAllOfMatcher<Stmt, ConstantExpr> constantExpr;
David Blaikieac7e3d62017-11-15 16:52:12 +0000671const internal::VariadicDynCastAllOfMatcher<Stmt, ParenExpr> parenExpr;
672const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstructExpr>
673 cxxConstructExpr;
674const internal::VariadicDynCastAllOfMatcher<Stmt, CXXUnresolvedConstructExpr>
675 cxxUnresolvedConstructExpr;
676const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThisExpr> cxxThisExpr;
677const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBindTemporaryExpr>
678 cxxBindTemporaryExpr;
679const internal::VariadicDynCastAllOfMatcher<Stmt, MaterializeTemporaryExpr>
680 materializeTemporaryExpr;
681const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> cxxNewExpr;
682const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDeleteExpr> cxxDeleteExpr;
683const internal::VariadicDynCastAllOfMatcher<Stmt, ArraySubscriptExpr>
684 arraySubscriptExpr;
685const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDefaultArgExpr>
686 cxxDefaultArgExpr;
687const internal::VariadicDynCastAllOfMatcher<Stmt, CXXOperatorCallExpr>
688 cxxOperatorCallExpr;
689const internal::VariadicDynCastAllOfMatcher<Stmt, Expr> expr;
690const internal::VariadicDynCastAllOfMatcher<Stmt, DeclRefExpr> declRefExpr;
George Karpenkov079275b2018-07-27 17:26:11 +0000691const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCIvarRefExpr> objcIvarRefExpr;
Stephane Moore3897b2d2018-12-13 03:35:10 +0000692const internal::VariadicDynCastAllOfMatcher<Stmt, BlockExpr> blockExpr;
David Blaikieac7e3d62017-11-15 16:52:12 +0000693const internal::VariadicDynCastAllOfMatcher<Stmt, IfStmt> ifStmt;
694const internal::VariadicDynCastAllOfMatcher<Stmt, ForStmt> forStmt;
695const internal::VariadicDynCastAllOfMatcher<Stmt, CXXForRangeStmt>
696 cxxForRangeStmt;
697const internal::VariadicDynCastAllOfMatcher<Stmt, WhileStmt> whileStmt;
698const internal::VariadicDynCastAllOfMatcher<Stmt, DoStmt> doStmt;
699const internal::VariadicDynCastAllOfMatcher<Stmt, BreakStmt> breakStmt;
700const internal::VariadicDynCastAllOfMatcher<Stmt, ContinueStmt> continueStmt;
701const internal::VariadicDynCastAllOfMatcher<Stmt, ReturnStmt> returnStmt;
702const internal::VariadicDynCastAllOfMatcher<Stmt, GotoStmt> gotoStmt;
703const internal::VariadicDynCastAllOfMatcher<Stmt, LabelStmt> labelStmt;
704const internal::VariadicDynCastAllOfMatcher<Stmt, AddrLabelExpr> addrLabelExpr;
705const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchStmt> switchStmt;
706const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchCase> switchCase;
707const internal::VariadicDynCastAllOfMatcher<Stmt, CaseStmt> caseStmt;
708const internal::VariadicDynCastAllOfMatcher<Stmt, DefaultStmt> defaultStmt;
709const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundStmt> compoundStmt;
710const internal::VariadicDynCastAllOfMatcher<Stmt, CXXCatchStmt> cxxCatchStmt;
711const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTryStmt> cxxTryStmt;
712const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThrowExpr> cxxThrowExpr;
713const internal::VariadicDynCastAllOfMatcher<Stmt, NullStmt> nullStmt;
714const internal::VariadicDynCastAllOfMatcher<Stmt, AsmStmt> asmStmt;
715const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBoolLiteralExpr>
716 cxxBoolLiteral;
717const internal::VariadicDynCastAllOfMatcher<Stmt, StringLiteral> stringLiteral;
718const internal::VariadicDynCastAllOfMatcher<Stmt, CharacterLiteral>
719 characterLiteral;
720const internal::VariadicDynCastAllOfMatcher<Stmt, IntegerLiteral>
721 integerLiteral;
722const internal::VariadicDynCastAllOfMatcher<Stmt, FloatingLiteral> floatLiteral;
Gabor Martonbf7f18b2018-08-09 12:18:07 +0000723const internal::VariadicDynCastAllOfMatcher<Stmt, ImaginaryLiteral> imaginaryLiteral;
David Blaikieac7e3d62017-11-15 16:52:12 +0000724const internal::VariadicDynCastAllOfMatcher<Stmt, UserDefinedLiteral>
725 userDefinedLiteral;
726const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundLiteralExpr>
727 compoundLiteralExpr;
728const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNullPtrLiteralExpr>
729 cxxNullPtrLiteralExpr;
Tom Roeder521f0042019-02-26 19:26:41 +0000730const internal::VariadicDynCastAllOfMatcher<Stmt, ChooseExpr> chooseExpr;
David Blaikieac7e3d62017-11-15 16:52:12 +0000731const internal::VariadicDynCastAllOfMatcher<Stmt, GNUNullExpr> gnuNullExpr;
732const internal::VariadicDynCastAllOfMatcher<Stmt, AtomicExpr> atomicExpr;
733const internal::VariadicDynCastAllOfMatcher<Stmt, StmtExpr> stmtExpr;
734const internal::VariadicDynCastAllOfMatcher<Stmt, BinaryOperator>
735 binaryOperator;
736const internal::VariadicDynCastAllOfMatcher<Stmt, UnaryOperator> unaryOperator;
737const internal::VariadicDynCastAllOfMatcher<Stmt, ConditionalOperator>
738 conditionalOperator;
739const internal::VariadicDynCastAllOfMatcher<Stmt, BinaryConditionalOperator>
740 binaryConditionalOperator;
741const internal::VariadicDynCastAllOfMatcher<Stmt, OpaqueValueExpr>
742 opaqueValueExpr;
743const internal::VariadicDynCastAllOfMatcher<Decl, StaticAssertDecl>
744 staticAssertDecl;
745const internal::VariadicDynCastAllOfMatcher<Stmt, CXXReinterpretCastExpr>
746 cxxReinterpretCastExpr;
747const internal::VariadicDynCastAllOfMatcher<Stmt, CXXStaticCastExpr>
748 cxxStaticCastExpr;
749const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDynamicCastExpr>
750 cxxDynamicCastExpr;
751const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstCastExpr>
752 cxxConstCastExpr;
753const internal::VariadicDynCastAllOfMatcher<Stmt, CStyleCastExpr>
754 cStyleCastExpr;
755const internal::VariadicDynCastAllOfMatcher<Stmt, ExplicitCastExpr>
756 explicitCastExpr;
757const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitCastExpr>
758 implicitCastExpr;
759const internal::VariadicDynCastAllOfMatcher<Stmt, CastExpr> castExpr;
760const internal::VariadicDynCastAllOfMatcher<Stmt, CXXFunctionalCastExpr>
761 cxxFunctionalCastExpr;
762const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTemporaryObjectExpr>
763 cxxTemporaryObjectExpr;
764const internal::VariadicDynCastAllOfMatcher<Stmt, PredefinedExpr>
765 predefinedExpr;
766const internal::VariadicDynCastAllOfMatcher<Stmt, DesignatedInitExpr>
767 designatedInitExpr;
768const internal::VariadicOperatorMatcherFunc<
769 2, std::numeric_limits<unsigned>::max()>
770 eachOf = {internal::DynTypedMatcher::VO_EachOf};
771const internal::VariadicOperatorMatcherFunc<
772 2, std::numeric_limits<unsigned>::max()>
773 anyOf = {internal::DynTypedMatcher::VO_AnyOf};
774const internal::VariadicOperatorMatcherFunc<
775 2, std::numeric_limits<unsigned>::max()>
776 allOf = {internal::DynTypedMatcher::VO_AllOf};
777const internal::VariadicFunction<internal::Matcher<NamedDecl>, StringRef,
778 internal::hasAnyNameFunc>
779 hasAnyName = {};
George Karpenkov10f4c962018-03-29 02:47:28 +0000780const internal::VariadicFunction<internal::Matcher<ObjCMessageExpr>, StringRef,
781 internal::hasAnySelectorFunc>
782 hasAnySelector = {};
David Blaikieac7e3d62017-11-15 16:52:12 +0000783const internal::ArgumentAdaptingMatcherFunc<internal::HasMatcher> has = {};
784const internal::ArgumentAdaptingMatcherFunc<internal::HasDescendantMatcher>
785 hasDescendant = {};
786const internal::ArgumentAdaptingMatcherFunc<internal::ForEachMatcher> forEach =
787 {};
788const internal::ArgumentAdaptingMatcherFunc<internal::ForEachDescendantMatcher>
789 forEachDescendant = {};
790const internal::ArgumentAdaptingMatcherFunc<
791 internal::HasParentMatcher,
792 internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>,
793 internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>>
794 hasParent = {};
795const internal::ArgumentAdaptingMatcherFunc<
796 internal::HasAncestorMatcher,
797 internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>,
798 internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>>
799 hasAncestor = {};
800const internal::VariadicOperatorMatcherFunc<1, 1> unless = {
801 internal::DynTypedMatcher::VO_UnaryNot};
802const internal::VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier;
803const internal::VariadicAllOfMatcher<NestedNameSpecifierLoc>
804 nestedNameSpecifierLoc;
805const internal::VariadicDynCastAllOfMatcher<Stmt, CUDAKernelCallExpr>
806 cudaKernelCallExpr;
807const AstTypeMatcher<BuiltinType> builtinType;
808const AstTypeMatcher<ArrayType> arrayType;
809const AstTypeMatcher<ComplexType> complexType;
810const AstTypeMatcher<ConstantArrayType> constantArrayType;
811const AstTypeMatcher<DependentSizedArrayType> dependentSizedArrayType;
812const AstTypeMatcher<IncompleteArrayType> incompleteArrayType;
813const AstTypeMatcher<VariableArrayType> variableArrayType;
814const AstTypeMatcher<AtomicType> atomicType;
815const AstTypeMatcher<AutoType> autoType;
Jonas Tothfa1ea692018-07-23 15:59:27 +0000816const AstTypeMatcher<DecltypeType> decltypeType;
David Blaikieac7e3d62017-11-15 16:52:12 +0000817const AstTypeMatcher<FunctionType> functionType;
818const AstTypeMatcher<FunctionProtoType> functionProtoType;
819const AstTypeMatcher<ParenType> parenType;
820const AstTypeMatcher<BlockPointerType> blockPointerType;
821const AstTypeMatcher<MemberPointerType> memberPointerType;
822const AstTypeMatcher<PointerType> pointerType;
823const AstTypeMatcher<ObjCObjectPointerType> objcObjectPointerType;
824const AstTypeMatcher<ReferenceType> referenceType;
825const AstTypeMatcher<LValueReferenceType> lValueReferenceType;
826const AstTypeMatcher<RValueReferenceType> rValueReferenceType;
827const AstTypeMatcher<TypedefType> typedefType;
828const AstTypeMatcher<EnumType> enumType;
829const AstTypeMatcher<TemplateSpecializationType> templateSpecializationType;
830const AstTypeMatcher<UnaryTransformType> unaryTransformType;
831const AstTypeMatcher<RecordType> recordType;
832const AstTypeMatcher<TagType> tagType;
833const AstTypeMatcher<ElaboratedType> elaboratedType;
834const AstTypeMatcher<SubstTemplateTypeParmType> substTemplateTypeParmType;
835const AstTypeMatcher<TemplateTypeParmType> templateTypeParmType;
836const AstTypeMatcher<InjectedClassNameType> injectedClassNameType;
837const AstTypeMatcher<DecayedType> decayedType;
David Blaikie1de35432017-11-21 01:09:18 +0000838AST_TYPELOC_TRAVERSE_MATCHER_DEF(hasElementType,
839 AST_POLYMORPHIC_SUPPORTED_TYPES(ArrayType,
840 ComplexType));
841AST_TYPELOC_TRAVERSE_MATCHER_DEF(hasValueType,
842 AST_POLYMORPHIC_SUPPORTED_TYPES(AtomicType));
843AST_TYPELOC_TRAVERSE_MATCHER_DEF(
844 pointee,
845 AST_POLYMORPHIC_SUPPORTED_TYPES(BlockPointerType, MemberPointerType,
846 PointerType, ReferenceType));
David Blaikieac7e3d62017-11-15 16:52:12 +0000847
Manuel Klimek04616e42012-07-06 05:48:52 +0000848} // end namespace ast_matchers
849} // end namespace clang