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