blob: 7b551a4eee70566180808f57b7b8ad5918bed221 [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 {
George Karpenkov446f4982018-03-29 01:15:05 +000041
42AST_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 Klimek04616e42012-07-06 05:48:52 +000051namespace internal {
52
Hans Wennborgb27f2492015-07-14 16:50:14 +000053bool NotUnaryOperator(const ast_type_traits::DynTypedNode &DynNode,
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +000054 ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
55 ArrayRef<DynTypedMatcher> InnerMatchers);
56
Hans Wennborgb27f2492015-07-14 16:50:14 +000057bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +000058 ASTMatchFinder *Finder,
59 BoundNodesTreeBuilder *Builder,
60 ArrayRef<DynTypedMatcher> InnerMatchers);
61
Hans Wennborgb27f2492015-07-14 16:50:14 +000062bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +000063 ASTMatchFinder *Finder,
64 BoundNodesTreeBuilder *Builder,
65 ArrayRef<DynTypedMatcher> InnerMatchers);
66
Hans Wennborgb27f2492015-07-14 16:50:14 +000067bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +000068 ASTMatchFinder *Finder,
69 BoundNodesTreeBuilder *Builder,
70 ArrayRef<DynTypedMatcher> InnerMatchers);
71
Manuel Klimeka0c025f2013-06-19 15:42:45 +000072void BoundNodesTreeBuilder::visitMatches(Visitor *ResultVisitor) {
73 if (Bindings.empty())
74 Bindings.push_back(BoundNodesMap());
Benjamin Kramer79f15902014-10-24 13:29:15 +000075 for (BoundNodesMap &Binding : Bindings) {
76 ResultVisitor->visitMatch(BoundNodes(Binding));
Manuel Klimek021d56f2012-08-28 23:26:39 +000077 }
78}
79
Samuel Benzaquenf28d9972014-10-01 15:08:07 +000080namespace {
81
Eugene Zelenko06becf82017-11-01 23:09:49 +000082using VariadicOperatorFunction = bool (*)(
Hans Wennborgb27f2492015-07-14 16:50:14 +000083 const ast_type_traits::DynTypedNode &DynNode, ASTMatchFinder *Finder,
Samuel Benzaquen95636e52014-12-01 14:46:14 +000084 BoundNodesTreeBuilder *Builder, ArrayRef<DynTypedMatcher> InnerMatchers);
85
86template <VariadicOperatorFunction Func>
Samuel Benzaquenf28d9972014-10-01 15:08:07 +000087class VariadicMatcher : public DynMatcherInterface {
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +000088public:
Samuel Benzaquen95636e52014-12-01 14:46:14 +000089 VariadicMatcher(std::vector<DynTypedMatcher> InnerMatchers)
90 : InnerMatchers(std::move(InnerMatchers)) {}
Samuel Benzaquenf28d9972014-10-01 15:08:07 +000091
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 Benzaquen2c15e8c2014-11-20 15:45:53 +000098private:
Samuel Benzaquenf28d9972014-10-01 15:08:07 +000099 std::vector<DynTypedMatcher> InnerMatchers;
100};
101
102class IdDynMatcher : public DynMatcherInterface {
Benjamin Kramer018b6d42016-07-21 15:06:51 +0000103public:
Samuel Benzaquenf28d9972014-10-01 15:08:07 +0000104 IdDynMatcher(StringRef ID,
Benjamin Kramer018b6d42016-07-21 15:06:51 +0000105 IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher)
106 : ID(ID), InnerMatcher(std::move(InnerMatcher)) {}
Samuel Benzaquenf28d9972014-10-01 15:08:07 +0000107
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 Kramer018b6d42016-07-21 15:06:51 +0000116private:
Samuel Benzaquenf28d9972014-10-01 15:08:07 +0000117 const std::string ID;
118 const IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher;
119};
120
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000121/// A matcher that always returns true.
Samuel Benzaquen96039d72014-10-09 19:28:18 +0000122///
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 Kramer967c0792014-10-24 13:29:21 +0000126class TrueMatcherImpl : public DynMatcherInterface {
127public:
128 TrueMatcherImpl() {
129 Retain(); // Reference count will never become zero.
130 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000131
Benjamin Kramer967c0792014-10-24 13:29:21 +0000132 bool dynMatches(const ast_type_traits::DynTypedNode &, ASTMatchFinder *,
133 BoundNodesTreeBuilder *) const override {
134 return true;
135 }
Samuel Benzaquen96039d72014-10-09 19:28:18 +0000136};
Samuel Benzaquen96039d72014-10-09 19:28:18 +0000137
Eugene Zelenko06becf82017-11-01 23:09:49 +0000138} // namespace
139
140static llvm::ManagedStatic<TrueMatcherImpl> TrueMatcherInstance;
Samuel Benzaquenf28d9972014-10-01 15:08:07 +0000141
142DynTypedMatcher DynTypedMatcher::constructVariadic(
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000143 DynTypedMatcher::VariadicOperator Op,
Samuel Benzaquenb063f5c2015-07-17 16:05:27 +0000144 ast_type_traits::ASTNodeKind SupportedKind,
Samuel Benzaquen9743c9d2014-11-17 14:55:49 +0000145 std::vector<DynTypedMatcher> InnerMatchers) {
Eugene Zelenko06becf82017-11-01 23:09:49 +0000146 assert(!InnerMatchers.empty() && "Array must not be empty.");
Samuel Benzaquen20099602014-10-13 17:38:12 +0000147 assert(std::all_of(InnerMatchers.begin(), InnerMatchers.end(),
Samuel Benzaquenb063f5c2015-07-17 16:05:27 +0000148 [SupportedKind](const DynTypedMatcher &M) {
149 return M.canConvertTo(SupportedKind);
150 }) &&
151 "InnerMatchers must be convertible to SupportedKind!");
Samuel Benzaquen20099602014-10-13 17:38:12 +0000152
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 Benzaquen95636e52014-12-01 14:46:14 +0000157 auto RestrictKind = SupportedKind;
158
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000159 switch (Op) {
160 case VO_AllOf:
Samuel Benzaquen95636e52014-12-01 14:46:14 +0000161 // 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 Benzaquen2c15e8c2014-11-20 15:45:53 +0000172
Samuel Benzaquen95636e52014-12-01 14:46:14 +0000173 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 Benzaquenf28d9972014-10-01 15:08:07 +0000191}
192
Samuel Benzaquen96039d72014-10-09 19:28:18 +0000193DynTypedMatcher DynTypedMatcher::trueMatcher(
194 ast_type_traits::ASTNodeKind NodeKind) {
Benjamin Kramer967c0792014-10-24 13:29:21 +0000195 return DynTypedMatcher(NodeKind, NodeKind, &*TrueMatcherInstance);
Samuel Benzaquen96039d72014-10-09 19:28:18 +0000196}
197
Samuel Benzaquen074bbb62014-11-24 21:21:09 +0000198bool DynTypedMatcher::canMatchNodesOfKind(
199 ast_type_traits::ASTNodeKind Kind) const {
200 return RestrictKind.isBaseOf(Kind);
201}
202
Samuel Benzaquenf28d9972014-10-01 15:08:07 +0000203DynTypedMatcher DynTypedMatcher::dynCastTo(
204 const ast_type_traits::ASTNodeKind Kind) const {
205 auto Copy = *this;
206 Copy.SupportedKind = Kind;
Samuel Benzaquena1170022014-10-06 13:14:30 +0000207 Copy.RestrictKind =
208 ast_type_traits::ASTNodeKind::getMostDerivedType(Kind, RestrictKind);
Samuel Benzaquenf28d9972014-10-01 15:08:07 +0000209 return Copy;
210}
211
212bool 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 Benzaquen074bbb62014-11-24 21:21:09 +0000226bool 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 Benzaquenf28d9972014-10-01 15:08:07 +0000240llvm::Optional<DynTypedMatcher> DynTypedMatcher::tryBind(StringRef ID) const {
241 if (!AllowBind) return llvm::None;
242 auto Result = *this;
Benjamin Kramer018b6d42016-07-21 15:06:51 +0000243 Result.Implementation =
244 new IdDynMatcher(ID, std::move(Result.Implementation));
245 return std::move(Result);
Samuel Benzaquenf28d9972014-10-01 15:08:07 +0000246}
247
Samuel Benzaquenab005ed2014-09-04 14:13:58 +0000248bool 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 Klimeka0c025f2013-06-19 15:42:45 +0000259void BoundNodesTreeBuilder::addMatch(const BoundNodesTreeBuilder &Other) {
Benjamin Kramer79f15902014-10-24 13:29:15 +0000260 Bindings.append(Other.Bindings.begin(), Other.Bindings.end());
Manuel Klimek021d56f2012-08-28 23:26:39 +0000261}
262
Hans Wennborgb27f2492015-07-14 16:50:14 +0000263bool NotUnaryOperator(const ast_type_traits::DynTypedNode &DynNode,
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000264 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 Wennborgb27f2492015-07-14 16:50:14 +0000283bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000284 ASTMatchFinder *Finder,
285 BoundNodesTreeBuilder *Builder,
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000286 ArrayRef<DynTypedMatcher> InnerMatchers) {
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000287 // 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 Kramer79f15902014-10-24 13:29:15 +0000290 for (const DynTypedMatcher &InnerMatcher : InnerMatchers) {
Samuel Benzaquen95636e52014-12-01 14:46:14 +0000291 if (!InnerMatcher.matchesNoKindCheck(DynNode, Finder, Builder))
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000292 return false;
293 }
294 return true;
295}
296
Hans Wennborgb27f2492015-07-14 16:50:14 +0000297bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000298 ASTMatchFinder *Finder,
299 BoundNodesTreeBuilder *Builder,
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000300 ArrayRef<DynTypedMatcher> InnerMatchers) {
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000301 BoundNodesTreeBuilder Result;
302 bool Matched = false;
Benjamin Kramer79f15902014-10-24 13:29:15 +0000303 for (const DynTypedMatcher &InnerMatcher : InnerMatchers) {
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000304 BoundNodesTreeBuilder BuilderInner(*Builder);
Benjamin Kramer79f15902014-10-24 13:29:15 +0000305 if (InnerMatcher.matches(DynNode, Finder, &BuilderInner)) {
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000306 Matched = true;
307 Result.addMatch(BuilderInner);
308 }
309 }
Benjamin Kramerd9c91622014-08-29 11:22:47 +0000310 *Builder = std::move(Result);
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000311 return Matched;
312}
313
Hans Wennborgb27f2492015-07-14 16:50:14 +0000314bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000315 ASTMatchFinder *Finder,
316 BoundNodesTreeBuilder *Builder,
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000317 ArrayRef<DynTypedMatcher> InnerMatchers) {
Benjamin Kramer79f15902014-10-24 13:29:15 +0000318 for (const DynTypedMatcher &InnerMatcher : InnerMatchers) {
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000319 BoundNodesTreeBuilder Result = *Builder;
Benjamin Kramer79f15902014-10-24 13:29:15 +0000320 if (InnerMatcher.matches(DynNode, Finder, &Result)) {
Benjamin Kramerd9c91622014-08-29 11:22:47 +0000321 *Builder = std::move(Result);
Samuel Benzaquen85ec25d2013-08-27 15:11:16 +0000322 return true;
323 }
324 }
325 return false;
326}
327
George Karpenkov88a16a02018-03-29 00:51:12 +0000328inline static
329std::vector<std::string> vectorFromRefs(ArrayRef<const StringRef *> NameRefs) {
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000330 std::vector<std::string> Names;
331 for (auto *Name : NameRefs)
332 Names.emplace_back(*Name);
George Karpenkov88a16a02018-03-29 00:51:12 +0000333 return Names;
334}
335
336Matcher<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 Karpenkov88a16a02018-03-29 00:51:12 +0000341Matcher<ObjCMessageExpr> hasAnySelectorFunc(
342 ArrayRef<const StringRef *> NameRefs) {
343 return hasAnySelectorMatcher(vectorFromRefs(NameRefs));
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000344}
345
346HasNameMatcher::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 Kornienko1eeac192016-02-23 10:29:04 +0000351#ifndef NDEBUG
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000352 for (StringRef Name : Names)
353 assert(!Name.empty());
Alexander Kornienko1eeac192016-02-23 10:29:04 +0000354#endif
Samuel Benzaquen8513d622014-10-15 14:58:46 +0000355}
356
Eugene Zelenko06becf82017-11-01 23:09:49 +0000357static bool consumeNameSuffix(StringRef &FullName, StringRef Suffix) {
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000358 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 Benzaquenb6f73bc2014-10-16 17:50:19 +0000366 }
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000367 FullName = Name;
368 return true;
369}
370
Eugene Zelenko06becf82017-11-01 23:09:49 +0000371static StringRef getNodeName(const NamedDecl &Node,
372 llvm::SmallString<128> &Scratch) {
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000373 // Simple name.
374 if (Node.getIdentifier())
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000375 return Node.getName();
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000376
Samuel Benzaquenb6f73bc2014-10-16 17:50:19 +0000377 if (Node.getDeclName()) {
Samuel Benzaquen8513d622014-10-15 14:58:46 +0000378 // Name needs to be constructed.
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000379 Scratch.clear();
380 llvm::raw_svector_ostream OS(Scratch);
Samuel Benzaquen8513d622014-10-15 14:58:46 +0000381 Node.printName(OS);
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000382 return OS.str();
Samuel Benzaquen8513d622014-10-15 14:58:46 +0000383 }
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000384
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000385 return "(anonymous)";
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000386}
387
Eugene Zelenko06becf82017-11-01 23:09:49 +0000388static StringRef getNodeName(const RecordDecl &Node,
389 llvm::SmallString<128> &Scratch) {
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000390 if (Node.getIdentifier()) {
391 return Node.getName();
392 }
393 Scratch.clear();
394 return ("(anonymous " + Node.getKindName() + ")").toStringRef(Scratch);
395}
396
Eugene Zelenko06becf82017-11-01 23:09:49 +0000397static StringRef getNodeName(const NamespaceDecl &Node,
398 llvm::SmallString<128> &Scratch) {
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000399 return Node.isAnonymousNamespace() ? "(anonymous namespace)" : Node.getName();
400}
401
Eugene Zelenko06becf82017-11-01 23:09:49 +0000402namespace {
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000403
404class PatternSet {
405public:
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 Karpenkov88a16a02018-03-29 00:51:12 +0000416 if (::clang::ast_matchers::internal::consumeNameSuffix(Patterns[I].P,
417 NodeName) ||
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000418 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 Wennborg157a5d52016-02-22 22:21:58 +0000432 if (P.P.empty() && (AllowFullyQualified || !P.IsFullyQualified))
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000433 return true;
434 return false;
435 }
436
437private:
438 struct Pattern {
Hans Wennborg157a5d52016-02-22 22:21:58 +0000439 StringRef P;
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000440 bool IsFullyQualified;
441 };
Eugene Zelenko06becf82017-11-01 23:09:49 +0000442
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000443 llvm::SmallVector<Pattern, 8> Patterns;
444};
445
Eugene Zelenko06becf82017-11-01 23:09:49 +0000446} // namespace
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000447
448bool HasNameMatcher::matchesNodeUnqualified(const NamedDecl &Node) const {
449 assert(UseUnqualifiedMatch);
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000450 llvm::SmallString<128> Scratch;
451 StringRef NodeName = getNodeName(Node, Scratch);
452 return std::any_of(Names.begin(), Names.end(), [&](StringRef Name) {
453 return consumeNameSuffix(Name, NodeName) && Name.empty();
454 });
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000455}
456
457bool HasNameMatcher::matchesNodeFullFast(const NamedDecl &Node) const {
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000458 PatternSet Patterns(Names);
459 llvm::SmallString<128> Scratch;
460
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000461 // 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 Benzaquen8e566f32016-02-05 18:29:24 +0000467
468 // First, match the name.
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000469 if (!Patterns.consumeNameSuffix(getNodeName(Node, Scratch),
470 /*CanSkip=*/false))
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000471 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 Benzaquen922bef42016-02-22 21:13:02 +0000478 return Patterns.foundMatch(/*AllowFullyQualified=*/false);
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000479
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000480 for (; Ctx && isa<NamedDecl>(Ctx); Ctx = Ctx->getParent()) {
481 if (Patterns.foundMatch(/*AllowFullyQualified=*/false))
482 return true;
483
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000484 if (const auto *ND = dyn_cast<NamespaceDecl>(Ctx)) {
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000485 // If it matches (or we can skip it), continue.
486 if (Patterns.consumeNameSuffix(getNodeName(*ND, Scratch),
487 /*CanSkip=*/ND->isAnonymousNamespace() ||
488 ND->isInline()))
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000489 continue;
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000490 return false;
491 }
492 if (const auto *RD = dyn_cast<RecordDecl>(Ctx)) {
493 if (!isa<ClassTemplateSpecializationDecl>(Ctx)) {
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000494 if (Patterns.consumeNameSuffix(getNodeName(*RD, Scratch),
495 /*CanSkip=*/false))
496 continue;
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000497
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 Benzaquen922bef42016-02-22 21:13:02 +0000507 return Patterns.foundMatch(/*AllowFullyQualified=*/true);
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000508}
509
510bool HasNameMatcher::matchesNodeFullSlow(const NamedDecl &Node) const {
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000511 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 Benzaquen922bef42016-02-22 21:13:02 +0000526 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 Benzaquen8e566f32016-02-05 18:29:24 +0000532 return true;
Samuel Benzaquen922bef42016-02-22 21:13:02 +0000533 }
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000534 }
535 }
536
Samuel Benzaquenb6f73bc2014-10-16 17:50:19 +0000537 return false;
Samuel Benzaquen8513d622014-10-15 14:58:46 +0000538}
539
Samuel Benzaquen8513d622014-10-15 14:58:46 +0000540bool HasNameMatcher::matchesNode(const NamedDecl &Node) const {
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000541 assert(matchesNodeFullFast(Node) == matchesNodeFullSlow(Node));
Samuel Benzaquen8513d622014-10-15 14:58:46 +0000542 if (UseUnqualifiedMatch) {
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000543 assert(matchesNodeUnqualified(Node) == matchesNodeFullFast(Node));
Samuel Benzaquen8513d622014-10-15 14:58:46 +0000544 return matchesNodeUnqualified(Node);
545 }
Samuel Benzaquen8e566f32016-02-05 18:29:24 +0000546 return matchesNodeFullFast(Node);
Samuel Benzaquen8513d622014-10-15 14:58:46 +0000547}
548
Manuel Klimek04616e42012-07-06 05:48:52 +0000549} // end namespace internal
David Blaikieac7e3d62017-11-15 16:52:12 +0000550
George Karpenkovba02bc52018-07-06 21:36:04 +0000551const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAutoreleasePoolStmt>
552 autoreleasePoolStmt;
David Blaikieac7e3d62017-11-15 16:52:12 +0000553const internal::VariadicDynCastAllOfMatcher<Decl, TranslationUnitDecl>
554 translationUnitDecl;
555const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl> typedefDecl;
556const internal::VariadicDynCastAllOfMatcher<Decl, TypedefNameDecl>
557 typedefNameDecl;
558const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasDecl> typeAliasDecl;
559const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasTemplateDecl>
560 typeAliasTemplateDecl;
561const internal::VariadicAllOfMatcher<Decl> decl;
562const internal::VariadicDynCastAllOfMatcher<Decl, LinkageSpecDecl>
563 linkageSpecDecl;
564const internal::VariadicDynCastAllOfMatcher<Decl, NamedDecl> namedDecl;
565const internal::VariadicDynCastAllOfMatcher<Decl, LabelDecl> labelDecl;
566const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceDecl> namespaceDecl;
567const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceAliasDecl>
568 namespaceAliasDecl;
569const internal::VariadicDynCastAllOfMatcher<Decl, RecordDecl> recordDecl;
570const internal::VariadicDynCastAllOfMatcher<Decl, CXXRecordDecl> cxxRecordDecl;
571const internal::VariadicDynCastAllOfMatcher<Decl, ClassTemplateDecl>
572 classTemplateDecl;
573const internal::VariadicDynCastAllOfMatcher<Decl,
574 ClassTemplateSpecializationDecl>
575 classTemplateSpecializationDecl;
Gabor Marton42e15de2018-08-22 11:52:14 +0000576const internal::VariadicDynCastAllOfMatcher<
577 Decl, ClassTemplatePartialSpecializationDecl>
578 classTemplatePartialSpecializationDecl;
David Blaikieac7e3d62017-11-15 16:52:12 +0000579const internal::VariadicDynCastAllOfMatcher<Decl, DeclaratorDecl>
580 declaratorDecl;
581const internal::VariadicDynCastAllOfMatcher<Decl, ParmVarDecl> parmVarDecl;
582const internal::VariadicDynCastAllOfMatcher<Decl, AccessSpecDecl>
583 accessSpecDecl;
584const internal::VariadicAllOfMatcher<CXXCtorInitializer> cxxCtorInitializer;
585const internal::VariadicAllOfMatcher<TemplateArgument> templateArgument;
586const internal::VariadicAllOfMatcher<TemplateName> templateName;
587const internal::VariadicDynCastAllOfMatcher<Decl, NonTypeTemplateParmDecl>
588 nonTypeTemplateParmDecl;
589const internal::VariadicDynCastAllOfMatcher<Decl, TemplateTypeParmDecl>
590 templateTypeParmDecl;
591const internal::VariadicAllOfMatcher<QualType> qualType;
592const internal::VariadicAllOfMatcher<Type> type;
593const internal::VariadicAllOfMatcher<TypeLoc> typeLoc;
594const internal::VariadicDynCastAllOfMatcher<Stmt, UnaryExprOrTypeTraitExpr>
595 unaryExprOrTypeTraitExpr;
596const internal::VariadicDynCastAllOfMatcher<Decl, ValueDecl> valueDecl;
597const internal::VariadicDynCastAllOfMatcher<Decl, CXXConstructorDecl>
598 cxxConstructorDecl;
599const internal::VariadicDynCastAllOfMatcher<Decl, CXXDestructorDecl>
600 cxxDestructorDecl;
601const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl;
602const internal::VariadicDynCastAllOfMatcher<Decl, EnumConstantDecl>
603 enumConstantDecl;
604const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> cxxMethodDecl;
605const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl>
606 cxxConversionDecl;
607const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> varDecl;
608const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> fieldDecl;
609const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl> functionDecl;
610const internal::VariadicDynCastAllOfMatcher<Decl, FunctionTemplateDecl>
611 functionTemplateDecl;
612const internal::VariadicDynCastAllOfMatcher<Decl, FriendDecl> friendDecl;
613const internal::VariadicAllOfMatcher<Stmt> stmt;
614const internal::VariadicDynCastAllOfMatcher<Stmt, DeclStmt> declStmt;
615const internal::VariadicDynCastAllOfMatcher<Stmt, MemberExpr> memberExpr;
Shuai Wang72b56ed2018-08-12 17:34:36 +0000616const internal::VariadicDynCastAllOfMatcher<Stmt, UnresolvedMemberExpr>
617 unresolvedMemberExpr;
618const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDependentScopeMemberExpr>
619 cxxDependentScopeMemberExpr;
David Blaikieac7e3d62017-11-15 16:52:12 +0000620const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> callExpr;
621const internal::VariadicDynCastAllOfMatcher<Stmt, LambdaExpr> lambdaExpr;
622const internal::VariadicDynCastAllOfMatcher<Stmt, CXXMemberCallExpr>
623 cxxMemberCallExpr;
624const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCMessageExpr>
625 objcMessageExpr;
626const internal::VariadicDynCastAllOfMatcher<Decl, ObjCInterfaceDecl>
627 objcInterfaceDecl;
628const internal::VariadicDynCastAllOfMatcher<Decl, ObjCImplementationDecl>
629 objcImplementationDecl;
630const internal::VariadicDynCastAllOfMatcher<Decl, ObjCProtocolDecl>
631 objcProtocolDecl;
632const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryDecl>
633 objcCategoryDecl;
634const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryImplDecl>
635 objcCategoryImplDecl;
636const internal::VariadicDynCastAllOfMatcher<Decl, ObjCMethodDecl>
637 objcMethodDecl;
George Karpenkovb4c0cbd2018-05-16 22:47:03 +0000638const internal::VariadicDynCastAllOfMatcher<Decl, BlockDecl>
639 blockDecl;
David Blaikieac7e3d62017-11-15 16:52:12 +0000640const internal::VariadicDynCastAllOfMatcher<Decl, ObjCIvarDecl> objcIvarDecl;
641const internal::VariadicDynCastAllOfMatcher<Decl, ObjCPropertyDecl>
642 objcPropertyDecl;
643const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtThrowStmt>
644 objcThrowStmt;
645const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtTryStmt> objcTryStmt;
646const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtCatchStmt>
647 objcCatchStmt;
648const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtFinallyStmt>
649 objcFinallyStmt;
650const internal::VariadicDynCastAllOfMatcher<Stmt, ExprWithCleanups>
651 exprWithCleanups;
652const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr> initListExpr;
653const internal::VariadicDynCastAllOfMatcher<Stmt, CXXStdInitializerListExpr>
654 cxxStdInitializerListExpr;
655const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitValueInitExpr>
656 implicitValueInitExpr;
657const internal::VariadicDynCastAllOfMatcher<Stmt, ParenListExpr> parenListExpr;
658const internal::VariadicDynCastAllOfMatcher<Stmt, SubstNonTypeTemplateParmExpr>
659 substNonTypeTemplateParmExpr;
660const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl;
661const internal::VariadicDynCastAllOfMatcher<Decl, UsingDirectiveDecl>
662 usingDirectiveDecl;
663const internal::VariadicDynCastAllOfMatcher<Stmt, UnresolvedLookupExpr>
664 unresolvedLookupExpr;
665const internal::VariadicDynCastAllOfMatcher<Decl, UnresolvedUsingValueDecl>
666 unresolvedUsingValueDecl;
667const internal::VariadicDynCastAllOfMatcher<Decl, UnresolvedUsingTypenameDecl>
668 unresolvedUsingTypenameDecl;
669const internal::VariadicDynCastAllOfMatcher<Stmt, ParenExpr> parenExpr;
670const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstructExpr>
671 cxxConstructExpr;
672const internal::VariadicDynCastAllOfMatcher<Stmt, CXXUnresolvedConstructExpr>
673 cxxUnresolvedConstructExpr;
674const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThisExpr> cxxThisExpr;
675const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBindTemporaryExpr>
676 cxxBindTemporaryExpr;
677const internal::VariadicDynCastAllOfMatcher<Stmt, MaterializeTemporaryExpr>
678 materializeTemporaryExpr;
679const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> cxxNewExpr;
680const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDeleteExpr> cxxDeleteExpr;
681const internal::VariadicDynCastAllOfMatcher<Stmt, ArraySubscriptExpr>
682 arraySubscriptExpr;
683const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDefaultArgExpr>
684 cxxDefaultArgExpr;
685const internal::VariadicDynCastAllOfMatcher<Stmt, CXXOperatorCallExpr>
686 cxxOperatorCallExpr;
687const internal::VariadicDynCastAllOfMatcher<Stmt, Expr> expr;
688const internal::VariadicDynCastAllOfMatcher<Stmt, DeclRefExpr> declRefExpr;
George Karpenkov079275b2018-07-27 17:26:11 +0000689const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCIvarRefExpr> objcIvarRefExpr;
David Blaikieac7e3d62017-11-15 16:52:12 +0000690const internal::VariadicDynCastAllOfMatcher<Stmt, IfStmt> ifStmt;
691const internal::VariadicDynCastAllOfMatcher<Stmt, ForStmt> forStmt;
692const internal::VariadicDynCastAllOfMatcher<Stmt, CXXForRangeStmt>
693 cxxForRangeStmt;
694const internal::VariadicDynCastAllOfMatcher<Stmt, WhileStmt> whileStmt;
695const internal::VariadicDynCastAllOfMatcher<Stmt, DoStmt> doStmt;
696const internal::VariadicDynCastAllOfMatcher<Stmt, BreakStmt> breakStmt;
697const internal::VariadicDynCastAllOfMatcher<Stmt, ContinueStmt> continueStmt;
698const internal::VariadicDynCastAllOfMatcher<Stmt, ReturnStmt> returnStmt;
699const internal::VariadicDynCastAllOfMatcher<Stmt, GotoStmt> gotoStmt;
700const internal::VariadicDynCastAllOfMatcher<Stmt, LabelStmt> labelStmt;
701const internal::VariadicDynCastAllOfMatcher<Stmt, AddrLabelExpr> addrLabelExpr;
702const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchStmt> switchStmt;
703const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchCase> switchCase;
704const internal::VariadicDynCastAllOfMatcher<Stmt, CaseStmt> caseStmt;
705const internal::VariadicDynCastAllOfMatcher<Stmt, DefaultStmt> defaultStmt;
706const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundStmt> compoundStmt;
707const internal::VariadicDynCastAllOfMatcher<Stmt, CXXCatchStmt> cxxCatchStmt;
708const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTryStmt> cxxTryStmt;
709const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThrowExpr> cxxThrowExpr;
710const internal::VariadicDynCastAllOfMatcher<Stmt, NullStmt> nullStmt;
711const internal::VariadicDynCastAllOfMatcher<Stmt, AsmStmt> asmStmt;
712const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBoolLiteralExpr>
713 cxxBoolLiteral;
714const internal::VariadicDynCastAllOfMatcher<Stmt, StringLiteral> stringLiteral;
715const internal::VariadicDynCastAllOfMatcher<Stmt, CharacterLiteral>
716 characterLiteral;
717const internal::VariadicDynCastAllOfMatcher<Stmt, IntegerLiteral>
718 integerLiteral;
719const internal::VariadicDynCastAllOfMatcher<Stmt, FloatingLiteral> floatLiteral;
Gabor Martonbf7f18b2018-08-09 12:18:07 +0000720const internal::VariadicDynCastAllOfMatcher<Stmt, ImaginaryLiteral> imaginaryLiteral;
David Blaikieac7e3d62017-11-15 16:52:12 +0000721const internal::VariadicDynCastAllOfMatcher<Stmt, UserDefinedLiteral>
722 userDefinedLiteral;
723const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundLiteralExpr>
724 compoundLiteralExpr;
725const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNullPtrLiteralExpr>
726 cxxNullPtrLiteralExpr;
727const internal::VariadicDynCastAllOfMatcher<Stmt, GNUNullExpr> gnuNullExpr;
728const internal::VariadicDynCastAllOfMatcher<Stmt, AtomicExpr> atomicExpr;
729const internal::VariadicDynCastAllOfMatcher<Stmt, StmtExpr> stmtExpr;
730const internal::VariadicDynCastAllOfMatcher<Stmt, BinaryOperator>
731 binaryOperator;
732const internal::VariadicDynCastAllOfMatcher<Stmt, UnaryOperator> unaryOperator;
733const internal::VariadicDynCastAllOfMatcher<Stmt, ConditionalOperator>
734 conditionalOperator;
735const internal::VariadicDynCastAllOfMatcher<Stmt, BinaryConditionalOperator>
736 binaryConditionalOperator;
737const internal::VariadicDynCastAllOfMatcher<Stmt, OpaqueValueExpr>
738 opaqueValueExpr;
739const internal::VariadicDynCastAllOfMatcher<Decl, StaticAssertDecl>
740 staticAssertDecl;
741const internal::VariadicDynCastAllOfMatcher<Stmt, CXXReinterpretCastExpr>
742 cxxReinterpretCastExpr;
743const internal::VariadicDynCastAllOfMatcher<Stmt, CXXStaticCastExpr>
744 cxxStaticCastExpr;
745const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDynamicCastExpr>
746 cxxDynamicCastExpr;
747const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstCastExpr>
748 cxxConstCastExpr;
749const internal::VariadicDynCastAllOfMatcher<Stmt, CStyleCastExpr>
750 cStyleCastExpr;
751const internal::VariadicDynCastAllOfMatcher<Stmt, ExplicitCastExpr>
752 explicitCastExpr;
753const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitCastExpr>
754 implicitCastExpr;
755const internal::VariadicDynCastAllOfMatcher<Stmt, CastExpr> castExpr;
756const internal::VariadicDynCastAllOfMatcher<Stmt, CXXFunctionalCastExpr>
757 cxxFunctionalCastExpr;
758const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTemporaryObjectExpr>
759 cxxTemporaryObjectExpr;
760const internal::VariadicDynCastAllOfMatcher<Stmt, PredefinedExpr>
761 predefinedExpr;
762const internal::VariadicDynCastAllOfMatcher<Stmt, DesignatedInitExpr>
763 designatedInitExpr;
764const internal::VariadicOperatorMatcherFunc<
765 2, std::numeric_limits<unsigned>::max()>
766 eachOf = {internal::DynTypedMatcher::VO_EachOf};
767const internal::VariadicOperatorMatcherFunc<
768 2, std::numeric_limits<unsigned>::max()>
769 anyOf = {internal::DynTypedMatcher::VO_AnyOf};
770const internal::VariadicOperatorMatcherFunc<
771 2, std::numeric_limits<unsigned>::max()>
772 allOf = {internal::DynTypedMatcher::VO_AllOf};
773const internal::VariadicFunction<internal::Matcher<NamedDecl>, StringRef,
774 internal::hasAnyNameFunc>
775 hasAnyName = {};
George Karpenkov10f4c962018-03-29 02:47:28 +0000776const internal::VariadicFunction<internal::Matcher<ObjCMessageExpr>, StringRef,
777 internal::hasAnySelectorFunc>
778 hasAnySelector = {};
David Blaikieac7e3d62017-11-15 16:52:12 +0000779const internal::ArgumentAdaptingMatcherFunc<internal::HasMatcher> has = {};
780const internal::ArgumentAdaptingMatcherFunc<internal::HasDescendantMatcher>
781 hasDescendant = {};
782const internal::ArgumentAdaptingMatcherFunc<internal::ForEachMatcher> forEach =
783 {};
784const internal::ArgumentAdaptingMatcherFunc<internal::ForEachDescendantMatcher>
785 forEachDescendant = {};
786const internal::ArgumentAdaptingMatcherFunc<
787 internal::HasParentMatcher,
788 internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>,
789 internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>>
790 hasParent = {};
791const internal::ArgumentAdaptingMatcherFunc<
792 internal::HasAncestorMatcher,
793 internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>,
794 internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>>
795 hasAncestor = {};
796const internal::VariadicOperatorMatcherFunc<1, 1> unless = {
797 internal::DynTypedMatcher::VO_UnaryNot};
798const internal::VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier;
799const internal::VariadicAllOfMatcher<NestedNameSpecifierLoc>
800 nestedNameSpecifierLoc;
801const internal::VariadicDynCastAllOfMatcher<Stmt, CUDAKernelCallExpr>
802 cudaKernelCallExpr;
803const AstTypeMatcher<BuiltinType> builtinType;
804const AstTypeMatcher<ArrayType> arrayType;
805const AstTypeMatcher<ComplexType> complexType;
806const AstTypeMatcher<ConstantArrayType> constantArrayType;
807const AstTypeMatcher<DependentSizedArrayType> dependentSizedArrayType;
808const AstTypeMatcher<IncompleteArrayType> incompleteArrayType;
809const AstTypeMatcher<VariableArrayType> variableArrayType;
810const AstTypeMatcher<AtomicType> atomicType;
811const AstTypeMatcher<AutoType> autoType;
Jonas Tothfa1ea692018-07-23 15:59:27 +0000812const AstTypeMatcher<DecltypeType> decltypeType;
David Blaikieac7e3d62017-11-15 16:52:12 +0000813const AstTypeMatcher<FunctionType> functionType;
814const AstTypeMatcher<FunctionProtoType> functionProtoType;
815const AstTypeMatcher<ParenType> parenType;
816const AstTypeMatcher<BlockPointerType> blockPointerType;
817const AstTypeMatcher<MemberPointerType> memberPointerType;
818const AstTypeMatcher<PointerType> pointerType;
819const AstTypeMatcher<ObjCObjectPointerType> objcObjectPointerType;
820const AstTypeMatcher<ReferenceType> referenceType;
821const AstTypeMatcher<LValueReferenceType> lValueReferenceType;
822const AstTypeMatcher<RValueReferenceType> rValueReferenceType;
823const AstTypeMatcher<TypedefType> typedefType;
824const AstTypeMatcher<EnumType> enumType;
825const AstTypeMatcher<TemplateSpecializationType> templateSpecializationType;
826const AstTypeMatcher<UnaryTransformType> unaryTransformType;
827const AstTypeMatcher<RecordType> recordType;
828const AstTypeMatcher<TagType> tagType;
829const AstTypeMatcher<ElaboratedType> elaboratedType;
830const AstTypeMatcher<SubstTemplateTypeParmType> substTemplateTypeParmType;
831const AstTypeMatcher<TemplateTypeParmType> templateTypeParmType;
832const AstTypeMatcher<InjectedClassNameType> injectedClassNameType;
833const AstTypeMatcher<DecayedType> decayedType;
David Blaikie1de35432017-11-21 01:09:18 +0000834AST_TYPELOC_TRAVERSE_MATCHER_DEF(hasElementType,
835 AST_POLYMORPHIC_SUPPORTED_TYPES(ArrayType,
836 ComplexType));
837AST_TYPELOC_TRAVERSE_MATCHER_DEF(hasValueType,
838 AST_POLYMORPHIC_SUPPORTED_TYPES(AtomicType));
839AST_TYPELOC_TRAVERSE_MATCHER_DEF(
840 pointee,
841 AST_POLYMORPHIC_SUPPORTED_TYPES(BlockPointerType, MemberPointerType,
842 PointerType, ReferenceType));
David Blaikieac7e3d62017-11-15 16:52:12 +0000843
Manuel Klimek04616e42012-07-06 05:48:52 +0000844} // end namespace ast_matchers
845} // end namespace clang