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