Bug Summary

File:clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
Warning:line 234, column 11
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ContainerSizeEmptyCheck.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-15~++20220212111237+869c066ca8a4/build-llvm/tools/clang/stage2-bins -resource-dir /usr/lib/llvm-15/lib/clang/15.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I tools/clang/tools/extra/clang-tidy/readability -I /build/llvm-toolchain-snapshot-15~++20220212111237+869c066ca8a4/clang-tools-extra/clang-tidy/readability -I tools/clang/tools/extra/clang-tidy -I /build/llvm-toolchain-snapshot-15~++20220212111237+869c066ca8a4/clang/include -I tools/clang/include -I include -I /build/llvm-toolchain-snapshot-15~++20220212111237+869c066ca8a4/llvm/include -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-15/lib/clang/15.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/build/llvm-toolchain-snapshot-15~++20220212111237+869c066ca8a4/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fmacro-prefix-map=/build/llvm-toolchain-snapshot-15~++20220212111237+869c066ca8a4/= -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-15~++20220212111237+869c066ca8a4/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-15~++20220212111237+869c066ca8a4/= -O3 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-15~++20220212111237+869c066ca8a4/build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/llvm-toolchain-snapshot-15~++20220212111237+869c066ca8a4/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/llvm-toolchain-snapshot-15~++20220212111237+869c066ca8a4/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-02-12-124252-137181-1 -x c++ /build/llvm-toolchain-snapshot-15~++20220212111237+869c066ca8a4/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp

/build/llvm-toolchain-snapshot-15~++20220212111237+869c066ca8a4/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp

1//===--- ContainerSizeEmptyCheck.cpp - clang-tidy -------------------------===//
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#include "ContainerSizeEmptyCheck.h"
9#include "../utils/ASTUtils.h"
10#include "../utils/Matchers.h"
11#include "clang/AST/ASTContext.h"
12#include "clang/ASTMatchers/ASTMatchers.h"
13#include "clang/Lex/Lexer.h"
14#include "llvm/ADT/StringRef.h"
15
16using namespace clang::ast_matchers;
17
18namespace clang {
19namespace ast_matchers {
20AST_POLYMORPHIC_MATCHER_P2(hasAnyArgumentWithParam,namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasAnyArgumentWithParam0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasAnyArgumentWithParam0Matcher
(internal::Matcher<Expr> const &AArgMatcher, internal
::Matcher<ParmVarDecl> const &AParamMatcher) : ArgMatcher
(AArgMatcher), ParamMatcher(AParamMatcher) {} bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> ArgMatcher; internal::Matcher<ParmVarDecl> ParamMatcher
; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasAnyArgumentWithParam0Matcher, void(
::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<ParmVarDecl
> > hasAnyArgumentWithParam(internal::Matcher<Expr>
const &ArgMatcher, internal::Matcher<ParmVarDecl> const
&ParamMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_hasAnyArgumentWithParam0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr>), internal::Matcher<Expr>, internal
::Matcher<ParmVarDecl> >(ArgMatcher, ParamMatcher); }
typedef ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_hasAnyArgumentWithParam0Matcher, void(::clang
::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<ParmVarDecl
> > (&hasAnyArgumentWithParam_Type0)( internal::Matcher
<Expr> const &ArgMatcher, internal::Matcher<ParmVarDecl
> const &ParamMatcher); template <typename NodeType
, typename ParamT1, typename ParamT2> bool internal::matcher_hasAnyArgumentWithParam0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
21 AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasAnyArgumentWithParam0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasAnyArgumentWithParam0Matcher
(internal::Matcher<Expr> const &AArgMatcher, internal
::Matcher<ParmVarDecl> const &AParamMatcher) : ArgMatcher
(AArgMatcher), ParamMatcher(AParamMatcher) {} bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> ArgMatcher; internal::Matcher<ParmVarDecl> ParamMatcher
; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasAnyArgumentWithParam0Matcher, void(
::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<ParmVarDecl
> > hasAnyArgumentWithParam(internal::Matcher<Expr>
const &ArgMatcher, internal::Matcher<ParmVarDecl> const
&ParamMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_hasAnyArgumentWithParam0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr>), internal::Matcher<Expr>, internal
::Matcher<ParmVarDecl> >(ArgMatcher, ParamMatcher); }
typedef ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_hasAnyArgumentWithParam0Matcher, void(::clang
::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<ParmVarDecl
> > (&hasAnyArgumentWithParam_Type0)( internal::Matcher
<Expr> const &ArgMatcher, internal::Matcher<ParmVarDecl
> const &ParamMatcher); template <typename NodeType
, typename ParamT1, typename ParamT2> bool internal::matcher_hasAnyArgumentWithParam0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
22 CXXConstructExpr),namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasAnyArgumentWithParam0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasAnyArgumentWithParam0Matcher
(internal::Matcher<Expr> const &AArgMatcher, internal
::Matcher<ParmVarDecl> const &AParamMatcher) : ArgMatcher
(AArgMatcher), ParamMatcher(AParamMatcher) {} bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> ArgMatcher; internal::Matcher<ParmVarDecl> ParamMatcher
; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasAnyArgumentWithParam0Matcher, void(
::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<ParmVarDecl
> > hasAnyArgumentWithParam(internal::Matcher<Expr>
const &ArgMatcher, internal::Matcher<ParmVarDecl> const
&ParamMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_hasAnyArgumentWithParam0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr>), internal::Matcher<Expr>, internal
::Matcher<ParmVarDecl> >(ArgMatcher, ParamMatcher); }
typedef ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_hasAnyArgumentWithParam0Matcher, void(::clang
::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<ParmVarDecl
> > (&hasAnyArgumentWithParam_Type0)( internal::Matcher
<Expr> const &ArgMatcher, internal::Matcher<ParmVarDecl
> const &ParamMatcher); template <typename NodeType
, typename ParamT1, typename ParamT2> bool internal::matcher_hasAnyArgumentWithParam0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
23 internal::Matcher<Expr>, ArgMatcher,namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasAnyArgumentWithParam0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasAnyArgumentWithParam0Matcher
(internal::Matcher<Expr> const &AArgMatcher, internal
::Matcher<ParmVarDecl> const &AParamMatcher) : ArgMatcher
(AArgMatcher), ParamMatcher(AParamMatcher) {} bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> ArgMatcher; internal::Matcher<ParmVarDecl> ParamMatcher
; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasAnyArgumentWithParam0Matcher, void(
::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<ParmVarDecl
> > hasAnyArgumentWithParam(internal::Matcher<Expr>
const &ArgMatcher, internal::Matcher<ParmVarDecl> const
&ParamMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_hasAnyArgumentWithParam0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr>), internal::Matcher<Expr>, internal
::Matcher<ParmVarDecl> >(ArgMatcher, ParamMatcher); }
typedef ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_hasAnyArgumentWithParam0Matcher, void(::clang
::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<ParmVarDecl
> > (&hasAnyArgumentWithParam_Type0)( internal::Matcher
<Expr> const &ArgMatcher, internal::Matcher<ParmVarDecl
> const &ParamMatcher); template <typename NodeType
, typename ParamT1, typename ParamT2> bool internal::matcher_hasAnyArgumentWithParam0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
24 internal::Matcher<ParmVarDecl>, ParamMatcher)namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasAnyArgumentWithParam0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasAnyArgumentWithParam0Matcher
(internal::Matcher<Expr> const &AArgMatcher, internal
::Matcher<ParmVarDecl> const &AParamMatcher) : ArgMatcher
(AArgMatcher), ParamMatcher(AParamMatcher) {} bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> ArgMatcher; internal::Matcher<ParmVarDecl> ParamMatcher
; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasAnyArgumentWithParam0Matcher, void(
::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<ParmVarDecl
> > hasAnyArgumentWithParam(internal::Matcher<Expr>
const &ArgMatcher, internal::Matcher<ParmVarDecl> const
&ParamMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_hasAnyArgumentWithParam0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr>), internal::Matcher<Expr>, internal
::Matcher<ParmVarDecl> >(ArgMatcher, ParamMatcher); }
typedef ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_hasAnyArgumentWithParam0Matcher, void(::clang
::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<ParmVarDecl
> > (&hasAnyArgumentWithParam_Type0)( internal::Matcher
<Expr> const &ArgMatcher, internal::Matcher<ParmVarDecl
> const &ParamMatcher); template <typename NodeType
, typename ParamT1, typename ParamT2> bool internal::matcher_hasAnyArgumentWithParam0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
25 BoundNodesTreeBuilder Result;
26 // The first argument of an overloaded member operator is the implicit object
27 // argument of the method which should not be matched against a parameter, so
28 // we skip over it here.
29 BoundNodesTreeBuilder Matches;
30 unsigned ArgIndex = cxxOperatorCallExpr(callee(cxxMethodDecl()))
31 .matches(Node, Finder, &Matches)
32 ? 1
33 : 0;
34 int ParamIndex = 0;
35 for (; ArgIndex < Node.getNumArgs(); ++ArgIndex) {
36 BoundNodesTreeBuilder ArgMatches(*Builder);
37 if (ArgMatcher.matches(*(Node.getArg(ArgIndex)->IgnoreParenCasts()), Finder,
38 &ArgMatches)) {
39 BoundNodesTreeBuilder ParamMatches(ArgMatches);
40 if (expr(anyOf(cxxConstructExpr(hasDeclaration(cxxConstructorDecl(
41 hasParameter(ParamIndex, ParamMatcher)))),
42 callExpr(callee(functionDecl(
43 hasParameter(ParamIndex, ParamMatcher))))))
44 .matches(Node, Finder, &ParamMatches)) {
45 Result.addMatch(ParamMatches);
46 *Builder = std::move(Result);
47 return true;
48 }
49 }
50 ++ParamIndex;
51 }
52 return false;
53}
54
55AST_MATCHER(Expr, usedInBooleanContext)namespace internal { class matcher_usedInBooleanContextMatcher
: public ::clang::ast_matchers::internal::MatcherInterface<
Expr> { public: explicit matcher_usedInBooleanContextMatcher
() = default; bool matches(const Expr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<Expr> usedInBooleanContext
() { return ::clang::ast_matchers::internal::makeMatcher( new
internal::matcher_usedInBooleanContextMatcher()); } inline bool
internal::matcher_usedInBooleanContextMatcher::matches( const
Expr &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
56 const char *ExprName = "__booleanContextExpr";
57 auto Result =
58 expr(expr().bind(ExprName),
59 anyOf(hasParent(
60 mapAnyOf(varDecl, fieldDecl).with(hasType(booleanType()))),
61 hasParent(cxxConstructorDecl(
62 hasAnyConstructorInitializer(cxxCtorInitializer(
63 withInitializer(expr(equalsBoundNode(ExprName))),
64 forField(hasType(booleanType())))))),
65 hasParent(stmt(anyOf(
66 explicitCastExpr(hasDestinationType(booleanType())),
67 mapAnyOf(ifStmt, doStmt, whileStmt, forStmt,
68 conditionalOperator)
69 .with(hasCondition(expr(equalsBoundNode(ExprName)))),
70 parenListExpr(hasParent(varDecl(hasType(booleanType())))),
71 parenExpr(hasParent(
72 explicitCastExpr(hasDestinationType(booleanType())))),
73 returnStmt(forFunction(returns(booleanType()))),
74 cxxUnresolvedConstructExpr(hasType(booleanType())),
75 invocation(hasAnyArgumentWithParam(
76 expr(equalsBoundNode(ExprName)),
77 parmVarDecl(hasType(booleanType())))),
78 binaryOperator(hasAnyOperatorName("&&", "||")),
79 unaryOperator(hasOperatorName("!")).bind("NegOnSize"))))))
80 .matches(Node, Finder, Builder);
81 Builder->removeBindings([ExprName](const BoundNodesMap &Nodes) {
82 return Nodes.getNode(ExprName).getNodeKind().isNone();
83 });
84 return Result;
85}
86AST_MATCHER(CXXConstructExpr, isDefaultConstruction)namespace internal { class matcher_isDefaultConstructionMatcher
: public ::clang::ast_matchers::internal::MatcherInterface<
CXXConstructExpr> { public: explicit matcher_isDefaultConstructionMatcher
() = default; bool matches(const CXXConstructExpr &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
override; }; } inline ::clang::ast_matchers::internal::Matcher
<CXXConstructExpr> isDefaultConstruction() { return ::clang
::ast_matchers::internal::makeMatcher( new internal::matcher_isDefaultConstructionMatcher
()); } inline bool internal::matcher_isDefaultConstructionMatcher
::matches( const CXXConstructExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
87 return Node.getConstructor()->isDefaultConstructor();
88}
89} // namespace ast_matchers
90namespace tidy {
91namespace readability {
92
93using utils::isBinaryOrTernary;
94
95ContainerSizeEmptyCheck::ContainerSizeEmptyCheck(StringRef Name,
96 ClangTidyContext *Context)
97 : ClangTidyCheck(Name, Context) {}
98
99void ContainerSizeEmptyCheck::registerMatchers(MatchFinder *Finder) {
100 const auto ValidContainerRecord = cxxRecordDecl(isSameOrDerivedFrom(
101 namedDecl(
102 has(cxxMethodDecl(isConst(), parameterCountIs(0), isPublic(),
103 hasName("size"),
104 returns(qualType(isInteger(), unless(booleanType()),
105 unless(elaboratedType()))))
106 .bind("size")),
107 has(cxxMethodDecl(isConst(), parameterCountIs(0), isPublic(),
108 hasName("empty"), returns(booleanType()))
109 .bind("empty")))
110 .bind("container")));
111
112 const auto ValidContainerNonTemplateType =
113 qualType(hasUnqualifiedDesugaredType(
114 recordType(hasDeclaration(ValidContainerRecord))));
115 const auto ValidContainerTemplateType =
116 qualType(hasUnqualifiedDesugaredType(templateSpecializationType(
117 hasDeclaration(classTemplateDecl(has(ValidContainerRecord))))));
118
119 const auto ValidContainer = qualType(
120 anyOf(ValidContainerNonTemplateType, ValidContainerTemplateType));
121
122 const auto WrongUse =
123 anyOf(hasParent(binaryOperator(
124 isComparisonOperator(),
125 hasEitherOperand(anyOf(integerLiteral(equals(1)),
126 integerLiteral(equals(0)))))
127 .bind("SizeBinaryOp")),
128 usedInBooleanContext());
129
130 Finder->addMatcher(
131 cxxMemberCallExpr(on(expr(anyOf(hasType(ValidContainer),
132 hasType(pointsTo(ValidContainer)),
133 hasType(references(ValidContainer))))
134 .bind("MemberCallObject")),
135 callee(cxxMethodDecl(hasName("size"))), WrongUse,
136 unless(hasAncestor(cxxMethodDecl(
137 ofClass(equalsBoundNode("container"))))))
138 .bind("SizeCallExpr"),
139 this);
140
141 Finder->addMatcher(
142 callExpr(has(cxxDependentScopeMemberExpr(
143 hasObjectExpression(
144 expr(anyOf(hasType(ValidContainer),
145 hasType(pointsTo(ValidContainer)),
146 hasType(references(ValidContainer))))
147 .bind("MemberCallObject")),
148 hasMemberName("size"))),
149 WrongUse,
150 unless(hasAncestor(
151 cxxMethodDecl(ofClass(equalsBoundNode("container"))))))
152 .bind("SizeCallExpr"),
153 this);
154
155 // Comparison to empty string or empty constructor.
156 const auto WrongComparend = anyOf(
157 stringLiteral(hasSize(0)), cxxConstructExpr(isDefaultConstruction()),
158 cxxUnresolvedConstructExpr(argumentCountIs(0)));
159 // Match the object being compared.
160 const auto STLArg =
161 anyOf(unaryOperator(
162 hasOperatorName("*"),
163 hasUnaryOperand(
164 expr(hasType(pointsTo(ValidContainer))).bind("Pointee"))),
165 expr(hasType(ValidContainer)).bind("STLObject"));
166 Finder->addMatcher(
167 binaryOperation(hasAnyOperatorName("==", "!="),
168 hasOperands(WrongComparend,
169 STLArg),
170 unless(hasAncestor(cxxMethodDecl(
171 ofClass(equalsBoundNode("container"))))))
172 .bind("BinCmp"),
173 this);
174}
175
176void ContainerSizeEmptyCheck::check(const MatchFinder::MatchResult &Result) {
177 const auto *MemberCall = Result.Nodes.getNodeAs<Expr>("SizeCallExpr");
178 const auto *MemberCallObject =
179 Result.Nodes.getNodeAs<Expr>("MemberCallObject");
180 const auto *BinCmp = Result.Nodes.getNodeAs<CXXOperatorCallExpr>("BinCmp");
1
Calling 'BoundNodes::getNodeAs'
19
Returning from 'BoundNodes::getNodeAs'
181 const auto *BinCmpTempl = Result.Nodes.getNodeAs<BinaryOperator>("BinCmp");
20
Calling 'BoundNodes::getNodeAs'
38
Returning from 'BoundNodes::getNodeAs'
182 const auto *BinCmpRewritten =
183 Result.Nodes.getNodeAs<CXXRewrittenBinaryOperator>("BinCmp");
39
Calling 'BoundNodes::getNodeAs'
57
Returning from 'BoundNodes::getNodeAs'
184 const auto *BinaryOp = Result.Nodes.getNodeAs<BinaryOperator>("SizeBinaryOp");
58
Calling 'BoundNodes::getNodeAs'
76
Returning from 'BoundNodes::getNodeAs'
185 const auto *Pointee = Result.Nodes.getNodeAs<Expr>("Pointee");
186 const auto *E =
187 MemberCallObject
76.1
'MemberCallObject' is null
76.1
'MemberCallObject' is null
76.1
'MemberCallObject' is null
76.1
'MemberCallObject' is null
76.1
'MemberCallObject' is null
77
'?' condition is false
188 ? MemberCallObject 189 : (Pointee
77.1
'Pointee' is non-null
77.1
'Pointee' is non-null
77.1
'Pointee' is non-null
77.1
'Pointee' is non-null
77.1
'Pointee' is non-null
? Pointee : Result.Nodes.getNodeAs<Expr>("STLObject"));
78
'?' condition is true
190 FixItHint Hint; 191 std::string ReplacementText = std::string( 192 Lexer::getSourceText(CharSourceRange::getTokenRange(E->getSourceRange()), 193 *Result.SourceManager, getLangOpts())); 194 if (isBinaryOrTernary(E) || isa<UnaryOperator>(E)) {
79
Assuming the condition is false
80
Assuming 'E' is not a 'UnaryOperator'
81
Taking false branch
195 ReplacementText = "(" + ReplacementText + ")"; 196 } 197 if (E->getType()->isPointerType())
82
Taking false branch
198 ReplacementText += "->empty()"; 199 else 200 ReplacementText += ".empty()"; 201 202 if (BinCmp
82.1
'BinCmp' is null
82.1
'BinCmp' is null
82.1
'BinCmp' is null
82.1
'BinCmp' is null
82.1
'BinCmp' is null
) {
83
Taking false branch
203 if (BinCmp->getOperator() == OO_ExclaimEqual) { 204 ReplacementText = "!" + ReplacementText; 205 } 206 Hint = 207 FixItHint::CreateReplacement(BinCmp->getSourceRange(), ReplacementText); 208 } else if (BinCmpTempl
83.1
'BinCmpTempl' is null
83.1
'BinCmpTempl' is null
83.1
'BinCmpTempl' is null
83.1
'BinCmpTempl' is null
83.1
'BinCmpTempl' is null
) {
84
Taking false branch
209 if (BinCmpTempl->getOpcode() == BinaryOperatorKind::BO_NE) { 210 ReplacementText = "!" + ReplacementText; 211 } 212 Hint = FixItHint::CreateReplacement(BinCmpTempl->getSourceRange(), 213 ReplacementText); 214 } else if (BinCmpRewritten
84.1
'BinCmpRewritten' is null
84.1
'BinCmpRewritten' is null
84.1
'BinCmpRewritten' is null
84.1
'BinCmpRewritten' is null
84.1
'BinCmpRewritten' is null
) {
85
Taking false branch
215 if (BinCmpRewritten->getOpcode() == BinaryOperatorKind::BO_NE) { 216 ReplacementText = "!" + ReplacementText; 217 } 218 Hint = FixItHint::CreateReplacement(BinCmpRewritten->getSourceRange(), 219 ReplacementText); 220 } else if (BinaryOp
85.1
'BinaryOp' is non-null
85.1
'BinaryOp' is non-null
85.1
'BinaryOp' is non-null
85.1
'BinaryOp' is non-null
85.1
'BinaryOp' is non-null
) { // Determine the correct transformation.
86
Taking true branch
221 bool Negation = false; 222 const bool ContainerIsLHS = 223 !llvm::isa<IntegerLiteral>(BinaryOp->getLHS()->IgnoreImpCasts());
87
Assuming the object is a 'IntegerLiteral'
224 const auto OpCode = BinaryOp->getOpcode(); 225 uint64_t Value = 0; 226 if (ContainerIsLHS
87.1
'ContainerIsLHS' is false
87.1
'ContainerIsLHS' is false
87.1
'ContainerIsLHS' is false
87.1
'ContainerIsLHS' is false
87.1
'ContainerIsLHS' is false
) {
88
Taking false branch
227 if (const auto *Literal = llvm::dyn_cast<IntegerLiteral>( 228 BinaryOp->getRHS()->IgnoreImpCasts())) 229 Value = Literal->getValue().getLimitedValue(); 230 else 231 return; 232 } else { 233 Value = 234 llvm::dyn_cast<IntegerLiteral>(BinaryOp->getLHS()->IgnoreImpCasts())
89
Assuming the object is not a 'IntegerLiteral'
90
Called C++ object pointer is null
235 ->getValue() 236 .getLimitedValue(); 237 } 238 239 // Constant that is not handled. 240 if (Value > 1) 241 return; 242 243 if (Value == 1 && (OpCode == BinaryOperatorKind::BO_EQ || 244 OpCode == BinaryOperatorKind::BO_NE)) 245 return; 246 247 // Always true, no warnings for that. 248 if ((OpCode == BinaryOperatorKind::BO_GE && Value == 0 && ContainerIsLHS) || 249 (OpCode == BinaryOperatorKind::BO_LE && Value == 0 && !ContainerIsLHS)) 250 return; 251 252 // Do not warn for size > 1, 1 < size, size <= 1, 1 >= size. 253 if (Value == 1) { 254 if ((OpCode == BinaryOperatorKind::BO_GT && ContainerIsLHS) || 255 (OpCode == BinaryOperatorKind::BO_LT && !ContainerIsLHS)) 256 return; 257 if ((OpCode == BinaryOperatorKind::BO_LE && ContainerIsLHS) || 258 (OpCode == BinaryOperatorKind::BO_GE && !ContainerIsLHS)) 259 return; 260 } 261 262 if (OpCode == BinaryOperatorKind::BO_NE && Value == 0) 263 Negation = true; 264 if ((OpCode == BinaryOperatorKind::BO_GT || 265 OpCode == BinaryOperatorKind::BO_GE) && 266 ContainerIsLHS) 267 Negation = true; 268 if ((OpCode == BinaryOperatorKind::BO_LT || 269 OpCode == BinaryOperatorKind::BO_LE) && 270 !ContainerIsLHS) 271 Negation = true; 272 273 if (Negation) 274 ReplacementText = "!" + ReplacementText; 275 Hint = FixItHint::CreateReplacement(BinaryOp->getSourceRange(), 276 ReplacementText); 277 278 } else { 279 // If there is a conversion above the size call to bool, it is safe to just 280 // replace size with empty. 281 if (const auto *UnaryOp = 282 Result.Nodes.getNodeAs<UnaryOperator>("NegOnSize")) 283 Hint = FixItHint::CreateReplacement(UnaryOp->getSourceRange(), 284 ReplacementText); 285 else 286 Hint = FixItHint::CreateReplacement(MemberCall->getSourceRange(), 287 "!" + ReplacementText); 288 } 289 290 auto WarnLoc = MemberCall ? MemberCall->getBeginLoc() : SourceLocation{}; 291 292 if (WarnLoc.isValid()) { 293 diag(WarnLoc, "the 'empty' method should be used to check " 294 "for emptiness instead of 'size'") 295 << Hint; 296 } else { 297 WarnLoc = BinCmpTempl 298 ? BinCmpTempl->getBeginLoc() 299 : (BinCmp ? BinCmp->getBeginLoc() 300 : (BinCmpRewritten ? BinCmpRewritten->getBeginLoc() 301 : SourceLocation{})); 302 diag(WarnLoc, "the 'empty' method should be used to check " 303 "for emptiness instead of comparing to an empty object") 304 << Hint; 305 } 306 307 const auto *Container = Result.Nodes.getNodeAs<NamedDecl>("container"); 308 if (const auto *CTS = dyn_cast<ClassTemplateSpecializationDecl>(Container)) { 309 // The definition of the empty() method is the same for all implicit 310 // instantiations. In order to avoid duplicate or inconsistent warnings 311 // (depending on how deduplication is done), we use the same class name 312 // for all implicit instantiations of a template. 313 if (CTS->getSpecializationKind() == TSK_ImplicitInstantiation) 314 Container = CTS->getSpecializedTemplate(); 315 } 316 const auto *Empty = Result.Nodes.getNodeAs<FunctionDecl>("empty"); 317 318 diag(Empty->getLocation(), "method %0::empty() defined here", 319 DiagnosticIDs::Note) 320 << Container; 321} 322 323} // namespace readability 324} // namespace tidy 325} // namespace clang

/build/llvm-toolchain-snapshot-15~++20220212111237+869c066ca8a4/clang/include/clang/ASTMatchers/ASTMatchers.h

1//===- ASTMatchers.h - Structural query framework ---------------*- C++ -*-===//
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// This file implements matchers to be used together with the MatchFinder to
10// match AST nodes.
11//
12// Matchers are created by generator functions, which can be combined in
13// a functional in-language DSL to express queries over the C++ AST.
14//
15// For example, to match a class with a certain name, one would call:
16// cxxRecordDecl(hasName("MyClass"))
17// which returns a matcher that can be used to find all AST nodes that declare
18// a class named 'MyClass'.
19//
20// For more complicated match expressions we're often interested in accessing
21// multiple parts of the matched AST nodes once a match is found. In that case,
22// call `.bind("name")` on match expressions that match the nodes you want to
23// access.
24//
25// For example, when we're interested in child classes of a certain class, we
26// would write:
27// cxxRecordDecl(hasName("MyClass"), has(recordDecl().bind("child")))
28// When the match is found via the MatchFinder, a user provided callback will
29// be called with a BoundNodes instance that contains a mapping from the
30// strings that we provided for the `.bind()` calls to the nodes that were
31// matched.
32// In the given example, each time our matcher finds a match we get a callback
33// where "child" is bound to the RecordDecl node of the matching child
34// class declaration.
35//
36// See ASTMatchersInternal.h for a more in-depth explanation of the
37// implementation details of the matcher framework.
38//
39// See ASTMatchFinder.h for how to use the generated matchers to run over
40// an AST.
41//
42//===----------------------------------------------------------------------===//
43
44#ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERS_H
45#define LLVM_CLANG_ASTMATCHERS_ASTMATCHERS_H
46
47#include "clang/AST/ASTContext.h"
48#include "clang/AST/ASTTypeTraits.h"
49#include "clang/AST/Attr.h"
50#include "clang/AST/CXXInheritance.h"
51#include "clang/AST/Decl.h"
52#include "clang/AST/DeclCXX.h"
53#include "clang/AST/DeclFriend.h"
54#include "clang/AST/DeclObjC.h"
55#include "clang/AST/DeclTemplate.h"
56#include "clang/AST/Expr.h"
57#include "clang/AST/ExprCXX.h"
58#include "clang/AST/ExprObjC.h"
59#include "clang/AST/LambdaCapture.h"
60#include "clang/AST/NestedNameSpecifier.h"
61#include "clang/AST/OpenMPClause.h"
62#include "clang/AST/OperationKinds.h"
63#include "clang/AST/ParentMapContext.h"
64#include "clang/AST/Stmt.h"
65#include "clang/AST/StmtCXX.h"
66#include "clang/AST/StmtObjC.h"
67#include "clang/AST/StmtOpenMP.h"
68#include "clang/AST/TemplateBase.h"
69#include "clang/AST/TemplateName.h"
70#include "clang/AST/Type.h"
71#include "clang/AST/TypeLoc.h"
72#include "clang/ASTMatchers/ASTMatchersInternal.h"
73#include "clang/ASTMatchers/ASTMatchersMacros.h"
74#include "clang/Basic/AttrKinds.h"
75#include "clang/Basic/ExceptionSpecificationType.h"
76#include "clang/Basic/FileManager.h"
77#include "clang/Basic/IdentifierTable.h"
78#include "clang/Basic/LLVM.h"
79#include "clang/Basic/SourceManager.h"
80#include "clang/Basic/Specifiers.h"
81#include "clang/Basic/TypeTraits.h"
82#include "llvm/ADT/ArrayRef.h"
83#include "llvm/ADT/SmallVector.h"
84#include "llvm/ADT/StringRef.h"
85#include "llvm/Support/Casting.h"
86#include "llvm/Support/Compiler.h"
87#include "llvm/Support/ErrorHandling.h"
88#include "llvm/Support/Regex.h"
89#include <cassert>
90#include <cstddef>
91#include <iterator>
92#include <limits>
93#include <string>
94#include <utility>
95#include <vector>
96
97namespace clang {
98namespace ast_matchers {
99
100/// Maps string IDs to AST nodes matched by parts of a matcher.
101///
102/// The bound nodes are generated by calling \c bind("id") on the node matchers
103/// of the nodes we want to access later.
104///
105/// The instances of BoundNodes are created by \c MatchFinder when the user's
106/// callbacks are executed every time a match is found.
107class BoundNodes {
108public:
109 /// Returns the AST node bound to \c ID.
110 ///
111 /// Returns NULL if there was no node bound to \c ID or if there is a node but
112 /// it cannot be converted to the specified type.
113 template <typename T>
114 const T *getNodeAs(StringRef ID) const {
115 return MyBoundNodes.getNodeAs<T>(ID);
2
Calling 'BoundNodesMap::getNodeAs'
17
Returning from 'BoundNodesMap::getNodeAs'
18
Returning null pointer, which participates in a condition later
21
Calling 'BoundNodesMap::getNodeAs'
36
Returning from 'BoundNodesMap::getNodeAs'
37
Returning null pointer, which participates in a condition later
40
Calling 'BoundNodesMap::getNodeAs'
55
Returning from 'BoundNodesMap::getNodeAs'
56
Returning null pointer, which participates in a condition later
59
Calling 'BoundNodesMap::getNodeAs'
74
Returning from 'BoundNodesMap::getNodeAs'
75
Returning pointer, which participates in a condition later
116 }
117
118 /// Type of mapping from binding identifiers to bound nodes. This type
119 /// is an associative container with a key type of \c std::string and a value
120 /// type of \c clang::DynTypedNode
121 using IDToNodeMap = internal::BoundNodesMap::IDToNodeMap;
122
123 /// Retrieve mapping from binding identifiers to bound nodes.
124 const IDToNodeMap &getMap() const {
125 return MyBoundNodes.getMap();
126 }
127
128private:
129 friend class internal::BoundNodesTreeBuilder;
130
131 /// Create BoundNodes from a pre-filled map of bindings.
132 BoundNodes(internal::BoundNodesMap &MyBoundNodes)
133 : MyBoundNodes(MyBoundNodes) {}
134
135 internal::BoundNodesMap MyBoundNodes;
136};
137
138/// Types of matchers for the top-level classes in the AST class
139/// hierarchy.
140/// @{
141using DeclarationMatcher = internal::Matcher<Decl>;
142using StatementMatcher = internal::Matcher<Stmt>;
143using TypeMatcher = internal::Matcher<QualType>;
144using TypeLocMatcher = internal::Matcher<TypeLoc>;
145using NestedNameSpecifierMatcher = internal::Matcher<NestedNameSpecifier>;
146using NestedNameSpecifierLocMatcher = internal::Matcher<NestedNameSpecifierLoc>;
147using CXXBaseSpecifierMatcher = internal::Matcher<CXXBaseSpecifier>;
148using CXXCtorInitializerMatcher = internal::Matcher<CXXCtorInitializer>;
149using TemplateArgumentMatcher = internal::Matcher<TemplateArgument>;
150using TemplateArgumentLocMatcher = internal::Matcher<TemplateArgumentLoc>;
151using LambdaCaptureMatcher = internal::Matcher<LambdaCapture>;
152using AttrMatcher = internal::Matcher<Attr>;
153/// @}
154
155/// Matches any node.
156///
157/// Useful when another matcher requires a child matcher, but there's no
158/// additional constraint. This will often be used with an explicit conversion
159/// to an \c internal::Matcher<> type such as \c TypeMatcher.
160///
161/// Example: \c DeclarationMatcher(anything()) matches all declarations, e.g.,
162/// \code
163/// "int* p" and "void f()" in
164/// int* p;
165/// void f();
166/// \endcode
167///
168/// Usable as: Any Matcher
169inline internal::TrueMatcher anything() { return internal::TrueMatcher(); }
170
171/// Matches the top declaration context.
172///
173/// Given
174/// \code
175/// int X;
176/// namespace NS {
177/// int Y;
178/// } // namespace NS
179/// \endcode
180/// decl(hasDeclContext(translationUnitDecl()))
181/// matches "int X", but not "int Y".
182extern const internal::VariadicDynCastAllOfMatcher<Decl, TranslationUnitDecl>
183 translationUnitDecl;
184
185/// Matches typedef declarations.
186///
187/// Given
188/// \code
189/// typedef int X;
190/// using Y = int;
191/// \endcode
192/// typedefDecl()
193/// matches "typedef int X", but not "using Y = int"
194extern const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl>
195 typedefDecl;
196
197/// Matches typedef name declarations.
198///
199/// Given
200/// \code
201/// typedef int X;
202/// using Y = int;
203/// \endcode
204/// typedefNameDecl()
205/// matches "typedef int X" and "using Y = int"
206extern const internal::VariadicDynCastAllOfMatcher<Decl, TypedefNameDecl>
207 typedefNameDecl;
208
209/// Matches type alias declarations.
210///
211/// Given
212/// \code
213/// typedef int X;
214/// using Y = int;
215/// \endcode
216/// typeAliasDecl()
217/// matches "using Y = int", but not "typedef int X"
218extern const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasDecl>
219 typeAliasDecl;
220
221/// Matches type alias template declarations.
222///
223/// typeAliasTemplateDecl() matches
224/// \code
225/// template <typename T>
226/// using Y = X<T>;
227/// \endcode
228extern const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasTemplateDecl>
229 typeAliasTemplateDecl;
230
231/// Matches AST nodes that were expanded within the main-file.
232///
233/// Example matches X but not Y
234/// (matcher = cxxRecordDecl(isExpansionInMainFile())
235/// \code
236/// #include <Y.h>
237/// class X {};
238/// \endcode
239/// Y.h:
240/// \code
241/// class Y {};
242/// \endcode
243///
244/// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
245AST_POLYMORPHIC_MATCHER(isExpansionInMainFile,namespace internal { template <typename NodeType> class
matcher_isExpansionInMainFileMatcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isExpansionInMainFileMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>)> isExpansionInMainFile() { return ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_isExpansionInMainFileMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>)>(); } template <typename NodeType> bool
internal::matcher_isExpansionInMainFileMatcher<NodeType>
::matches( const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
246 AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc))namespace internal { template <typename NodeType> class
matcher_isExpansionInMainFileMatcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isExpansionInMainFileMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>)> isExpansionInMainFile() { return ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_isExpansionInMainFileMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>)>(); } template <typename NodeType> bool
internal::matcher_isExpansionInMainFileMatcher<NodeType>
::matches( const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
247 auto &SourceManager = Finder->getASTContext().getSourceManager();
248 return SourceManager.isInMainFile(
249 SourceManager.getExpansionLoc(Node.getBeginLoc()));
250}
251
252/// Matches AST nodes that were expanded within system-header-files.
253///
254/// Example matches Y but not X
255/// (matcher = cxxRecordDecl(isExpansionInSystemHeader())
256/// \code
257/// #include <SystemHeader.h>
258/// class X {};
259/// \endcode
260/// SystemHeader.h:
261/// \code
262/// class Y {};
263/// \endcode
264///
265/// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
266AST_POLYMORPHIC_MATCHER(isExpansionInSystemHeader,namespace internal { template <typename NodeType> class
matcher_isExpansionInSystemHeaderMatcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isExpansionInSystemHeaderMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>)> isExpansionInSystemHeader() { return ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_isExpansionInSystemHeaderMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>)>(); } template <typename NodeType> bool
internal::matcher_isExpansionInSystemHeaderMatcher<NodeType
>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
267 AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc))namespace internal { template <typename NodeType> class
matcher_isExpansionInSystemHeaderMatcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isExpansionInSystemHeaderMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>)> isExpansionInSystemHeader() { return ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_isExpansionInSystemHeaderMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>)>(); } template <typename NodeType> bool
internal::matcher_isExpansionInSystemHeaderMatcher<NodeType
>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
268 auto &SourceManager = Finder->getASTContext().getSourceManager();
269 auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getBeginLoc());
270 if (ExpansionLoc.isInvalid()) {
271 return false;
272 }
273 return SourceManager.isInSystemHeader(ExpansionLoc);
274}
275
276/// Matches AST nodes that were expanded within files whose name is
277/// partially matching a given regex.
278///
279/// Example matches Y but not X
280/// (matcher = cxxRecordDecl(isExpansionInFileMatching("AST.*"))
281/// \code
282/// #include "ASTMatcher.h"
283/// class X {};
284/// \endcode
285/// ASTMatcher.h:
286/// \code
287/// class Y {};
288/// \endcode
289///
290/// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
291AST_POLYMORPHIC_MATCHER_REGEX(isExpansionInFileMatching,namespace internal { template <typename NodeType, typename
ParamT> class matcher_isExpansionInFileMatching0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: explicit matcher_isExpansionInFileMatching0Matcher
( std::shared_ptr<llvm::Regex> RE) : RegExp(std::move(RE
)) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: std
::shared_ptr<llvm::Regex> RegExp; }; } inline ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_isExpansionInFileMatching0Matcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>), std::shared_ptr<llvm::Regex>> isExpansionInFileMatching
(llvm::StringRef RegExp, llvm::Regex::RegexFlags RegexFlags) {
return ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_isExpansionInFileMatching0Matcher, void(::
clang::ast_matchers::internal::TypeList<Decl, Stmt, TypeLoc
>), std::shared_ptr<llvm::Regex>>( ::clang::ast_matchers
::internal::createAndVerifyRegex( RegExp, RegexFlags, "isExpansionInFileMatching"
)); } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isExpansionInFileMatching0Matcher, void
(::clang::ast_matchers::internal::TypeList<Decl, Stmt, TypeLoc
>), std::shared_ptr<llvm::Regex>> isExpansionInFileMatching
(llvm::StringRef RegExp) { return isExpansionInFileMatching(RegExp
, llvm::Regex::NoFlags); } typedef ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_isExpansionInFileMatching0Matcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>), std::shared_ptr<llvm::Regex>> ( &
isExpansionInFileMatching_Type0Flags)( llvm::StringRef RegExp
, llvm::Regex::RegexFlags RegexFlags); typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isExpansionInFileMatching0Matcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>), std::shared_ptr<llvm::Regex>> (&
isExpansionInFileMatching_Type0)( llvm::StringRef RegExp); template
<typename NodeType, typename ParamT> bool internal:: matcher_isExpansionInFileMatching0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
292 AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt,namespace internal { template <typename NodeType, typename
ParamT> class matcher_isExpansionInFileMatching0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: explicit matcher_isExpansionInFileMatching0Matcher
( std::shared_ptr<llvm::Regex> RE) : RegExp(std::move(RE
)) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: std
::shared_ptr<llvm::Regex> RegExp; }; } inline ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_isExpansionInFileMatching0Matcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>), std::shared_ptr<llvm::Regex>> isExpansionInFileMatching
(llvm::StringRef RegExp, llvm::Regex::RegexFlags RegexFlags) {
return ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_isExpansionInFileMatching0Matcher, void(::
clang::ast_matchers::internal::TypeList<Decl, Stmt, TypeLoc
>), std::shared_ptr<llvm::Regex>>( ::clang::ast_matchers
::internal::createAndVerifyRegex( RegExp, RegexFlags, "isExpansionInFileMatching"
)); } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isExpansionInFileMatching0Matcher, void
(::clang::ast_matchers::internal::TypeList<Decl, Stmt, TypeLoc
>), std::shared_ptr<llvm::Regex>> isExpansionInFileMatching
(llvm::StringRef RegExp) { return isExpansionInFileMatching(RegExp
, llvm::Regex::NoFlags); } typedef ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_isExpansionInFileMatching0Matcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>), std::shared_ptr<llvm::Regex>> ( &
isExpansionInFileMatching_Type0Flags)( llvm::StringRef RegExp
, llvm::Regex::RegexFlags RegexFlags); typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isExpansionInFileMatching0Matcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>), std::shared_ptr<llvm::Regex>> (&
isExpansionInFileMatching_Type0)( llvm::StringRef RegExp); template
<typename NodeType, typename ParamT> bool internal:: matcher_isExpansionInFileMatching0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
293 TypeLoc),namespace internal { template <typename NodeType, typename
ParamT> class matcher_isExpansionInFileMatching0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: explicit matcher_isExpansionInFileMatching0Matcher
( std::shared_ptr<llvm::Regex> RE) : RegExp(std::move(RE
)) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: std
::shared_ptr<llvm::Regex> RegExp; }; } inline ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_isExpansionInFileMatching0Matcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>), std::shared_ptr<llvm::Regex>> isExpansionInFileMatching
(llvm::StringRef RegExp, llvm::Regex::RegexFlags RegexFlags) {
return ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_isExpansionInFileMatching0Matcher, void(::
clang::ast_matchers::internal::TypeList<Decl, Stmt, TypeLoc
>), std::shared_ptr<llvm::Regex>>( ::clang::ast_matchers
::internal::createAndVerifyRegex( RegExp, RegexFlags, "isExpansionInFileMatching"
)); } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isExpansionInFileMatching0Matcher, void
(::clang::ast_matchers::internal::TypeList<Decl, Stmt, TypeLoc
>), std::shared_ptr<llvm::Regex>> isExpansionInFileMatching
(llvm::StringRef RegExp) { return isExpansionInFileMatching(RegExp
, llvm::Regex::NoFlags); } typedef ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_isExpansionInFileMatching0Matcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>), std::shared_ptr<llvm::Regex>> ( &
isExpansionInFileMatching_Type0Flags)( llvm::StringRef RegExp
, llvm::Regex::RegexFlags RegexFlags); typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isExpansionInFileMatching0Matcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>), std::shared_ptr<llvm::Regex>> (&
isExpansionInFileMatching_Type0)( llvm::StringRef RegExp); template
<typename NodeType, typename ParamT> bool internal:: matcher_isExpansionInFileMatching0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
294 RegExp)namespace internal { template <typename NodeType, typename
ParamT> class matcher_isExpansionInFileMatching0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: explicit matcher_isExpansionInFileMatching0Matcher
( std::shared_ptr<llvm::Regex> RE) : RegExp(std::move(RE
)) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: std
::shared_ptr<llvm::Regex> RegExp; }; } inline ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_isExpansionInFileMatching0Matcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>), std::shared_ptr<llvm::Regex>> isExpansionInFileMatching
(llvm::StringRef RegExp, llvm::Regex::RegexFlags RegexFlags) {
return ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_isExpansionInFileMatching0Matcher, void(::
clang::ast_matchers::internal::TypeList<Decl, Stmt, TypeLoc
>), std::shared_ptr<llvm::Regex>>( ::clang::ast_matchers
::internal::createAndVerifyRegex( RegExp, RegexFlags, "isExpansionInFileMatching"
)); } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isExpansionInFileMatching0Matcher, void
(::clang::ast_matchers::internal::TypeList<Decl, Stmt, TypeLoc
>), std::shared_ptr<llvm::Regex>> isExpansionInFileMatching
(llvm::StringRef RegExp) { return isExpansionInFileMatching(RegExp
, llvm::Regex::NoFlags); } typedef ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_isExpansionInFileMatching0Matcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>), std::shared_ptr<llvm::Regex>> ( &
isExpansionInFileMatching_Type0Flags)( llvm::StringRef RegExp
, llvm::Regex::RegexFlags RegexFlags); typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isExpansionInFileMatching0Matcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>), std::shared_ptr<llvm::Regex>> (&
isExpansionInFileMatching_Type0)( llvm::StringRef RegExp); template
<typename NodeType, typename ParamT> bool internal:: matcher_isExpansionInFileMatching0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
{
295 auto &SourceManager = Finder->getASTContext().getSourceManager();
296 auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getBeginLoc());
297 if (ExpansionLoc.isInvalid()) {
298 return false;
299 }
300 auto FileEntry =
301 SourceManager.getFileEntryForID(SourceManager.getFileID(ExpansionLoc));
302 if (!FileEntry) {
303 return false;
304 }
305
306 auto Filename = FileEntry->getName();
307 return RegExp->match(Filename);
308}
309
310/// Matches statements that are (transitively) expanded from the named macro.
311/// Does not match if only part of the statement is expanded from that macro or
312/// if different parts of the statement are expanded from different
313/// appearances of the macro.
314AST_POLYMORPHIC_MATCHER_P(isExpandedFromMacro,namespace internal { template <typename NodeType, typename
ParamT> class matcher_isExpandedFromMacro0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_isExpandedFromMacro0Matcher( std
::string const &AMacroName) : MacroName(AMacroName) {} bool
matches(const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string MacroName; };
} inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isExpandedFromMacro0Matcher, void(::clang
::ast_matchers::internal::TypeList<Decl, Stmt, TypeLoc>
), std::string> isExpandedFromMacro(std::string const &
MacroName) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isExpandedFromMacro0Matcher, void(::clang
::ast_matchers::internal::TypeList<Decl, Stmt, TypeLoc>
), std::string>(MacroName); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isExpandedFromMacro0Matcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>), std::string> (&isExpandedFromMacro_Type0
)(std::string const &MacroName); template <typename NodeType
, typename ParamT> bool internal:: matcher_isExpandedFromMacro0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
315 AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc),namespace internal { template <typename NodeType, typename
ParamT> class matcher_isExpandedFromMacro0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_isExpandedFromMacro0Matcher( std
::string const &AMacroName) : MacroName(AMacroName) {} bool
matches(const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string MacroName; };
} inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isExpandedFromMacro0Matcher, void(::clang
::ast_matchers::internal::TypeList<Decl, Stmt, TypeLoc>
), std::string> isExpandedFromMacro(std::string const &
MacroName) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isExpandedFromMacro0Matcher, void(::clang
::ast_matchers::internal::TypeList<Decl, Stmt, TypeLoc>
), std::string>(MacroName); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isExpandedFromMacro0Matcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>), std::string> (&isExpandedFromMacro_Type0
)(std::string const &MacroName); template <typename NodeType
, typename ParamT> bool internal:: matcher_isExpandedFromMacro0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
316 std::string, MacroName)namespace internal { template <typename NodeType, typename
ParamT> class matcher_isExpandedFromMacro0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_isExpandedFromMacro0Matcher( std
::string const &AMacroName) : MacroName(AMacroName) {} bool
matches(const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string MacroName; };
} inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isExpandedFromMacro0Matcher, void(::clang
::ast_matchers::internal::TypeList<Decl, Stmt, TypeLoc>
), std::string> isExpandedFromMacro(std::string const &
MacroName) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isExpandedFromMacro0Matcher, void(::clang
::ast_matchers::internal::TypeList<Decl, Stmt, TypeLoc>
), std::string>(MacroName); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isExpandedFromMacro0Matcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>), std::string> (&isExpandedFromMacro_Type0
)(std::string const &MacroName); template <typename NodeType
, typename ParamT> bool internal:: matcher_isExpandedFromMacro0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
{
317 // Verifies that the statement' beginning and ending are both expanded from
318 // the same instance of the given macro.
319 auto& Context = Finder->getASTContext();
320 llvm::Optional<SourceLocation> B =
321 internal::getExpansionLocOfMacro(MacroName, Node.getBeginLoc(), Context);
322 if (!B) return false;
323 llvm::Optional<SourceLocation> E =
324 internal::getExpansionLocOfMacro(MacroName, Node.getEndLoc(), Context);
325 if (!E) return false;
326 return *B == *E;
327}
328
329/// Matches declarations.
330///
331/// Examples matches \c X, \c C, and the friend declaration inside \c C;
332/// \code
333/// void X();
334/// class C {
335/// friend X;
336/// };
337/// \endcode
338extern const internal::VariadicAllOfMatcher<Decl> decl;
339
340/// Matches decomposition-declarations.
341///
342/// Examples matches the declaration node with \c foo and \c bar, but not
343/// \c number.
344/// (matcher = declStmt(has(decompositionDecl())))
345///
346/// \code
347/// int number = 42;
348/// auto [foo, bar] = std::make_pair{42, 42};
349/// \endcode
350extern const internal::VariadicDynCastAllOfMatcher<Decl, DecompositionDecl>
351 decompositionDecl;
352
353/// Matches binding declarations
354/// Example matches \c foo and \c bar
355/// (matcher = bindingDecl()
356///
357/// \code
358/// auto [foo, bar] = std::make_pair{42, 42};
359/// \endcode
360extern const internal::VariadicDynCastAllOfMatcher<Decl, BindingDecl>
361 bindingDecl;
362
363/// Matches a declaration of a linkage specification.
364///
365/// Given
366/// \code
367/// extern "C" {}
368/// \endcode
369/// linkageSpecDecl()
370/// matches "extern "C" {}"
371extern const internal::VariadicDynCastAllOfMatcher<Decl, LinkageSpecDecl>
372 linkageSpecDecl;
373
374/// Matches a declaration of anything that could have a name.
375///
376/// Example matches \c X, \c S, the anonymous union type, \c i, and \c U;
377/// \code
378/// typedef int X;
379/// struct S {
380/// union {
381/// int i;
382/// } U;
383/// };
384/// \endcode
385extern const internal::VariadicDynCastAllOfMatcher<Decl, NamedDecl> namedDecl;
386
387/// Matches a declaration of label.
388///
389/// Given
390/// \code
391/// goto FOO;
392/// FOO: bar();
393/// \endcode
394/// labelDecl()
395/// matches 'FOO:'
396extern const internal::VariadicDynCastAllOfMatcher<Decl, LabelDecl> labelDecl;
397
398/// Matches a declaration of a namespace.
399///
400/// Given
401/// \code
402/// namespace {}
403/// namespace test {}
404/// \endcode
405/// namespaceDecl()
406/// matches "namespace {}" and "namespace test {}"
407extern const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceDecl>
408 namespaceDecl;
409
410/// Matches a declaration of a namespace alias.
411///
412/// Given
413/// \code
414/// namespace test {}
415/// namespace alias = ::test;
416/// \endcode
417/// namespaceAliasDecl()
418/// matches "namespace alias" but not "namespace test"
419extern const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceAliasDecl>
420 namespaceAliasDecl;
421
422/// Matches class, struct, and union declarations.
423///
424/// Example matches \c X, \c Z, \c U, and \c S
425/// \code
426/// class X;
427/// template<class T> class Z {};
428/// struct S {};
429/// union U {};
430/// \endcode
431extern const internal::VariadicDynCastAllOfMatcher<Decl, RecordDecl> recordDecl;
432
433/// Matches C++ class declarations.
434///
435/// Example matches \c X, \c Z
436/// \code
437/// class X;
438/// template<class T> class Z {};
439/// \endcode
440extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXRecordDecl>
441 cxxRecordDecl;
442
443/// Matches C++ class template declarations.
444///
445/// Example matches \c Z
446/// \code
447/// template<class T> class Z {};
448/// \endcode
449extern const internal::VariadicDynCastAllOfMatcher<Decl, ClassTemplateDecl>
450 classTemplateDecl;
451
452/// Matches C++ class template specializations.
453///
454/// Given
455/// \code
456/// template<typename T> class A {};
457/// template<> class A<double> {};
458/// A<int> a;
459/// \endcode
460/// classTemplateSpecializationDecl()
461/// matches the specializations \c A<int> and \c A<double>
462extern const internal::VariadicDynCastAllOfMatcher<
463 Decl, ClassTemplateSpecializationDecl>
464 classTemplateSpecializationDecl;
465
466/// Matches C++ class template partial specializations.
467///
468/// Given
469/// \code
470/// template<class T1, class T2, int I>
471/// class A {};
472///
473/// template<class T, int I>
474/// class A<T, T*, I> {};
475///
476/// template<>
477/// class A<int, int, 1> {};
478/// \endcode
479/// classTemplatePartialSpecializationDecl()
480/// matches the specialization \c A<T,T*,I> but not \c A<int,int,1>
481extern const internal::VariadicDynCastAllOfMatcher<
482 Decl, ClassTemplatePartialSpecializationDecl>
483 classTemplatePartialSpecializationDecl;
484
485/// Matches declarator declarations (field, variable, function
486/// and non-type template parameter declarations).
487///
488/// Given
489/// \code
490/// class X { int y; };
491/// \endcode
492/// declaratorDecl()
493/// matches \c int y.
494extern const internal::VariadicDynCastAllOfMatcher<Decl, DeclaratorDecl>
495 declaratorDecl;
496
497/// Matches parameter variable declarations.
498///
499/// Given
500/// \code
501/// void f(int x);
502/// \endcode
503/// parmVarDecl()
504/// matches \c int x.
505extern const internal::VariadicDynCastAllOfMatcher<Decl, ParmVarDecl>
506 parmVarDecl;
507
508/// Matches C++ access specifier declarations.
509///
510/// Given
511/// \code
512/// class C {
513/// public:
514/// int a;
515/// };
516/// \endcode
517/// accessSpecDecl()
518/// matches 'public:'
519extern const internal::VariadicDynCastAllOfMatcher<Decl, AccessSpecDecl>
520 accessSpecDecl;
521
522/// Matches class bases.
523///
524/// Examples matches \c public virtual B.
525/// \code
526/// class B {};
527/// class C : public virtual B {};
528/// \endcode
529extern const internal::VariadicAllOfMatcher<CXXBaseSpecifier> cxxBaseSpecifier;
530
531/// Matches constructor initializers.
532///
533/// Examples matches \c i(42).
534/// \code
535/// class C {
536/// C() : i(42) {}
537/// int i;
538/// };
539/// \endcode
540extern const internal::VariadicAllOfMatcher<CXXCtorInitializer>
541 cxxCtorInitializer;
542
543/// Matches template arguments.
544///
545/// Given
546/// \code
547/// template <typename T> struct C {};
548/// C<int> c;
549/// \endcode
550/// templateArgument()
551/// matches 'int' in C<int>.
552extern const internal::VariadicAllOfMatcher<TemplateArgument> templateArgument;
553
554/// Matches template arguments (with location info).
555///
556/// Given
557/// \code
558/// template <typename T> struct C {};
559/// C<int> c;
560/// \endcode
561/// templateArgumentLoc()
562/// matches 'int' in C<int>.
563extern const internal::VariadicAllOfMatcher<TemplateArgumentLoc>
564 templateArgumentLoc;
565
566/// Matches template name.
567///
568/// Given
569/// \code
570/// template <typename T> class X { };
571/// X<int> xi;
572/// \endcode
573/// templateName()
574/// matches 'X' in X<int>.
575extern const internal::VariadicAllOfMatcher<TemplateName> templateName;
576
577/// Matches non-type template parameter declarations.
578///
579/// Given
580/// \code
581/// template <typename T, int N> struct C {};
582/// \endcode
583/// nonTypeTemplateParmDecl()
584/// matches 'N', but not 'T'.
585extern const internal::VariadicDynCastAllOfMatcher<Decl,
586 NonTypeTemplateParmDecl>
587 nonTypeTemplateParmDecl;
588
589/// Matches template type parameter declarations.
590///
591/// Given
592/// \code
593/// template <typename T, int N> struct C {};
594/// \endcode
595/// templateTypeParmDecl()
596/// matches 'T', but not 'N'.
597extern const internal::VariadicDynCastAllOfMatcher<Decl, TemplateTypeParmDecl>
598 templateTypeParmDecl;
599
600/// Matches template template parameter declarations.
601///
602/// Given
603/// \code
604/// template <template <typename> class Z, int N> struct C {};
605/// \endcode
606/// templateTypeParmDecl()
607/// matches 'Z', but not 'N'.
608extern const internal::VariadicDynCastAllOfMatcher<Decl,
609 TemplateTemplateParmDecl>
610 templateTemplateParmDecl;
611
612/// Matches public C++ declarations and C++ base specifers that specify public
613/// inheritance.
614///
615/// Examples:
616/// \code
617/// class C {
618/// public: int a; // fieldDecl(isPublic()) matches 'a'
619/// protected: int b;
620/// private: int c;
621/// };
622/// \endcode
623///
624/// \code
625/// class Base {};
626/// class Derived1 : public Base {}; // matches 'Base'
627/// struct Derived2 : Base {}; // matches 'Base'
628/// \endcode
629AST_POLYMORPHIC_MATCHER(isPublic,namespace internal { template <typename NodeType> class
matcher_isPublicMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isPublicMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, CXXBaseSpecifier
>)> isPublic() { return ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_isPublicMatcher, void
(::clang::ast_matchers::internal::TypeList<Decl, CXXBaseSpecifier
>)>(); } template <typename NodeType> bool internal
::matcher_isPublicMatcher<NodeType>::matches( const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
630 AST_POLYMORPHIC_SUPPORTED_TYPES(Decl,namespace internal { template <typename NodeType> class
matcher_isPublicMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isPublicMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, CXXBaseSpecifier
>)> isPublic() { return ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_isPublicMatcher, void
(::clang::ast_matchers::internal::TypeList<Decl, CXXBaseSpecifier
>)>(); } template <typename NodeType> bool internal
::matcher_isPublicMatcher<NodeType>::matches( const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
631 CXXBaseSpecifier))namespace internal { template <typename NodeType> class
matcher_isPublicMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isPublicMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, CXXBaseSpecifier
>)> isPublic() { return ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_isPublicMatcher, void
(::clang::ast_matchers::internal::TypeList<Decl, CXXBaseSpecifier
>)>(); } template <typename NodeType> bool internal
::matcher_isPublicMatcher<NodeType>::matches( const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
632 return getAccessSpecifier(Node) == AS_public;
633}
634
635/// Matches protected C++ declarations and C++ base specifers that specify
636/// protected inheritance.
637///
638/// Examples:
639/// \code
640/// class C {
641/// public: int a;
642/// protected: int b; // fieldDecl(isProtected()) matches 'b'
643/// private: int c;
644/// };
645/// \endcode
646///
647/// \code
648/// class Base {};
649/// class Derived : protected Base {}; // matches 'Base'
650/// \endcode
651AST_POLYMORPHIC_MATCHER(isProtected,namespace internal { template <typename NodeType> class
matcher_isProtectedMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isProtectedMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, CXXBaseSpecifier
>)> isProtected() { return ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_isProtectedMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, CXXBaseSpecifier
>)>(); } template <typename NodeType> bool internal
::matcher_isProtectedMatcher<NodeType>::matches( const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
652 AST_POLYMORPHIC_SUPPORTED_TYPES(Decl,namespace internal { template <typename NodeType> class
matcher_isProtectedMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isProtectedMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, CXXBaseSpecifier
>)> isProtected() { return ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_isProtectedMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, CXXBaseSpecifier
>)>(); } template <typename NodeType> bool internal
::matcher_isProtectedMatcher<NodeType>::matches( const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
653 CXXBaseSpecifier))namespace internal { template <typename NodeType> class
matcher_isProtectedMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isProtectedMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, CXXBaseSpecifier
>)> isProtected() { return ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_isProtectedMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, CXXBaseSpecifier
>)>(); } template <typename NodeType> bool internal
::matcher_isProtectedMatcher<NodeType>::matches( const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
654 return getAccessSpecifier(Node) == AS_protected;
655}
656
657/// Matches private C++ declarations and C++ base specifers that specify private
658/// inheritance.
659///
660/// Examples:
661/// \code
662/// class C {
663/// public: int a;
664/// protected: int b;
665/// private: int c; // fieldDecl(isPrivate()) matches 'c'
666/// };
667/// \endcode
668///
669/// \code
670/// struct Base {};
671/// struct Derived1 : private Base {}; // matches 'Base'
672/// class Derived2 : Base {}; // matches 'Base'
673/// \endcode
674AST_POLYMORPHIC_MATCHER(isPrivate,namespace internal { template <typename NodeType> class
matcher_isPrivateMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isPrivateMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, CXXBaseSpecifier
>)> isPrivate() { return ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_isPrivateMatcher, void
(::clang::ast_matchers::internal::TypeList<Decl, CXXBaseSpecifier
>)>(); } template <typename NodeType> bool internal
::matcher_isPrivateMatcher<NodeType>::matches( const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
675 AST_POLYMORPHIC_SUPPORTED_TYPES(Decl,namespace internal { template <typename NodeType> class
matcher_isPrivateMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isPrivateMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, CXXBaseSpecifier
>)> isPrivate() { return ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_isPrivateMatcher, void
(::clang::ast_matchers::internal::TypeList<Decl, CXXBaseSpecifier
>)>(); } template <typename NodeType> bool internal
::matcher_isPrivateMatcher<NodeType>::matches( const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
676 CXXBaseSpecifier))namespace internal { template <typename NodeType> class
matcher_isPrivateMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isPrivateMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, CXXBaseSpecifier
>)> isPrivate() { return ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_isPrivateMatcher, void
(::clang::ast_matchers::internal::TypeList<Decl, CXXBaseSpecifier
>)>(); } template <typename NodeType> bool internal
::matcher_isPrivateMatcher<NodeType>::matches( const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
677 return getAccessSpecifier(Node) == AS_private;
678}
679
680/// Matches non-static data members that are bit-fields.
681///
682/// Given
683/// \code
684/// class C {
685/// int a : 2;
686/// int b;
687/// };
688/// \endcode
689/// fieldDecl(isBitField())
690/// matches 'int a;' but not 'int b;'.
691AST_MATCHER(FieldDecl, isBitField)namespace internal { class matcher_isBitFieldMatcher : public
::clang::ast_matchers::internal::MatcherInterface<FieldDecl
> { public: explicit matcher_isBitFieldMatcher() = default
; bool matches(const FieldDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<FieldDecl> isBitField
() { return ::clang::ast_matchers::internal::makeMatcher( new
internal::matcher_isBitFieldMatcher()); } inline bool internal
::matcher_isBitFieldMatcher::matches( const FieldDecl &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
692 return Node.isBitField();
693}
694
695/// Matches non-static data members that are bit-fields of the specified
696/// bit width.
697///
698/// Given
699/// \code
700/// class C {
701/// int a : 2;
702/// int b : 4;
703/// int c : 2;
704/// };
705/// \endcode
706/// fieldDecl(hasBitWidth(2))
707/// matches 'int a;' and 'int c;' but not 'int b;'.
708AST_MATCHER_P(FieldDecl, hasBitWidth, unsigned, Width)namespace internal { class matcher_hasBitWidth0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<FieldDecl
> { public: explicit matcher_hasBitWidth0Matcher( unsigned
const &AWidth) : Width(AWidth) {} bool matches(const FieldDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned Width; }; } inline
::clang::ast_matchers::internal::Matcher<FieldDecl> hasBitWidth
( unsigned const &Width) { return ::clang::ast_matchers::
internal::makeMatcher( new internal::matcher_hasBitWidth0Matcher
(Width)); } typedef ::clang::ast_matchers::internal::Matcher<
FieldDecl> ( &hasBitWidth_Type0)(unsigned const &Width
); inline bool internal::matcher_hasBitWidth0Matcher::matches
( const FieldDecl &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
709 return Node.isBitField() &&
710 Node.getBitWidthValue(Finder->getASTContext()) == Width;
711}
712
713/// Matches non-static data members that have an in-class initializer.
714///
715/// Given
716/// \code
717/// class C {
718/// int a = 2;
719/// int b = 3;
720/// int c;
721/// };
722/// \endcode
723/// fieldDecl(hasInClassInitializer(integerLiteral(equals(2))))
724/// matches 'int a;' but not 'int b;'.
725/// fieldDecl(hasInClassInitializer(anything()))
726/// matches 'int a;' and 'int b;' but not 'int c;'.
727AST_MATCHER_P(FieldDecl, hasInClassInitializer, internal::Matcher<Expr>,namespace internal { class matcher_hasInClassInitializer0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
FieldDecl> { public: explicit matcher_hasInClassInitializer0Matcher
( internal::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const FieldDecl &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
override; private: internal::Matcher<Expr> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<FieldDecl
> hasInClassInitializer( internal::Matcher<Expr> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
makeMatcher( new internal::matcher_hasInClassInitializer0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<FieldDecl> ( &hasInClassInitializer_Type0)(internal
::Matcher<Expr> const &InnerMatcher); inline bool internal
::matcher_hasInClassInitializer0Matcher::matches( const FieldDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
728 InnerMatcher)namespace internal { class matcher_hasInClassInitializer0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
FieldDecl> { public: explicit matcher_hasInClassInitializer0Matcher
( internal::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const FieldDecl &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
override; private: internal::Matcher<Expr> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<FieldDecl
> hasInClassInitializer( internal::Matcher<Expr> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
makeMatcher( new internal::matcher_hasInClassInitializer0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<FieldDecl> ( &hasInClassInitializer_Type0)(internal
::Matcher<Expr> const &InnerMatcher); inline bool internal
::matcher_hasInClassInitializer0Matcher::matches( const FieldDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
729 const Expr *Initializer = Node.getInClassInitializer();
730 return (Initializer != nullptr &&
731 InnerMatcher.matches(*Initializer, Finder, Builder));
732}
733
734/// Determines whether the function is "main", which is the entry point
735/// into an executable program.
736AST_MATCHER(FunctionDecl, isMain)namespace internal { class matcher_isMainMatcher : public ::clang
::ast_matchers::internal::MatcherInterface<FunctionDecl>
{ public: explicit matcher_isMainMatcher() = default; bool matches
(const FunctionDecl &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::Matcher<FunctionDecl> isMain() { return ::clang
::ast_matchers::internal::makeMatcher( new internal::matcher_isMainMatcher
()); } inline bool internal::matcher_isMainMatcher::matches( const
FunctionDecl &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
737 return Node.isMain();
738}
739
740/// Matches the specialized template of a specialization declaration.
741///
742/// Given
743/// \code
744/// template<typename T> class A {}; #1
745/// template<> class A<int> {}; #2
746/// \endcode
747/// classTemplateSpecializationDecl(hasSpecializedTemplate(classTemplateDecl()))
748/// matches '#2' with classTemplateDecl() matching the class template
749/// declaration of 'A' at #1.
750AST_MATCHER_P(ClassTemplateSpecializationDecl, hasSpecializedTemplate,namespace internal { class matcher_hasSpecializedTemplate0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
ClassTemplateSpecializationDecl> { public: explicit matcher_hasSpecializedTemplate0Matcher
( internal::Matcher<ClassTemplateDecl> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const ClassTemplateSpecializationDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<ClassTemplateDecl
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<ClassTemplateSpecializationDecl> hasSpecializedTemplate
( internal::Matcher<ClassTemplateDecl> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_hasSpecializedTemplate0Matcher(InnerMatcher)); } typedef
::clang::ast_matchers::internal::Matcher<ClassTemplateSpecializationDecl
> ( &hasSpecializedTemplate_Type0)(internal::Matcher<
ClassTemplateDecl> const &InnerMatcher); inline bool internal
::matcher_hasSpecializedTemplate0Matcher::matches( const ClassTemplateSpecializationDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
751 internal::Matcher<ClassTemplateDecl>, InnerMatcher)namespace internal { class matcher_hasSpecializedTemplate0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
ClassTemplateSpecializationDecl> { public: explicit matcher_hasSpecializedTemplate0Matcher
( internal::Matcher<ClassTemplateDecl> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const ClassTemplateSpecializationDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<ClassTemplateDecl
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<ClassTemplateSpecializationDecl> hasSpecializedTemplate
( internal::Matcher<ClassTemplateDecl> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_hasSpecializedTemplate0Matcher(InnerMatcher)); } typedef
::clang::ast_matchers::internal::Matcher<ClassTemplateSpecializationDecl
> ( &hasSpecializedTemplate_Type0)(internal::Matcher<
ClassTemplateDecl> const &InnerMatcher); inline bool internal
::matcher_hasSpecializedTemplate0Matcher::matches( const ClassTemplateSpecializationDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
752 const ClassTemplateDecl* Decl = Node.getSpecializedTemplate();
753 return (Decl != nullptr &&
754 InnerMatcher.matches(*Decl, Finder, Builder));
755}
756
757/// Matches an entity that has been implicitly added by the compiler (e.g.
758/// implicit default/copy constructors).
759AST_POLYMORPHIC_MATCHER(isImplicit,namespace internal { template <typename NodeType> class
matcher_isImplicitMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isImplicitMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Attr
, LambdaCapture>)> isImplicit() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isImplicitMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Attr
, LambdaCapture>)>(); } template <typename NodeType>
bool internal::matcher_isImplicitMatcher<NodeType>::matches
( const NodeType &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
760 AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Attr,namespace internal { template <typename NodeType> class
matcher_isImplicitMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isImplicitMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Attr
, LambdaCapture>)> isImplicit() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isImplicitMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Attr
, LambdaCapture>)>(); } template <typename NodeType>
bool internal::matcher_isImplicitMatcher<NodeType>::matches
( const NodeType &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
761 LambdaCapture))namespace internal { template <typename NodeType> class
matcher_isImplicitMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isImplicitMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Attr
, LambdaCapture>)> isImplicit() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isImplicitMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Attr
, LambdaCapture>)>(); } template <typename NodeType>
bool internal::matcher_isImplicitMatcher<NodeType>::matches
( const NodeType &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
762 return Node.isImplicit();
763}
764
765/// Matches classTemplateSpecializations, templateSpecializationType and
766/// functionDecl that have at least one TemplateArgument matching the given
767/// InnerMatcher.
768///
769/// Given
770/// \code
771/// template<typename T> class A {};
772/// template<> class A<double> {};
773/// A<int> a;
774///
775/// template<typename T> f() {};
776/// void func() { f<int>(); };
777/// \endcode
778///
779/// \endcode
780/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
781/// refersToType(asString("int"))))
782/// matches the specialization \c A<int>
783///
784/// functionDecl(hasAnyTemplateArgument(refersToType(asString("int"))))
785/// matches the specialization \c f<int>
786AST_POLYMORPHIC_MATCHER_P(namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasAnyTemplateArgument0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_hasAnyTemplateArgument0Matcher
( internal::Matcher<TemplateArgument> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<TemplateArgument
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasAnyTemplateArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType, FunctionDecl>), internal::Matcher
<TemplateArgument> > hasAnyTemplateArgument(internal
::Matcher<TemplateArgument> const &InnerMatcher) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasAnyTemplateArgument0Matcher, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>), internal::Matcher<TemplateArgument>
>(InnerMatcher); } typedef ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasAnyTemplateArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType, FunctionDecl>), internal::Matcher
<TemplateArgument> > (&hasAnyTemplateArgument_Type0
)(internal::Matcher<TemplateArgument> const &InnerMatcher
); template <typename NodeType, typename ParamT> bool internal
:: matcher_hasAnyTemplateArgument0Matcher<NodeType, ParamT
>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
787 hasAnyTemplateArgument,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasAnyTemplateArgument0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_hasAnyTemplateArgument0Matcher
( internal::Matcher<TemplateArgument> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<TemplateArgument
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasAnyTemplateArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType, FunctionDecl>), internal::Matcher
<TemplateArgument> > hasAnyTemplateArgument(internal
::Matcher<TemplateArgument> const &InnerMatcher) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasAnyTemplateArgument0Matcher, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>), internal::Matcher<TemplateArgument>
>(InnerMatcher); } typedef ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasAnyTemplateArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType, FunctionDecl>), internal::Matcher
<TemplateArgument> > (&hasAnyTemplateArgument_Type0
)(internal::Matcher<TemplateArgument> const &InnerMatcher
); template <typename NodeType, typename ParamT> bool internal
:: matcher_hasAnyTemplateArgument0Matcher<NodeType, ParamT
>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
788 AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasAnyTemplateArgument0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_hasAnyTemplateArgument0Matcher
( internal::Matcher<TemplateArgument> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<TemplateArgument
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasAnyTemplateArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType, FunctionDecl>), internal::Matcher
<TemplateArgument> > hasAnyTemplateArgument(internal
::Matcher<TemplateArgument> const &InnerMatcher) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasAnyTemplateArgument0Matcher, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>), internal::Matcher<TemplateArgument>
>(InnerMatcher); } typedef ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasAnyTemplateArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType, FunctionDecl>), internal::Matcher
<TemplateArgument> > (&hasAnyTemplateArgument_Type0
)(internal::Matcher<TemplateArgument> const &InnerMatcher
); template <typename NodeType, typename ParamT> bool internal
:: matcher_hasAnyTemplateArgument0Matcher<NodeType, ParamT
>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
789 TemplateSpecializationType,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasAnyTemplateArgument0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_hasAnyTemplateArgument0Matcher
( internal::Matcher<TemplateArgument> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<TemplateArgument
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasAnyTemplateArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType, FunctionDecl>), internal::Matcher
<TemplateArgument> > hasAnyTemplateArgument(internal
::Matcher<TemplateArgument> const &InnerMatcher) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasAnyTemplateArgument0Matcher, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>), internal::Matcher<TemplateArgument>
>(InnerMatcher); } typedef ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasAnyTemplateArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType, FunctionDecl>), internal::Matcher
<TemplateArgument> > (&hasAnyTemplateArgument_Type0
)(internal::Matcher<TemplateArgument> const &InnerMatcher
); template <typename NodeType, typename ParamT> bool internal
:: matcher_hasAnyTemplateArgument0Matcher<NodeType, ParamT
>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
790 FunctionDecl),namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasAnyTemplateArgument0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_hasAnyTemplateArgument0Matcher
( internal::Matcher<TemplateArgument> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<TemplateArgument
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasAnyTemplateArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType, FunctionDecl>), internal::Matcher
<TemplateArgument> > hasAnyTemplateArgument(internal
::Matcher<TemplateArgument> const &InnerMatcher) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasAnyTemplateArgument0Matcher, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>), internal::Matcher<TemplateArgument>
>(InnerMatcher); } typedef ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasAnyTemplateArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType, FunctionDecl>), internal::Matcher
<TemplateArgument> > (&hasAnyTemplateArgument_Type0
)(internal::Matcher<TemplateArgument> const &InnerMatcher
); template <typename NodeType, typename ParamT> bool internal
:: matcher_hasAnyTemplateArgument0Matcher<NodeType, ParamT
>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
791 internal::Matcher<TemplateArgument>, InnerMatcher)namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasAnyTemplateArgument0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_hasAnyTemplateArgument0Matcher
( internal::Matcher<TemplateArgument> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<TemplateArgument
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasAnyTemplateArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType, FunctionDecl>), internal::Matcher
<TemplateArgument> > hasAnyTemplateArgument(internal
::Matcher<TemplateArgument> const &InnerMatcher) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasAnyTemplateArgument0Matcher, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>), internal::Matcher<TemplateArgument>
>(InnerMatcher); } typedef ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasAnyTemplateArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType, FunctionDecl>), internal::Matcher
<TemplateArgument> > (&hasAnyTemplateArgument_Type0
)(internal::Matcher<TemplateArgument> const &InnerMatcher
); template <typename NodeType, typename ParamT> bool internal
:: matcher_hasAnyTemplateArgument0Matcher<NodeType, ParamT
>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
792 ArrayRef<TemplateArgument> List =
793 internal::getTemplateSpecializationArgs(Node);
794 return matchesFirstInRange(InnerMatcher, List.begin(), List.end(), Finder,
795 Builder) != List.end();
796}
797
798/// Causes all nested matchers to be matched with the specified traversal kind.
799///
800/// Given
801/// \code
802/// void foo()
803/// {
804/// int i = 3.0;
805/// }
806/// \endcode
807/// The matcher
808/// \code
809/// traverse(TK_IgnoreUnlessSpelledInSource,
810/// varDecl(hasInitializer(floatLiteral().bind("init")))
811/// )
812/// \endcode
813/// matches the variable declaration with "init" bound to the "3.0".
814template <typename T>
815internal::Matcher<T> traverse(TraversalKind TK,
816 const internal::Matcher<T> &InnerMatcher) {
817 return internal::DynTypedMatcher::constructRestrictedWrapper(
818 new internal::TraversalMatcher<T>(TK, InnerMatcher),
819 InnerMatcher.getID().first)
820 .template unconditionalConvertTo<T>();
821}
822
823template <typename T>
824internal::BindableMatcher<T>
825traverse(TraversalKind TK, const internal::BindableMatcher<T> &InnerMatcher) {
826 return internal::BindableMatcher<T>(
827 internal::DynTypedMatcher::constructRestrictedWrapper(
828 new internal::TraversalMatcher<T>(TK, InnerMatcher),
829 InnerMatcher.getID().first)
830 .template unconditionalConvertTo<T>());
831}
832
833template <typename... T>
834internal::TraversalWrapper<internal::VariadicOperatorMatcher<T...>>
835traverse(TraversalKind TK,
836 const internal::VariadicOperatorMatcher<T...> &InnerMatcher) {
837 return internal::TraversalWrapper<internal::VariadicOperatorMatcher<T...>>(
838 TK, InnerMatcher);
839}
840
841template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
842 typename T, typename ToTypes>
843internal::TraversalWrapper<
844 internal::ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>>
845traverse(TraversalKind TK, const internal::ArgumentAdaptingMatcherFuncAdaptor<
846 ArgumentAdapterT, T, ToTypes> &InnerMatcher) {
847 return internal::TraversalWrapper<
848 internal::ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T,
849 ToTypes>>(TK, InnerMatcher);
850}
851
852template <template <typename T, typename... P> class MatcherT, typename... P,
853 typename ReturnTypesF>
854internal::TraversalWrapper<
855 internal::PolymorphicMatcher<MatcherT, ReturnTypesF, P...>>
856traverse(TraversalKind TK,
857 const internal::PolymorphicMatcher<MatcherT, ReturnTypesF, P...>
858 &InnerMatcher) {
859 return internal::TraversalWrapper<
860 internal::PolymorphicMatcher<MatcherT, ReturnTypesF, P...>>(TK,
861 InnerMatcher);
862}
863
864template <typename... T>
865internal::Matcher<typename internal::GetClade<T...>::Type>
866traverse(TraversalKind TK, const internal::MapAnyOfHelper<T...> &InnerMatcher) {
867 return traverse(TK, InnerMatcher.with());
868}
869
870/// Matches expressions that match InnerMatcher after any implicit AST
871/// nodes are stripped off.
872///
873/// Parentheses and explicit casts are not discarded.
874/// Given
875/// \code
876/// class C {};
877/// C a = C();
878/// C b;
879/// C c = b;
880/// \endcode
881/// The matchers
882/// \code
883/// varDecl(hasInitializer(ignoringImplicit(cxxConstructExpr())))
884/// \endcode
885/// would match the declarations for a, b, and c.
886/// While
887/// \code
888/// varDecl(hasInitializer(cxxConstructExpr()))
889/// \endcode
890/// only match the declarations for b and c.
891AST_MATCHER_P(Expr, ignoringImplicit, internal::Matcher<Expr>,namespace internal { class matcher_ignoringImplicit0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
Expr> { public: explicit matcher_ignoringImplicit0Matcher(
internal::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const Expr &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<Expr> ignoringImplicit
( internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_ignoringImplicit0Matcher(InnerMatcher)); } typedef ::
clang::ast_matchers::internal::Matcher<Expr> ( &ignoringImplicit_Type0
)(internal::Matcher<Expr> const &InnerMatcher); inline
bool internal::matcher_ignoringImplicit0Matcher::matches( const
Expr &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
892 InnerMatcher)namespace internal { class matcher_ignoringImplicit0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
Expr> { public: explicit matcher_ignoringImplicit0Matcher(
internal::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const Expr &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<Expr> ignoringImplicit
( internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_ignoringImplicit0Matcher(InnerMatcher)); } typedef ::
clang::ast_matchers::internal::Matcher<Expr> ( &ignoringImplicit_Type0
)(internal::Matcher<Expr> const &InnerMatcher); inline
bool internal::matcher_ignoringImplicit0Matcher::matches( const
Expr &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
893 return InnerMatcher.matches(*Node.IgnoreImplicit(), Finder, Builder);
894}
895
896/// Matches expressions that match InnerMatcher after any implicit casts
897/// are stripped off.
898///
899/// Parentheses and explicit casts are not discarded.
900/// Given
901/// \code
902/// int arr[5];
903/// int a = 0;
904/// char b = 0;
905/// const int c = a;
906/// int *d = arr;
907/// long e = (long) 0l;
908/// \endcode
909/// The matchers
910/// \code
911/// varDecl(hasInitializer(ignoringImpCasts(integerLiteral())))
912/// varDecl(hasInitializer(ignoringImpCasts(declRefExpr())))
913/// \endcode
914/// would match the declarations for a, b, c, and d, but not e.
915/// While
916/// \code
917/// varDecl(hasInitializer(integerLiteral()))
918/// varDecl(hasInitializer(declRefExpr()))
919/// \endcode
920/// only match the declarations for a.
921AST_MATCHER_P(Expr, ignoringImpCasts,namespace internal { class matcher_ignoringImpCasts0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
Expr> { public: explicit matcher_ignoringImpCasts0Matcher(
internal::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const Expr &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<Expr> ignoringImpCasts
( internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_ignoringImpCasts0Matcher(InnerMatcher)); } typedef ::
clang::ast_matchers::internal::Matcher<Expr> ( &ignoringImpCasts_Type0
)(internal::Matcher<Expr> const &InnerMatcher); inline
bool internal::matcher_ignoringImpCasts0Matcher::matches( const
Expr &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
922 internal::Matcher<Expr>, InnerMatcher)namespace internal { class matcher_ignoringImpCasts0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
Expr> { public: explicit matcher_ignoringImpCasts0Matcher(
internal::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const Expr &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<Expr> ignoringImpCasts
( internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_ignoringImpCasts0Matcher(InnerMatcher)); } typedef ::
clang::ast_matchers::internal::Matcher<Expr> ( &ignoringImpCasts_Type0
)(internal::Matcher<Expr> const &InnerMatcher); inline
bool internal::matcher_ignoringImpCasts0Matcher::matches( const
Expr &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
923 return InnerMatcher.matches(*Node.IgnoreImpCasts(), Finder, Builder);
924}
925
926/// Matches expressions that match InnerMatcher after parentheses and
927/// casts are stripped off.
928///
929/// Implicit and non-C Style casts are also discarded.
930/// Given
931/// \code
932/// int a = 0;
933/// char b = (0);
934/// void* c = reinterpret_cast<char*>(0);
935/// char d = char(0);
936/// \endcode
937/// The matcher
938/// varDecl(hasInitializer(ignoringParenCasts(integerLiteral())))
939/// would match the declarations for a, b, c, and d.
940/// while
941/// varDecl(hasInitializer(integerLiteral()))
942/// only match the declaration for a.
943AST_MATCHER_P(Expr, ignoringParenCasts, internal::Matcher<Expr>, InnerMatcher)namespace internal { class matcher_ignoringParenCasts0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
Expr> { public: explicit matcher_ignoringParenCasts0Matcher
( internal::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const Expr &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<Expr> ignoringParenCasts
( internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_ignoringParenCasts0Matcher(InnerMatcher)); } typedef ::
clang::ast_matchers::internal::Matcher<Expr> ( &ignoringParenCasts_Type0
)(internal::Matcher<Expr> const &InnerMatcher); inline
bool internal::matcher_ignoringParenCasts0Matcher::matches( const
Expr &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
944 return InnerMatcher.matches(*Node.IgnoreParenCasts(), Finder, Builder);
945}
946
947/// Matches expressions that match InnerMatcher after implicit casts and
948/// parentheses are stripped off.
949///
950/// Explicit casts are not discarded.
951/// Given
952/// \code
953/// int arr[5];
954/// int a = 0;
955/// char b = (0);
956/// const int c = a;
957/// int *d = (arr);
958/// long e = ((long) 0l);
959/// \endcode
960/// The matchers
961/// varDecl(hasInitializer(ignoringParenImpCasts(integerLiteral())))
962/// varDecl(hasInitializer(ignoringParenImpCasts(declRefExpr())))
963/// would match the declarations for a, b, c, and d, but not e.
964/// while
965/// varDecl(hasInitializer(integerLiteral()))
966/// varDecl(hasInitializer(declRefExpr()))
967/// would only match the declaration for a.
968AST_MATCHER_P(Expr, ignoringParenImpCasts,namespace internal { class matcher_ignoringParenImpCasts0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
Expr> { public: explicit matcher_ignoringParenImpCasts0Matcher
( internal::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const Expr &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<Expr> ignoringParenImpCasts
( internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_ignoringParenImpCasts0Matcher(InnerMatcher)); } typedef
::clang::ast_matchers::internal::Matcher<Expr> ( &
ignoringParenImpCasts_Type0)(internal::Matcher<Expr> const
&InnerMatcher); inline bool internal::matcher_ignoringParenImpCasts0Matcher
::matches( const Expr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
969 internal::Matcher<Expr>, InnerMatcher)namespace internal { class matcher_ignoringParenImpCasts0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
Expr> { public: explicit matcher_ignoringParenImpCasts0Matcher
( internal::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const Expr &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<Expr> ignoringParenImpCasts
( internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_ignoringParenImpCasts0Matcher(InnerMatcher)); } typedef
::clang::ast_matchers::internal::Matcher<Expr> ( &
ignoringParenImpCasts_Type0)(internal::Matcher<Expr> const
&InnerMatcher); inline bool internal::matcher_ignoringParenImpCasts0Matcher
::matches( const Expr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
970 return InnerMatcher.matches(*Node.IgnoreParenImpCasts(), Finder, Builder);
971}
972
973/// Matches types that match InnerMatcher after any parens are stripped.
974///
975/// Given
976/// \code
977/// void (*fp)(void);
978/// \endcode
979/// The matcher
980/// \code
981/// varDecl(hasType(pointerType(pointee(ignoringParens(functionType())))))
982/// \endcode
983/// would match the declaration for fp.
984AST_MATCHER_P_OVERLOAD(QualType, ignoringParens, internal::Matcher<QualType>,namespace internal { class matcher_ignoringParens0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<QualType
> { public: explicit matcher_ignoringParens0Matcher( internal
::Matcher<QualType> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const QualType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<QualType> InnerMatcher; }; } inline
::clang::ast_matchers::internal::Matcher<QualType> ignoringParens
( internal::Matcher<QualType> const &InnerMatcher) {
return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_ignoringParens0Matcher(InnerMatcher)); } typedef ::
clang::ast_matchers::internal::Matcher<QualType> ( &
ignoringParens_Type0)(internal::Matcher<QualType> const
&InnerMatcher); inline bool internal::matcher_ignoringParens0Matcher
::matches( const QualType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
985 InnerMatcher, 0)namespace internal { class matcher_ignoringParens0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<QualType
> { public: explicit matcher_ignoringParens0Matcher( internal
::Matcher<QualType> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const QualType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<QualType> InnerMatcher; }; } inline
::clang::ast_matchers::internal::Matcher<QualType> ignoringParens
( internal::Matcher<QualType> const &InnerMatcher) {
return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_ignoringParens0Matcher(InnerMatcher)); } typedef ::
clang::ast_matchers::internal::Matcher<QualType> ( &
ignoringParens_Type0)(internal::Matcher<QualType> const
&InnerMatcher); inline bool internal::matcher_ignoringParens0Matcher
::matches( const QualType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
986 return InnerMatcher.matches(Node.IgnoreParens(), Finder, Builder);
987}
988
989/// Overload \c ignoringParens for \c Expr.
990///
991/// Given
992/// \code
993/// const char* str = ("my-string");
994/// \endcode
995/// The matcher
996/// \code
997/// implicitCastExpr(hasSourceExpression(ignoringParens(stringLiteral())))
998/// \endcode
999/// would match the implicit cast resulting from the assignment.
1000AST_MATCHER_P_OVERLOAD(Expr, ignoringParens, internal::Matcher<Expr>,namespace internal { class matcher_ignoringParens1Matcher : public
::clang::ast_matchers::internal::MatcherInterface<Expr>
{ public: explicit matcher_ignoringParens1Matcher( internal::
Matcher<Expr> const &AInnerMatcher) : InnerMatcher(
AInnerMatcher) {} bool matches(const Expr &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<Expr> ignoringParens(
internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_ignoringParens1Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<Expr> ( &ignoringParens_Type1
)(internal::Matcher<Expr> const &InnerMatcher); inline
bool internal::matcher_ignoringParens1Matcher::matches( const
Expr &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
1001 InnerMatcher, 1)namespace internal { class matcher_ignoringParens1Matcher : public
::clang::ast_matchers::internal::MatcherInterface<Expr>
{ public: explicit matcher_ignoringParens1Matcher( internal::
Matcher<Expr> const &AInnerMatcher) : InnerMatcher(
AInnerMatcher) {} bool matches(const Expr &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<Expr> ignoringParens(
internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_ignoringParens1Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<Expr> ( &ignoringParens_Type1
)(internal::Matcher<Expr> const &InnerMatcher); inline
bool internal::matcher_ignoringParens1Matcher::matches( const
Expr &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
1002 const Expr *E = Node.IgnoreParens();
1003 return InnerMatcher.matches(*E, Finder, Builder);
1004}
1005
1006/// Matches expressions that are instantiation-dependent even if it is
1007/// neither type- nor value-dependent.
1008///
1009/// In the following example, the expression sizeof(sizeof(T() + T()))
1010/// is instantiation-dependent (since it involves a template parameter T),
1011/// but is neither type- nor value-dependent, since the type of the inner
1012/// sizeof is known (std::size_t) and therefore the size of the outer
1013/// sizeof is known.
1014/// \code
1015/// template<typename T>
1016/// void f(T x, T y) { sizeof(sizeof(T() + T()); }
1017/// \endcode
1018/// expr(isInstantiationDependent()) matches sizeof(sizeof(T() + T())
1019AST_MATCHER(Expr, isInstantiationDependent)namespace internal { class matcher_isInstantiationDependentMatcher
: public ::clang::ast_matchers::internal::MatcherInterface<
Expr> { public: explicit matcher_isInstantiationDependentMatcher
() = default; bool matches(const Expr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<Expr> isInstantiationDependent
() { return ::clang::ast_matchers::internal::makeMatcher( new
internal::matcher_isInstantiationDependentMatcher()); } inline
bool internal::matcher_isInstantiationDependentMatcher::matches
( const Expr &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
1020 return Node.isInstantiationDependent();
1021}
1022
1023/// Matches expressions that are type-dependent because the template type
1024/// is not yet instantiated.
1025///
1026/// For example, the expressions "x" and "x + y" are type-dependent in
1027/// the following code, but "y" is not type-dependent:
1028/// \code
1029/// template<typename T>
1030/// void add(T x, int y) {
1031/// x + y;
1032/// }
1033/// \endcode
1034/// expr(isTypeDependent()) matches x + y
1035AST_MATCHER(Expr, isTypeDependent)namespace internal { class matcher_isTypeDependentMatcher : public
::clang::ast_matchers::internal::MatcherInterface<Expr>
{ public: explicit matcher_isTypeDependentMatcher() = default
; bool matches(const Expr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::Matcher<Expr> isTypeDependent() { return ::clang
::ast_matchers::internal::makeMatcher( new internal::matcher_isTypeDependentMatcher
()); } inline bool internal::matcher_isTypeDependentMatcher::
matches( const Expr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{ return Node.isTypeDependent(); }
1036
1037/// Matches expression that are value-dependent because they contain a
1038/// non-type template parameter.
1039///
1040/// For example, the array bound of "Chars" in the following example is
1041/// value-dependent.
1042/// \code
1043/// template<int Size> int f() { return Size; }
1044/// \endcode
1045/// expr(isValueDependent()) matches return Size
1046AST_MATCHER(Expr, isValueDependent)namespace internal { class matcher_isValueDependentMatcher : public
::clang::ast_matchers::internal::MatcherInterface<Expr>
{ public: explicit matcher_isValueDependentMatcher() = default
; bool matches(const Expr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::Matcher<Expr> isValueDependent() { return ::clang
::ast_matchers::internal::makeMatcher( new internal::matcher_isValueDependentMatcher
()); } inline bool internal::matcher_isValueDependentMatcher::
matches( const Expr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{ return Node.isValueDependent(); }
1047
1048/// Matches classTemplateSpecializations, templateSpecializationType and
1049/// functionDecl where the n'th TemplateArgument matches the given InnerMatcher.
1050///
1051/// Given
1052/// \code
1053/// template<typename T, typename U> class A {};
1054/// A<bool, int> b;
1055/// A<int, bool> c;
1056///
1057/// template<typename T> void f() {}
1058/// void func() { f<int>(); };
1059/// \endcode
1060/// classTemplateSpecializationDecl(hasTemplateArgument(
1061/// 1, refersToType(asString("int"))))
1062/// matches the specialization \c A<bool, int>
1063///
1064/// functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))
1065/// matches the specialization \c f<int>
1066AST_POLYMORPHIC_MATCHER_P2(namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasTemplateArgument0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasTemplateArgument0Matcher(unsigned
const &AN, internal::Matcher<TemplateArgument> const
&AInnerMatcher) : N(AN), InnerMatcher(AInnerMatcher) {} bool
matches(const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; internal::Matcher
<TemplateArgument> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasTemplateArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType, FunctionDecl>), unsigned, internal
::Matcher<TemplateArgument> > hasTemplateArgument(unsigned
const &N, internal::Matcher<TemplateArgument> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_hasTemplateArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType, FunctionDecl>), unsigned, internal
::Matcher<TemplateArgument> >(N, InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasTemplateArgument0Matcher, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>), unsigned, internal::Matcher<TemplateArgument
> > (&hasTemplateArgument_Type0)( unsigned const &
N, internal::Matcher<TemplateArgument> const &InnerMatcher
); template <typename NodeType, typename ParamT1, typename
ParamT2> bool internal::matcher_hasTemplateArgument0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
1067 hasTemplateArgument,namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasTemplateArgument0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasTemplateArgument0Matcher(unsigned
const &AN, internal::Matcher<TemplateArgument> const
&AInnerMatcher) : N(AN), InnerMatcher(AInnerMatcher) {} bool
matches(const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; internal::Matcher
<TemplateArgument> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasTemplateArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType, FunctionDecl>), unsigned, internal
::Matcher<TemplateArgument> > hasTemplateArgument(unsigned
const &N, internal::Matcher<TemplateArgument> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_hasTemplateArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType, FunctionDecl>), unsigned, internal
::Matcher<TemplateArgument> >(N, InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasTemplateArgument0Matcher, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>), unsigned, internal::Matcher<TemplateArgument
> > (&hasTemplateArgument_Type0)( unsigned const &
N, internal::Matcher<TemplateArgument> const &InnerMatcher
); template <typename NodeType, typename ParamT1, typename
ParamT2> bool internal::matcher_hasTemplateArgument0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
1068 AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasTemplateArgument0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasTemplateArgument0Matcher(unsigned
const &AN, internal::Matcher<TemplateArgument> const
&AInnerMatcher) : N(AN), InnerMatcher(AInnerMatcher) {} bool
matches(const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; internal::Matcher
<TemplateArgument> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasTemplateArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType, FunctionDecl>), unsigned, internal
::Matcher<TemplateArgument> > hasTemplateArgument(unsigned
const &N, internal::Matcher<TemplateArgument> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_hasTemplateArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType, FunctionDecl>), unsigned, internal
::Matcher<TemplateArgument> >(N, InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasTemplateArgument0Matcher, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>), unsigned, internal::Matcher<TemplateArgument
> > (&hasTemplateArgument_Type0)( unsigned const &
N, internal::Matcher<TemplateArgument> const &InnerMatcher
); template <typename NodeType, typename ParamT1, typename
ParamT2> bool internal::matcher_hasTemplateArgument0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
1069 TemplateSpecializationType,namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasTemplateArgument0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasTemplateArgument0Matcher(unsigned
const &AN, internal::Matcher<TemplateArgument> const
&AInnerMatcher) : N(AN), InnerMatcher(AInnerMatcher) {} bool
matches(const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; internal::Matcher
<TemplateArgument> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasTemplateArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType, FunctionDecl>), unsigned, internal
::Matcher<TemplateArgument> > hasTemplateArgument(unsigned
const &N, internal::Matcher<TemplateArgument> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_hasTemplateArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType, FunctionDecl>), unsigned, internal
::Matcher<TemplateArgument> >(N, InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasTemplateArgument0Matcher, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>), unsigned, internal::Matcher<TemplateArgument
> > (&hasTemplateArgument_Type0)( unsigned const &
N, internal::Matcher<TemplateArgument> const &InnerMatcher
); template <typename NodeType, typename ParamT1, typename
ParamT2> bool internal::matcher_hasTemplateArgument0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
1070 FunctionDecl),namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasTemplateArgument0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasTemplateArgument0Matcher(unsigned
const &AN, internal::Matcher<TemplateArgument> const
&AInnerMatcher) : N(AN), InnerMatcher(AInnerMatcher) {} bool
matches(const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; internal::Matcher
<TemplateArgument> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasTemplateArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType, FunctionDecl>), unsigned, internal
::Matcher<TemplateArgument> > hasTemplateArgument(unsigned
const &N, internal::Matcher<TemplateArgument> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_hasTemplateArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType, FunctionDecl>), unsigned, internal
::Matcher<TemplateArgument> >(N, InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasTemplateArgument0Matcher, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>), unsigned, internal::Matcher<TemplateArgument
> > (&hasTemplateArgument_Type0)( unsigned const &
N, internal::Matcher<TemplateArgument> const &InnerMatcher
); template <typename NodeType, typename ParamT1, typename
ParamT2> bool internal::matcher_hasTemplateArgument0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
1071 unsigned, N, internal::Matcher<TemplateArgument>, InnerMatcher)namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasTemplateArgument0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasTemplateArgument0Matcher(unsigned
const &AN, internal::Matcher<TemplateArgument> const
&AInnerMatcher) : N(AN), InnerMatcher(AInnerMatcher) {} bool
matches(const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; internal::Matcher
<TemplateArgument> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasTemplateArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType, FunctionDecl>), unsigned, internal
::Matcher<TemplateArgument> > hasTemplateArgument(unsigned
const &N, internal::Matcher<TemplateArgument> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_hasTemplateArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType, FunctionDecl>), unsigned, internal
::Matcher<TemplateArgument> >(N, InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasTemplateArgument0Matcher, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>), unsigned, internal::Matcher<TemplateArgument
> > (&hasTemplateArgument_Type0)( unsigned const &
N, internal::Matcher<TemplateArgument> const &InnerMatcher
); template <typename NodeType, typename ParamT1, typename
ParamT2> bool internal::matcher_hasTemplateArgument0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
1072 ArrayRef<TemplateArgument> List =
1073 internal::getTemplateSpecializationArgs(Node);
1074 if (List.size() <= N)
1075 return false;
1076 return InnerMatcher.matches(List[N], Finder, Builder);
1077}
1078
1079/// Matches if the number of template arguments equals \p N.
1080///
1081/// Given
1082/// \code
1083/// template<typename T> struct C {};
1084/// C<int> c;
1085/// \endcode
1086/// classTemplateSpecializationDecl(templateArgumentCountIs(1))
1087/// matches C<int>.
1088AST_POLYMORPHIC_MATCHER_P(namespace internal { template <typename NodeType, typename
ParamT> class matcher_templateArgumentCountIs0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_templateArgumentCountIs0Matcher
( unsigned const &AN) : N(AN) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; }; } inline ::
clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_templateArgumentCountIs0Matcher, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
>), unsigned> templateArgumentCountIs(unsigned const &
N) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_templateArgumentCountIs0Matcher, void(
::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType>), unsigned>(N); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_templateArgumentCountIs0Matcher, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
>), unsigned> (&templateArgumentCountIs_Type0)(unsigned
const &N); template <typename NodeType, typename ParamT
> bool internal:: matcher_templateArgumentCountIs0Matcher<
NodeType, ParamT>::matches( const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
1089 templateArgumentCountIs,namespace internal { template <typename NodeType, typename
ParamT> class matcher_templateArgumentCountIs0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_templateArgumentCountIs0Matcher
( unsigned const &AN) : N(AN) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; }; } inline ::
clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_templateArgumentCountIs0Matcher, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
>), unsigned> templateArgumentCountIs(unsigned const &
N) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_templateArgumentCountIs0Matcher, void(
::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType>), unsigned>(N); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_templateArgumentCountIs0Matcher, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
>), unsigned> (&templateArgumentCountIs_Type0)(unsigned
const &N); template <typename NodeType, typename ParamT
> bool internal:: matcher_templateArgumentCountIs0Matcher<
NodeType, ParamT>::matches( const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
1090 AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,namespace internal { template <typename NodeType, typename
ParamT> class matcher_templateArgumentCountIs0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_templateArgumentCountIs0Matcher
( unsigned const &AN) : N(AN) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; }; } inline ::
clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_templateArgumentCountIs0Matcher, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
>), unsigned> templateArgumentCountIs(unsigned const &
N) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_templateArgumentCountIs0Matcher, void(
::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType>), unsigned>(N); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_templateArgumentCountIs0Matcher, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
>), unsigned> (&templateArgumentCountIs_Type0)(unsigned
const &N); template <typename NodeType, typename ParamT
> bool internal:: matcher_templateArgumentCountIs0Matcher<
NodeType, ParamT>::matches( const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
1091 TemplateSpecializationType),namespace internal { template <typename NodeType, typename
ParamT> class matcher_templateArgumentCountIs0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_templateArgumentCountIs0Matcher
( unsigned const &AN) : N(AN) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; }; } inline ::
clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_templateArgumentCountIs0Matcher, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
>), unsigned> templateArgumentCountIs(unsigned const &
N) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_templateArgumentCountIs0Matcher, void(
::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType>), unsigned>(N); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_templateArgumentCountIs0Matcher, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
>), unsigned> (&templateArgumentCountIs_Type0)(unsigned
const &N); template <typename NodeType, typename ParamT
> bool internal:: matcher_templateArgumentCountIs0Matcher<
NodeType, ParamT>::matches( const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
1092 unsigned, N)namespace internal { template <typename NodeType, typename
ParamT> class matcher_templateArgumentCountIs0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_templateArgumentCountIs0Matcher
( unsigned const &AN) : N(AN) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; }; } inline ::
clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_templateArgumentCountIs0Matcher, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
>), unsigned> templateArgumentCountIs(unsigned const &
N) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_templateArgumentCountIs0Matcher, void(
::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType>), unsigned>(N); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_templateArgumentCountIs0Matcher, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
>), unsigned> (&templateArgumentCountIs_Type0)(unsigned
const &N); template <typename NodeType, typename ParamT
> bool internal:: matcher_templateArgumentCountIs0Matcher<
NodeType, ParamT>::matches( const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
{
1093 return internal::getTemplateSpecializationArgs(Node).size() == N;
1094}
1095
1096/// Matches a TemplateArgument that refers to a certain type.
1097///
1098/// Given
1099/// \code
1100/// struct X {};
1101/// template<typename T> struct A {};
1102/// A<X> a;
1103/// \endcode
1104/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
1105/// refersToType(class(hasName("X")))))
1106/// matches the specialization \c A<X>
1107AST_MATCHER_P(TemplateArgument, refersToType,namespace internal { class matcher_refersToType0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<TemplateArgument
> { public: explicit matcher_refersToType0Matcher( internal
::Matcher<QualType> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const TemplateArgument &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<QualType> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<TemplateArgument
> refersToType( internal::Matcher<QualType> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_refersToType0Matcher(InnerMatcher)); }
typedef ::clang::ast_matchers::internal::Matcher<TemplateArgument
> ( &refersToType_Type0)(internal::Matcher<QualType
> const &InnerMatcher); inline bool internal::matcher_refersToType0Matcher
::matches( const TemplateArgument &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
1108 internal::Matcher<QualType>, InnerMatcher)namespace internal { class matcher_refersToType0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<TemplateArgument
> { public: explicit matcher_refersToType0Matcher( internal
::Matcher<QualType> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const TemplateArgument &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<QualType> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<TemplateArgument
> refersToType( internal::Matcher<QualType> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_refersToType0Matcher(InnerMatcher)); }
typedef ::clang::ast_matchers::internal::Matcher<TemplateArgument
> ( &refersToType_Type0)(internal::Matcher<QualType
> const &InnerMatcher); inline bool internal::matcher_refersToType0Matcher
::matches( const TemplateArgument &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
1109 if (Node.getKind() != TemplateArgument::Type)
1110 return false;
1111 return InnerMatcher.matches(Node.getAsType(), Finder, Builder);
1112}
1113
1114/// Matches a TemplateArgument that refers to a certain template.
1115///
1116/// Given
1117/// \code
1118/// template<template <typename> class S> class X {};
1119/// template<typename T> class Y {};
1120/// X<Y> xi;
1121/// \endcode
1122/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
1123/// refersToTemplate(templateName())))
1124/// matches the specialization \c X<Y>
1125AST_MATCHER_P(TemplateArgument, refersToTemplate,namespace internal { class matcher_refersToTemplate0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
TemplateArgument> { public: explicit matcher_refersToTemplate0Matcher
( internal::Matcher<TemplateName> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const TemplateArgument
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<TemplateName
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<TemplateArgument> refersToTemplate( internal::
Matcher<TemplateName> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_refersToTemplate0Matcher(InnerMatcher)); } typedef ::
clang::ast_matchers::internal::Matcher<TemplateArgument>
( &refersToTemplate_Type0)(internal::Matcher<TemplateName
> const &InnerMatcher); inline bool internal::matcher_refersToTemplate0Matcher
::matches( const TemplateArgument &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
1126 internal::Matcher<TemplateName>, InnerMatcher)namespace internal { class matcher_refersToTemplate0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
TemplateArgument> { public: explicit matcher_refersToTemplate0Matcher
( internal::Matcher<TemplateName> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const TemplateArgument
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<TemplateName
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<TemplateArgument> refersToTemplate( internal::
Matcher<TemplateName> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_refersToTemplate0Matcher(InnerMatcher)); } typedef ::
clang::ast_matchers::internal::Matcher<TemplateArgument>
( &refersToTemplate_Type0)(internal::Matcher<TemplateName
> const &InnerMatcher); inline bool internal::matcher_refersToTemplate0Matcher
::matches( const TemplateArgument &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
1127 if (Node.getKind() != TemplateArgument::Template)
1128 return false;
1129 return InnerMatcher.matches(Node.getAsTemplate(), Finder, Builder);
1130}
1131
1132/// Matches a canonical TemplateArgument that refers to a certain
1133/// declaration.
1134///
1135/// Given
1136/// \code
1137/// struct B { int next; };
1138/// template<int(B::*next_ptr)> struct A {};
1139/// A<&B::next> a;
1140/// \endcode
1141/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
1142/// refersToDeclaration(fieldDecl(hasName("next")))))
1143/// matches the specialization \c A<&B::next> with \c fieldDecl(...) matching
1144/// \c B::next
1145AST_MATCHER_P(TemplateArgument, refersToDeclaration,namespace internal { class matcher_refersToDeclaration0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
TemplateArgument> { public: explicit matcher_refersToDeclaration0Matcher
( internal::Matcher<Decl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const TemplateArgument &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<Decl> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<TemplateArgument
> refersToDeclaration( internal::Matcher<Decl> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
makeMatcher( new internal::matcher_refersToDeclaration0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<TemplateArgument> ( &refersToDeclaration_Type0)(internal
::Matcher<Decl> const &InnerMatcher); inline bool internal
::matcher_refersToDeclaration0Matcher::matches( const TemplateArgument
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
1146 internal::Matcher<Decl>, InnerMatcher)namespace internal { class matcher_refersToDeclaration0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
TemplateArgument> { public: explicit matcher_refersToDeclaration0Matcher
( internal::Matcher<Decl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const TemplateArgument &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<Decl> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<TemplateArgument
> refersToDeclaration( internal::Matcher<Decl> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
makeMatcher( new internal::matcher_refersToDeclaration0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<TemplateArgument> ( &refersToDeclaration_Type0)(internal
::Matcher<Decl> const &InnerMatcher); inline bool internal
::matcher_refersToDeclaration0Matcher::matches( const TemplateArgument
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
1147 if (Node.getKind() == TemplateArgument::Declaration)
1148 return InnerMatcher.matches(*Node.getAsDecl(), Finder, Builder);
1149 return false;
1150}
1151
1152/// Matches a sugar TemplateArgument that refers to a certain expression.
1153///
1154/// Given
1155/// \code
1156/// struct B { int next; };
1157/// template<int(B::*next_ptr)> struct A {};
1158/// A<&B::next> a;
1159/// \endcode
1160/// templateSpecializationType(hasAnyTemplateArgument(
1161/// isExpr(hasDescendant(declRefExpr(to(fieldDecl(hasName("next"))))))))
1162/// matches the specialization \c A<&B::next> with \c fieldDecl(...) matching
1163/// \c B::next
1164AST_MATCHER_P(TemplateArgument, isExpr, internal::Matcher<Expr>, InnerMatcher)namespace internal { class matcher_isExpr0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<TemplateArgument
> { public: explicit matcher_isExpr0Matcher( internal::Matcher
<Expr> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const TemplateArgument &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<TemplateArgument> isExpr
( internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_isExpr0Matcher(InnerMatcher)); } typedef ::clang::ast_matchers
::internal::Matcher<TemplateArgument> ( &isExpr_Type0
)(internal::Matcher<Expr> const &InnerMatcher); inline
bool internal::matcher_isExpr0Matcher::matches( const TemplateArgument
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
1165 if (Node.getKind() == TemplateArgument::Expression)
1166 return InnerMatcher.matches(*Node.getAsExpr(), Finder, Builder);
1167 return false;
1168}
1169
1170/// Matches a TemplateArgument that is an integral value.
1171///
1172/// Given
1173/// \code
1174/// template<int T> struct C {};
1175/// C<42> c;
1176/// \endcode
1177/// classTemplateSpecializationDecl(
1178/// hasAnyTemplateArgument(isIntegral()))
1179/// matches the implicit instantiation of C in C<42>
1180/// with isIntegral() matching 42.
1181AST_MATCHER(TemplateArgument, isIntegral)namespace internal { class matcher_isIntegralMatcher : public
::clang::ast_matchers::internal::MatcherInterface<TemplateArgument
> { public: explicit matcher_isIntegralMatcher() = default
; bool matches(const TemplateArgument &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<TemplateArgument
> isIntegral() { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_isIntegralMatcher()); } inline bool internal
::matcher_isIntegralMatcher::matches( const TemplateArgument &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
1182 return Node.getKind() == TemplateArgument::Integral;
1183}
1184
1185/// Matches a TemplateArgument that refers to an integral type.
1186///
1187/// Given
1188/// \code
1189/// template<int T> struct C {};
1190/// C<42> c;
1191/// \endcode
1192/// classTemplateSpecializationDecl(
1193/// hasAnyTemplateArgument(refersToIntegralType(asString("int"))))
1194/// matches the implicit instantiation of C in C<42>.
1195AST_MATCHER_P(TemplateArgument, refersToIntegralType,namespace internal { class matcher_refersToIntegralType0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
TemplateArgument> { public: explicit matcher_refersToIntegralType0Matcher
( internal::Matcher<QualType> const &AInnerMatcher)
: InnerMatcher(AInnerMatcher) {} bool matches(const TemplateArgument
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<QualType
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<TemplateArgument> refersToIntegralType( internal
::Matcher<QualType> const &InnerMatcher) { return ::
clang::ast_matchers::internal::makeMatcher( new internal::matcher_refersToIntegralType0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<TemplateArgument> ( &refersToIntegralType_Type0)(internal
::Matcher<QualType> const &InnerMatcher); inline bool
internal::matcher_refersToIntegralType0Matcher::matches( const
TemplateArgument &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
1196 internal::Matcher<QualType>, InnerMatcher)namespace internal { class matcher_refersToIntegralType0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
TemplateArgument> { public: explicit matcher_refersToIntegralType0Matcher
( internal::Matcher<QualType> const &AInnerMatcher)
: InnerMatcher(AInnerMatcher) {} bool matches(const TemplateArgument
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<QualType
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<TemplateArgument> refersToIntegralType( internal
::Matcher<QualType> const &InnerMatcher) { return ::
clang::ast_matchers::internal::makeMatcher( new internal::matcher_refersToIntegralType0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<TemplateArgument> ( &refersToIntegralType_Type0)(internal
::Matcher<QualType> const &InnerMatcher); inline bool
internal::matcher_refersToIntegralType0Matcher::matches( const
TemplateArgument &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
1197 if (Node.getKind() != TemplateArgument::Integral)
1198 return false;
1199 return InnerMatcher.matches(Node.getIntegralType(), Finder, Builder);
1200}
1201
1202/// Matches a TemplateArgument of integral type with a given value.
1203///
1204/// Note that 'Value' is a string as the template argument's value is
1205/// an arbitrary precision integer. 'Value' must be euqal to the canonical
1206/// representation of that integral value in base 10.
1207///
1208/// Given
1209/// \code
1210/// template<int T> struct C {};
1211/// C<42> c;
1212/// \endcode
1213/// classTemplateSpecializationDecl(
1214/// hasAnyTemplateArgument(equalsIntegralValue("42")))
1215/// matches the implicit instantiation of C in C<42>.
1216AST_MATCHER_P(TemplateArgument, equalsIntegralValue,namespace internal { class matcher_equalsIntegralValue0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
TemplateArgument> { public: explicit matcher_equalsIntegralValue0Matcher
( std::string const &AValue) : Value(AValue) {} bool matches
(const TemplateArgument &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string Value; }; } inline
::clang::ast_matchers::internal::Matcher<TemplateArgument
> equalsIntegralValue( std::string const &Value) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_equalsIntegralValue0Matcher(Value)); } typedef ::clang
::ast_matchers::internal::Matcher<TemplateArgument> ( &
equalsIntegralValue_Type0)(std::string const &Value); inline
bool internal::matcher_equalsIntegralValue0Matcher::matches(
const TemplateArgument &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
1217 std::string, Value)namespace internal { class matcher_equalsIntegralValue0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
TemplateArgument> { public: explicit matcher_equalsIntegralValue0Matcher
( std::string const &AValue) : Value(AValue) {} bool matches
(const TemplateArgument &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string Value; }; } inline
::clang::ast_matchers::internal::Matcher<TemplateArgument
> equalsIntegralValue( std::string const &Value) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_equalsIntegralValue0Matcher(Value)); } typedef ::clang
::ast_matchers::internal::Matcher<TemplateArgument> ( &
equalsIntegralValue_Type0)(std::string const &Value); inline
bool internal::matcher_equalsIntegralValue0Matcher::matches(
const TemplateArgument &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
1218 if (Node.getKind() != TemplateArgument::Integral)
1219 return false;
1220 return toString(Node.getAsIntegral(), 10) == Value;
1221}
1222
1223/// Matches an Objective-C autorelease pool statement.
1224///
1225/// Given
1226/// \code
1227/// @autoreleasepool {
1228/// int x = 0;
1229/// }
1230/// \endcode
1231/// autoreleasePoolStmt(stmt()) matches the declaration of "x"
1232/// inside the autorelease pool.
1233extern const internal::VariadicDynCastAllOfMatcher<Stmt,
1234 ObjCAutoreleasePoolStmt> autoreleasePoolStmt;
1235
1236/// Matches any value declaration.
1237///
1238/// Example matches A, B, C and F
1239/// \code
1240/// enum X { A, B, C };
1241/// void F();
1242/// \endcode
1243extern const internal::VariadicDynCastAllOfMatcher<Decl, ValueDecl> valueDecl;
1244
1245/// Matches C++ constructor declarations.
1246///
1247/// Example matches Foo::Foo() and Foo::Foo(int)
1248/// \code
1249/// class Foo {
1250/// public:
1251/// Foo();
1252/// Foo(int);
1253/// int DoSomething();
1254/// };
1255/// \endcode
1256extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXConstructorDecl>
1257 cxxConstructorDecl;
1258
1259/// Matches explicit C++ destructor declarations.
1260///
1261/// Example matches Foo::~Foo()
1262/// \code
1263/// class Foo {
1264/// public:
1265/// virtual ~Foo();
1266/// };
1267/// \endcode
1268extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXDestructorDecl>
1269 cxxDestructorDecl;
1270
1271/// Matches enum declarations.
1272///
1273/// Example matches X
1274/// \code
1275/// enum X {
1276/// A, B, C
1277/// };
1278/// \endcode
1279extern const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl;
1280
1281/// Matches enum constants.
1282///
1283/// Example matches A, B, C
1284/// \code
1285/// enum X {
1286/// A, B, C
1287/// };
1288/// \endcode
1289extern const internal::VariadicDynCastAllOfMatcher<Decl, EnumConstantDecl>
1290 enumConstantDecl;
1291
1292/// Matches tag declarations.
1293///
1294/// Example matches X, Z, U, S, E
1295/// \code
1296/// class X;
1297/// template<class T> class Z {};
1298/// struct S {};
1299/// union U {};
1300/// enum E {
1301/// A, B, C
1302/// };
1303/// \endcode
1304extern const internal::VariadicDynCastAllOfMatcher<Decl, TagDecl> tagDecl;
1305
1306/// Matches method declarations.
1307///
1308/// Example matches y
1309/// \code
1310/// class X { void y(); };
1311/// \endcode
1312extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl>
1313 cxxMethodDecl;
1314
1315/// Matches conversion operator declarations.
1316///
1317/// Example matches the operator.
1318/// \code
1319/// class X { operator int() const; };
1320/// \endcode
1321extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl>
1322 cxxConversionDecl;
1323
1324/// Matches user-defined and implicitly generated deduction guide.
1325///
1326/// Example matches the deduction guide.
1327/// \code
1328/// template<typename T>
1329/// class X { X(int) };
1330/// X(int) -> X<int>;
1331/// \endcode
1332extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXDeductionGuideDecl>
1333 cxxDeductionGuideDecl;
1334
1335/// Matches variable declarations.
1336///
1337/// Note: this does not match declarations of member variables, which are
1338/// "field" declarations in Clang parlance.
1339///
1340/// Example matches a
1341/// \code
1342/// int a;
1343/// \endcode
1344extern const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> varDecl;
1345
1346/// Matches field declarations.
1347///
1348/// Given
1349/// \code
1350/// class X { int m; };
1351/// \endcode
1352/// fieldDecl()
1353/// matches 'm'.
1354extern const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> fieldDecl;
1355
1356/// Matches indirect field declarations.
1357///
1358/// Given
1359/// \code
1360/// struct X { struct { int a; }; };
1361/// \endcode
1362/// indirectFieldDecl()
1363/// matches 'a'.
1364extern const internal::VariadicDynCastAllOfMatcher<Decl, IndirectFieldDecl>
1365 indirectFieldDecl;
1366
1367/// Matches function declarations.
1368///
1369/// Example matches f
1370/// \code
1371/// void f();
1372/// \endcode
1373extern const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl>
1374 functionDecl;
1375
1376/// Matches C++ function template declarations.
1377///
1378/// Example matches f
1379/// \code
1380/// template<class T> void f(T t) {}
1381/// \endcode
1382extern const internal::VariadicDynCastAllOfMatcher<Decl, FunctionTemplateDecl>
1383 functionTemplateDecl;
1384
1385/// Matches friend declarations.
1386///
1387/// Given
1388/// \code
1389/// class X { friend void foo(); };
1390/// \endcode
1391/// friendDecl()
1392/// matches 'friend void foo()'.
1393extern const internal::VariadicDynCastAllOfMatcher<Decl, FriendDecl> friendDecl;
1394
1395/// Matches statements.
1396///
1397/// Given
1398/// \code
1399/// { ++a; }
1400/// \endcode
1401/// stmt()
1402/// matches both the compound statement '{ ++a; }' and '++a'.
1403extern const internal::VariadicAllOfMatcher<Stmt> stmt;
1404
1405/// Matches declaration statements.
1406///
1407/// Given
1408/// \code
1409/// int a;
1410/// \endcode
1411/// declStmt()
1412/// matches 'int a'.
1413extern const internal::VariadicDynCastAllOfMatcher<Stmt, DeclStmt> declStmt;
1414
1415/// Matches member expressions.
1416///
1417/// Given
1418/// \code
1419/// class Y {
1420/// void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; }
1421/// int a; static int b;
1422/// };
1423/// \endcode
1424/// memberExpr()
1425/// matches this->x, x, y.x, a, this->b
1426extern const internal::VariadicDynCastAllOfMatcher<Stmt, MemberExpr> memberExpr;
1427
1428/// Matches unresolved member expressions.
1429///
1430/// Given
1431/// \code
1432/// struct X {
1433/// template <class T> void f();
1434/// void g();
1435/// };
1436/// template <class T> void h() { X x; x.f<T>(); x.g(); }
1437/// \endcode
1438/// unresolvedMemberExpr()
1439/// matches x.f<T>
1440extern const internal::VariadicDynCastAllOfMatcher<Stmt, UnresolvedMemberExpr>
1441 unresolvedMemberExpr;
1442
1443/// Matches member expressions where the actual member referenced could not be
1444/// resolved because the base expression or the member name was dependent.
1445///
1446/// Given
1447/// \code
1448/// template <class T> void f() { T t; t.g(); }
1449/// \endcode
1450/// cxxDependentScopeMemberExpr()
1451/// matches t.g
1452extern const internal::VariadicDynCastAllOfMatcher<Stmt,
1453 CXXDependentScopeMemberExpr>
1454 cxxDependentScopeMemberExpr;
1455
1456/// Matches call expressions.
1457///
1458/// Example matches x.y() and y()
1459/// \code
1460/// X x;
1461/// x.y();
1462/// y();
1463/// \endcode
1464extern const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> callExpr;
1465
1466/// Matches call expressions which were resolved using ADL.
1467///
1468/// Example matches y(x) but not y(42) or NS::y(x).
1469/// \code
1470/// namespace NS {
1471/// struct X {};
1472/// void y(X);
1473/// }
1474///
1475/// void y(...);
1476///
1477/// void test() {
1478/// NS::X x;
1479/// y(x); // Matches
1480/// NS::y(x); // Doesn't match
1481/// y(42); // Doesn't match
1482/// using NS::y;
1483/// y(x); // Found by both unqualified lookup and ADL, doesn't match
1484// }
1485/// \endcode
1486AST_MATCHER(CallExpr, usesADL)namespace internal { class matcher_usesADLMatcher : public ::
clang::ast_matchers::internal::MatcherInterface<CallExpr>
{ public: explicit matcher_usesADLMatcher() = default; bool matches
(const CallExpr &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::Matcher<CallExpr> usesADL() { return ::clang::
ast_matchers::internal::makeMatcher( new internal::matcher_usesADLMatcher
()); } inline bool internal::matcher_usesADLMatcher::matches(
const CallExpr &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{ return Node.usesADL(); }
1487
1488/// Matches lambda expressions.
1489///
1490/// Example matches [&](){return 5;}
1491/// \code
1492/// [&](){return 5;}
1493/// \endcode
1494extern const internal::VariadicDynCastAllOfMatcher<Stmt, LambdaExpr> lambdaExpr;
1495
1496/// Matches member call expressions.
1497///
1498/// Example matches x.y()
1499/// \code
1500/// X x;
1501/// x.y();
1502/// \endcode
1503extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXMemberCallExpr>
1504 cxxMemberCallExpr;
1505
1506/// Matches ObjectiveC Message invocation expressions.
1507///
1508/// The innermost message send invokes the "alloc" class method on the
1509/// NSString class, while the outermost message send invokes the
1510/// "initWithString" instance method on the object returned from
1511/// NSString's "alloc". This matcher should match both message sends.
1512/// \code
1513/// [[NSString alloc] initWithString:@"Hello"]
1514/// \endcode
1515extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCMessageExpr>
1516 objcMessageExpr;
1517
1518/// Matches Objective-C interface declarations.
1519///
1520/// Example matches Foo
1521/// \code
1522/// @interface Foo
1523/// @end
1524/// \endcode
1525extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCInterfaceDecl>
1526 objcInterfaceDecl;
1527
1528/// Matches Objective-C implementation declarations.
1529///
1530/// Example matches Foo
1531/// \code
1532/// @implementation Foo
1533/// @end
1534/// \endcode
1535extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCImplementationDecl>
1536 objcImplementationDecl;
1537
1538/// Matches Objective-C protocol declarations.
1539///
1540/// Example matches FooDelegate
1541/// \code
1542/// @protocol FooDelegate
1543/// @end
1544/// \endcode
1545extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCProtocolDecl>
1546 objcProtocolDecl;
1547
1548/// Matches Objective-C category declarations.
1549///
1550/// Example matches Foo (Additions)
1551/// \code
1552/// @interface Foo (Additions)
1553/// @end
1554/// \endcode
1555extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryDecl>
1556 objcCategoryDecl;
1557
1558/// Matches Objective-C category definitions.
1559///
1560/// Example matches Foo (Additions)
1561/// \code
1562/// @implementation Foo (Additions)
1563/// @end
1564/// \endcode
1565extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryImplDecl>
1566 objcCategoryImplDecl;
1567
1568/// Matches Objective-C method declarations.
1569///
1570/// Example matches both declaration and definition of -[Foo method]
1571/// \code
1572/// @interface Foo
1573/// - (void)method;
1574/// @end
1575///
1576/// @implementation Foo
1577/// - (void)method {}
1578/// @end
1579/// \endcode
1580extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCMethodDecl>
1581 objcMethodDecl;
1582
1583/// Matches block declarations.
1584///
1585/// Example matches the declaration of the nameless block printing an input
1586/// integer.
1587///
1588/// \code
1589/// myFunc(^(int p) {
1590/// printf("%d", p);
1591/// })
1592/// \endcode
1593extern const internal::VariadicDynCastAllOfMatcher<Decl, BlockDecl>
1594 blockDecl;
1595
1596/// Matches Objective-C instance variable declarations.
1597///
1598/// Example matches _enabled
1599/// \code
1600/// @implementation Foo {
1601/// BOOL _enabled;
1602/// }
1603/// @end
1604/// \endcode
1605extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCIvarDecl>
1606 objcIvarDecl;
1607
1608/// Matches Objective-C property declarations.
1609///
1610/// Example matches enabled
1611/// \code
1612/// @interface Foo
1613/// @property BOOL enabled;
1614/// @end
1615/// \endcode
1616extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCPropertyDecl>
1617 objcPropertyDecl;
1618
1619/// Matches Objective-C \@throw statements.
1620///
1621/// Example matches \@throw
1622/// \code
1623/// @throw obj;
1624/// \endcode
1625extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtThrowStmt>
1626 objcThrowStmt;
1627
1628/// Matches Objective-C @try statements.
1629///
1630/// Example matches @try
1631/// \code
1632/// @try {}
1633/// @catch (...) {}
1634/// \endcode
1635extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtTryStmt>
1636 objcTryStmt;
1637
1638/// Matches Objective-C @catch statements.
1639///
1640/// Example matches @catch
1641/// \code
1642/// @try {}
1643/// @catch (...) {}
1644/// \endcode
1645extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtCatchStmt>
1646 objcCatchStmt;
1647
1648/// Matches Objective-C @finally statements.
1649///
1650/// Example matches @finally
1651/// \code
1652/// @try {}
1653/// @finally {}
1654/// \endcode
1655extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtFinallyStmt>
1656 objcFinallyStmt;
1657
1658/// Matches expressions that introduce cleanups to be run at the end
1659/// of the sub-expression's evaluation.
1660///
1661/// Example matches std::string()
1662/// \code
1663/// const std::string str = std::string();
1664/// \endcode
1665extern const internal::VariadicDynCastAllOfMatcher<Stmt, ExprWithCleanups>
1666 exprWithCleanups;
1667
1668/// Matches init list expressions.
1669///
1670/// Given
1671/// \code
1672/// int a[] = { 1, 2 };
1673/// struct B { int x, y; };
1674/// B b = { 5, 6 };
1675/// \endcode
1676/// initListExpr()
1677/// matches "{ 1, 2 }" and "{ 5, 6 }"
1678extern const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr>
1679 initListExpr;
1680
1681/// Matches the syntactic form of init list expressions
1682/// (if expression have it).
1683AST_MATCHER_P(InitListExpr, hasSyntacticForm,namespace internal { class matcher_hasSyntacticForm0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
InitListExpr> { public: explicit matcher_hasSyntacticForm0Matcher
( internal::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const InitListExpr &Node,
::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
override; private: internal::Matcher<Expr> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<InitListExpr
> hasSyntacticForm( internal::Matcher<Expr> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_hasSyntacticForm0Matcher(InnerMatcher
)); } typedef ::clang::ast_matchers::internal::Matcher<InitListExpr
> ( &hasSyntacticForm_Type0)(internal::Matcher<Expr
> const &InnerMatcher); inline bool internal::matcher_hasSyntacticForm0Matcher
::matches( const InitListExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
1684 internal::Matcher<Expr>, InnerMatcher)namespace internal { class matcher_hasSyntacticForm0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
InitListExpr> { public: explicit matcher_hasSyntacticForm0Matcher
( internal::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const InitListExpr &Node,
::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
override; private: internal::Matcher<Expr> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<InitListExpr
> hasSyntacticForm( internal::Matcher<Expr> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_hasSyntacticForm0Matcher(InnerMatcher
)); } typedef ::clang::ast_matchers::internal::Matcher<InitListExpr
> ( &hasSyntacticForm_Type0)(internal::Matcher<Expr
> const &InnerMatcher); inline bool internal::matcher_hasSyntacticForm0Matcher
::matches( const InitListExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
1685 const Expr *SyntForm = Node.getSyntacticForm();
1686 return (SyntForm != nullptr &&
1687 InnerMatcher.matches(*SyntForm, Finder, Builder));
1688}
1689
1690/// Matches C++ initializer list expressions.
1691///
1692/// Given
1693/// \code
1694/// std::vector<int> a({ 1, 2, 3 });
1695/// std::vector<int> b = { 4, 5 };
1696/// int c[] = { 6, 7 };
1697/// std::pair<int, int> d = { 8, 9 };
1698/// \endcode
1699/// cxxStdInitializerListExpr()
1700/// matches "{ 1, 2, 3 }" and "{ 4, 5 }"
1701extern const internal::VariadicDynCastAllOfMatcher<Stmt,
1702 CXXStdInitializerListExpr>
1703 cxxStdInitializerListExpr;
1704
1705/// Matches implicit initializers of init list expressions.
1706///
1707/// Given
1708/// \code
1709/// point ptarray[10] = { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 };
1710/// \endcode
1711/// implicitValueInitExpr()
1712/// matches "[0].y" (implicitly)
1713extern const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitValueInitExpr>
1714 implicitValueInitExpr;
1715
1716/// Matches paren list expressions.
1717/// ParenListExprs don't have a predefined type and are used for late parsing.
1718/// In the final AST, they can be met in template declarations.
1719///
1720/// Given
1721/// \code
1722/// template<typename T> class X {
1723/// void f() {
1724/// X x(*this);
1725/// int a = 0, b = 1; int i = (a, b);
1726/// }
1727/// };
1728/// \endcode
1729/// parenListExpr() matches "*this" but NOT matches (a, b) because (a, b)
1730/// has a predefined type and is a ParenExpr, not a ParenListExpr.
1731extern const internal::VariadicDynCastAllOfMatcher<Stmt, ParenListExpr>
1732 parenListExpr;
1733
1734/// Matches substitutions of non-type template parameters.
1735///
1736/// Given
1737/// \code
1738/// template <int N>
1739/// struct A { static const int n = N; };
1740/// struct B : public A<42> {};
1741/// \endcode
1742/// substNonTypeTemplateParmExpr()
1743/// matches "N" in the right-hand side of "static const int n = N;"
1744extern const internal::VariadicDynCastAllOfMatcher<Stmt,
1745 SubstNonTypeTemplateParmExpr>
1746 substNonTypeTemplateParmExpr;
1747
1748/// Matches using declarations.
1749///
1750/// Given
1751/// \code
1752/// namespace X { int x; }
1753/// using X::x;
1754/// \endcode
1755/// usingDecl()
1756/// matches \code using X::x \endcode
1757extern const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl;
1758
1759/// Matches using-enum declarations.
1760///
1761/// Given
1762/// \code
1763/// namespace X { enum x {...}; }
1764/// using enum X::x;
1765/// \endcode
1766/// usingEnumDecl()
1767/// matches \code using enum X::x \endcode
1768extern const internal::VariadicDynCastAllOfMatcher<Decl, UsingEnumDecl>
1769 usingEnumDecl;
1770
1771/// Matches using namespace declarations.
1772///
1773/// Given
1774/// \code
1775/// namespace X { int x; }
1776/// using namespace X;
1777/// \endcode
1778/// usingDirectiveDecl()
1779/// matches \code using namespace X \endcode
1780extern const internal::VariadicDynCastAllOfMatcher<Decl, UsingDirectiveDecl>
1781 usingDirectiveDecl;
1782
1783/// Matches reference to a name that can be looked up during parsing
1784/// but could not be resolved to a specific declaration.
1785///
1786/// Given
1787/// \code
1788/// template<typename T>
1789/// T foo() { T a; return a; }
1790/// template<typename T>
1791/// void bar() {
1792/// foo<T>();
1793/// }
1794/// \endcode
1795/// unresolvedLookupExpr()
1796/// matches \code foo<T>() \endcode
1797extern const internal::VariadicDynCastAllOfMatcher<Stmt, UnresolvedLookupExpr>
1798 unresolvedLookupExpr;
1799
1800/// Matches unresolved using value declarations.
1801///
1802/// Given
1803/// \code
1804/// template<typename X>
1805/// class C : private X {
1806/// using X::x;
1807/// };
1808/// \endcode
1809/// unresolvedUsingValueDecl()
1810/// matches \code using X::x \endcode
1811extern const internal::VariadicDynCastAllOfMatcher<Decl,
1812 UnresolvedUsingValueDecl>
1813 unresolvedUsingValueDecl;
1814
1815/// Matches unresolved using value declarations that involve the
1816/// typename.
1817///
1818/// Given
1819/// \code
1820/// template <typename T>
1821/// struct Base { typedef T Foo; };
1822///
1823/// template<typename T>
1824/// struct S : private Base<T> {
1825/// using typename Base<T>::Foo;
1826/// };
1827/// \endcode
1828/// unresolvedUsingTypenameDecl()
1829/// matches \code using Base<T>::Foo \endcode
1830extern const internal::VariadicDynCastAllOfMatcher<Decl,
1831 UnresolvedUsingTypenameDecl>
1832 unresolvedUsingTypenameDecl;
1833
1834/// Matches a constant expression wrapper.
1835///
1836/// Example matches the constant in the case statement:
1837/// (matcher = constantExpr())
1838/// \code
1839/// switch (a) {
1840/// case 37: break;
1841/// }
1842/// \endcode
1843extern const internal::VariadicDynCastAllOfMatcher<Stmt, ConstantExpr>
1844 constantExpr;
1845
1846/// Matches parentheses used in expressions.
1847///
1848/// Example matches (foo() + 1)
1849/// \code
1850/// int foo() { return 1; }
1851/// int a = (foo() + 1);
1852/// \endcode
1853extern const internal::VariadicDynCastAllOfMatcher<Stmt, ParenExpr> parenExpr;
1854
1855/// Matches constructor call expressions (including implicit ones).
1856///
1857/// Example matches string(ptr, n) and ptr within arguments of f
1858/// (matcher = cxxConstructExpr())
1859/// \code
1860/// void f(const string &a, const string &b);
1861/// char *ptr;
1862/// int n;
1863/// f(string(ptr, n), ptr);
1864/// \endcode
1865extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstructExpr>
1866 cxxConstructExpr;
1867
1868/// Matches unresolved constructor call expressions.
1869///
1870/// Example matches T(t) in return statement of f
1871/// (matcher = cxxUnresolvedConstructExpr())
1872/// \code
1873/// template <typename T>
1874/// void f(const T& t) { return T(t); }
1875/// \endcode
1876extern const internal::VariadicDynCastAllOfMatcher<Stmt,
1877 CXXUnresolvedConstructExpr>
1878 cxxUnresolvedConstructExpr;
1879
1880/// Matches implicit and explicit this expressions.
1881///
1882/// Example matches the implicit this expression in "return i".
1883/// (matcher = cxxThisExpr())
1884/// \code
1885/// struct foo {
1886/// int i;
1887/// int f() { return i; }
1888/// };
1889/// \endcode
1890extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThisExpr>
1891 cxxThisExpr;
1892
1893/// Matches nodes where temporaries are created.
1894///
1895/// Example matches FunctionTakesString(GetStringByValue())
1896/// (matcher = cxxBindTemporaryExpr())
1897/// \code
1898/// FunctionTakesString(GetStringByValue());
1899/// FunctionTakesStringByPointer(GetStringPointer());
1900/// \endcode
1901extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBindTemporaryExpr>
1902 cxxBindTemporaryExpr;
1903
1904/// Matches nodes where temporaries are materialized.
1905///
1906/// Example: Given
1907/// \code
1908/// struct T {void func();};
1909/// T f();
1910/// void g(T);
1911/// \endcode
1912/// materializeTemporaryExpr() matches 'f()' in these statements
1913/// \code
1914/// T u(f());
1915/// g(f());
1916/// f().func();
1917/// \endcode
1918/// but does not match
1919/// \code
1920/// f();
1921/// \endcode
1922extern const internal::VariadicDynCastAllOfMatcher<Stmt,
1923 MaterializeTemporaryExpr>
1924 materializeTemporaryExpr;
1925
1926/// Matches new expressions.
1927///
1928/// Given
1929/// \code
1930/// new X;
1931/// \endcode
1932/// cxxNewExpr()
1933/// matches 'new X'.
1934extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> cxxNewExpr;
1935
1936/// Matches delete expressions.
1937///
1938/// Given
1939/// \code
1940/// delete X;
1941/// \endcode
1942/// cxxDeleteExpr()
1943/// matches 'delete X'.
1944extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDeleteExpr>
1945 cxxDeleteExpr;
1946
1947/// Matches noexcept expressions.
1948///
1949/// Given
1950/// \code
1951/// bool a() noexcept;
1952/// bool b() noexcept(true);
1953/// bool c() noexcept(false);
1954/// bool d() noexcept(noexcept(a()));
1955/// bool e = noexcept(b()) || noexcept(c());
1956/// \endcode
1957/// cxxNoexceptExpr()
1958/// matches `noexcept(a())`, `noexcept(b())` and `noexcept(c())`.
1959/// doesn't match the noexcept specifier in the declarations a, b, c or d.
1960extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNoexceptExpr>
1961 cxxNoexceptExpr;
1962
1963/// Matches array subscript expressions.
1964///
1965/// Given
1966/// \code
1967/// int i = a[1];
1968/// \endcode
1969/// arraySubscriptExpr()
1970/// matches "a[1]"
1971extern const internal::VariadicDynCastAllOfMatcher<Stmt, ArraySubscriptExpr>
1972 arraySubscriptExpr;
1973
1974/// Matches the value of a default argument at the call site.
1975///
1976/// Example matches the CXXDefaultArgExpr placeholder inserted for the
1977/// default value of the second parameter in the call expression f(42)
1978/// (matcher = cxxDefaultArgExpr())
1979/// \code
1980/// void f(int x, int y = 0);
1981/// f(42);
1982/// \endcode
1983extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDefaultArgExpr>
1984 cxxDefaultArgExpr;
1985
1986/// Matches overloaded operator calls.
1987///
1988/// Note that if an operator isn't overloaded, it won't match. Instead, use
1989/// binaryOperator matcher.
1990/// Currently it does not match operators such as new delete.
1991/// FIXME: figure out why these do not match?
1992///
1993/// Example matches both operator<<((o << b), c) and operator<<(o, b)
1994/// (matcher = cxxOperatorCallExpr())
1995/// \code
1996/// ostream &operator<< (ostream &out, int i) { };
1997/// ostream &o; int b = 1, c = 1;
1998/// o << b << c;
1999/// \endcode
2000/// See also the binaryOperation() matcher for more-general matching of binary
2001/// uses of this AST node.
2002extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXOperatorCallExpr>
2003 cxxOperatorCallExpr;
2004
2005/// Matches rewritten binary operators
2006///
2007/// Example matches use of "<":
2008/// \code
2009/// #include <compare>
2010/// struct HasSpaceshipMem {
2011/// int a;
2012/// constexpr auto operator<=>(const HasSpaceshipMem&) const = default;
2013/// };
2014/// void compare() {
2015/// HasSpaceshipMem hs1, hs2;
2016/// if (hs1 < hs2)
2017/// return;
2018/// }
2019/// \endcode
2020/// See also the binaryOperation() matcher for more-general matching
2021/// of this AST node.
2022extern const internal::VariadicDynCastAllOfMatcher<Stmt,
2023 CXXRewrittenBinaryOperator>
2024 cxxRewrittenBinaryOperator;
2025
2026/// Matches expressions.
2027///
2028/// Example matches x()
2029/// \code
2030/// void f() { x(); }
2031/// \endcode
2032extern const internal::VariadicDynCastAllOfMatcher<Stmt, Expr> expr;
2033
2034/// Matches expressions that refer to declarations.
2035///
2036/// Example matches x in if (x)
2037/// \code
2038/// bool x;
2039/// if (x) {}
2040/// \endcode
2041extern const internal::VariadicDynCastAllOfMatcher<Stmt, DeclRefExpr>
2042 declRefExpr;
2043
2044/// Matches a reference to an ObjCIvar.
2045///
2046/// Example: matches "a" in "init" method:
2047/// \code
2048/// @implementation A {
2049/// NSString *a;
2050/// }
2051/// - (void) init {
2052/// a = @"hello";
2053/// }
2054/// \endcode
2055extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCIvarRefExpr>
2056 objcIvarRefExpr;
2057
2058/// Matches a reference to a block.
2059///
2060/// Example: matches "^{}":
2061/// \code
2062/// void f() { ^{}(); }
2063/// \endcode
2064extern const internal::VariadicDynCastAllOfMatcher<Stmt, BlockExpr> blockExpr;
2065
2066/// Matches if statements.
2067///
2068/// Example matches 'if (x) {}'
2069/// \code
2070/// if (x) {}
2071/// \endcode
2072extern const internal::VariadicDynCastAllOfMatcher<Stmt, IfStmt> ifStmt;
2073
2074/// Matches for statements.
2075///
2076/// Example matches 'for (;;) {}'
2077/// \code
2078/// for (;;) {}
2079/// int i[] = {1, 2, 3}; for (auto a : i);
2080/// \endcode
2081extern const internal::VariadicDynCastAllOfMatcher<Stmt, ForStmt> forStmt;
2082
2083/// Matches the increment statement of a for loop.
2084///
2085/// Example:
2086/// forStmt(hasIncrement(unaryOperator(hasOperatorName("++"))))
2087/// matches '++x' in
2088/// \code
2089/// for (x; x < N; ++x) { }
2090/// \endcode
2091AST_MATCHER_P(ForStmt, hasIncrement, internal::Matcher<Stmt>,namespace internal { class matcher_hasIncrement0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<ForStmt
> { public: explicit matcher_hasIncrement0Matcher( internal
::Matcher<Stmt> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const ForStmt &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Stmt> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<ForStmt> hasIncrement
( internal::Matcher<Stmt> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasIncrement0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<ForStmt> ( &hasIncrement_Type0
)(internal::Matcher<Stmt> const &InnerMatcher); inline
bool internal::matcher_hasIncrement0Matcher::matches( const ForStmt
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
2092 InnerMatcher)namespace internal { class matcher_hasIncrement0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<ForStmt
> { public: explicit matcher_hasIncrement0Matcher( internal
::Matcher<Stmt> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const ForStmt &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Stmt> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<ForStmt> hasIncrement
( internal::Matcher<Stmt> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasIncrement0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<ForStmt> ( &hasIncrement_Type0
)(internal::Matcher<Stmt> const &InnerMatcher); inline
bool internal::matcher_hasIncrement0Matcher::matches( const ForStmt
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
2093 const Stmt *const Increment = Node.getInc();
2094 return (Increment != nullptr &&
2095 InnerMatcher.matches(*Increment, Finder, Builder));
2096}
2097
2098/// Matches the initialization statement of a for loop.
2099///
2100/// Example:
2101/// forStmt(hasLoopInit(declStmt()))
2102/// matches 'int x = 0' in
2103/// \code
2104/// for (int x = 0; x < N; ++x) { }
2105/// \endcode
2106AST_MATCHER_P(ForStmt, hasLoopInit, internal::Matcher<Stmt>,namespace internal { class matcher_hasLoopInit0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<ForStmt
> { public: explicit matcher_hasLoopInit0Matcher( internal
::Matcher<Stmt> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const ForStmt &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Stmt> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<ForStmt> hasLoopInit(
internal::Matcher<Stmt> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasLoopInit0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<ForStmt> ( &hasLoopInit_Type0
)(internal::Matcher<Stmt> const &InnerMatcher); inline
bool internal::matcher_hasLoopInit0Matcher::matches( const ForStmt
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
2107 InnerMatcher)namespace internal { class matcher_hasLoopInit0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<ForStmt
> { public: explicit matcher_hasLoopInit0Matcher( internal
::Matcher<Stmt> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const ForStmt &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Stmt> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<ForStmt> hasLoopInit(
internal::Matcher<Stmt> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasLoopInit0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<ForStmt> ( &hasLoopInit_Type0
)(internal::Matcher<Stmt> const &InnerMatcher); inline
bool internal::matcher_hasLoopInit0Matcher::matches( const ForStmt
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
2108 const Stmt *const Init = Node.getInit();
2109 return (Init != nullptr && InnerMatcher.matches(*Init, Finder, Builder));
2110}
2111
2112/// Matches range-based for statements.
2113///
2114/// cxxForRangeStmt() matches 'for (auto a : i)'
2115/// \code
2116/// int i[] = {1, 2, 3}; for (auto a : i);
2117/// for(int j = 0; j < 5; ++j);
2118/// \endcode
2119extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXForRangeStmt>
2120 cxxForRangeStmt;
2121
2122/// Matches the initialization statement of a for loop.
2123///
2124/// Example:
2125/// forStmt(hasLoopVariable(anything()))
2126/// matches 'int x' in
2127/// \code
2128/// for (int x : a) { }
2129/// \endcode
2130AST_MATCHER_P(CXXForRangeStmt, hasLoopVariable, internal::Matcher<VarDecl>,namespace internal { class matcher_hasLoopVariable0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXForRangeStmt
> { public: explicit matcher_hasLoopVariable0Matcher( internal
::Matcher<VarDecl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const CXXForRangeStmt &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<VarDecl> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<CXXForRangeStmt
> hasLoopVariable( internal::Matcher<VarDecl> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_hasLoopVariable0Matcher(InnerMatcher)
); } typedef ::clang::ast_matchers::internal::Matcher<CXXForRangeStmt
> ( &hasLoopVariable_Type0)(internal::Matcher<VarDecl
> const &InnerMatcher); inline bool internal::matcher_hasLoopVariable0Matcher
::matches( const CXXForRangeStmt &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
2131 InnerMatcher)namespace internal { class matcher_hasLoopVariable0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXForRangeStmt
> { public: explicit matcher_hasLoopVariable0Matcher( internal
::Matcher<VarDecl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const CXXForRangeStmt &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<VarDecl> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<CXXForRangeStmt
> hasLoopVariable( internal::Matcher<VarDecl> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_hasLoopVariable0Matcher(InnerMatcher)
); } typedef ::clang::ast_matchers::internal::Matcher<CXXForRangeStmt
> ( &hasLoopVariable_Type0)(internal::Matcher<VarDecl
> const &InnerMatcher); inline bool internal::matcher_hasLoopVariable0Matcher
::matches( const CXXForRangeStmt &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
2132 const VarDecl *const Var = Node.getLoopVariable();
2133 return (Var != nullptr && InnerMatcher.matches(*Var, Finder, Builder));
2134}
2135
2136/// Matches the range initialization statement of a for loop.
2137///
2138/// Example:
2139/// forStmt(hasRangeInit(anything()))
2140/// matches 'a' in
2141/// \code
2142/// for (int x : a) { }
2143/// \endcode
2144AST_MATCHER_P(CXXForRangeStmt, hasRangeInit, internal::Matcher<Expr>,namespace internal { class matcher_hasRangeInit0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXForRangeStmt
> { public: explicit matcher_hasRangeInit0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const CXXForRangeStmt &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<Expr> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<CXXForRangeStmt
> hasRangeInit( internal::Matcher<Expr> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_hasRangeInit0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<CXXForRangeStmt> ( &
hasRangeInit_Type0)(internal::Matcher<Expr> const &
InnerMatcher); inline bool internal::matcher_hasRangeInit0Matcher
::matches( const CXXForRangeStmt &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
2145 InnerMatcher)namespace internal { class matcher_hasRangeInit0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXForRangeStmt
> { public: explicit matcher_hasRangeInit0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const CXXForRangeStmt &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<Expr> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<CXXForRangeStmt
> hasRangeInit( internal::Matcher<Expr> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_hasRangeInit0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<CXXForRangeStmt> ( &
hasRangeInit_Type0)(internal::Matcher<Expr> const &
InnerMatcher); inline bool internal::matcher_hasRangeInit0Matcher
::matches( const CXXForRangeStmt &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
2146 const Expr *const Init = Node.getRangeInit();
2147 return (Init != nullptr && InnerMatcher.matches(*Init, Finder, Builder));
2148}
2149
2150/// Matches while statements.
2151///
2152/// Given
2153/// \code
2154/// while (true) {}
2155/// \endcode
2156/// whileStmt()
2157/// matches 'while (true) {}'.
2158extern const internal::VariadicDynCastAllOfMatcher<Stmt, WhileStmt> whileStmt;
2159
2160/// Matches do statements.
2161///
2162/// Given
2163/// \code
2164/// do {} while (true);
2165/// \endcode
2166/// doStmt()
2167/// matches 'do {} while(true)'
2168extern const internal::VariadicDynCastAllOfMatcher<Stmt, DoStmt> doStmt;
2169
2170/// Matches break statements.
2171///
2172/// Given
2173/// \code
2174/// while (true) { break; }
2175/// \endcode
2176/// breakStmt()
2177/// matches 'break'
2178extern const internal::VariadicDynCastAllOfMatcher<Stmt, BreakStmt> breakStmt;
2179
2180/// Matches continue statements.
2181///
2182/// Given
2183/// \code
2184/// while (true) { continue; }
2185/// \endcode
2186/// continueStmt()
2187/// matches 'continue'
2188extern const internal::VariadicDynCastAllOfMatcher<Stmt, ContinueStmt>
2189 continueStmt;
2190
2191/// Matches co_return statements.
2192///
2193/// Given
2194/// \code
2195/// while (true) { co_return; }
2196/// \endcode
2197/// coreturnStmt()
2198/// matches 'co_return'
2199extern const internal::VariadicDynCastAllOfMatcher<Stmt, CoreturnStmt>
2200 coreturnStmt;
2201
2202/// Matches return statements.
2203///
2204/// Given
2205/// \code
2206/// return 1;
2207/// \endcode
2208/// returnStmt()
2209/// matches 'return 1'
2210extern const internal::VariadicDynCastAllOfMatcher<Stmt, ReturnStmt> returnStmt;
2211
2212/// Matches goto statements.
2213///
2214/// Given
2215/// \code
2216/// goto FOO;
2217/// FOO: bar();
2218/// \endcode
2219/// gotoStmt()
2220/// matches 'goto FOO'
2221extern const internal::VariadicDynCastAllOfMatcher<Stmt, GotoStmt> gotoStmt;
2222
2223/// Matches label statements.
2224///
2225/// Given
2226/// \code
2227/// goto FOO;
2228/// FOO: bar();
2229/// \endcode
2230/// labelStmt()
2231/// matches 'FOO:'
2232extern const internal::VariadicDynCastAllOfMatcher<Stmt, LabelStmt> labelStmt;
2233
2234/// Matches address of label statements (GNU extension).
2235///
2236/// Given
2237/// \code
2238/// FOO: bar();
2239/// void *ptr = &&FOO;
2240/// goto *bar;
2241/// \endcode
2242/// addrLabelExpr()
2243/// matches '&&FOO'
2244extern const internal::VariadicDynCastAllOfMatcher<Stmt, AddrLabelExpr>
2245 addrLabelExpr;
2246
2247/// Matches switch statements.
2248///
2249/// Given
2250/// \code
2251/// switch(a) { case 42: break; default: break; }
2252/// \endcode
2253/// switchStmt()
2254/// matches 'switch(a)'.
2255extern const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchStmt> switchStmt;
2256
2257/// Matches case and default statements inside switch statements.
2258///
2259/// Given
2260/// \code
2261/// switch(a) { case 42: break; default: break; }
2262/// \endcode
2263/// switchCase()
2264/// matches 'case 42:' and 'default:'.
2265extern const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchCase> switchCase;
2266
2267/// Matches case statements inside switch statements.
2268///
2269/// Given
2270/// \code
2271/// switch(a) { case 42: break; default: break; }
2272/// \endcode
2273/// caseStmt()
2274/// matches 'case 42:'.
2275extern const internal::VariadicDynCastAllOfMatcher<Stmt, CaseStmt> caseStmt;
2276
2277/// Matches default statements inside switch statements.
2278///
2279/// Given
2280/// \code
2281/// switch(a) { case 42: break; default: break; }
2282/// \endcode
2283/// defaultStmt()
2284/// matches 'default:'.
2285extern const internal::VariadicDynCastAllOfMatcher<Stmt, DefaultStmt>
2286 defaultStmt;
2287
2288/// Matches compound statements.
2289///
2290/// Example matches '{}' and '{{}}' in 'for (;;) {{}}'
2291/// \code
2292/// for (;;) {{}}
2293/// \endcode
2294extern const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundStmt>
2295 compoundStmt;
2296
2297/// Matches catch statements.
2298///
2299/// \code
2300/// try {} catch(int i) {}
2301/// \endcode
2302/// cxxCatchStmt()
2303/// matches 'catch(int i)'
2304extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXCatchStmt>
2305 cxxCatchStmt;
2306
2307/// Matches try statements.
2308///
2309/// \code
2310/// try {} catch(int i) {}
2311/// \endcode
2312/// cxxTryStmt()
2313/// matches 'try {}'
2314extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTryStmt> cxxTryStmt;
2315
2316/// Matches throw expressions.
2317///
2318/// \code
2319/// try { throw 5; } catch(int i) {}
2320/// \endcode
2321/// cxxThrowExpr()
2322/// matches 'throw 5'
2323extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThrowExpr>
2324 cxxThrowExpr;
2325
2326/// Matches null statements.
2327///
2328/// \code
2329/// foo();;
2330/// \endcode
2331/// nullStmt()
2332/// matches the second ';'
2333extern const internal::VariadicDynCastAllOfMatcher<Stmt, NullStmt> nullStmt;
2334
2335/// Matches asm statements.
2336///
2337/// \code
2338/// int i = 100;
2339/// __asm("mov al, 2");
2340/// \endcode
2341/// asmStmt()
2342/// matches '__asm("mov al, 2")'
2343extern const internal::VariadicDynCastAllOfMatcher<Stmt, AsmStmt> asmStmt;
2344
2345/// Matches bool literals.
2346///
2347/// Example matches true
2348/// \code
2349/// true
2350/// \endcode
2351extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBoolLiteralExpr>
2352 cxxBoolLiteral;
2353
2354/// Matches string literals (also matches wide string literals).
2355///
2356/// Example matches "abcd", L"abcd"
2357/// \code
2358/// char *s = "abcd";
2359/// wchar_t *ws = L"abcd";
2360/// \endcode
2361extern const internal::VariadicDynCastAllOfMatcher<Stmt, StringLiteral>
2362 stringLiteral;
2363
2364/// Matches character literals (also matches wchar_t).
2365///
2366/// Not matching Hex-encoded chars (e.g. 0x1234, which is a IntegerLiteral),
2367/// though.
2368///
2369/// Example matches 'a', L'a'
2370/// \code
2371/// char ch = 'a';
2372/// wchar_t chw = L'a';
2373/// \endcode
2374extern const internal::VariadicDynCastAllOfMatcher<Stmt, CharacterLiteral>
2375 characterLiteral;
2376
2377/// Matches integer literals of all sizes / encodings, e.g.
2378/// 1, 1L, 0x1 and 1U.
2379///
2380/// Does not match character-encoded integers such as L'a'.
2381extern const internal::VariadicDynCastAllOfMatcher<Stmt, IntegerLiteral>
2382 integerLiteral;
2383
2384/// Matches float literals of all sizes / encodings, e.g.
2385/// 1.0, 1.0f, 1.0L and 1e10.
2386///
2387/// Does not match implicit conversions such as
2388/// \code
2389/// float a = 10;
2390/// \endcode
2391extern const internal::VariadicDynCastAllOfMatcher<Stmt, FloatingLiteral>
2392 floatLiteral;
2393
2394/// Matches imaginary literals, which are based on integer and floating
2395/// point literals e.g.: 1i, 1.0i
2396extern const internal::VariadicDynCastAllOfMatcher<Stmt, ImaginaryLiteral>
2397 imaginaryLiteral;
2398
2399/// Matches fixed point literals
2400extern const internal::VariadicDynCastAllOfMatcher<Stmt, FixedPointLiteral>
2401 fixedPointLiteral;
2402
2403/// Matches user defined literal operator call.
2404///
2405/// Example match: "foo"_suffix
2406extern const internal::VariadicDynCastAllOfMatcher<Stmt, UserDefinedLiteral>
2407 userDefinedLiteral;
2408
2409/// Matches compound (i.e. non-scalar) literals
2410///
2411/// Example match: {1}, (1, 2)
2412/// \code
2413/// int array[4] = {1};
2414/// vector int myvec = (vector int)(1, 2);
2415/// \endcode
2416extern const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundLiteralExpr>
2417 compoundLiteralExpr;
2418
2419/// Matches co_await expressions.
2420///
2421/// Given
2422/// \code
2423/// co_await 1;
2424/// \endcode
2425/// coawaitExpr()
2426/// matches 'co_await 1'
2427extern const internal::VariadicDynCastAllOfMatcher<Stmt, CoawaitExpr>
2428 coawaitExpr;
2429/// Matches co_await expressions where the type of the promise is dependent
2430extern const internal::VariadicDynCastAllOfMatcher<Stmt, DependentCoawaitExpr>
2431 dependentCoawaitExpr;
2432/// Matches co_yield expressions.
2433///
2434/// Given
2435/// \code
2436/// co_yield 1;
2437/// \endcode
2438/// coyieldExpr()
2439/// matches 'co_yield 1'
2440extern const internal::VariadicDynCastAllOfMatcher<Stmt, CoyieldExpr>
2441 coyieldExpr;
2442
2443/// Matches nullptr literal.
2444extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNullPtrLiteralExpr>
2445 cxxNullPtrLiteralExpr;
2446
2447/// Matches GNU __builtin_choose_expr.
2448extern const internal::VariadicDynCastAllOfMatcher<Stmt, ChooseExpr>
2449 chooseExpr;
2450
2451/// Matches GNU __null expression.
2452extern const internal::VariadicDynCastAllOfMatcher<Stmt, GNUNullExpr>
2453 gnuNullExpr;
2454
2455/// Matches C11 _Generic expression.
2456extern const internal::VariadicDynCastAllOfMatcher<Stmt, GenericSelectionExpr>
2457 genericSelectionExpr;
2458
2459/// Matches atomic builtins.
2460/// Example matches __atomic_load_n(ptr, 1)
2461/// \code
2462/// void foo() { int *ptr; __atomic_load_n(ptr, 1); }
2463/// \endcode
2464extern const internal::VariadicDynCastAllOfMatcher<Stmt, AtomicExpr> atomicExpr;
2465
2466/// Matches statement expression (GNU extension).
2467///
2468/// Example match: ({ int X = 4; X; })
2469/// \code
2470/// int C = ({ int X = 4; X; });
2471/// \endcode
2472extern const internal::VariadicDynCastAllOfMatcher<Stmt, StmtExpr> stmtExpr;
2473
2474/// Matches binary operator expressions.
2475///
2476/// Example matches a || b
2477/// \code
2478/// !(a || b)
2479/// \endcode
2480/// See also the binaryOperation() matcher for more-general matching.
2481extern const internal::VariadicDynCastAllOfMatcher<Stmt, BinaryOperator>
2482 binaryOperator;
2483
2484/// Matches unary operator expressions.
2485///
2486/// Example matches !a
2487/// \code
2488/// !a || b
2489/// \endcode
2490extern const internal::VariadicDynCastAllOfMatcher<Stmt, UnaryOperator>
2491 unaryOperator;
2492
2493/// Matches conditional operator expressions.
2494///
2495/// Example matches a ? b : c
2496/// \code
2497/// (a ? b : c) + 42
2498/// \endcode
2499extern const internal::VariadicDynCastAllOfMatcher<Stmt, ConditionalOperator>
2500 conditionalOperator;
2501
2502/// Matches binary conditional operator expressions (GNU extension).
2503///
2504/// Example matches a ?: b
2505/// \code
2506/// (a ?: b) + 42;
2507/// \endcode
2508extern const internal::VariadicDynCastAllOfMatcher<Stmt,
2509 BinaryConditionalOperator>
2510 binaryConditionalOperator;
2511
2512/// Matches opaque value expressions. They are used as helpers
2513/// to reference another expressions and can be met
2514/// in BinaryConditionalOperators, for example.
2515///
2516/// Example matches 'a'
2517/// \code
2518/// (a ?: c) + 42;
2519/// \endcode
2520extern const internal::VariadicDynCastAllOfMatcher<Stmt, OpaqueValueExpr>
2521 opaqueValueExpr;
2522
2523/// Matches a C++ static_assert declaration.
2524///
2525/// Example:
2526/// staticAssertExpr()
2527/// matches
2528/// static_assert(sizeof(S) == sizeof(int))
2529/// in
2530/// \code
2531/// struct S {
2532/// int x;
2533/// };
2534/// static_assert(sizeof(S) == sizeof(int));
2535/// \endcode
2536extern const internal::VariadicDynCastAllOfMatcher<Decl, StaticAssertDecl>
2537 staticAssertDecl;
2538
2539/// Matches a reinterpret_cast expression.
2540///
2541/// Either the source expression or the destination type can be matched
2542/// using has(), but hasDestinationType() is more specific and can be
2543/// more readable.
2544///
2545/// Example matches reinterpret_cast<char*>(&p) in
2546/// \code
2547/// void* p = reinterpret_cast<char*>(&p);
2548/// \endcode
2549extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXReinterpretCastExpr>
2550 cxxReinterpretCastExpr;
2551
2552/// Matches a C++ static_cast expression.
2553///
2554/// \see hasDestinationType
2555/// \see reinterpretCast
2556///
2557/// Example:
2558/// cxxStaticCastExpr()
2559/// matches
2560/// static_cast<long>(8)
2561/// in
2562/// \code
2563/// long eight(static_cast<long>(8));
2564/// \endcode
2565extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXStaticCastExpr>
2566 cxxStaticCastExpr;
2567
2568/// Matches a dynamic_cast expression.
2569///
2570/// Example:
2571/// cxxDynamicCastExpr()
2572/// matches
2573/// dynamic_cast<D*>(&b);
2574/// in
2575/// \code
2576/// struct B { virtual ~B() {} }; struct D : B {};
2577/// B b;
2578/// D* p = dynamic_cast<D*>(&b);
2579/// \endcode
2580extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDynamicCastExpr>
2581 cxxDynamicCastExpr;
2582
2583/// Matches a const_cast expression.
2584///
2585/// Example: Matches const_cast<int*>(&r) in
2586/// \code
2587/// int n = 42;
2588/// const int &r(n);
2589/// int* p = const_cast<int*>(&r);
2590/// \endcode
2591extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstCastExpr>
2592 cxxConstCastExpr;
2593
2594/// Matches a C-style cast expression.
2595///
2596/// Example: Matches (int) 2.2f in
2597/// \code
2598/// int i = (int) 2.2f;
2599/// \endcode
2600extern const internal::VariadicDynCastAllOfMatcher<Stmt, CStyleCastExpr>
2601 cStyleCastExpr;
2602
2603/// Matches explicit cast expressions.
2604///
2605/// Matches any cast expression written in user code, whether it be a
2606/// C-style cast, a functional-style cast, or a keyword cast.
2607///
2608/// Does not match implicit conversions.
2609///
2610/// Note: the name "explicitCast" is chosen to match Clang's terminology, as
2611/// Clang uses the term "cast" to apply to implicit conversions as well as to
2612/// actual cast expressions.
2613///
2614/// \see hasDestinationType.
2615///
2616/// Example: matches all five of the casts in
2617/// \code
2618/// int((int)(reinterpret_cast<int>(static_cast<int>(const_cast<int>(42)))))
2619/// \endcode
2620/// but does not match the implicit conversion in
2621/// \code
2622/// long ell = 42;
2623/// \endcode
2624extern const internal::VariadicDynCastAllOfMatcher<Stmt, ExplicitCastExpr>
2625 explicitCastExpr;
2626
2627/// Matches the implicit cast nodes of Clang's AST.
2628///
2629/// This matches many different places, including function call return value
2630/// eliding, as well as any type conversions.
2631extern const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitCastExpr>
2632 implicitCastExpr;
2633
2634/// Matches any cast nodes of Clang's AST.
2635///
2636/// Example: castExpr() matches each of the following:
2637/// \code
2638/// (int) 3;
2639/// const_cast<Expr *>(SubExpr);
2640/// char c = 0;
2641/// \endcode
2642/// but does not match
2643/// \code
2644/// int i = (0);
2645/// int k = 0;
2646/// \endcode
2647extern const internal::VariadicDynCastAllOfMatcher<Stmt, CastExpr> castExpr;
2648
2649/// Matches functional cast expressions
2650///
2651/// Example: Matches Foo(bar);
2652/// \code
2653/// Foo f = bar;
2654/// Foo g = (Foo) bar;
2655/// Foo h = Foo(bar);
2656/// \endcode
2657extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXFunctionalCastExpr>
2658 cxxFunctionalCastExpr;
2659
2660/// Matches functional cast expressions having N != 1 arguments
2661///
2662/// Example: Matches Foo(bar, bar)
2663/// \code
2664/// Foo h = Foo(bar, bar);
2665/// \endcode
2666extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTemporaryObjectExpr>
2667 cxxTemporaryObjectExpr;
2668
2669/// Matches predefined identifier expressions [C99 6.4.2.2].
2670///
2671/// Example: Matches __func__
2672/// \code
2673/// printf("%s", __func__);
2674/// \endcode
2675extern const internal::VariadicDynCastAllOfMatcher<Stmt, PredefinedExpr>
2676 predefinedExpr;
2677
2678/// Matches C99 designated initializer expressions [C99 6.7.8].
2679///
2680/// Example: Matches { [2].y = 1.0, [0].x = 1.0 }
2681/// \code
2682/// point ptarray[10] = { [2].y = 1.0, [0].x = 1.0 };
2683/// \endcode
2684extern const internal::VariadicDynCastAllOfMatcher<Stmt, DesignatedInitExpr>
2685 designatedInitExpr;
2686
2687/// Matches designated initializer expressions that contain
2688/// a specific number of designators.
2689///
2690/// Example: Given
2691/// \code
2692/// point ptarray[10] = { [2].y = 1.0, [0].x = 1.0 };
2693/// point ptarray2[10] = { [2].y = 1.0, [2].x = 0.0, [0].x = 1.0 };
2694/// \endcode
2695/// designatorCountIs(2)
2696/// matches '{ [2].y = 1.0, [0].x = 1.0 }',
2697/// but not '{ [2].y = 1.0, [2].x = 0.0, [0].x = 1.0 }'.
2698AST_MATCHER_P(DesignatedInitExpr, designatorCountIs, unsigned, N)namespace internal { class matcher_designatorCountIs0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
DesignatedInitExpr> { public: explicit matcher_designatorCountIs0Matcher
( unsigned const &AN) : N(AN) {} bool matches(const DesignatedInitExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; }; } inline ::
clang::ast_matchers::internal::Matcher<DesignatedInitExpr>
designatorCountIs( unsigned const &N) { return ::clang::
ast_matchers::internal::makeMatcher( new internal::matcher_designatorCountIs0Matcher
(N)); } typedef ::clang::ast_matchers::internal::Matcher<DesignatedInitExpr
> ( &designatorCountIs_Type0)(unsigned const &N); inline
bool internal::matcher_designatorCountIs0Matcher::matches( const
DesignatedInitExpr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
2699 return Node.size() == N;
2700}
2701
2702/// Matches \c QualTypes in the clang AST.
2703extern const internal::VariadicAllOfMatcher<QualType> qualType;
2704
2705/// Matches \c Types in the clang AST.
2706extern const internal::VariadicAllOfMatcher<Type> type;
2707
2708/// Matches \c TypeLocs in the clang AST.
2709extern const internal::VariadicAllOfMatcher<TypeLoc> typeLoc;
2710
2711/// Matches if any of the given matchers matches.
2712///
2713/// Unlike \c anyOf, \c eachOf will generate a match result for each
2714/// matching submatcher.
2715///
2716/// For example, in:
2717/// \code
2718/// class A { int a; int b; };
2719/// \endcode
2720/// The matcher:
2721/// \code
2722/// cxxRecordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
2723/// has(fieldDecl(hasName("b")).bind("v"))))
2724/// \endcode
2725/// will generate two results binding "v", the first of which binds
2726/// the field declaration of \c a, the second the field declaration of
2727/// \c b.
2728///
2729/// Usable as: Any Matcher
2730extern const internal::VariadicOperatorMatcherFunc<
2731 2, std::numeric_limits<unsigned>::max()>
2732 eachOf;
2733
2734/// Matches if any of the given matchers matches.
2735///
2736/// Usable as: Any Matcher
2737extern const internal::VariadicOperatorMatcherFunc<
2738 2, std::numeric_limits<unsigned>::max()>
2739 anyOf;
2740
2741/// Matches if all given matchers match.
2742///
2743/// Usable as: Any Matcher
2744extern const internal::VariadicOperatorMatcherFunc<
2745 2, std::numeric_limits<unsigned>::max()>
2746 allOf;
2747
2748/// Matches any node regardless of the submatcher.
2749///
2750/// However, \c optionally will retain any bindings generated by the submatcher.
2751/// Useful when additional information which may or may not present about a main
2752/// matching node is desired.
2753///
2754/// For example, in:
2755/// \code
2756/// class Foo {
2757/// int bar;
2758/// }
2759/// \endcode
2760/// The matcher:
2761/// \code
2762/// cxxRecordDecl(
2763/// optionally(has(
2764/// fieldDecl(hasName("bar")).bind("var")
2765/// ))).bind("record")
2766/// \endcode
2767/// will produce a result binding for both "record" and "var".
2768/// The matcher will produce a "record" binding for even if there is no data
2769/// member named "bar" in that class.
2770///
2771/// Usable as: Any Matcher
2772extern const internal::VariadicOperatorMatcherFunc<1, 1> optionally;
2773
2774/// Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL)
2775///
2776/// Given
2777/// \code
2778/// Foo x = bar;
2779/// int y = sizeof(x) + alignof(x);
2780/// \endcode
2781/// unaryExprOrTypeTraitExpr()
2782/// matches \c sizeof(x) and \c alignof(x)
2783extern const internal::VariadicDynCastAllOfMatcher<Stmt,
2784 UnaryExprOrTypeTraitExpr>
2785 unaryExprOrTypeTraitExpr;
2786
2787/// Matches any of the \p NodeMatchers with InnerMatchers nested within
2788///
2789/// Given
2790/// \code
2791/// if (true);
2792/// for (; true; );
2793/// \endcode
2794/// with the matcher
2795/// \code
2796/// mapAnyOf(ifStmt, forStmt).with(
2797/// hasCondition(cxxBoolLiteralExpr(equals(true)))
2798/// ).bind("trueCond")
2799/// \endcode
2800/// matches the \c if and the \c for. It is equivalent to:
2801/// \code
2802/// auto trueCond = hasCondition(cxxBoolLiteralExpr(equals(true)));
2803/// anyOf(
2804/// ifStmt(trueCond).bind("trueCond"),
2805/// forStmt(trueCond).bind("trueCond")
2806/// );
2807/// \endcode
2808///
2809/// The with() chain-call accepts zero or more matchers which are combined
2810/// as-if with allOf() in each of the node matchers.
2811/// Usable as: Any Matcher
2812template <typename T, typename... U>
2813auto mapAnyOf(internal::VariadicDynCastAllOfMatcher<T, U> const &...) {
2814 return internal::MapAnyOfHelper<U...>();
2815}
2816
2817/// Matches nodes which can be used with binary operators.
2818///
2819/// The code
2820/// \code
2821/// var1 != var2;
2822/// \endcode
2823/// might be represented in the clang AST as a binaryOperator, a
2824/// cxxOperatorCallExpr or a cxxRewrittenBinaryOperator, depending on
2825///
2826/// * whether the types of var1 and var2 are fundamental (binaryOperator) or at
2827/// least one is a class type (cxxOperatorCallExpr)
2828/// * whether the code appears in a template declaration, if at least one of the
2829/// vars is a dependent-type (binaryOperator)
2830/// * whether the code relies on a rewritten binary operator, such as a
2831/// spaceship operator or an inverted equality operator
2832/// (cxxRewrittenBinaryOperator)
2833///
2834/// This matcher elides details in places where the matchers for the nodes are
2835/// compatible.
2836///
2837/// Given
2838/// \code
2839/// binaryOperation(
2840/// hasOperatorName("!="),
2841/// hasLHS(expr().bind("lhs")),
2842/// hasRHS(expr().bind("rhs"))
2843/// )
2844/// \endcode
2845/// matches each use of "!=" in:
2846/// \code
2847/// struct S{
2848/// bool operator!=(const S&) const;
2849/// };
2850///
2851/// void foo()
2852/// {
2853/// 1 != 2;
2854/// S() != S();
2855/// }
2856///
2857/// template<typename T>
2858/// void templ()
2859/// {
2860/// 1 != 2;
2861/// T() != S();
2862/// }
2863/// struct HasOpEq
2864/// {
2865/// bool operator==(const HasOpEq &) const;
2866/// };
2867///
2868/// void inverse()
2869/// {
2870/// HasOpEq s1;
2871/// HasOpEq s2;
2872/// if (s1 != s2)
2873/// return;
2874/// }
2875///
2876/// struct HasSpaceship
2877/// {
2878/// bool operator<=>(const HasOpEq &) const;
2879/// };
2880///
2881/// void use_spaceship()
2882/// {
2883/// HasSpaceship s1;
2884/// HasSpaceship s2;
2885/// if (s1 != s2)
2886/// return;
2887/// }
2888/// \endcode
2889extern const internal::MapAnyOfMatcher<BinaryOperator, CXXOperatorCallExpr,
2890 CXXRewrittenBinaryOperator>
2891 binaryOperation;
2892
2893/// Matches function calls and constructor calls
2894///
2895/// Because CallExpr and CXXConstructExpr do not share a common
2896/// base class with API accessing arguments etc, AST Matchers for code
2897/// which should match both are typically duplicated. This matcher
2898/// removes the need for duplication.
2899///
2900/// Given code
2901/// \code
2902/// struct ConstructorTakesInt
2903/// {
2904/// ConstructorTakesInt(int i) {}
2905/// };
2906///
2907/// void callTakesInt(int i)
2908/// {
2909/// }
2910///
2911/// void doCall()
2912/// {
2913/// callTakesInt(42);
2914/// }
2915///
2916/// void doConstruct()
2917/// {
2918/// ConstructorTakesInt cti(42);
2919/// }
2920/// \endcode
2921///
2922/// The matcher
2923/// \code
2924/// invocation(hasArgument(0, integerLiteral(equals(42))))
2925/// \endcode
2926/// matches the expression in both doCall and doConstruct
2927extern const internal::MapAnyOfMatcher<CallExpr, CXXConstructExpr> invocation;
2928
2929/// Matches unary expressions that have a specific type of argument.
2930///
2931/// Given
2932/// \code
2933/// int a, c; float b; int s = sizeof(a) + sizeof(b) + alignof(c);
2934/// \endcode
2935/// unaryExprOrTypeTraitExpr(hasArgumentOfType(asString("int"))
2936/// matches \c sizeof(a) and \c alignof(c)
2937AST_MATCHER_P(UnaryExprOrTypeTraitExpr, hasArgumentOfType,namespace internal { class matcher_hasArgumentOfType0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
UnaryExprOrTypeTraitExpr> { public: explicit matcher_hasArgumentOfType0Matcher
( internal::Matcher<QualType> const &AInnerMatcher)
: InnerMatcher(AInnerMatcher) {} bool matches(const UnaryExprOrTypeTraitExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<QualType
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<UnaryExprOrTypeTraitExpr> hasArgumentOfType( internal
::Matcher<QualType> const &InnerMatcher) { return ::
clang::ast_matchers::internal::makeMatcher( new internal::matcher_hasArgumentOfType0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<UnaryExprOrTypeTraitExpr> ( &hasArgumentOfType_Type0
)(internal::Matcher<QualType> const &InnerMatcher);
inline bool internal::matcher_hasArgumentOfType0Matcher::matches
( const UnaryExprOrTypeTraitExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
2938 internal::Matcher<QualType>, InnerMatcher)namespace internal { class matcher_hasArgumentOfType0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
UnaryExprOrTypeTraitExpr> { public: explicit matcher_hasArgumentOfType0Matcher
( internal::Matcher<QualType> const &AInnerMatcher)
: InnerMatcher(AInnerMatcher) {} bool matches(const UnaryExprOrTypeTraitExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<QualType
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<UnaryExprOrTypeTraitExpr> hasArgumentOfType( internal
::Matcher<QualType> const &InnerMatcher) { return ::
clang::ast_matchers::internal::makeMatcher( new internal::matcher_hasArgumentOfType0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<UnaryExprOrTypeTraitExpr> ( &hasArgumentOfType_Type0
)(internal::Matcher<QualType> const &InnerMatcher);
inline bool internal::matcher_hasArgumentOfType0Matcher::matches
( const UnaryExprOrTypeTraitExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
2939 const QualType ArgumentType = Node.getTypeOfArgument();
2940 return InnerMatcher.matches(ArgumentType, Finder, Builder);
2941}
2942
2943/// Matches unary expressions of a certain kind.
2944///
2945/// Given
2946/// \code
2947/// int x;
2948/// int s = sizeof(x) + alignof(x)
2949/// \endcode
2950/// unaryExprOrTypeTraitExpr(ofKind(UETT_SizeOf))
2951/// matches \c sizeof(x)
2952///
2953/// If the matcher is use from clang-query, UnaryExprOrTypeTrait parameter
2954/// should be passed as a quoted string. e.g., ofKind("UETT_SizeOf").
2955AST_MATCHER_P(UnaryExprOrTypeTraitExpr, ofKind, UnaryExprOrTypeTrait, Kind)namespace internal { class matcher_ofKind0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<UnaryExprOrTypeTraitExpr
> { public: explicit matcher_ofKind0Matcher( UnaryExprOrTypeTrait
const &AKind) : Kind(AKind) {} bool matches(const UnaryExprOrTypeTraitExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: UnaryExprOrTypeTrait Kind
; }; } inline ::clang::ast_matchers::internal::Matcher<UnaryExprOrTypeTraitExpr
> ofKind( UnaryExprOrTypeTrait const &Kind) { return ::
clang::ast_matchers::internal::makeMatcher( new internal::matcher_ofKind0Matcher
(Kind)); } typedef ::clang::ast_matchers::internal::Matcher<
UnaryExprOrTypeTraitExpr> ( &ofKind_Type0)(UnaryExprOrTypeTrait
const &Kind); inline bool internal::matcher_ofKind0Matcher
::matches( const UnaryExprOrTypeTraitExpr &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
{
2956 return Node.getKind() == Kind;
2957}
2958
2959/// Same as unaryExprOrTypeTraitExpr, but only matching
2960/// alignof.
2961inline internal::BindableMatcher<Stmt> alignOfExpr(
2962 const internal::Matcher<UnaryExprOrTypeTraitExpr> &InnerMatcher) {
2963 return stmt(unaryExprOrTypeTraitExpr(
2964 allOf(anyOf(ofKind(UETT_AlignOf), ofKind(UETT_PreferredAlignOf)),
2965 InnerMatcher)));
2966}
2967
2968/// Same as unaryExprOrTypeTraitExpr, but only matching
2969/// sizeof.
2970inline internal::BindableMatcher<Stmt> sizeOfExpr(
2971 const internal::Matcher<UnaryExprOrTypeTraitExpr> &InnerMatcher) {
2972 return stmt(unaryExprOrTypeTraitExpr(
2973 allOf(ofKind(UETT_SizeOf), InnerMatcher)));
2974}
2975
2976/// Matches NamedDecl nodes that have the specified name.
2977///
2978/// Supports specifying enclosing namespaces or classes by prefixing the name
2979/// with '<enclosing>::'.
2980/// Does not match typedefs of an underlying type with the given name.
2981///
2982/// Example matches X (Name == "X")
2983/// \code
2984/// class X;
2985/// \endcode
2986///
2987/// Example matches X (Name is one of "::a::b::X", "a::b::X", "b::X", "X")
2988/// \code
2989/// namespace a { namespace b { class X; } }
2990/// \endcode
2991inline internal::Matcher<NamedDecl> hasName(StringRef Name) {
2992 return internal::Matcher<NamedDecl>(
2993 new internal::HasNameMatcher({std::string(Name)}));
2994}
2995
2996/// Matches NamedDecl nodes that have any of the specified names.
2997///
2998/// This matcher is only provided as a performance optimization of hasName.
2999/// \code
3000/// hasAnyName(a, b, c)
3001/// \endcode
3002/// is equivalent to, but faster than
3003/// \code
3004/// anyOf(hasName(a), hasName(b), hasName(c))
3005/// \endcode
3006extern const internal::VariadicFunction<internal::Matcher<NamedDecl>, StringRef,
3007 internal::hasAnyNameFunc>
3008 hasAnyName;
3009
3010/// Matches NamedDecl nodes whose fully qualified names contain
3011/// a substring matched by the given RegExp.
3012///
3013/// Supports specifying enclosing namespaces or classes by
3014/// prefixing the name with '<enclosing>::'. Does not match typedefs
3015/// of an underlying type with the given name.
3016///
3017/// Example matches X (regexp == "::X")
3018/// \code
3019/// class X;
3020/// \endcode
3021///
3022/// Example matches X (regexp is one of "::X", "^foo::.*X", among others)
3023/// \code
3024/// namespace foo { namespace bar { class X; } }
3025/// \endcode
3026AST_MATCHER_REGEX(NamedDecl, matchesName, RegExp)namespace internal { class matcher_matchesName0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NamedDecl
> { public: explicit matcher_matchesName0Matcher( std::shared_ptr
<llvm::Regex> RE) : RegExp(std::move(RE)) {} bool matches
(const NamedDecl &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::shared_ptr<llvm::
Regex> RegExp; }; } inline ::clang::ast_matchers::internal
::Matcher<NamedDecl> matchesName( llvm::StringRef RegExp
, llvm::Regex::RegexFlags RegexFlags) { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_matchesName0Matcher
( ::clang::ast_matchers::internal::createAndVerifyRegex( RegExp
, RegexFlags, "matchesName"))); } inline ::clang::ast_matchers
::internal::Matcher<NamedDecl> matchesName( llvm::StringRef
RegExp) { return matchesName(RegExp, llvm::Regex::NoFlags); }
typedef ::clang::ast_matchers::internal::Matcher<NamedDecl
> ( &matchesName_Type0Flags)(llvm::StringRef, llvm::Regex
::RegexFlags); typedef ::clang::ast_matchers::internal::Matcher
<NamedDecl> ( &matchesName_Type0)(llvm::StringRef);
inline bool internal::matcher_matchesName0Matcher::matches( const
NamedDecl &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
3027 std::string FullNameString = "::" + Node.getQualifiedNameAsString();
3028 return RegExp->match(FullNameString);
3029}
3030
3031/// Matches overloaded operator names.
3032///
3033/// Matches overloaded operator names specified in strings without the
3034/// "operator" prefix: e.g. "<<".
3035///
3036/// Given:
3037/// \code
3038/// class A { int operator*(); };
3039/// const A &operator<<(const A &a, const A &b);
3040/// A a;
3041/// a << a; // <-- This matches
3042/// \endcode
3043///
3044/// \c cxxOperatorCallExpr(hasOverloadedOperatorName("<<"))) matches the
3045/// specified line and
3046/// \c cxxRecordDecl(hasMethod(hasOverloadedOperatorName("*")))
3047/// matches the declaration of \c A.
3048///
3049/// Usable as: Matcher<CXXOperatorCallExpr>, Matcher<FunctionDecl>
3050inline internal::PolymorphicMatcher<
3051 internal::HasOverloadedOperatorNameMatcher,
3052 AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)void(::clang::ast_matchers::internal::TypeList<CXXOperatorCallExpr
, FunctionDecl>)
,
3053 std::vector<std::string>>
3054hasOverloadedOperatorName(StringRef Name) {
3055 return internal::PolymorphicMatcher<
3056 internal::HasOverloadedOperatorNameMatcher,
3057 AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)void(::clang::ast_matchers::internal::TypeList<CXXOperatorCallExpr
, FunctionDecl>)
,
3058 std::vector<std::string>>({std::string(Name)});
3059}
3060
3061/// Matches overloaded operator names.
3062///
3063/// Matches overloaded operator names specified in strings without the
3064/// "operator" prefix: e.g. "<<".
3065///
3066/// hasAnyOverloadedOperatorName("+", "-")
3067/// Is equivalent to
3068/// anyOf(hasOverloadedOperatorName("+"), hasOverloadedOperatorName("-"))
3069extern const internal::VariadicFunction<
3070 internal::PolymorphicMatcher<internal::HasOverloadedOperatorNameMatcher,
3071 AST_POLYMORPHIC_SUPPORTED_TYPES(void(::clang::ast_matchers::internal::TypeList<CXXOperatorCallExpr
, FunctionDecl>)
3072 CXXOperatorCallExpr, FunctionDecl)void(::clang::ast_matchers::internal::TypeList<CXXOperatorCallExpr
, FunctionDecl>)
,
3073 std::vector<std::string>>,
3074 StringRef, internal::hasAnyOverloadedOperatorNameFunc>
3075 hasAnyOverloadedOperatorName;
3076
3077/// Matches template-dependent, but known, member names.
3078///
3079/// In template declarations, dependent members are not resolved and so can
3080/// not be matched to particular named declarations.
3081///
3082/// This matcher allows to match on the known name of members.
3083///
3084/// Given
3085/// \code
3086/// template <typename T>
3087/// struct S {
3088/// void mem();
3089/// };
3090/// template <typename T>
3091/// void x() {
3092/// S<T> s;
3093/// s.mem();
3094/// }
3095/// \endcode
3096/// \c cxxDependentScopeMemberExpr(hasMemberName("mem")) matches `s.mem()`
3097AST_MATCHER_P(CXXDependentScopeMemberExpr, hasMemberName, std::string, N)namespace internal { class matcher_hasMemberName0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXDependentScopeMemberExpr
> { public: explicit matcher_hasMemberName0Matcher( std::string
const &AN) : N(AN) {} bool matches(const CXXDependentScopeMemberExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string N; }; } inline
::clang::ast_matchers::internal::Matcher<CXXDependentScopeMemberExpr
> hasMemberName( std::string const &N) { return ::clang
::ast_matchers::internal::makeMatcher( new internal::matcher_hasMemberName0Matcher
(N)); } typedef ::clang::ast_matchers::internal::Matcher<CXXDependentScopeMemberExpr
> ( &hasMemberName_Type0)(std::string const &N); inline
bool internal::matcher_hasMemberName0Matcher::matches( const
CXXDependentScopeMemberExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
3098 return Node.getMember().getAsString() == N;
3099}
3100
3101/// Matches template-dependent, but known, member names against an already-bound
3102/// node
3103///
3104/// In template declarations, dependent members are not resolved and so can
3105/// not be matched to particular named declarations.
3106///
3107/// This matcher allows to match on the name of already-bound VarDecl, FieldDecl
3108/// and CXXMethodDecl nodes.
3109///
3110/// Given
3111/// \code
3112/// template <typename T>
3113/// struct S {
3114/// void mem();
3115/// };
3116/// template <typename T>
3117/// void x() {
3118/// S<T> s;
3119/// s.mem();
3120/// }
3121/// \endcode
3122/// The matcher
3123/// @code
3124/// \c cxxDependentScopeMemberExpr(
3125/// hasObjectExpression(declRefExpr(hasType(templateSpecializationType(
3126/// hasDeclaration(classTemplateDecl(has(cxxRecordDecl(has(
3127/// cxxMethodDecl(hasName("mem")).bind("templMem")
3128/// )))))
3129/// )))),
3130/// memberHasSameNameAsBoundNode("templMem")
3131/// )
3132/// @endcode
3133/// first matches and binds the @c mem member of the @c S template, then
3134/// compares its name to the usage in @c s.mem() in the @c x function template
3135AST_MATCHER_P(CXXDependentScopeMemberExpr, memberHasSameNameAsBoundNode,namespace internal { class matcher_memberHasSameNameAsBoundNode0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
CXXDependentScopeMemberExpr> { public: explicit matcher_memberHasSameNameAsBoundNode0Matcher
( std::string const &ABindingID) : BindingID(ABindingID) {
} bool matches(const CXXDependentScopeMemberExpr &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
override; private: std::string BindingID; }; } inline ::clang
::ast_matchers::internal::Matcher<CXXDependentScopeMemberExpr
> memberHasSameNameAsBoundNode( std::string const &BindingID
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_memberHasSameNameAsBoundNode0Matcher(BindingID)); }
typedef ::clang::ast_matchers::internal::Matcher<CXXDependentScopeMemberExpr
> ( &memberHasSameNameAsBoundNode_Type0)(std::string const
&BindingID); inline bool internal::matcher_memberHasSameNameAsBoundNode0Matcher
::matches( const CXXDependentScopeMemberExpr &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
3136 std::string, BindingID)namespace internal { class matcher_memberHasSameNameAsBoundNode0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
CXXDependentScopeMemberExpr> { public: explicit matcher_memberHasSameNameAsBoundNode0Matcher
( std::string const &ABindingID) : BindingID(ABindingID) {
} bool matches(const CXXDependentScopeMemberExpr &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
override; private: std::string BindingID; }; } inline ::clang
::ast_matchers::internal::Matcher<CXXDependentScopeMemberExpr
> memberHasSameNameAsBoundNode( std::string const &BindingID
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_memberHasSameNameAsBoundNode0Matcher(BindingID)); }
typedef ::clang::ast_matchers::internal::Matcher<CXXDependentScopeMemberExpr
> ( &memberHasSameNameAsBoundNode_Type0)(std::string const
&BindingID); inline bool internal::matcher_memberHasSameNameAsBoundNode0Matcher
::matches( const CXXDependentScopeMemberExpr &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
{
3137 auto MemberName = Node.getMember().getAsString();
3138
3139 return Builder->removeBindings(
3140 [this, MemberName](const BoundNodesMap &Nodes) {
3141 const auto &BN = Nodes.getNode(this->BindingID);
3142 if (const auto *ND = BN.get<NamedDecl>()) {
3143 if (!isa<FieldDecl, CXXMethodDecl, VarDecl>(ND))
3144 return true;
3145 return ND->getName() != MemberName;
3146 }
3147 return true;
3148 });
3149}
3150
3151/// Matches C++ classes that are directly or indirectly derived from a class
3152/// matching \c Base, or Objective-C classes that directly or indirectly
3153/// subclass a class matching \c Base.
3154///
3155/// Note that a class is not considered to be derived from itself.
3156///
3157/// Example matches Y, Z, C (Base == hasName("X"))
3158/// \code
3159/// class X;
3160/// class Y : public X {}; // directly derived
3161/// class Z : public Y {}; // indirectly derived
3162/// typedef X A;
3163/// typedef A B;
3164/// class C : public B {}; // derived from a typedef of X
3165/// \endcode
3166///
3167/// In the following example, Bar matches isDerivedFrom(hasName("X")):
3168/// \code
3169/// class Foo;
3170/// typedef Foo X;
3171/// class Bar : public Foo {}; // derived from a type that X is a typedef of
3172/// \endcode
3173///
3174/// In the following example, Bar matches isDerivedFrom(hasName("NSObject"))
3175/// \code
3176/// @interface NSObject @end
3177/// @interface Bar : NSObject @end
3178/// \endcode
3179///
3180/// Usable as: Matcher<CXXRecordDecl>, Matcher<ObjCInterfaceDecl>
3181AST_POLYMORPHIC_MATCHER_P(namespace internal { template <typename NodeType, typename
ParamT> class matcher_isDerivedFrom0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_isDerivedFrom0Matcher( internal::Matcher<
NamedDecl> const &ABase) : Base(ABase) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<NamedDecl
> Base; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isDerivedFrom0Matcher, void(::clang::ast_matchers
::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl>)
, internal::Matcher<NamedDecl> > isDerivedFrom(internal
::Matcher<NamedDecl> const &Base) { return ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_isDerivedFrom0Matcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, ObjCInterfaceDecl>), internal::Matcher<NamedDecl> >
(Base); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isDerivedFrom0Matcher, void(::clang::ast_matchers
::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl>)
, internal::Matcher<NamedDecl> > (&isDerivedFrom_Type0
)(internal::Matcher<NamedDecl> const &Base); template
<typename NodeType, typename ParamT> bool internal:: matcher_isDerivedFrom0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3182 isDerivedFrom,namespace internal { template <typename NodeType, typename
ParamT> class matcher_isDerivedFrom0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_isDerivedFrom0Matcher( internal::Matcher<
NamedDecl> const &ABase) : Base(ABase) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<NamedDecl
> Base; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isDerivedFrom0Matcher, void(::clang::ast_matchers
::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl>)
, internal::Matcher<NamedDecl> > isDerivedFrom(internal
::Matcher<NamedDecl> const &Base) { return ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_isDerivedFrom0Matcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, ObjCInterfaceDecl>), internal::Matcher<NamedDecl> >
(Base); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isDerivedFrom0Matcher, void(::clang::ast_matchers
::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl>)
, internal::Matcher<NamedDecl> > (&isDerivedFrom_Type0
)(internal::Matcher<NamedDecl> const &Base); template
<typename NodeType, typename ParamT> bool internal:: matcher_isDerivedFrom0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3183 AST_POLYMORPHIC_SUPPORTED_TYPES(CXXRecordDecl, ObjCInterfaceDecl),namespace internal { template <typename NodeType, typename
ParamT> class matcher_isDerivedFrom0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_isDerivedFrom0Matcher( internal::Matcher<
NamedDecl> const &ABase) : Base(ABase) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<NamedDecl
> Base; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isDerivedFrom0Matcher, void(::clang::ast_matchers
::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl>)
, internal::Matcher<NamedDecl> > isDerivedFrom(internal
::Matcher<NamedDecl> const &Base) { return ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_isDerivedFrom0Matcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, ObjCInterfaceDecl>), internal::Matcher<NamedDecl> >
(Base); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isDerivedFrom0Matcher, void(::clang::ast_matchers
::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl>)
, internal::Matcher<NamedDecl> > (&isDerivedFrom_Type0
)(internal::Matcher<NamedDecl> const &Base); template
<typename NodeType, typename ParamT> bool internal:: matcher_isDerivedFrom0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3184 internal::Matcher<NamedDecl>, Base)namespace internal { template <typename NodeType, typename
ParamT> class matcher_isDerivedFrom0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_isDerivedFrom0Matcher( internal::Matcher<
NamedDecl> const &ABase) : Base(ABase) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<NamedDecl
> Base; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isDerivedFrom0Matcher, void(::clang::ast_matchers
::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl>)
, internal::Matcher<NamedDecl> > isDerivedFrom(internal
::Matcher<NamedDecl> const &Base) { return ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_isDerivedFrom0Matcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, ObjCInterfaceDecl>), internal::Matcher<NamedDecl> >
(Base); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isDerivedFrom0Matcher, void(::clang::ast_matchers
::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl>)
, internal::Matcher<NamedDecl> > (&isDerivedFrom_Type0
)(internal::Matcher<NamedDecl> const &Base); template
<typename NodeType, typename ParamT> bool internal:: matcher_isDerivedFrom0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
{
3185 // Check if the node is a C++ struct/union/class.
3186 if (const auto *RD = dyn_cast<CXXRecordDecl>(&Node))
3187 return Finder->classIsDerivedFrom(RD, Base, Builder, /*Directly=*/false);
3188
3189 // The node must be an Objective-C class.
3190 const auto *InterfaceDecl = cast<ObjCInterfaceDecl>(&Node);
3191 return Finder->objcClassIsDerivedFrom(InterfaceDecl, Base, Builder,
3192 /*Directly=*/false);
3193}
3194
3195/// Overloaded method as shortcut for \c isDerivedFrom(hasName(...)).
3196AST_POLYMORPHIC_MATCHER_P_OVERLOAD(namespace internal { template <typename NodeType, typename
ParamT> class matcher_isDerivedFrom1Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_isDerivedFrom1Matcher( std::string const &
ABaseName) : BaseName(ABaseName) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string BaseName; }; }
inline ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_isDerivedFrom1Matcher, void(::clang::ast_matchers
::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl>)
, std::string> isDerivedFrom(std::string const &BaseName
) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isDerivedFrom1Matcher, void(::clang::ast_matchers
::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl>)
, std::string>(BaseName); } typedef ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isDerivedFrom1Matcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, ObjCInterfaceDecl>), std::string> (&isDerivedFrom_Type1
)(std::string const &BaseName); template <typename NodeType
, typename ParamT> bool internal:: matcher_isDerivedFrom1Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3197 isDerivedFrom,namespace internal { template <typename NodeType, typename
ParamT> class matcher_isDerivedFrom1Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_isDerivedFrom1Matcher( std::string const &
ABaseName) : BaseName(ABaseName) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string BaseName; }; }
inline ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_isDerivedFrom1Matcher, void(::clang::ast_matchers
::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl>)
, std::string> isDerivedFrom(std::string const &BaseName
) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isDerivedFrom1Matcher, void(::clang::ast_matchers
::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl>)
, std::string>(BaseName); } typedef ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isDerivedFrom1Matcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, ObjCInterfaceDecl>), std::string> (&isDerivedFrom_Type1
)(std::string const &BaseName); template <typename NodeType
, typename ParamT> bool internal:: matcher_isDerivedFrom1Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3198 AST_POLYMORPHIC_SUPPORTED_TYPES(CXXRecordDecl, ObjCInterfaceDecl),namespace internal { template <typename NodeType, typename
ParamT> class matcher_isDerivedFrom1Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_isDerivedFrom1Matcher( std::string const &
ABaseName) : BaseName(ABaseName) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string BaseName; }; }
inline ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_isDerivedFrom1Matcher, void(::clang::ast_matchers
::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl>)
, std::string> isDerivedFrom(std::string const &BaseName
) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isDerivedFrom1Matcher, void(::clang::ast_matchers
::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl>)
, std::string>(BaseName); } typedef ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isDerivedFrom1Matcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, ObjCInterfaceDecl>), std::string> (&isDerivedFrom_Type1
)(std::string const &BaseName); template <typename NodeType
, typename ParamT> bool internal:: matcher_isDerivedFrom1Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3199 std::string, BaseName, 1)namespace internal { template <typename NodeType, typename
ParamT> class matcher_isDerivedFrom1Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_isDerivedFrom1Matcher( std::string const &
ABaseName) : BaseName(ABaseName) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string BaseName; }; }
inline ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_isDerivedFrom1Matcher, void(::clang::ast_matchers
::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl>)
, std::string> isDerivedFrom(std::string const &BaseName
) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isDerivedFrom1Matcher, void(::clang::ast_matchers
::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl>)
, std::string>(BaseName); } typedef ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isDerivedFrom1Matcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, ObjCInterfaceDecl>), std::string> (&isDerivedFrom_Type1
)(std::string const &BaseName); template <typename NodeType
, typename ParamT> bool internal:: matcher_isDerivedFrom1Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
{
3200 if (BaseName.empty())
3201 return false;
3202
3203 const auto M = isDerivedFrom(hasName(BaseName));
3204
3205 if (const auto *RD = dyn_cast<CXXRecordDecl>(&Node))
3206 return Matcher<CXXRecordDecl>(M).matches(*RD, Finder, Builder);
3207
3208 const auto *InterfaceDecl = cast<ObjCInterfaceDecl>(&Node);
3209 return Matcher<ObjCInterfaceDecl>(M).matches(*InterfaceDecl, Finder, Builder);
3210}
3211
3212/// Matches C++ classes that have a direct or indirect base matching \p
3213/// BaseSpecMatcher.
3214///
3215/// Example:
3216/// matcher hasAnyBase(hasType(cxxRecordDecl(hasName("SpecialBase"))))
3217/// \code
3218/// class Foo;
3219/// class Bar : Foo {};
3220/// class Baz : Bar {};
3221/// class SpecialBase;
3222/// class Proxy : SpecialBase {}; // matches Proxy
3223/// class IndirectlyDerived : Proxy {}; //matches IndirectlyDerived
3224/// \endcode
3225///
3226// FIXME: Refactor this and isDerivedFrom to reuse implementation.
3227AST_MATCHER_P(CXXRecordDecl, hasAnyBase, internal::Matcher<CXXBaseSpecifier>,namespace internal { class matcher_hasAnyBase0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXRecordDecl
> { public: explicit matcher_hasAnyBase0Matcher( internal::
Matcher<CXXBaseSpecifier> const &ABaseSpecMatcher) :
BaseSpecMatcher(ABaseSpecMatcher) {} bool matches(const CXXRecordDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<CXXBaseSpecifier
> BaseSpecMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<CXXRecordDecl> hasAnyBase( internal::Matcher<
CXXBaseSpecifier> const &BaseSpecMatcher) { return ::clang
::ast_matchers::internal::makeMatcher( new internal::matcher_hasAnyBase0Matcher
(BaseSpecMatcher)); } typedef ::clang::ast_matchers::internal
::Matcher<CXXRecordDecl> ( &hasAnyBase_Type0)(internal
::Matcher<CXXBaseSpecifier> const &BaseSpecMatcher)
; inline bool internal::matcher_hasAnyBase0Matcher::matches( const
CXXRecordDecl &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
3228 BaseSpecMatcher)namespace internal { class matcher_hasAnyBase0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXRecordDecl
> { public: explicit matcher_hasAnyBase0Matcher( internal::
Matcher<CXXBaseSpecifier> const &ABaseSpecMatcher) :
BaseSpecMatcher(ABaseSpecMatcher) {} bool matches(const CXXRecordDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<CXXBaseSpecifier
> BaseSpecMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<CXXRecordDecl> hasAnyBase( internal::Matcher<
CXXBaseSpecifier> const &BaseSpecMatcher) { return ::clang
::ast_matchers::internal::makeMatcher( new internal::matcher_hasAnyBase0Matcher
(BaseSpecMatcher)); } typedef ::clang::ast_matchers::internal
::Matcher<CXXRecordDecl> ( &hasAnyBase_Type0)(internal
::Matcher<CXXBaseSpecifier> const &BaseSpecMatcher)
; inline bool internal::matcher_hasAnyBase0Matcher::matches( const
CXXRecordDecl &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
3229 return internal::matchesAnyBase(Node, BaseSpecMatcher, Finder, Builder);
3230}
3231
3232/// Matches C++ classes that have a direct base matching \p BaseSpecMatcher.
3233///
3234/// Example:
3235/// matcher hasDirectBase(hasType(cxxRecordDecl(hasName("SpecialBase"))))
3236/// \code
3237/// class Foo;
3238/// class Bar : Foo {};
3239/// class Baz : Bar {};
3240/// class SpecialBase;
3241/// class Proxy : SpecialBase {}; // matches Proxy
3242/// class IndirectlyDerived : Proxy {}; // doesn't match
3243/// \endcode
3244AST_MATCHER_P(CXXRecordDecl, hasDirectBase, internal::Matcher<CXXBaseSpecifier>,namespace internal { class matcher_hasDirectBase0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXRecordDecl
> { public: explicit matcher_hasDirectBase0Matcher( internal
::Matcher<CXXBaseSpecifier> const &ABaseSpecMatcher
) : BaseSpecMatcher(ABaseSpecMatcher) {} bool matches(const CXXRecordDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<CXXBaseSpecifier
> BaseSpecMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<CXXRecordDecl> hasDirectBase( internal::Matcher
<CXXBaseSpecifier> const &BaseSpecMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasDirectBase0Matcher(BaseSpecMatcher)); } typedef ::
clang::ast_matchers::internal::Matcher<CXXRecordDecl> (
&hasDirectBase_Type0)(internal::Matcher<CXXBaseSpecifier
> const &BaseSpecMatcher); inline bool internal::matcher_hasDirectBase0Matcher
::matches( const CXXRecordDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
3245 BaseSpecMatcher)namespace internal { class matcher_hasDirectBase0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXRecordDecl
> { public: explicit matcher_hasDirectBase0Matcher( internal
::Matcher<CXXBaseSpecifier> const &ABaseSpecMatcher
) : BaseSpecMatcher(ABaseSpecMatcher) {} bool matches(const CXXRecordDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<CXXBaseSpecifier
> BaseSpecMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<CXXRecordDecl> hasDirectBase( internal::Matcher
<CXXBaseSpecifier> const &BaseSpecMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasDirectBase0Matcher(BaseSpecMatcher)); } typedef ::
clang::ast_matchers::internal::Matcher<CXXRecordDecl> (
&hasDirectBase_Type0)(internal::Matcher<CXXBaseSpecifier
> const &BaseSpecMatcher); inline bool internal::matcher_hasDirectBase0Matcher
::matches( const CXXRecordDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
3246 return Node.hasDefinition() &&
3247 llvm::any_of(Node.bases(), [&](const CXXBaseSpecifier &Base) {
3248 return BaseSpecMatcher.matches(Base, Finder, Builder);
3249 });
3250}
3251
3252/// Similar to \c isDerivedFrom(), but also matches classes that directly
3253/// match \c Base.
3254AST_POLYMORPHIC_MATCHER_P_OVERLOAD(namespace internal { template <typename NodeType, typename
ParamT> class matcher_isSameOrDerivedFrom0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_isSameOrDerivedFrom0Matcher( internal
::Matcher<NamedDecl> const &ABase) : Base(ABase) {}
bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<NamedDecl> Base; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isSameOrDerivedFrom0Matcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, ObjCInterfaceDecl>), internal::Matcher<NamedDecl> >
isSameOrDerivedFrom(internal::Matcher<NamedDecl> const
&Base) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isSameOrDerivedFrom0Matcher, void(::clang
::ast_matchers::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl
>), internal::Matcher<NamedDecl> >(Base); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_isSameOrDerivedFrom0Matcher, void(::clang::ast_matchers
::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl>)
, internal::Matcher<NamedDecl> > (&isSameOrDerivedFrom_Type0
)(internal::Matcher<NamedDecl> const &Base); template
<typename NodeType, typename ParamT> bool internal:: matcher_isSameOrDerivedFrom0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3255 isSameOrDerivedFrom,namespace internal { template <typename NodeType, typename
ParamT> class matcher_isSameOrDerivedFrom0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_isSameOrDerivedFrom0Matcher( internal
::Matcher<NamedDecl> const &ABase) : Base(ABase) {}
bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<NamedDecl> Base; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isSameOrDerivedFrom0Matcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, ObjCInterfaceDecl>), internal::Matcher<NamedDecl> >
isSameOrDerivedFrom(internal::Matcher<NamedDecl> const
&Base) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isSameOrDerivedFrom0Matcher, void(::clang
::ast_matchers::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl
>), internal::Matcher<NamedDecl> >(Base); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_isSameOrDerivedFrom0Matcher, void(::clang::ast_matchers
::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl>)
, internal::Matcher<NamedDecl> > (&isSameOrDerivedFrom_Type0
)(internal::Matcher<NamedDecl> const &Base); template
<typename NodeType, typename ParamT> bool internal:: matcher_isSameOrDerivedFrom0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3256 AST_POLYMORPHIC_SUPPORTED_TYPES(CXXRecordDecl, ObjCInterfaceDecl),namespace internal { template <typename NodeType, typename
ParamT> class matcher_isSameOrDerivedFrom0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_isSameOrDerivedFrom0Matcher( internal
::Matcher<NamedDecl> const &ABase) : Base(ABase) {}
bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<NamedDecl> Base; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isSameOrDerivedFrom0Matcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, ObjCInterfaceDecl>), internal::Matcher<NamedDecl> >
isSameOrDerivedFrom(internal::Matcher<NamedDecl> const
&Base) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isSameOrDerivedFrom0Matcher, void(::clang
::ast_matchers::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl
>), internal::Matcher<NamedDecl> >(Base); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_isSameOrDerivedFrom0Matcher, void(::clang::ast_matchers
::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl>)
, internal::Matcher<NamedDecl> > (&isSameOrDerivedFrom_Type0
)(internal::Matcher<NamedDecl> const &Base); template
<typename NodeType, typename ParamT> bool internal:: matcher_isSameOrDerivedFrom0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3257 internal::Matcher<NamedDecl>, Base, 0)namespace internal { template <typename NodeType, typename
ParamT> class matcher_isSameOrDerivedFrom0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_isSameOrDerivedFrom0Matcher( internal
::Matcher<NamedDecl> const &ABase) : Base(ABase) {}
bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<NamedDecl> Base; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isSameOrDerivedFrom0Matcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, ObjCInterfaceDecl>), internal::Matcher<NamedDecl> >
isSameOrDerivedFrom(internal::Matcher<NamedDecl> const
&Base) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isSameOrDerivedFrom0Matcher, void(::clang
::ast_matchers::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl
>), internal::Matcher<NamedDecl> >(Base); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_isSameOrDerivedFrom0Matcher, void(::clang::ast_matchers
::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl>)
, internal::Matcher<NamedDecl> > (&isSameOrDerivedFrom_Type0
)(internal::Matcher<NamedDecl> const &Base); template
<typename NodeType, typename ParamT> bool internal:: matcher_isSameOrDerivedFrom0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
{
3258 const auto M = anyOf(Base, isDerivedFrom(Base));
3259
3260 if (const auto *RD = dyn_cast<CXXRecordDecl>(&Node))
3261 return Matcher<CXXRecordDecl>(M).matches(*RD, Finder, Builder);
3262
3263 const auto *InterfaceDecl = cast<ObjCInterfaceDecl>(&Node);
3264 return Matcher<ObjCInterfaceDecl>(M).matches(*InterfaceDecl, Finder, Builder);
3265}
3266
3267/// Overloaded method as shortcut for
3268/// \c isSameOrDerivedFrom(hasName(...)).
3269AST_POLYMORPHIC_MATCHER_P_OVERLOAD(namespace internal { template <typename NodeType, typename
ParamT> class matcher_isSameOrDerivedFrom1Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_isSameOrDerivedFrom1Matcher( std
::string const &ABaseName) : BaseName(ABaseName) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string BaseName; }; }
inline ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_isSameOrDerivedFrom1Matcher, void(::clang::
ast_matchers::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl
>), std::string> isSameOrDerivedFrom(std::string const &
BaseName) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isSameOrDerivedFrom1Matcher, void(::clang
::ast_matchers::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl
>), std::string>(BaseName); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isSameOrDerivedFrom1Matcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, ObjCInterfaceDecl>), std::string> (&isSameOrDerivedFrom_Type1
)(std::string const &BaseName); template <typename NodeType
, typename ParamT> bool internal:: matcher_isSameOrDerivedFrom1Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3270 isSameOrDerivedFrom,namespace internal { template <typename NodeType, typename
ParamT> class matcher_isSameOrDerivedFrom1Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_isSameOrDerivedFrom1Matcher( std
::string const &ABaseName) : BaseName(ABaseName) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string BaseName; }; }
inline ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_isSameOrDerivedFrom1Matcher, void(::clang::
ast_matchers::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl
>), std::string> isSameOrDerivedFrom(std::string const &
BaseName) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isSameOrDerivedFrom1Matcher, void(::clang
::ast_matchers::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl
>), std::string>(BaseName); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isSameOrDerivedFrom1Matcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, ObjCInterfaceDecl>), std::string> (&isSameOrDerivedFrom_Type1
)(std::string const &BaseName); template <typename NodeType
, typename ParamT> bool internal:: matcher_isSameOrDerivedFrom1Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3271 AST_POLYMORPHIC_SUPPORTED_TYPES(CXXRecordDecl, ObjCInterfaceDecl),namespace internal { template <typename NodeType, typename
ParamT> class matcher_isSameOrDerivedFrom1Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_isSameOrDerivedFrom1Matcher( std
::string const &ABaseName) : BaseName(ABaseName) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string BaseName; }; }
inline ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_isSameOrDerivedFrom1Matcher, void(::clang::
ast_matchers::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl
>), std::string> isSameOrDerivedFrom(std::string const &
BaseName) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isSameOrDerivedFrom1Matcher, void(::clang
::ast_matchers::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl
>), std::string>(BaseName); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isSameOrDerivedFrom1Matcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, ObjCInterfaceDecl>), std::string> (&isSameOrDerivedFrom_Type1
)(std::string const &BaseName); template <typename NodeType
, typename ParamT> bool internal:: matcher_isSameOrDerivedFrom1Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3272 std::string, BaseName, 1)namespace internal { template <typename NodeType, typename
ParamT> class matcher_isSameOrDerivedFrom1Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_isSameOrDerivedFrom1Matcher( std
::string const &ABaseName) : BaseName(ABaseName) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string BaseName; }; }
inline ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_isSameOrDerivedFrom1Matcher, void(::clang::
ast_matchers::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl
>), std::string> isSameOrDerivedFrom(std::string const &
BaseName) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isSameOrDerivedFrom1Matcher, void(::clang
::ast_matchers::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl
>), std::string>(BaseName); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isSameOrDerivedFrom1Matcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, ObjCInterfaceDecl>), std::string> (&isSameOrDerivedFrom_Type1
)(std::string const &BaseName); template <typename NodeType
, typename ParamT> bool internal:: matcher_isSameOrDerivedFrom1Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
{
3273 if (BaseName.empty())
3274 return false;
3275
3276 const auto M = isSameOrDerivedFrom(hasName(BaseName));
3277
3278 if (const auto *RD = dyn_cast<CXXRecordDecl>(&Node))
3279 return Matcher<CXXRecordDecl>(M).matches(*RD, Finder, Builder);
3280
3281 const auto *InterfaceDecl = cast<ObjCInterfaceDecl>(&Node);
3282 return Matcher<ObjCInterfaceDecl>(M).matches(*InterfaceDecl, Finder, Builder);
3283}
3284
3285/// Matches C++ or Objective-C classes that are directly derived from a class
3286/// matching \c Base.
3287///
3288/// Note that a class is not considered to be derived from itself.
3289///
3290/// Example matches Y, C (Base == hasName("X"))
3291/// \code
3292/// class X;
3293/// class Y : public X {}; // directly derived
3294/// class Z : public Y {}; // indirectly derived
3295/// typedef X A;
3296/// typedef A B;
3297/// class C : public B {}; // derived from a typedef of X
3298/// \endcode
3299///
3300/// In the following example, Bar matches isDerivedFrom(hasName("X")):
3301/// \code
3302/// class Foo;
3303/// typedef Foo X;
3304/// class Bar : public Foo {}; // derived from a type that X is a typedef of
3305/// \endcode
3306AST_POLYMORPHIC_MATCHER_P_OVERLOAD(namespace internal { template <typename NodeType, typename
ParamT> class matcher_isDirectlyDerivedFrom0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_isDirectlyDerivedFrom0Matcher
( internal::Matcher<NamedDecl> const &ABase) : Base
(ABase) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<NamedDecl> Base; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isDirectlyDerivedFrom0Matcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, ObjCInterfaceDecl>), internal::Matcher<NamedDecl> >
isDirectlyDerivedFrom(internal::Matcher<NamedDecl> const
&Base) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isDirectlyDerivedFrom0Matcher, void(::
clang::ast_matchers::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl
>), internal::Matcher<NamedDecl> >(Base); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_isDirectlyDerivedFrom0Matcher, void(::clang::ast_matchers
::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl>)
, internal::Matcher<NamedDecl> > (&isDirectlyDerivedFrom_Type0
)(internal::Matcher<NamedDecl> const &Base); template
<typename NodeType, typename ParamT> bool internal:: matcher_isDirectlyDerivedFrom0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3307 isDirectlyDerivedFrom,namespace internal { template <typename NodeType, typename
ParamT> class matcher_isDirectlyDerivedFrom0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_isDirectlyDerivedFrom0Matcher
( internal::Matcher<NamedDecl> const &ABase) : Base
(ABase) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<NamedDecl> Base; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isDirectlyDerivedFrom0Matcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, ObjCInterfaceDecl>), internal::Matcher<NamedDecl> >
isDirectlyDerivedFrom(internal::Matcher<NamedDecl> const
&Base) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isDirectlyDerivedFrom0Matcher, void(::
clang::ast_matchers::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl
>), internal::Matcher<NamedDecl> >(Base); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_isDirectlyDerivedFrom0Matcher, void(::clang::ast_matchers
::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl>)
, internal::Matcher<NamedDecl> > (&isDirectlyDerivedFrom_Type0
)(internal::Matcher<NamedDecl> const &Base); template
<typename NodeType, typename ParamT> bool internal:: matcher_isDirectlyDerivedFrom0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3308 AST_POLYMORPHIC_SUPPORTED_TYPES(CXXRecordDecl, ObjCInterfaceDecl),namespace internal { template <typename NodeType, typename
ParamT> class matcher_isDirectlyDerivedFrom0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_isDirectlyDerivedFrom0Matcher
( internal::Matcher<NamedDecl> const &ABase) : Base
(ABase) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<NamedDecl> Base; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isDirectlyDerivedFrom0Matcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, ObjCInterfaceDecl>), internal::Matcher<NamedDecl> >
isDirectlyDerivedFrom(internal::Matcher<NamedDecl> const
&Base) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isDirectlyDerivedFrom0Matcher, void(::
clang::ast_matchers::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl
>), internal::Matcher<NamedDecl> >(Base); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_isDirectlyDerivedFrom0Matcher, void(::clang::ast_matchers
::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl>)
, internal::Matcher<NamedDecl> > (&isDirectlyDerivedFrom_Type0
)(internal::Matcher<NamedDecl> const &Base); template
<typename NodeType, typename ParamT> bool internal:: matcher_isDirectlyDerivedFrom0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3309 internal::Matcher<NamedDecl>, Base, 0)namespace internal { template <typename NodeType, typename
ParamT> class matcher_isDirectlyDerivedFrom0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_isDirectlyDerivedFrom0Matcher
( internal::Matcher<NamedDecl> const &ABase) : Base
(ABase) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<NamedDecl> Base; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isDirectlyDerivedFrom0Matcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, ObjCInterfaceDecl>), internal::Matcher<NamedDecl> >
isDirectlyDerivedFrom(internal::Matcher<NamedDecl> const
&Base) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isDirectlyDerivedFrom0Matcher, void(::
clang::ast_matchers::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl
>), internal::Matcher<NamedDecl> >(Base); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_isDirectlyDerivedFrom0Matcher, void(::clang::ast_matchers
::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl>)
, internal::Matcher<NamedDecl> > (&isDirectlyDerivedFrom_Type0
)(internal::Matcher<NamedDecl> const &Base); template
<typename NodeType, typename ParamT> bool internal:: matcher_isDirectlyDerivedFrom0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
{
3310 // Check if the node is a C++ struct/union/class.
3311 if (const auto *RD = dyn_cast<CXXRecordDecl>(&Node))
3312 return Finder->classIsDerivedFrom(RD, Base, Builder, /*Directly=*/true);
3313
3314 // The node must be an Objective-C class.
3315 const auto *InterfaceDecl = cast<ObjCInterfaceDecl>(&Node);
3316 return Finder->objcClassIsDerivedFrom(InterfaceDecl, Base, Builder,
3317 /*Directly=*/true);
3318}
3319
3320/// Overloaded method as shortcut for \c isDirectlyDerivedFrom(hasName(...)).
3321AST_POLYMORPHIC_MATCHER_P_OVERLOAD(namespace internal { template <typename NodeType, typename
ParamT> class matcher_isDirectlyDerivedFrom1Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_isDirectlyDerivedFrom1Matcher
( std::string const &ABaseName) : BaseName(ABaseName) {} bool
matches(const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string BaseName; }; }
inline ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_isDirectlyDerivedFrom1Matcher, void(::clang
::ast_matchers::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl
>), std::string> isDirectlyDerivedFrom(std::string const
&BaseName) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isDirectlyDerivedFrom1Matcher, void(::
clang::ast_matchers::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl
>), std::string>(BaseName); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isDirectlyDerivedFrom1Matcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, ObjCInterfaceDecl>), std::string> (&isDirectlyDerivedFrom_Type1
)(std::string const &BaseName); template <typename NodeType
, typename ParamT> bool internal:: matcher_isDirectlyDerivedFrom1Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3322 isDirectlyDerivedFrom,namespace internal { template <typename NodeType, typename
ParamT> class matcher_isDirectlyDerivedFrom1Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_isDirectlyDerivedFrom1Matcher
( std::string const &ABaseName) : BaseName(ABaseName) {} bool
matches(const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string BaseName; }; }
inline ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_isDirectlyDerivedFrom1Matcher, void(::clang
::ast_matchers::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl
>), std::string> isDirectlyDerivedFrom(std::string const
&BaseName) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isDirectlyDerivedFrom1Matcher, void(::
clang::ast_matchers::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl
>), std::string>(BaseName); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isDirectlyDerivedFrom1Matcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, ObjCInterfaceDecl>), std::string> (&isDirectlyDerivedFrom_Type1
)(std::string const &BaseName); template <typename NodeType
, typename ParamT> bool internal:: matcher_isDirectlyDerivedFrom1Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3323 AST_POLYMORPHIC_SUPPORTED_TYPES(CXXRecordDecl, ObjCInterfaceDecl),namespace internal { template <typename NodeType, typename
ParamT> class matcher_isDirectlyDerivedFrom1Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_isDirectlyDerivedFrom1Matcher
( std::string const &ABaseName) : BaseName(ABaseName) {} bool
matches(const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string BaseName; }; }
inline ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_isDirectlyDerivedFrom1Matcher, void(::clang
::ast_matchers::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl
>), std::string> isDirectlyDerivedFrom(std::string const
&BaseName) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isDirectlyDerivedFrom1Matcher, void(::
clang::ast_matchers::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl
>), std::string>(BaseName); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isDirectlyDerivedFrom1Matcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, ObjCInterfaceDecl>), std::string> (&isDirectlyDerivedFrom_Type1
)(std::string const &BaseName); template <typename NodeType
, typename ParamT> bool internal:: matcher_isDirectlyDerivedFrom1Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3324 std::string, BaseName, 1)namespace internal { template <typename NodeType, typename
ParamT> class matcher_isDirectlyDerivedFrom1Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_isDirectlyDerivedFrom1Matcher
( std::string const &ABaseName) : BaseName(ABaseName) {} bool
matches(const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string BaseName; }; }
inline ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_isDirectlyDerivedFrom1Matcher, void(::clang
::ast_matchers::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl
>), std::string> isDirectlyDerivedFrom(std::string const
&BaseName) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isDirectlyDerivedFrom1Matcher, void(::
clang::ast_matchers::internal::TypeList<CXXRecordDecl, ObjCInterfaceDecl
>), std::string>(BaseName); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isDirectlyDerivedFrom1Matcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, ObjCInterfaceDecl>), std::string> (&isDirectlyDerivedFrom_Type1
)(std::string const &BaseName); template <typename NodeType
, typename ParamT> bool internal:: matcher_isDirectlyDerivedFrom1Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
{
3325 if (BaseName.empty())
3326 return false;
3327 const auto M = isDirectlyDerivedFrom(hasName(BaseName));
3328
3329 if (const auto *RD = dyn_cast<CXXRecordDecl>(&Node))
3330 return Matcher<CXXRecordDecl>(M).matches(*RD, Finder, Builder);
3331
3332 const auto *InterfaceDecl = cast<ObjCInterfaceDecl>(&Node);
3333 return Matcher<ObjCInterfaceDecl>(M).matches(*InterfaceDecl, Finder, Builder);
3334}
3335/// Matches the first method of a class or struct that satisfies \c
3336/// InnerMatcher.
3337///
3338/// Given:
3339/// \code
3340/// class A { void func(); };
3341/// class B { void member(); };
3342/// \endcode
3343///
3344/// \c cxxRecordDecl(hasMethod(hasName("func"))) matches the declaration of
3345/// \c A but not \c B.
3346AST_MATCHER_P(CXXRecordDecl, hasMethod, internal::Matcher<CXXMethodDecl>,namespace internal { class matcher_hasMethod0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXRecordDecl
> { public: explicit matcher_hasMethod0Matcher( internal::
Matcher<CXXMethodDecl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const CXXRecordDecl &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<CXXMethodDecl
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<CXXRecordDecl> hasMethod( internal::Matcher<
CXXMethodDecl> const &InnerMatcher) { return ::clang::
ast_matchers::internal::makeMatcher( new internal::matcher_hasMethod0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<CXXRecordDecl> ( &hasMethod_Type0)(internal::Matcher
<CXXMethodDecl> const &InnerMatcher); inline bool internal
::matcher_hasMethod0Matcher::matches( const CXXRecordDecl &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
3347 InnerMatcher)namespace internal { class matcher_hasMethod0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXRecordDecl
> { public: explicit matcher_hasMethod0Matcher( internal::
Matcher<CXXMethodDecl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const CXXRecordDecl &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<CXXMethodDecl
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<CXXRecordDecl> hasMethod( internal::Matcher<
CXXMethodDecl> const &InnerMatcher) { return ::clang::
ast_matchers::internal::makeMatcher( new internal::matcher_hasMethod0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<CXXRecordDecl> ( &hasMethod_Type0)(internal::Matcher
<CXXMethodDecl> const &InnerMatcher); inline bool internal
::matcher_hasMethod0Matcher::matches( const CXXRecordDecl &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
3348 BoundNodesTreeBuilder Result(*Builder);
3349 auto MatchIt = matchesFirstInPointerRange(InnerMatcher, Node.method_begin(),
3350 Node.method_end(), Finder, &Result);
3351 if (MatchIt == Node.method_end())
3352 return false;
3353
3354 if (Finder->isTraversalIgnoringImplicitNodes() && (*MatchIt)->isImplicit())
3355 return false;
3356 *Builder = std::move(Result);
3357 return true;
3358}
3359
3360/// Matches the generated class of lambda expressions.
3361///
3362/// Given:
3363/// \code
3364/// auto x = []{};
3365/// \endcode
3366///
3367/// \c cxxRecordDecl(isLambda()) matches the implicit class declaration of
3368/// \c decltype(x)
3369AST_MATCHER(CXXRecordDecl, isLambda)namespace internal { class matcher_isLambdaMatcher : public ::
clang::ast_matchers::internal::MatcherInterface<CXXRecordDecl
> { public: explicit matcher_isLambdaMatcher() = default; bool
matches(const CXXRecordDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<CXXRecordDecl>
isLambda() { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_isLambdaMatcher()); } inline bool internal
::matcher_isLambdaMatcher::matches( const CXXRecordDecl &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
3370 return Node.isLambda();
3371}
3372
3373/// Matches AST nodes that have child AST nodes that match the
3374/// provided matcher.
3375///
3376/// Example matches X, Y
3377/// (matcher = cxxRecordDecl(has(cxxRecordDecl(hasName("X")))
3378/// \code
3379/// class X {}; // Matches X, because X::X is a class of name X inside X.
3380/// class Y { class X {}; };
3381/// class Z { class Y { class X {}; }; }; // Does not match Z.
3382/// \endcode
3383///
3384/// ChildT must be an AST base type.
3385///
3386/// Usable as: Any Matcher
3387/// Note that has is direct matcher, so it also matches things like implicit
3388/// casts and paren casts. If you are matching with expr then you should
3389/// probably consider using ignoringParenImpCasts like:
3390/// has(ignoringParenImpCasts(expr())).
3391extern const internal::ArgumentAdaptingMatcherFunc<internal::HasMatcher> has;
3392
3393/// Matches AST nodes that have descendant AST nodes that match the
3394/// provided matcher.
3395///
3396/// Example matches X, Y, Z
3397/// (matcher = cxxRecordDecl(hasDescendant(cxxRecordDecl(hasName("X")))))
3398/// \code
3399/// class X {}; // Matches X, because X::X is a class of name X inside X.
3400/// class Y { class X {}; };
3401/// class Z { class Y { class X {}; }; };
3402/// \endcode
3403///
3404/// DescendantT must be an AST base type.
3405///
3406/// Usable as: Any Matcher
3407extern const internal::ArgumentAdaptingMatcherFunc<
3408 internal::HasDescendantMatcher>
3409 hasDescendant;
3410
3411/// Matches AST nodes that have child AST nodes that match the
3412/// provided matcher.
3413///
3414/// Example matches X, Y, Y::X, Z::Y, Z::Y::X
3415/// (matcher = cxxRecordDecl(forEach(cxxRecordDecl(hasName("X")))
3416/// \code
3417/// class X {};
3418/// class Y { class X {}; }; // Matches Y, because Y::X is a class of name X
3419/// // inside Y.
3420/// class Z { class Y { class X {}; }; }; // Does not match Z.
3421/// \endcode
3422///
3423/// ChildT must be an AST base type.
3424///
3425/// As opposed to 'has', 'forEach' will cause a match for each result that
3426/// matches instead of only on the first one.
3427///
3428/// Usable as: Any Matcher
3429extern const internal::ArgumentAdaptingMatcherFunc<internal::ForEachMatcher>
3430 forEach;
3431
3432/// Matches AST nodes that have descendant AST nodes that match the
3433/// provided matcher.
3434///
3435/// Example matches X, A, A::X, B, B::C, B::C::X
3436/// (matcher = cxxRecordDecl(forEachDescendant(cxxRecordDecl(hasName("X")))))
3437/// \code
3438/// class X {};
3439/// class A { class X {}; }; // Matches A, because A::X is a class of name
3440/// // X inside A.
3441/// class B { class C { class X {}; }; };
3442/// \endcode
3443///
3444/// DescendantT must be an AST base type.
3445///
3446/// As opposed to 'hasDescendant', 'forEachDescendant' will cause a match for
3447/// each result that matches instead of only on the first one.
3448///
3449/// Note: Recursively combined ForEachDescendant can cause many matches:
3450/// cxxRecordDecl(forEachDescendant(cxxRecordDecl(
3451/// forEachDescendant(cxxRecordDecl())
3452/// )))
3453/// will match 10 times (plus injected class name matches) on:
3454/// \code
3455/// class A { class B { class C { class D { class E {}; }; }; }; };
3456/// \endcode
3457///
3458/// Usable as: Any Matcher
3459extern const internal::ArgumentAdaptingMatcherFunc<
3460 internal::ForEachDescendantMatcher>
3461 forEachDescendant;
3462
3463/// Matches if the node or any descendant matches.
3464///
3465/// Generates results for each match.
3466///
3467/// For example, in:
3468/// \code
3469/// class A { class B {}; class C {}; };
3470/// \endcode
3471/// The matcher:
3472/// \code
3473/// cxxRecordDecl(hasName("::A"),
3474/// findAll(cxxRecordDecl(isDefinition()).bind("m")))
3475/// \endcode
3476/// will generate results for \c A, \c B and \c C.
3477///
3478/// Usable as: Any Matcher
3479template <typename T>
3480internal::Matcher<T> findAll(const internal::Matcher<T> &Matcher) {
3481 return eachOf(Matcher, forEachDescendant(Matcher));
3482}
3483
3484/// Matches AST nodes that have a parent that matches the provided
3485/// matcher.
3486///
3487/// Given
3488/// \code
3489/// void f() { for (;;) { int x = 42; if (true) { int x = 43; } } }
3490/// \endcode
3491/// \c compoundStmt(hasParent(ifStmt())) matches "{ int x = 43; }".
3492///
3493/// Usable as: Any Matcher
3494extern const internal::ArgumentAdaptingMatcherFunc<
3495 internal::HasParentMatcher,
3496 internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>,
3497 internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>>
3498 hasParent;
3499
3500/// Matches AST nodes that have an ancestor that matches the provided
3501/// matcher.
3502///
3503/// Given
3504/// \code
3505/// void f() { if (true) { int x = 42; } }
3506/// void g() { for (;;) { int x = 43; } }
3507/// \endcode
3508/// \c expr(integerLiteral(hasAncestor(ifStmt()))) matches \c 42, but not 43.
3509///
3510/// Usable as: Any Matcher
3511extern const internal::ArgumentAdaptingMatcherFunc<
3512 internal::HasAncestorMatcher,
3513 internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>,
3514 internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>>
3515 hasAncestor;
3516
3517/// Matches if the provided matcher does not match.
3518///
3519/// Example matches Y (matcher = cxxRecordDecl(unless(hasName("X"))))
3520/// \code
3521/// class X {};
3522/// class Y {};
3523/// \endcode
3524///
3525/// Usable as: Any Matcher
3526extern const internal::VariadicOperatorMatcherFunc<1, 1> unless;
3527
3528/// Matches a node if the declaration associated with that node
3529/// matches the given matcher.
3530///
3531/// The associated declaration is:
3532/// - for type nodes, the declaration of the underlying type
3533/// - for CallExpr, the declaration of the callee
3534/// - for MemberExpr, the declaration of the referenced member
3535/// - for CXXConstructExpr, the declaration of the constructor
3536/// - for CXXNewExpr, the declaration of the operator new
3537/// - for ObjCIvarExpr, the declaration of the ivar
3538///
3539/// For type nodes, hasDeclaration will generally match the declaration of the
3540/// sugared type. Given
3541/// \code
3542/// class X {};
3543/// typedef X Y;
3544/// Y y;
3545/// \endcode
3546/// in varDecl(hasType(hasDeclaration(decl()))) the decl will match the
3547/// typedefDecl. A common use case is to match the underlying, desugared type.
3548/// This can be achieved by using the hasUnqualifiedDesugaredType matcher:
3549/// \code
3550/// varDecl(hasType(hasUnqualifiedDesugaredType(
3551/// recordType(hasDeclaration(decl())))))
3552/// \endcode
3553/// In this matcher, the decl will match the CXXRecordDecl of class X.
3554///
3555/// Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>,
3556/// Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>,
3557/// Matcher<EnumType>, Matcher<InjectedClassNameType>, Matcher<LabelStmt>,
3558/// Matcher<MemberExpr>, Matcher<QualType>, Matcher<RecordType>,
3559/// Matcher<TagType>, Matcher<TemplateSpecializationType>,
3560/// Matcher<TemplateTypeParmType>, Matcher<TypedefType>,
3561/// Matcher<UnresolvedUsingType>
3562inline internal::PolymorphicMatcher<
3563 internal::HasDeclarationMatcher,
3564 void(internal::HasDeclarationSupportedTypes), internal::Matcher<Decl>>
3565hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) {
3566 return internal::PolymorphicMatcher<
3567 internal::HasDeclarationMatcher,
3568 void(internal::HasDeclarationSupportedTypes), internal::Matcher<Decl>>(
3569 InnerMatcher);
3570}
3571
3572/// Matches a \c NamedDecl whose underlying declaration matches the given
3573/// matcher.
3574///
3575/// Given
3576/// \code
3577/// namespace N { template<class T> void f(T t); }
3578/// template <class T> void g() { using N::f; f(T()); }
3579/// \endcode
3580/// \c unresolvedLookupExpr(hasAnyDeclaration(
3581/// namedDecl(hasUnderlyingDecl(hasName("::N::f")))))
3582/// matches the use of \c f in \c g() .
3583AST_MATCHER_P(NamedDecl, hasUnderlyingDecl, internal::Matcher<NamedDecl>,namespace internal { class matcher_hasUnderlyingDecl0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
NamedDecl> { public: explicit matcher_hasUnderlyingDecl0Matcher
( internal::Matcher<NamedDecl> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const NamedDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<NamedDecl
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<NamedDecl> hasUnderlyingDecl( internal::Matcher
<NamedDecl> const &InnerMatcher) { return ::clang::
ast_matchers::internal::makeMatcher( new internal::matcher_hasUnderlyingDecl0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<NamedDecl> ( &hasUnderlyingDecl_Type0)(internal::Matcher
<NamedDecl> const &InnerMatcher); inline bool internal
::matcher_hasUnderlyingDecl0Matcher::matches( const NamedDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
3584 InnerMatcher)namespace internal { class matcher_hasUnderlyingDecl0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
NamedDecl> { public: explicit matcher_hasUnderlyingDecl0Matcher
( internal::Matcher<NamedDecl> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const NamedDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<NamedDecl
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<NamedDecl> hasUnderlyingDecl( internal::Matcher
<NamedDecl> const &InnerMatcher) { return ::clang::
ast_matchers::internal::makeMatcher( new internal::matcher_hasUnderlyingDecl0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<NamedDecl> ( &hasUnderlyingDecl_Type0)(internal::Matcher
<NamedDecl> const &InnerMatcher); inline bool internal
::matcher_hasUnderlyingDecl0Matcher::matches( const NamedDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
3585 const NamedDecl *UnderlyingDecl = Node.getUnderlyingDecl();
3586
3587 return UnderlyingDecl != nullptr &&
3588 InnerMatcher.matches(*UnderlyingDecl, Finder, Builder);
3589}
3590
3591/// Matches on the implicit object argument of a member call expression, after
3592/// stripping off any parentheses or implicit casts.
3593///
3594/// Given
3595/// \code
3596/// class Y { public: void m(); };
3597/// Y g();
3598/// class X : public Y {};
3599/// void z(Y y, X x) { y.m(); (g()).m(); x.m(); }
3600/// \endcode
3601/// cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y")))))
3602/// matches `y.m()` and `(g()).m()`.
3603/// cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("X")))))
3604/// matches `x.m()`.
3605/// cxxMemberCallExpr(on(callExpr()))
3606/// matches `(g()).m()`.
3607///
3608/// FIXME: Overload to allow directly matching types?
3609AST_MATCHER_P(CXXMemberCallExpr, on, internal::Matcher<Expr>,namespace internal { class matcher_on0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<CXXMemberCallExpr
> { public: explicit matcher_on0Matcher( internal::Matcher
<Expr> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const CXXMemberCallExpr &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<CXXMemberCallExpr> on
( internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_on0Matcher(InnerMatcher)); } typedef ::clang::ast_matchers
::internal::Matcher<CXXMemberCallExpr> ( &on_Type0)
(internal::Matcher<Expr> const &InnerMatcher); inline
bool internal::matcher_on0Matcher::matches( const CXXMemberCallExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
3610 InnerMatcher)namespace internal { class matcher_on0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<CXXMemberCallExpr
> { public: explicit matcher_on0Matcher( internal::Matcher
<Expr> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const CXXMemberCallExpr &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<CXXMemberCallExpr> on
( internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_on0Matcher(InnerMatcher)); } typedef ::clang::ast_matchers
::internal::Matcher<CXXMemberCallExpr> ( &on_Type0)
(internal::Matcher<Expr> const &InnerMatcher); inline
bool internal::matcher_on0Matcher::matches( const CXXMemberCallExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
3611 const Expr *ExprNode = Node.getImplicitObjectArgument()
3612 ->IgnoreParenImpCasts();
3613 return (ExprNode != nullptr &&
3614 InnerMatcher.matches(*ExprNode, Finder, Builder));
3615}
3616
3617
3618/// Matches on the receiver of an ObjectiveC Message expression.
3619///
3620/// Example
3621/// matcher = objCMessageExpr(hasReceiverType(asString("UIWebView *")));
3622/// matches the [webView ...] message invocation.
3623/// \code
3624/// NSString *webViewJavaScript = ...
3625/// UIWebView *webView = ...
3626/// [webView stringByEvaluatingJavaScriptFromString:webViewJavascript];
3627/// \endcode
3628AST_MATCHER_P(ObjCMessageExpr, hasReceiverType, internal::Matcher<QualType>,namespace internal { class matcher_hasReceiverType0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<ObjCMessageExpr
> { public: explicit matcher_hasReceiverType0Matcher( internal
::Matcher<QualType> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const ObjCMessageExpr &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<QualType> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<ObjCMessageExpr
> hasReceiverType( internal::Matcher<QualType> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
makeMatcher( new internal::matcher_hasReceiverType0Matcher(InnerMatcher
)); } typedef ::clang::ast_matchers::internal::Matcher<ObjCMessageExpr
> ( &hasReceiverType_Type0)(internal::Matcher<QualType
> const &InnerMatcher); inline bool internal::matcher_hasReceiverType0Matcher
::matches( const ObjCMessageExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
3629 InnerMatcher)namespace internal { class matcher_hasReceiverType0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<ObjCMessageExpr
> { public: explicit matcher_hasReceiverType0Matcher( internal
::Matcher<QualType> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const ObjCMessageExpr &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<QualType> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<ObjCMessageExpr
> hasReceiverType( internal::Matcher<QualType> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
makeMatcher( new internal::matcher_hasReceiverType0Matcher(InnerMatcher
)); } typedef ::clang::ast_matchers::internal::Matcher<ObjCMessageExpr
> ( &hasReceiverType_Type0)(internal::Matcher<QualType
> const &InnerMatcher); inline bool internal::matcher_hasReceiverType0Matcher
::matches( const ObjCMessageExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
3630 const QualType TypeDecl = Node.getReceiverType();
3631 return InnerMatcher.matches(TypeDecl, Finder, Builder);
3632}
3633
3634/// Returns true when the Objective-C method declaration is a class method.
3635///
3636/// Example
3637/// matcher = objcMethodDecl(isClassMethod())
3638/// matches
3639/// \code
3640/// @interface I + (void)foo; @end
3641/// \endcode
3642/// but not
3643/// \code
3644/// @interface I - (void)bar; @end
3645/// \endcode
3646AST_MATCHER(ObjCMethodDecl, isClassMethod)namespace internal { class matcher_isClassMethodMatcher : public
::clang::ast_matchers::internal::MatcherInterface<ObjCMethodDecl
> { public: explicit matcher_isClassMethodMatcher() = default
; bool matches(const ObjCMethodDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<ObjCMethodDecl>
isClassMethod() { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_isClassMethodMatcher()); } inline bool
internal::matcher_isClassMethodMatcher::matches( const ObjCMethodDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
3647 return Node.isClassMethod();
3648}
3649
3650/// Returns true when the Objective-C method declaration is an instance method.
3651///
3652/// Example
3653/// matcher = objcMethodDecl(isInstanceMethod())
3654/// matches
3655/// \code
3656/// @interface I - (void)bar; @end
3657/// \endcode
3658/// but not
3659/// \code
3660/// @interface I + (void)foo; @end
3661/// \endcode
3662AST_MATCHER(ObjCMethodDecl, isInstanceMethod)namespace internal { class matcher_isInstanceMethodMatcher : public
::clang::ast_matchers::internal::MatcherInterface<ObjCMethodDecl
> { public: explicit matcher_isInstanceMethodMatcher() = default
; bool matches(const ObjCMethodDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<ObjCMethodDecl>
isInstanceMethod() { return ::clang::ast_matchers::internal::
makeMatcher( new internal::matcher_isInstanceMethodMatcher())
; } inline bool internal::matcher_isInstanceMethodMatcher::matches
( const ObjCMethodDecl &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
3663 return Node.isInstanceMethod();
3664}
3665
3666/// Returns true when the Objective-C message is sent to a class.
3667///
3668/// Example
3669/// matcher = objcMessageExpr(isClassMessage())
3670/// matches
3671/// \code
3672/// [NSString stringWithFormat:@"format"];
3673/// \endcode
3674/// but not
3675/// \code
3676/// NSString *x = @"hello";
3677/// [x containsString:@"h"];
3678/// \endcode
3679AST_MATCHER(ObjCMessageExpr, isClassMessage)namespace internal { class matcher_isClassMessageMatcher : public
::clang::ast_matchers::internal::MatcherInterface<ObjCMessageExpr
> { public: explicit matcher_isClassMessageMatcher() = default
; bool matches(const ObjCMessageExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<ObjCMessageExpr>
isClassMessage() { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_isClassMessageMatcher()); } inline bool
internal::matcher_isClassMessageMatcher::matches( const ObjCMessageExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
3680 return Node.isClassMessage();
3681}
3682
3683/// Returns true when the Objective-C message is sent to an instance.
3684///
3685/// Example
3686/// matcher = objcMessageExpr(isInstanceMessage())
3687/// matches
3688/// \code
3689/// NSString *x = @"hello";
3690/// [x containsString:@"h"];
3691/// \endcode
3692/// but not
3693/// \code
3694/// [NSString stringWithFormat:@"format"];
3695/// \endcode
3696AST_MATCHER(ObjCMessageExpr, isInstanceMessage)namespace internal { class matcher_isInstanceMessageMatcher :
public ::clang::ast_matchers::internal::MatcherInterface<
ObjCMessageExpr> { public: explicit matcher_isInstanceMessageMatcher
() = default; bool matches(const ObjCMessageExpr &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
override; }; } inline ::clang::ast_matchers::internal::Matcher
<ObjCMessageExpr> isInstanceMessage() { return ::clang::
ast_matchers::internal::makeMatcher( new internal::matcher_isInstanceMessageMatcher
()); } inline bool internal::matcher_isInstanceMessageMatcher
::matches( const ObjCMessageExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
3697 return Node.isInstanceMessage();
3698}
3699
3700/// Matches if the Objective-C message is sent to an instance,
3701/// and the inner matcher matches on that instance.
3702///
3703/// For example the method call in
3704/// \code
3705/// NSString *x = @"hello";
3706/// [x containsString:@"h"];
3707/// \endcode
3708/// is matched by
3709/// objcMessageExpr(hasReceiver(declRefExpr(to(varDecl(hasName("x"))))))
3710AST_MATCHER_P(ObjCMessageExpr, hasReceiver, internal::Matcher<Expr>,namespace internal { class matcher_hasReceiver0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<ObjCMessageExpr
> { public: explicit matcher_hasReceiver0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const ObjCMessageExpr &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<Expr> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<ObjCMessageExpr
> hasReceiver( internal::Matcher<Expr> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_hasReceiver0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<ObjCMessageExpr> ( &
hasReceiver_Type0)(internal::Matcher<Expr> const &InnerMatcher
); inline bool internal::matcher_hasReceiver0Matcher::matches
( const ObjCMessageExpr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
3711 InnerMatcher)namespace internal { class matcher_hasReceiver0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<ObjCMessageExpr
> { public: explicit matcher_hasReceiver0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const ObjCMessageExpr &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<Expr> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<ObjCMessageExpr
> hasReceiver( internal::Matcher<Expr> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_hasReceiver0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<ObjCMessageExpr> ( &
hasReceiver_Type0)(internal::Matcher<Expr> const &InnerMatcher
); inline bool internal::matcher_hasReceiver0Matcher::matches
( const ObjCMessageExpr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
3712 const Expr *ReceiverNode = Node.getInstanceReceiver();
3713 return (ReceiverNode != nullptr &&
3714 InnerMatcher.matches(*ReceiverNode->IgnoreParenImpCasts(), Finder,
3715 Builder));
3716}
3717
3718/// Matches when BaseName == Selector.getAsString()
3719///
3720/// matcher = objCMessageExpr(hasSelector("loadHTMLString:baseURL:"));
3721/// matches the outer message expr in the code below, but NOT the message
3722/// invocation for self.bodyView.
3723/// \code
3724/// [self.bodyView loadHTMLString:html baseURL:NULL];
3725/// \endcode
3726AST_MATCHER_P(ObjCMessageExpr, hasSelector, std::string, BaseName)namespace internal { class matcher_hasSelector0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<ObjCMessageExpr
> { public: explicit matcher_hasSelector0Matcher( std::string
const &ABaseName) : BaseName(ABaseName) {} bool matches(
const ObjCMessageExpr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string BaseName; }; }
inline ::clang::ast_matchers::internal::Matcher<ObjCMessageExpr
> hasSelector( std::string const &BaseName) { return ::
clang::ast_matchers::internal::makeMatcher( new internal::matcher_hasSelector0Matcher
(BaseName)); } typedef ::clang::ast_matchers::internal::Matcher
<ObjCMessageExpr> ( &hasSelector_Type0)(std::string
const &BaseName); inline bool internal::matcher_hasSelector0Matcher
::matches( const ObjCMessageExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
3727 Selector Sel = Node.getSelector();
3728 return BaseName == Sel.getAsString();
3729}
3730
3731/// Matches when at least one of the supplied string equals to the
3732/// Selector.getAsString()
3733///
3734/// matcher = objCMessageExpr(hasSelector("methodA:", "methodB:"));
3735/// matches both of the expressions below:
3736/// \code
3737/// [myObj methodA:argA];
3738/// [myObj methodB:argB];
3739/// \endcode
3740extern const internal::VariadicFunction<internal::Matcher<ObjCMessageExpr>,
3741 StringRef,
3742 internal::hasAnySelectorFunc>
3743 hasAnySelector;
3744
3745/// Matches ObjC selectors whose name contains
3746/// a substring matched by the given RegExp.
3747/// matcher = objCMessageExpr(matchesSelector("loadHTMLString\:baseURL?"));
3748/// matches the outer message expr in the code below, but NOT the message
3749/// invocation for self.bodyView.
3750/// \code
3751/// [self.bodyView loadHTMLString:html baseURL:NULL];
3752/// \endcode
3753AST_MATCHER_REGEX(ObjCMessageExpr, matchesSelector, RegExp)namespace internal { class matcher_matchesSelector0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<ObjCMessageExpr
> { public: explicit matcher_matchesSelector0Matcher( std::
shared_ptr<llvm::Regex> RE) : RegExp(std::move(RE)) {} bool
matches(const ObjCMessageExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: std
::shared_ptr<llvm::Regex> RegExp; }; } inline ::clang::
ast_matchers::internal::Matcher<ObjCMessageExpr> matchesSelector
( llvm::StringRef RegExp, llvm::Regex::RegexFlags RegexFlags)
{ return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_matchesSelector0Matcher( ::clang::ast_matchers::internal
::createAndVerifyRegex( RegExp, RegexFlags, "matchesSelector"
))); } inline ::clang::ast_matchers::internal::Matcher<ObjCMessageExpr
> matchesSelector( llvm::StringRef RegExp) { return matchesSelector
(RegExp, llvm::Regex::NoFlags); } typedef ::clang::ast_matchers
::internal::Matcher<ObjCMessageExpr> ( &matchesSelector_Type0Flags
)(llvm::StringRef, llvm::Regex::RegexFlags); typedef ::clang::
ast_matchers::internal::Matcher<ObjCMessageExpr> ( &
matchesSelector_Type0)(llvm::StringRef); inline bool internal
::matcher_matchesSelector0Matcher::matches( const ObjCMessageExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
3754 std::string SelectorString = Node.getSelector().getAsString();
3755 return RegExp->match(SelectorString);
3756}
3757
3758/// Matches when the selector is the empty selector
3759///
3760/// Matches only when the selector of the objCMessageExpr is NULL. This may
3761/// represent an error condition in the tree!
3762AST_MATCHER(ObjCMessageExpr, hasNullSelector)namespace internal { class matcher_hasNullSelectorMatcher : public
::clang::ast_matchers::internal::MatcherInterface<ObjCMessageExpr
> { public: explicit matcher_hasNullSelectorMatcher() = default
; bool matches(const ObjCMessageExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<ObjCMessageExpr>
hasNullSelector() { return ::clang::ast_matchers::internal::
makeMatcher( new internal::matcher_hasNullSelectorMatcher());
} inline bool internal::matcher_hasNullSelectorMatcher::matches
( const ObjCMessageExpr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
3763 return Node.getSelector().isNull();
3764}
3765
3766/// Matches when the selector is a Unary Selector
3767///
3768/// matcher = objCMessageExpr(matchesSelector(hasUnarySelector());
3769/// matches self.bodyView in the code below, but NOT the outer message
3770/// invocation of "loadHTMLString:baseURL:".
3771/// \code
3772/// [self.bodyView loadHTMLString:html baseURL:NULL];
3773/// \endcode
3774AST_MATCHER(ObjCMessageExpr, hasUnarySelector)namespace internal { class matcher_hasUnarySelectorMatcher : public
::clang::ast_matchers::internal::MatcherInterface<ObjCMessageExpr
> { public: explicit matcher_hasUnarySelectorMatcher() = default
; bool matches(const ObjCMessageExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<ObjCMessageExpr>
hasUnarySelector() { return ::clang::ast_matchers::internal::
makeMatcher( new internal::matcher_hasUnarySelectorMatcher())
; } inline bool internal::matcher_hasUnarySelectorMatcher::matches
( const ObjCMessageExpr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
3775 return Node.getSelector().isUnarySelector();
3776}
3777
3778/// Matches when the selector is a keyword selector
3779///
3780/// objCMessageExpr(hasKeywordSelector()) matches the generated setFrame
3781/// message expression in
3782///
3783/// \code
3784/// UIWebView *webView = ...;
3785/// CGRect bodyFrame = webView.frame;
3786/// bodyFrame.size.height = self.bodyContentHeight;
3787/// webView.frame = bodyFrame;
3788/// // ^---- matches here
3789/// \endcode
3790AST_MATCHER(ObjCMessageExpr, hasKeywordSelector)namespace internal { class matcher_hasKeywordSelectorMatcher :
public ::clang::ast_matchers::internal::MatcherInterface<
ObjCMessageExpr> { public: explicit matcher_hasKeywordSelectorMatcher
() = default; bool matches(const ObjCMessageExpr &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
override; }; } inline ::clang::ast_matchers::internal::Matcher
<ObjCMessageExpr> hasKeywordSelector() { return ::clang
::ast_matchers::internal::makeMatcher( new internal::matcher_hasKeywordSelectorMatcher
()); } inline bool internal::matcher_hasKeywordSelectorMatcher
::matches( const ObjCMessageExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
3791 return Node.getSelector().isKeywordSelector();
3792}
3793
3794/// Matches when the selector has the specified number of arguments
3795///
3796/// matcher = objCMessageExpr(numSelectorArgs(0));
3797/// matches self.bodyView in the code below
3798///
3799/// matcher = objCMessageExpr(numSelectorArgs(2));
3800/// matches the invocation of "loadHTMLString:baseURL:" but not that
3801/// of self.bodyView
3802/// \code
3803/// [self.bodyView loadHTMLString:html baseURL:NULL];
3804/// \endcode
3805AST_MATCHER_P(ObjCMessageExpr, numSelectorArgs, unsigned, N)namespace internal { class matcher_numSelectorArgs0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<ObjCMessageExpr
> { public: explicit matcher_numSelectorArgs0Matcher( unsigned
const &AN) : N(AN) {} bool matches(const ObjCMessageExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; }; } inline ::
clang::ast_matchers::internal::Matcher<ObjCMessageExpr>
numSelectorArgs( unsigned const &N) { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_numSelectorArgs0Matcher
(N)); } typedef ::clang::ast_matchers::internal::Matcher<ObjCMessageExpr
> ( &numSelectorArgs_Type0)(unsigned const &N); inline
bool internal::matcher_numSelectorArgs0Matcher::matches( const
ObjCMessageExpr &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
3806 return Node.getSelector().getNumArgs() == N;
3807}
3808
3809/// Matches if the call expression's callee expression matches.
3810///
3811/// Given
3812/// \code
3813/// class Y { void x() { this->x(); x(); Y y; y.x(); } };
3814/// void f() { f(); }
3815/// \endcode
3816/// callExpr(callee(expr()))
3817/// matches this->x(), x(), y.x(), f()
3818/// with callee(...)
3819/// matching this->x, x, y.x, f respectively
3820///
3821/// Note: Callee cannot take the more general internal::Matcher<Expr>
3822/// because this introduces ambiguous overloads with calls to Callee taking a
3823/// internal::Matcher<Decl>, as the matcher hierarchy is purely
3824/// implemented in terms of implicit casts.
3825AST_MATCHER_P(CallExpr, callee, internal::Matcher<Stmt>,namespace internal { class matcher_callee0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<CallExpr>
{ public: explicit matcher_callee0Matcher( internal::Matcher
<Stmt> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const CallExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<Stmt> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::Matcher<CallExpr> callee( internal::Matcher
<Stmt> const &InnerMatcher) { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_callee0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<CallExpr> ( &callee_Type0)(internal::Matcher<Stmt
> const &InnerMatcher); inline bool internal::matcher_callee0Matcher
::matches( const CallExpr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
3826 InnerMatcher)namespace internal { class matcher_callee0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<CallExpr>
{ public: explicit matcher_callee0Matcher( internal::Matcher
<Stmt> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const CallExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<Stmt> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::Matcher<CallExpr> callee( internal::Matcher
<Stmt> const &InnerMatcher) { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_callee0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<CallExpr> ( &callee_Type0)(internal::Matcher<Stmt
> const &InnerMatcher); inline bool internal::matcher_callee0Matcher
::matches( const CallExpr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
3827 const Expr *ExprNode = Node.getCallee();
3828 return (ExprNode != nullptr &&
3829 InnerMatcher.matches(*ExprNode, Finder, Builder));
3830}
3831
3832/// Matches if the call expression's callee's declaration matches the
3833/// given matcher.
3834///
3835/// Example matches y.x() (matcher = callExpr(callee(
3836/// cxxMethodDecl(hasName("x")))))
3837/// \code
3838/// class Y { public: void x(); };
3839/// void z() { Y y; y.x(); }
3840/// \endcode
3841AST_MATCHER_P_OVERLOAD(CallExpr, callee, internal::Matcher<Decl>, InnerMatcher,namespace internal { class matcher_callee1Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<CallExpr>
{ public: explicit matcher_callee1Matcher( internal::Matcher
<Decl> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const CallExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<Decl> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::Matcher<CallExpr> callee( internal::Matcher
<Decl> const &InnerMatcher) { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_callee1Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<CallExpr> ( &callee_Type1)(internal::Matcher<Decl
> const &InnerMatcher); inline bool internal::matcher_callee1Matcher
::matches( const CallExpr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
3842 1)namespace internal { class matcher_callee1Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<CallExpr>
{ public: explicit matcher_callee1Matcher( internal::Matcher
<Decl> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const CallExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<Decl> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::Matcher<CallExpr> callee( internal::Matcher
<Decl> const &InnerMatcher) { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_callee1Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<CallExpr> ( &callee_Type1)(internal::Matcher<Decl
> const &InnerMatcher); inline bool internal::matcher_callee1Matcher
::matches( const CallExpr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
3843 return callExpr(hasDeclaration(InnerMatcher)).matches(Node, Finder, Builder);
3844}
3845
3846/// Matches if the expression's or declaration's type matches a type
3847/// matcher.
3848///
3849/// Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
3850/// and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
3851/// and U (matcher = typedefDecl(hasType(asString("int")))
3852/// and friend class X (matcher = friendDecl(hasType("X"))
3853/// and public virtual X (matcher = cxxBaseSpecifier(hasType(
3854/// asString("class X")))
3855/// \code
3856/// class X {};
3857/// void y(X &x) { x; X z; }
3858/// typedef int U;
3859/// class Y { friend class X; };
3860/// class Z : public virtual X {};
3861/// \endcode
3862AST_POLYMORPHIC_MATCHER_P_OVERLOAD(namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasType0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasType0Matcher( internal::Matcher<QualType> const
&AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<QualType
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasType0Matcher, void
(::clang::ast_matchers::internal::TypeList<Expr, FriendDecl
, TypedefNameDecl, ValueDecl, CXXBaseSpecifier>), internal
::Matcher<QualType> > hasType(internal::Matcher<QualType
> const &InnerMatcher) { return ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_hasType0Matcher
, void(::clang::ast_matchers::internal::TypeList<Expr, FriendDecl
, TypedefNameDecl, ValueDecl, CXXBaseSpecifier>), internal
::Matcher<QualType> >(InnerMatcher); } typedef ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasType0Matcher
, void(::clang::ast_matchers::internal::TypeList<Expr, FriendDecl
, TypedefNameDecl, ValueDecl, CXXBaseSpecifier>), internal
::Matcher<QualType> > (&hasType_Type0)(internal::
Matcher<QualType> const &InnerMatcher); template <
typename NodeType, typename ParamT> bool internal:: matcher_hasType0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3863 hasType,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasType0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasType0Matcher( internal::Matcher<QualType> const
&AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<QualType
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasType0Matcher, void
(::clang::ast_matchers::internal::TypeList<Expr, FriendDecl
, TypedefNameDecl, ValueDecl, CXXBaseSpecifier>), internal
::Matcher<QualType> > hasType(internal::Matcher<QualType
> const &InnerMatcher) { return ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_hasType0Matcher
, void(::clang::ast_matchers::internal::TypeList<Expr, FriendDecl
, TypedefNameDecl, ValueDecl, CXXBaseSpecifier>), internal
::Matcher<QualType> >(InnerMatcher); } typedef ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasType0Matcher
, void(::clang::ast_matchers::internal::TypeList<Expr, FriendDecl
, TypedefNameDecl, ValueDecl, CXXBaseSpecifier>), internal
::Matcher<QualType> > (&hasType_Type0)(internal::
Matcher<QualType> const &InnerMatcher); template <
typename NodeType, typename ParamT> bool internal:: matcher_hasType0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3864 AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, FriendDecl, TypedefNameDecl,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasType0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasType0Matcher( internal::Matcher<QualType> const
&AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<QualType
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasType0Matcher, void
(::clang::ast_matchers::internal::TypeList<Expr, FriendDecl
, TypedefNameDecl, ValueDecl, CXXBaseSpecifier>), internal
::Matcher<QualType> > hasType(internal::Matcher<QualType
> const &InnerMatcher) { return ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_hasType0Matcher
, void(::clang::ast_matchers::internal::TypeList<Expr, FriendDecl
, TypedefNameDecl, ValueDecl, CXXBaseSpecifier>), internal
::Matcher<QualType> >(InnerMatcher); } typedef ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasType0Matcher
, void(::clang::ast_matchers::internal::TypeList<Expr, FriendDecl
, TypedefNameDecl, ValueDecl, CXXBaseSpecifier>), internal
::Matcher<QualType> > (&hasType_Type0)(internal::
Matcher<QualType> const &InnerMatcher); template <
typename NodeType, typename ParamT> bool internal:: matcher_hasType0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3865 ValueDecl, CXXBaseSpecifier),namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasType0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasType0Matcher( internal::Matcher<QualType> const
&AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<QualType
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasType0Matcher, void
(::clang::ast_matchers::internal::TypeList<Expr, FriendDecl
, TypedefNameDecl, ValueDecl, CXXBaseSpecifier>), internal
::Matcher<QualType> > hasType(internal::Matcher<QualType
> const &InnerMatcher) { return ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_hasType0Matcher
, void(::clang::ast_matchers::internal::TypeList<Expr, FriendDecl
, TypedefNameDecl, ValueDecl, CXXBaseSpecifier>), internal
::Matcher<QualType> >(InnerMatcher); } typedef ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasType0Matcher
, void(::clang::ast_matchers::internal::TypeList<Expr, FriendDecl
, TypedefNameDecl, ValueDecl, CXXBaseSpecifier>), internal
::Matcher<QualType> > (&hasType_Type0)(internal::
Matcher<QualType> const &InnerMatcher); template <
typename NodeType, typename ParamT> bool internal:: matcher_hasType0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3866 internal::Matcher<QualType>, InnerMatcher, 0)namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasType0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasType0Matcher( internal::Matcher<QualType> const
&AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<QualType
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasType0Matcher, void
(::clang::ast_matchers::internal::TypeList<Expr, FriendDecl
, TypedefNameDecl, ValueDecl, CXXBaseSpecifier>), internal
::Matcher<QualType> > hasType(internal::Matcher<QualType
> const &InnerMatcher) { return ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_hasType0Matcher
, void(::clang::ast_matchers::internal::TypeList<Expr, FriendDecl
, TypedefNameDecl, ValueDecl, CXXBaseSpecifier>), internal
::Matcher<QualType> >(InnerMatcher); } typedef ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasType0Matcher
, void(::clang::ast_matchers::internal::TypeList<Expr, FriendDecl
, TypedefNameDecl, ValueDecl, CXXBaseSpecifier>), internal
::Matcher<QualType> > (&hasType_Type0)(internal::
Matcher<QualType> const &InnerMatcher); template <
typename NodeType, typename ParamT> bool internal:: matcher_hasType0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
{
3867 QualType QT = internal::getUnderlyingType(Node);
3868 if (!QT.isNull())
3869 return InnerMatcher.matches(QT, Finder, Builder);
3870 return false;
3871}
3872
3873/// Overloaded to match the declaration of the expression's or value
3874/// declaration's type.
3875///
3876/// In case of a value declaration (for example a variable declaration),
3877/// this resolves one layer of indirection. For example, in the value
3878/// declaration "X x;", cxxRecordDecl(hasName("X")) matches the declaration of
3879/// X, while varDecl(hasType(cxxRecordDecl(hasName("X")))) matches the
3880/// declaration of x.
3881///
3882/// Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
3883/// and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
3884/// and friend class X (matcher = friendDecl(hasType("X"))
3885/// and public virtual X (matcher = cxxBaseSpecifier(hasType(
3886/// cxxRecordDecl(hasName("X"))))
3887/// \code
3888/// class X {};
3889/// void y(X &x) { x; X z; }
3890/// class Y { friend class X; };
3891/// class Z : public virtual X {};
3892/// \endcode
3893///
3894/// Example matches class Derived
3895/// (matcher = cxxRecordDecl(hasAnyBase(hasType(cxxRecordDecl(hasName("Base"))))))
3896/// \code
3897/// class Base {};
3898/// class Derived : Base {};
3899/// \endcode
3900///
3901/// Usable as: Matcher<Expr>, Matcher<FriendDecl>, Matcher<ValueDecl>,
3902/// Matcher<CXXBaseSpecifier>
3903AST_POLYMORPHIC_MATCHER_P_OVERLOAD(namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasType1Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasType1Matcher( internal::Matcher<Decl> const
&AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Decl
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasType1Matcher, void
(::clang::ast_matchers::internal::TypeList<Expr, FriendDecl
, ValueDecl, CXXBaseSpecifier>), internal::Matcher<Decl
> > hasType(internal::Matcher<Decl> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasType1Matcher, void(::clang::ast_matchers
::internal::TypeList<Expr, FriendDecl, ValueDecl, CXXBaseSpecifier
>), internal::Matcher<Decl> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasType1Matcher, void(::clang::ast_matchers::internal
::TypeList<Expr, FriendDecl, ValueDecl, CXXBaseSpecifier>
), internal::Matcher<Decl> > (&hasType_Type1)(internal
::Matcher<Decl> const &InnerMatcher); template <
typename NodeType, typename ParamT> bool internal:: matcher_hasType1Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3904 hasType,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasType1Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasType1Matcher( internal::Matcher<Decl> const
&AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Decl
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasType1Matcher, void
(::clang::ast_matchers::internal::TypeList<Expr, FriendDecl
, ValueDecl, CXXBaseSpecifier>), internal::Matcher<Decl
> > hasType(internal::Matcher<Decl> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasType1Matcher, void(::clang::ast_matchers
::internal::TypeList<Expr, FriendDecl, ValueDecl, CXXBaseSpecifier
>), internal::Matcher<Decl> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasType1Matcher, void(::clang::ast_matchers::internal
::TypeList<Expr, FriendDecl, ValueDecl, CXXBaseSpecifier>
), internal::Matcher<Decl> > (&hasType_Type1)(internal
::Matcher<Decl> const &InnerMatcher); template <
typename NodeType, typename ParamT> bool internal:: matcher_hasType1Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3905 AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, FriendDecl, ValueDecl,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasType1Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasType1Matcher( internal::Matcher<Decl> const
&AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Decl
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasType1Matcher, void
(::clang::ast_matchers::internal::TypeList<Expr, FriendDecl
, ValueDecl, CXXBaseSpecifier>), internal::Matcher<Decl
> > hasType(internal::Matcher<Decl> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasType1Matcher, void(::clang::ast_matchers
::internal::TypeList<Expr, FriendDecl, ValueDecl, CXXBaseSpecifier
>), internal::Matcher<Decl> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasType1Matcher, void(::clang::ast_matchers::internal
::TypeList<Expr, FriendDecl, ValueDecl, CXXBaseSpecifier>
), internal::Matcher<Decl> > (&hasType_Type1)(internal
::Matcher<Decl> const &InnerMatcher); template <
typename NodeType, typename ParamT> bool internal:: matcher_hasType1Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3906 CXXBaseSpecifier),namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasType1Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasType1Matcher( internal::Matcher<Decl> const
&AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Decl
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasType1Matcher, void
(::clang::ast_matchers::internal::TypeList<Expr, FriendDecl
, ValueDecl, CXXBaseSpecifier>), internal::Matcher<Decl
> > hasType(internal::Matcher<Decl> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasType1Matcher, void(::clang::ast_matchers
::internal::TypeList<Expr, FriendDecl, ValueDecl, CXXBaseSpecifier
>), internal::Matcher<Decl> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasType1Matcher, void(::clang::ast_matchers::internal
::TypeList<Expr, FriendDecl, ValueDecl, CXXBaseSpecifier>
), internal::Matcher<Decl> > (&hasType_Type1)(internal
::Matcher<Decl> const &InnerMatcher); template <
typename NodeType, typename ParamT> bool internal:: matcher_hasType1Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3907 internal::Matcher<Decl>, InnerMatcher, 1)namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasType1Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasType1Matcher( internal::Matcher<Decl> const
&AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Decl
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasType1Matcher, void
(::clang::ast_matchers::internal::TypeList<Expr, FriendDecl
, ValueDecl, CXXBaseSpecifier>), internal::Matcher<Decl
> > hasType(internal::Matcher<Decl> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasType1Matcher, void(::clang::ast_matchers
::internal::TypeList<Expr, FriendDecl, ValueDecl, CXXBaseSpecifier
>), internal::Matcher<Decl> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasType1Matcher, void(::clang::ast_matchers::internal
::TypeList<Expr, FriendDecl, ValueDecl, CXXBaseSpecifier>
), internal::Matcher<Decl> > (&hasType_Type1)(internal
::Matcher<Decl> const &InnerMatcher); template <
typename NodeType, typename ParamT> bool internal:: matcher_hasType1Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
{
3908 QualType QT = internal::getUnderlyingType(Node);
3909 if (!QT.isNull())
3910 return qualType(hasDeclaration(InnerMatcher)).matches(QT, Finder, Builder);
3911 return false;
3912}
3913
3914/// Matches if the type location of a node matches the inner matcher.
3915///
3916/// Examples:
3917/// \code
3918/// int x;
3919/// \endcode
3920/// declaratorDecl(hasTypeLoc(loc(asString("int"))))
3921/// matches int x
3922///
3923/// \code
3924/// auto x = int(3);
3925/// \code
3926/// cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int"))))
3927/// matches int(3)
3928///
3929/// \code
3930/// struct Foo { Foo(int, int); };
3931/// auto x = Foo(1, 2);
3932/// \code
3933/// cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo"))))
3934/// matches Foo(1, 2)
3935///
3936/// Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>,
3937/// Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>,
3938/// Matcher<CXXNewExpr>, Matcher<CXXTemporaryObjectExpr>,
3939/// Matcher<CXXUnresolvedConstructExpr>,
3940/// Matcher<ClassTemplateSpecializationDecl>, Matcher<CompoundLiteralExpr>,
3941/// Matcher<DeclaratorDecl>, Matcher<ExplicitCastExpr>,
3942/// Matcher<ObjCPropertyDecl>, Matcher<TemplateArgumentLoc>,
3943/// Matcher<TypedefNameDecl>
3944AST_POLYMORPHIC_MATCHER_P(namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasTypeLoc0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_hasTypeLoc0Matcher( internal::Matcher<TypeLoc
> const &AInner) : Inner(AInner) {} bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<TypeLoc
> Inner; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasTypeLoc0Matcher, void(::clang::ast_matchers
::internal::TypeList<BlockDecl, CXXBaseSpecifier, CXXCtorInitializer
, CXXFunctionalCastExpr, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> > hasTypeLoc(internal
::Matcher<TypeLoc> const &Inner) { return ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasTypeLoc0Matcher
, void(::clang::ast_matchers::internal::TypeList<BlockDecl
, CXXBaseSpecifier, CXXCtorInitializer, CXXFunctionalCastExpr
, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> >(Inner); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasTypeLoc0Matcher, void(::clang::ast_matchers::internal
::TypeList<BlockDecl, CXXBaseSpecifier, CXXCtorInitializer
, CXXFunctionalCastExpr, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> > (&hasTypeLoc_Type0
)(internal::Matcher<TypeLoc> const &Inner); template
<typename NodeType, typename ParamT> bool internal:: matcher_hasTypeLoc0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3945 hasTypeLoc,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasTypeLoc0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_hasTypeLoc0Matcher( internal::Matcher<TypeLoc
> const &AInner) : Inner(AInner) {} bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<TypeLoc
> Inner; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasTypeLoc0Matcher, void(::clang::ast_matchers
::internal::TypeList<BlockDecl, CXXBaseSpecifier, CXXCtorInitializer
, CXXFunctionalCastExpr, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> > hasTypeLoc(internal
::Matcher<TypeLoc> const &Inner) { return ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasTypeLoc0Matcher
, void(::clang::ast_matchers::internal::TypeList<BlockDecl
, CXXBaseSpecifier, CXXCtorInitializer, CXXFunctionalCastExpr
, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> >(Inner); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasTypeLoc0Matcher, void(::clang::ast_matchers::internal
::TypeList<BlockDecl, CXXBaseSpecifier, CXXCtorInitializer
, CXXFunctionalCastExpr, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> > (&hasTypeLoc_Type0
)(internal::Matcher<TypeLoc> const &Inner); template
<typename NodeType, typename ParamT> bool internal:: matcher_hasTypeLoc0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3946 AST_POLYMORPHIC_SUPPORTED_TYPES(namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasTypeLoc0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_hasTypeLoc0Matcher( internal::Matcher<TypeLoc
> const &AInner) : Inner(AInner) {} bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<TypeLoc
> Inner; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasTypeLoc0Matcher, void(::clang::ast_matchers
::internal::TypeList<BlockDecl, CXXBaseSpecifier, CXXCtorInitializer
, CXXFunctionalCastExpr, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> > hasTypeLoc(internal
::Matcher<TypeLoc> const &Inner) { return ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasTypeLoc0Matcher
, void(::clang::ast_matchers::internal::TypeList<BlockDecl
, CXXBaseSpecifier, CXXCtorInitializer, CXXFunctionalCastExpr
, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> >(Inner); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasTypeLoc0Matcher, void(::clang::ast_matchers::internal
::TypeList<BlockDecl, CXXBaseSpecifier, CXXCtorInitializer
, CXXFunctionalCastExpr, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> > (&hasTypeLoc_Type0
)(internal::Matcher<TypeLoc> const &Inner); template
<typename NodeType, typename ParamT> bool internal:: matcher_hasTypeLoc0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3947 BlockDecl, CXXBaseSpecifier, CXXCtorInitializer, CXXFunctionalCastExpr,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasTypeLoc0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_hasTypeLoc0Matcher( internal::Matcher<TypeLoc
> const &AInner) : Inner(AInner) {} bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<TypeLoc
> Inner; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasTypeLoc0Matcher, void(::clang::ast_matchers
::internal::TypeList<BlockDecl, CXXBaseSpecifier, CXXCtorInitializer
, CXXFunctionalCastExpr, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> > hasTypeLoc(internal
::Matcher<TypeLoc> const &Inner) { return ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasTypeLoc0Matcher
, void(::clang::ast_matchers::internal::TypeList<BlockDecl
, CXXBaseSpecifier, CXXCtorInitializer, CXXFunctionalCastExpr
, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> >(Inner); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasTypeLoc0Matcher, void(::clang::ast_matchers::internal
::TypeList<BlockDecl, CXXBaseSpecifier, CXXCtorInitializer
, CXXFunctionalCastExpr, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> > (&hasTypeLoc_Type0
)(internal::Matcher<TypeLoc> const &Inner); template
<typename NodeType, typename ParamT> bool internal:: matcher_hasTypeLoc0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3948 CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasTypeLoc0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_hasTypeLoc0Matcher( internal::Matcher<TypeLoc
> const &AInner) : Inner(AInner) {} bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<TypeLoc
> Inner; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasTypeLoc0Matcher, void(::clang::ast_matchers
::internal::TypeList<BlockDecl, CXXBaseSpecifier, CXXCtorInitializer
, CXXFunctionalCastExpr, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> > hasTypeLoc(internal
::Matcher<TypeLoc> const &Inner) { return ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasTypeLoc0Matcher
, void(::clang::ast_matchers::internal::TypeList<BlockDecl
, CXXBaseSpecifier, CXXCtorInitializer, CXXFunctionalCastExpr
, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> >(Inner); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasTypeLoc0Matcher, void(::clang::ast_matchers::internal
::TypeList<BlockDecl, CXXBaseSpecifier, CXXCtorInitializer
, CXXFunctionalCastExpr, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> > (&hasTypeLoc_Type0
)(internal::Matcher<TypeLoc> const &Inner); template
<typename NodeType, typename ParamT> bool internal:: matcher_hasTypeLoc0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3949 ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasTypeLoc0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_hasTypeLoc0Matcher( internal::Matcher<TypeLoc
> const &AInner) : Inner(AInner) {} bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<TypeLoc
> Inner; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasTypeLoc0Matcher, void(::clang::ast_matchers
::internal::TypeList<BlockDecl, CXXBaseSpecifier, CXXCtorInitializer
, CXXFunctionalCastExpr, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> > hasTypeLoc(internal
::Matcher<TypeLoc> const &Inner) { return ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasTypeLoc0Matcher
, void(::clang::ast_matchers::internal::TypeList<BlockDecl
, CXXBaseSpecifier, CXXCtorInitializer, CXXFunctionalCastExpr
, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> >(Inner); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasTypeLoc0Matcher, void(::clang::ast_matchers::internal
::TypeList<BlockDecl, CXXBaseSpecifier, CXXCtorInitializer
, CXXFunctionalCastExpr, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> > (&hasTypeLoc_Type0
)(internal::Matcher<TypeLoc> const &Inner); template
<typename NodeType, typename ParamT> bool internal:: matcher_hasTypeLoc0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3950 ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasTypeLoc0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_hasTypeLoc0Matcher( internal::Matcher<TypeLoc
> const &AInner) : Inner(AInner) {} bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<TypeLoc
> Inner; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasTypeLoc0Matcher, void(::clang::ast_matchers
::internal::TypeList<BlockDecl, CXXBaseSpecifier, CXXCtorInitializer
, CXXFunctionalCastExpr, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> > hasTypeLoc(internal
::Matcher<TypeLoc> const &Inner) { return ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasTypeLoc0Matcher
, void(::clang::ast_matchers::internal::TypeList<BlockDecl
, CXXBaseSpecifier, CXXCtorInitializer, CXXFunctionalCastExpr
, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> >(Inner); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasTypeLoc0Matcher, void(::clang::ast_matchers::internal
::TypeList<BlockDecl, CXXBaseSpecifier, CXXCtorInitializer
, CXXFunctionalCastExpr, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> > (&hasTypeLoc_Type0
)(internal::Matcher<TypeLoc> const &Inner); template
<typename NodeType, typename ParamT> bool internal:: matcher_hasTypeLoc0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3951 TypedefNameDecl),namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasTypeLoc0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_hasTypeLoc0Matcher( internal::Matcher<TypeLoc
> const &AInner) : Inner(AInner) {} bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<TypeLoc
> Inner; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasTypeLoc0Matcher, void(::clang::ast_matchers
::internal::TypeList<BlockDecl, CXXBaseSpecifier, CXXCtorInitializer
, CXXFunctionalCastExpr, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> > hasTypeLoc(internal
::Matcher<TypeLoc> const &Inner) { return ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasTypeLoc0Matcher
, void(::clang::ast_matchers::internal::TypeList<BlockDecl
, CXXBaseSpecifier, CXXCtorInitializer, CXXFunctionalCastExpr
, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> >(Inner); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasTypeLoc0Matcher, void(::clang::ast_matchers::internal
::TypeList<BlockDecl, CXXBaseSpecifier, CXXCtorInitializer
, CXXFunctionalCastExpr, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> > (&hasTypeLoc_Type0
)(internal::Matcher<TypeLoc> const &Inner); template
<typename NodeType, typename ParamT> bool internal:: matcher_hasTypeLoc0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3952 internal::Matcher<TypeLoc>, Inner)namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasTypeLoc0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_hasTypeLoc0Matcher( internal::Matcher<TypeLoc
> const &AInner) : Inner(AInner) {} bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<TypeLoc
> Inner; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasTypeLoc0Matcher, void(::clang::ast_matchers
::internal::TypeList<BlockDecl, CXXBaseSpecifier, CXXCtorInitializer
, CXXFunctionalCastExpr, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> > hasTypeLoc(internal
::Matcher<TypeLoc> const &Inner) { return ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasTypeLoc0Matcher
, void(::clang::ast_matchers::internal::TypeList<BlockDecl
, CXXBaseSpecifier, CXXCtorInitializer, CXXFunctionalCastExpr
, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> >(Inner); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasTypeLoc0Matcher, void(::clang::ast_matchers::internal
::TypeList<BlockDecl, CXXBaseSpecifier, CXXCtorInitializer
, CXXFunctionalCastExpr, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr
, ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl
, ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, TypedefNameDecl
>), internal::Matcher<TypeLoc> > (&hasTypeLoc_Type0
)(internal::Matcher<TypeLoc> const &Inner); template
<typename NodeType, typename ParamT> bool internal:: matcher_hasTypeLoc0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
{
3953 TypeSourceInfo *source = internal::GetTypeSourceInfo(Node);
3954 if (source == nullptr) {
3955 // This happens for example for implicit destructors.
3956 return false;
3957 }
3958 return Inner.matches(source->getTypeLoc(), Finder, Builder);
3959}
3960
3961/// Matches if the matched type is represented by the given string.
3962///
3963/// Given
3964/// \code
3965/// class Y { public: void x(); };
3966/// void z() { Y* y; y->x(); }
3967/// \endcode
3968/// cxxMemberCallExpr(on(hasType(asString("class Y *"))))
3969/// matches y->x()
3970AST_MATCHER_P(QualType, asString, std::string, Name)namespace internal { class matcher_asString0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<QualType>
{ public: explicit matcher_asString0Matcher( std::string const
&AName) : Name(AName) {} bool matches(const QualType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: std::string Name; }; } inline ::clang
::ast_matchers::internal::Matcher<QualType> asString( std
::string const &Name) { return ::clang::ast_matchers::internal
::makeMatcher( new internal::matcher_asString0Matcher(Name));
} typedef ::clang::ast_matchers::internal::Matcher<QualType
> ( &asString_Type0)(std::string const &Name); inline
bool internal::matcher_asString0Matcher::matches( const QualType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
3971 return Name == Node.getAsString();
3972}
3973
3974/// Matches if the matched type is a pointer type and the pointee type
3975/// matches the specified matcher.
3976///
3977/// Example matches y->x()
3978/// (matcher = cxxMemberCallExpr(on(hasType(pointsTo
3979/// cxxRecordDecl(hasName("Y")))))))
3980/// \code
3981/// class Y { public: void x(); };
3982/// void z() { Y *y; y->x(); }
3983/// \endcode
3984AST_MATCHER_P(namespace internal { class matcher_pointsTo0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<QualType>
{ public: explicit matcher_pointsTo0Matcher( internal::Matcher
<QualType> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const QualType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<QualType> InnerMatcher; }; } inline ::clang::
ast_matchers::internal::Matcher<QualType> pointsTo( internal
::Matcher<QualType> const &InnerMatcher) { return ::
clang::ast_matchers::internal::makeMatcher( new internal::matcher_pointsTo0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<QualType> ( &pointsTo_Type0)(internal::Matcher<
QualType> const &InnerMatcher); inline bool internal::
matcher_pointsTo0Matcher::matches( const QualType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3985 QualType, pointsTo, internal::Matcher<QualType>,namespace internal { class matcher_pointsTo0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<QualType>
{ public: explicit matcher_pointsTo0Matcher( internal::Matcher
<QualType> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const QualType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<QualType> InnerMatcher; }; } inline ::clang::
ast_matchers::internal::Matcher<QualType> pointsTo( internal
::Matcher<QualType> const &InnerMatcher) { return ::
clang::ast_matchers::internal::makeMatcher( new internal::matcher_pointsTo0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<QualType> ( &pointsTo_Type0)(internal::Matcher<
QualType> const &InnerMatcher); inline bool internal::
matcher_pointsTo0Matcher::matches( const QualType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
3986 InnerMatcher)namespace internal { class matcher_pointsTo0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<QualType>
{ public: explicit matcher_pointsTo0Matcher( internal::Matcher
<QualType> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const QualType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<QualType> InnerMatcher; }; } inline ::clang::
ast_matchers::internal::Matcher<QualType> pointsTo( internal
::Matcher<QualType> const &InnerMatcher) { return ::
clang::ast_matchers::internal::makeMatcher( new internal::matcher_pointsTo0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<QualType> ( &pointsTo_Type0)(internal::Matcher<
QualType> const &InnerMatcher); inline bool internal::
matcher_pointsTo0Matcher::matches( const QualType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
{
3987 return (!Node.isNull() && Node->isAnyPointerType() &&
3988 InnerMatcher.matches(Node->getPointeeType(), Finder, Builder));
3989}
3990
3991/// Overloaded to match the pointee type's declaration.
3992AST_MATCHER_P_OVERLOAD(QualType, pointsTo, internal::Matcher<Decl>,namespace internal { class matcher_pointsTo1Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<QualType>
{ public: explicit matcher_pointsTo1Matcher( internal::Matcher
<Decl> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const QualType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<Decl> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::Matcher<QualType> pointsTo( internal::Matcher
<Decl> const &InnerMatcher) { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_pointsTo1Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<QualType> ( &pointsTo_Type1)(internal::Matcher<
Decl> const &InnerMatcher); inline bool internal::matcher_pointsTo1Matcher
::matches( const QualType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
3993 InnerMatcher, 1)namespace internal { class matcher_pointsTo1Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<QualType>
{ public: explicit matcher_pointsTo1Matcher( internal::Matcher
<Decl> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const QualType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<Decl> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::Matcher<QualType> pointsTo( internal::Matcher
<Decl> const &InnerMatcher) { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_pointsTo1Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<QualType> ( &pointsTo_Type1)(internal::Matcher<
Decl> const &InnerMatcher); inline bool internal::matcher_pointsTo1Matcher
::matches( const QualType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
3994 return pointsTo(qualType(hasDeclaration(InnerMatcher)))
3995 .matches(Node, Finder, Builder);
3996}
3997
3998/// Matches if the matched type matches the unqualified desugared
3999/// type of the matched node.
4000///
4001/// For example, in:
4002/// \code
4003/// class A {};
4004/// using B = A;
4005/// \endcode
4006/// The matcher type(hasUnqualifiedDesugaredType(recordType())) matches
4007/// both B and A.
4008AST_MATCHER_P(Type, hasUnqualifiedDesugaredType, internal::Matcher<Type>,namespace internal { class matcher_hasUnqualifiedDesugaredType0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
Type> { public: explicit matcher_hasUnqualifiedDesugaredType0Matcher
( internal::Matcher<Type> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const Type &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Type> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<Type> hasUnqualifiedDesugaredType
( internal::Matcher<Type> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasUnqualifiedDesugaredType0Matcher(InnerMatcher)); }
typedef ::clang::ast_matchers::internal::Matcher<Type>
( &hasUnqualifiedDesugaredType_Type0)(internal::Matcher<
Type> const &InnerMatcher); inline bool internal::matcher_hasUnqualifiedDesugaredType0Matcher
::matches( const Type &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
4009 InnerMatcher)namespace internal { class matcher_hasUnqualifiedDesugaredType0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
Type> { public: explicit matcher_hasUnqualifiedDesugaredType0Matcher
( internal::Matcher<Type> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const Type &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Type> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<Type> hasUnqualifiedDesugaredType
( internal::Matcher<Type> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasUnqualifiedDesugaredType0Matcher(InnerMatcher)); }
typedef ::clang::ast_matchers::internal::Matcher<Type>
( &hasUnqualifiedDesugaredType_Type0)(internal::Matcher<
Type> const &InnerMatcher); inline bool internal::matcher_hasUnqualifiedDesugaredType0Matcher
::matches( const Type &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
4010 return InnerMatcher.matches(*Node.getUnqualifiedDesugaredType(), Finder,
4011 Builder);
4012}
4013
4014/// Matches if the matched type is a reference type and the referenced
4015/// type matches the specified matcher.
4016///
4017/// Example matches X &x and const X &y
4018/// (matcher = varDecl(hasType(references(cxxRecordDecl(hasName("X"))))))
4019/// \code
4020/// class X {
4021/// void a(X b) {
4022/// X &x = b;
4023/// const X &y = b;
4024/// }
4025/// };
4026/// \endcode
4027AST_MATCHER_P(QualType, references, internal::Matcher<QualType>,namespace internal { class matcher_references0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<QualType
> { public: explicit matcher_references0Matcher( internal::
Matcher<QualType> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const QualType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<QualType> InnerMatcher; }; } inline
::clang::ast_matchers::internal::Matcher<QualType> references
( internal::Matcher<QualType> const &InnerMatcher) {
return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_references0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<QualType> ( &references_Type0
)(internal::Matcher<QualType> const &InnerMatcher);
inline bool internal::matcher_references0Matcher::matches( const
QualType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
4028 InnerMatcher)namespace internal { class matcher_references0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<QualType
> { public: explicit matcher_references0Matcher( internal::
Matcher<QualType> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const QualType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<QualType> InnerMatcher; }; } inline
::clang::ast_matchers::internal::Matcher<QualType> references
( internal::Matcher<QualType> const &InnerMatcher) {
return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_references0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<QualType> ( &references_Type0
)(internal::Matcher<QualType> const &InnerMatcher);
inline bool internal::matcher_references0Matcher::matches( const
QualType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
4029 return (!Node.isNull() && Node->isReferenceType() &&
4030 InnerMatcher.matches(Node->getPointeeType(), Finder, Builder));
4031}
4032
4033/// Matches QualTypes whose canonical type matches InnerMatcher.
4034///
4035/// Given:
4036/// \code
4037/// typedef int &int_ref;
4038/// int a;
4039/// int_ref b = a;
4040/// \endcode
4041///
4042/// \c varDecl(hasType(qualType(referenceType()))))) will not match the
4043/// declaration of b but \c
4044/// varDecl(hasType(qualType(hasCanonicalType(referenceType())))))) does.
4045AST_MATCHER_P(QualType, hasCanonicalType, internal::Matcher<QualType>,namespace internal { class matcher_hasCanonicalType0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
QualType> { public: explicit matcher_hasCanonicalType0Matcher
( internal::Matcher<QualType> const &AInnerMatcher)
: InnerMatcher(AInnerMatcher) {} bool matches(const QualType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<QualType
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<QualType> hasCanonicalType( internal::Matcher
<QualType> const &InnerMatcher) { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_hasCanonicalType0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<QualType> ( &hasCanonicalType_Type0)(internal::Matcher
<QualType> const &InnerMatcher); inline bool internal
::matcher_hasCanonicalType0Matcher::matches( const QualType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
4046 InnerMatcher)namespace internal { class matcher_hasCanonicalType0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
QualType> { public: explicit matcher_hasCanonicalType0Matcher
( internal::Matcher<QualType> const &AInnerMatcher)
: InnerMatcher(AInnerMatcher) {} bool matches(const QualType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<QualType
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<QualType> hasCanonicalType( internal::Matcher
<QualType> const &InnerMatcher) { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_hasCanonicalType0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<QualType> ( &hasCanonicalType_Type0)(internal::Matcher
<QualType> const &InnerMatcher); inline bool internal
::matcher_hasCanonicalType0Matcher::matches( const QualType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
4047 if (Node.isNull())
4048 return false;
4049 return InnerMatcher.matches(Node.getCanonicalType(), Finder, Builder);
4050}
4051
4052/// Overloaded to match the referenced type's declaration.
4053AST_MATCHER_P_OVERLOAD(QualType, references, internal::Matcher<Decl>,namespace internal { class matcher_references1Matcher : public
::clang::ast_matchers::internal::MatcherInterface<QualType
> { public: explicit matcher_references1Matcher( internal::
Matcher<Decl> const &AInnerMatcher) : InnerMatcher(
AInnerMatcher) {} bool matches(const QualType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Decl> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<QualType> references(
internal::Matcher<Decl> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_references1Matcher(InnerMatcher)); } typedef ::clang::
ast_matchers::internal::Matcher<QualType> ( &references_Type1
)(internal::Matcher<Decl> const &InnerMatcher); inline
bool internal::matcher_references1Matcher::matches( const QualType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
4054 InnerMatcher, 1)namespace internal { class matcher_references1Matcher : public
::clang::ast_matchers::internal::MatcherInterface<QualType
> { public: explicit matcher_references1Matcher( internal::
Matcher<Decl> const &AInnerMatcher) : InnerMatcher(
AInnerMatcher) {} bool matches(const QualType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Decl> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<QualType> references(
internal::Matcher<Decl> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_references1Matcher(InnerMatcher)); } typedef ::clang::
ast_matchers::internal::Matcher<QualType> ( &references_Type1
)(internal::Matcher<Decl> const &InnerMatcher); inline
bool internal::matcher_references1Matcher::matches( const QualType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
4055 return references(qualType(hasDeclaration(InnerMatcher)))
4056 .matches(Node, Finder, Builder);
4057}
4058
4059/// Matches on the implicit object argument of a member call expression. Unlike
4060/// `on`, matches the argument directly without stripping away anything.
4061///
4062/// Given
4063/// \code
4064/// class Y { public: void m(); };
4065/// Y g();
4066/// class X : public Y { void g(); };
4067/// void z(Y y, X x) { y.m(); x.m(); x.g(); (g()).m(); }
4068/// \endcode
4069/// cxxMemberCallExpr(onImplicitObjectArgument(hasType(
4070/// cxxRecordDecl(hasName("Y")))))
4071/// matches `y.m()`, `x.m()` and (g()).m(), but not `x.g()`.
4072/// cxxMemberCallExpr(on(callExpr()))
4073/// does not match `(g()).m()`, because the parens are not ignored.
4074///
4075/// FIXME: Overload to allow directly matching types?
4076AST_MATCHER_P(CXXMemberCallExpr, onImplicitObjectArgument,namespace internal { class matcher_onImplicitObjectArgument0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
CXXMemberCallExpr> { public: explicit matcher_onImplicitObjectArgument0Matcher
( internal::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const CXXMemberCallExpr &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<Expr> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<CXXMemberCallExpr
> onImplicitObjectArgument( internal::Matcher<Expr> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
makeMatcher( new internal::matcher_onImplicitObjectArgument0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<CXXMemberCallExpr> ( &onImplicitObjectArgument_Type0
)(internal::Matcher<Expr> const &InnerMatcher); inline
bool internal::matcher_onImplicitObjectArgument0Matcher::matches
( const CXXMemberCallExpr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
4077 internal::Matcher<Expr>, InnerMatcher)namespace internal { class matcher_onImplicitObjectArgument0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
CXXMemberCallExpr> { public: explicit matcher_onImplicitObjectArgument0Matcher
( internal::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const CXXMemberCallExpr &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<Expr> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<CXXMemberCallExpr
> onImplicitObjectArgument( internal::Matcher<Expr> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
makeMatcher( new internal::matcher_onImplicitObjectArgument0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<CXXMemberCallExpr> ( &onImplicitObjectArgument_Type0
)(internal::Matcher<Expr> const &InnerMatcher); inline
bool internal::matcher_onImplicitObjectArgument0Matcher::matches
( const CXXMemberCallExpr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
4078 const Expr *ExprNode = Node.getImplicitObjectArgument();
4079 return (ExprNode != nullptr &&
4080 InnerMatcher.matches(*ExprNode, Finder, Builder));
4081}
4082
4083/// Matches if the type of the expression's implicit object argument either
4084/// matches the InnerMatcher, or is a pointer to a type that matches the
4085/// InnerMatcher.
4086///
4087/// Given
4088/// \code
4089/// class Y { public: void m(); };
4090/// class X : public Y { void g(); };
4091/// void z() { Y y; y.m(); Y *p; p->m(); X x; x.m(); x.g(); }
4092/// \endcode
4093/// cxxMemberCallExpr(thisPointerType(hasDeclaration(
4094/// cxxRecordDecl(hasName("Y")))))
4095/// matches `y.m()`, `p->m()` and `x.m()`.
4096/// cxxMemberCallExpr(thisPointerType(hasDeclaration(
4097/// cxxRecordDecl(hasName("X")))))
4098/// matches `x.g()`.
4099AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType,namespace internal { class matcher_thisPointerType0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXMemberCallExpr
> { public: explicit matcher_thisPointerType0Matcher( internal
::Matcher<QualType> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const CXXMemberCallExpr &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<QualType> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<CXXMemberCallExpr
> thisPointerType( internal::Matcher<QualType> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
makeMatcher( new internal::matcher_thisPointerType0Matcher(InnerMatcher
)); } typedef ::clang::ast_matchers::internal::Matcher<CXXMemberCallExpr
> ( &thisPointerType_Type0)(internal::Matcher<QualType
> const &InnerMatcher); inline bool internal::matcher_thisPointerType0Matcher
::matches( const CXXMemberCallExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4100 internal::Matcher<QualType>, InnerMatcher, 0)namespace internal { class matcher_thisPointerType0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXMemberCallExpr
> { public: explicit matcher_thisPointerType0Matcher( internal
::Matcher<QualType> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const CXXMemberCallExpr &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<QualType> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<CXXMemberCallExpr
> thisPointerType( internal::Matcher<QualType> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
makeMatcher( new internal::matcher_thisPointerType0Matcher(InnerMatcher
)); } typedef ::clang::ast_matchers::internal::Matcher<CXXMemberCallExpr
> ( &thisPointerType_Type0)(internal::Matcher<QualType
> const &InnerMatcher); inline bool internal::matcher_thisPointerType0Matcher
::matches( const CXXMemberCallExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
4101 return onImplicitObjectArgument(
4102 anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher))))
4103 .matches(Node, Finder, Builder);
4104}
4105
4106/// Overloaded to match the type's declaration.
4107AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType,namespace internal { class matcher_thisPointerType1Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXMemberCallExpr
> { public: explicit matcher_thisPointerType1Matcher( internal
::Matcher<Decl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const CXXMemberCallExpr &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<Decl> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<CXXMemberCallExpr
> thisPointerType( internal::Matcher<Decl> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_thisPointerType1Matcher(InnerMatcher)
); } typedef ::clang::ast_matchers::internal::Matcher<CXXMemberCallExpr
> ( &thisPointerType_Type1)(internal::Matcher<Decl>
const &InnerMatcher); inline bool internal::matcher_thisPointerType1Matcher
::matches( const CXXMemberCallExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4108 internal::Matcher<Decl>, InnerMatcher, 1)namespace internal { class matcher_thisPointerType1Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXMemberCallExpr
> { public: explicit matcher_thisPointerType1Matcher( internal
::Matcher<Decl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const CXXMemberCallExpr &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<Decl> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<CXXMemberCallExpr
> thisPointerType( internal::Matcher<Decl> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_thisPointerType1Matcher(InnerMatcher)
); } typedef ::clang::ast_matchers::internal::Matcher<CXXMemberCallExpr
> ( &thisPointerType_Type1)(internal::Matcher<Decl>
const &InnerMatcher); inline bool internal::matcher_thisPointerType1Matcher
::matches( const CXXMemberCallExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
4109 return onImplicitObjectArgument(
4110 anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher))))
4111 .matches(Node, Finder, Builder);
4112}
4113
4114/// Matches a DeclRefExpr that refers to a declaration that matches the
4115/// specified matcher.
4116///
4117/// Example matches x in if(x)
4118/// (matcher = declRefExpr(to(varDecl(hasName("x")))))
4119/// \code
4120/// bool x;
4121/// if (x) {}
4122/// \endcode
4123AST_MATCHER_P(DeclRefExpr, to, internal::Matcher<Decl>,namespace internal { class matcher_to0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<DeclRefExpr>
{ public: explicit matcher_to0Matcher( internal::Matcher<
Decl> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const DeclRefExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<Decl> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::Matcher<DeclRefExpr> to( internal::Matcher<
Decl> const &InnerMatcher) { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_to0Matcher(InnerMatcher
)); } typedef ::clang::ast_matchers::internal::Matcher<DeclRefExpr
> ( &to_Type0)(internal::Matcher<Decl> const &
InnerMatcher); inline bool internal::matcher_to0Matcher::matches
( const DeclRefExpr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
4124 InnerMatcher)namespace internal { class matcher_to0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<DeclRefExpr>
{ public: explicit matcher_to0Matcher( internal::Matcher<
Decl> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const DeclRefExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<Decl> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::Matcher<DeclRefExpr> to( internal::Matcher<
Decl> const &InnerMatcher) { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_to0Matcher(InnerMatcher
)); } typedef ::clang::ast_matchers::internal::Matcher<DeclRefExpr
> ( &to_Type0)(internal::Matcher<Decl> const &
InnerMatcher); inline bool internal::matcher_to0Matcher::matches
( const DeclRefExpr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
4125 const Decl *DeclNode = Node.getDecl();
4126 return (DeclNode != nullptr &&
4127 InnerMatcher.matches(*DeclNode, Finder, Builder));
4128}
4129
4130/// Matches if a node refers to a declaration through a specific
4131/// using shadow declaration.
4132///
4133/// Examples:
4134/// \code
4135/// namespace a { int f(); }
4136/// using a::f;
4137/// int x = f();
4138/// \endcode
4139/// declRefExpr(throughUsingDecl(anything()))
4140/// matches \c f
4141///
4142/// \code
4143/// namespace a { class X{}; }
4144/// using a::X;
4145/// X x;
4146/// \code
4147/// typeLoc(loc(usingType(throughUsingDecl(anything()))))
4148/// matches \c X
4149///
4150/// Usable as: Matcher<DeclRefExpr>, Matcher<UsingType>
4151AST_POLYMORPHIC_MATCHER_P(throughUsingDecl,namespace internal { template <typename NodeType, typename
ParamT> class matcher_throughUsingDecl0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_throughUsingDecl0Matcher( internal
::Matcher<UsingShadowDecl> const &AInner) : Inner(AInner
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<UsingShadowDecl> Inner; }; } inline ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_throughUsingDecl0Matcher
, void(::clang::ast_matchers::internal::TypeList<DeclRefExpr
, UsingType>), internal::Matcher<UsingShadowDecl> >
throughUsingDecl(internal::Matcher<UsingShadowDecl> const
&Inner) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_throughUsingDecl0Matcher, void(::clang
::ast_matchers::internal::TypeList<DeclRefExpr, UsingType>
), internal::Matcher<UsingShadowDecl> >(Inner); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_throughUsingDecl0Matcher, void(::clang::ast_matchers
::internal::TypeList<DeclRefExpr, UsingType>), internal
::Matcher<UsingShadowDecl> > (&throughUsingDecl_Type0
)(internal::Matcher<UsingShadowDecl> const &Inner);
template <typename NodeType, typename ParamT> bool internal
:: matcher_throughUsingDecl0Matcher<NodeType, ParamT>::
matches( const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
4152 AST_POLYMORPHIC_SUPPORTED_TYPES(DeclRefExpr,namespace internal { template <typename NodeType, typename
ParamT> class matcher_throughUsingDecl0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_throughUsingDecl0Matcher( internal
::Matcher<UsingShadowDecl> const &AInner) : Inner(AInner
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<UsingShadowDecl> Inner; }; } inline ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_throughUsingDecl0Matcher
, void(::clang::ast_matchers::internal::TypeList<DeclRefExpr
, UsingType>), internal::Matcher<UsingShadowDecl> >
throughUsingDecl(internal::Matcher<UsingShadowDecl> const
&Inner) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_throughUsingDecl0Matcher, void(::clang
::ast_matchers::internal::TypeList<DeclRefExpr, UsingType>
), internal::Matcher<UsingShadowDecl> >(Inner); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_throughUsingDecl0Matcher, void(::clang::ast_matchers
::internal::TypeList<DeclRefExpr, UsingType>), internal
::Matcher<UsingShadowDecl> > (&throughUsingDecl_Type0
)(internal::Matcher<UsingShadowDecl> const &Inner);
template <typename NodeType, typename ParamT> bool internal
:: matcher_throughUsingDecl0Matcher<NodeType, ParamT>::
matches( const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
4153 UsingType),namespace internal { template <typename NodeType, typename
ParamT> class matcher_throughUsingDecl0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_throughUsingDecl0Matcher( internal
::Matcher<UsingShadowDecl> const &AInner) : Inner(AInner
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<UsingShadowDecl> Inner; }; } inline ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_throughUsingDecl0Matcher
, void(::clang::ast_matchers::internal::TypeList<DeclRefExpr
, UsingType>), internal::Matcher<UsingShadowDecl> >
throughUsingDecl(internal::Matcher<UsingShadowDecl> const
&Inner) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_throughUsingDecl0Matcher, void(::clang
::ast_matchers::internal::TypeList<DeclRefExpr, UsingType>
), internal::Matcher<UsingShadowDecl> >(Inner); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_throughUsingDecl0Matcher, void(::clang::ast_matchers
::internal::TypeList<DeclRefExpr, UsingType>), internal
::Matcher<UsingShadowDecl> > (&throughUsingDecl_Type0
)(internal::Matcher<UsingShadowDecl> const &Inner);
template <typename NodeType, typename ParamT> bool internal
:: matcher_throughUsingDecl0Matcher<NodeType, ParamT>::
matches( const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
4154 internal::Matcher<UsingShadowDecl>, Inner)namespace internal { template <typename NodeType, typename
ParamT> class matcher_throughUsingDecl0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_throughUsingDecl0Matcher( internal
::Matcher<UsingShadowDecl> const &AInner) : Inner(AInner
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<UsingShadowDecl> Inner; }; } inline ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_throughUsingDecl0Matcher
, void(::clang::ast_matchers::internal::TypeList<DeclRefExpr
, UsingType>), internal::Matcher<UsingShadowDecl> >
throughUsingDecl(internal::Matcher<UsingShadowDecl> const
&Inner) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_throughUsingDecl0Matcher, void(::clang
::ast_matchers::internal::TypeList<DeclRefExpr, UsingType>
), internal::Matcher<UsingShadowDecl> >(Inner); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_throughUsingDecl0Matcher, void(::clang::ast_matchers
::internal::TypeList<DeclRefExpr, UsingType>), internal
::Matcher<UsingShadowDecl> > (&throughUsingDecl_Type0
)(internal::Matcher<UsingShadowDecl> const &Inner);
template <typename NodeType, typename ParamT> bool internal
:: matcher_throughUsingDecl0Matcher<NodeType, ParamT>::
matches( const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
4155 const NamedDecl *FoundDecl = Node.getFoundDecl();
4156 if (const UsingShadowDecl *UsingDecl = dyn_cast<UsingShadowDecl>(FoundDecl))
4157 return Inner.matches(*UsingDecl, Finder, Builder);
4158 return false;
4159}
4160
4161/// Matches an \c OverloadExpr if any of the declarations in the set of
4162/// overloads matches the given matcher.
4163///
4164/// Given
4165/// \code
4166/// template <typename T> void foo(T);
4167/// template <typename T> void bar(T);
4168/// template <typename T> void baz(T t) {
4169/// foo(t);
4170/// bar(t);
4171/// }
4172/// \endcode
4173/// unresolvedLookupExpr(hasAnyDeclaration(
4174/// functionTemplateDecl(hasName("foo"))))
4175/// matches \c foo in \c foo(t); but not \c bar in \c bar(t);
4176AST_MATCHER_P(OverloadExpr, hasAnyDeclaration, internal::Matcher<Decl>,namespace internal { class matcher_hasAnyDeclaration0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
OverloadExpr> { public: explicit matcher_hasAnyDeclaration0Matcher
( internal::Matcher<Decl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const OverloadExpr &Node,
::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
override; private: internal::Matcher<Decl> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<OverloadExpr
> hasAnyDeclaration( internal::Matcher<Decl> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_hasAnyDeclaration0Matcher(InnerMatcher
)); } typedef ::clang::ast_matchers::internal::Matcher<OverloadExpr
> ( &hasAnyDeclaration_Type0)(internal::Matcher<Decl
> const &InnerMatcher); inline bool internal::matcher_hasAnyDeclaration0Matcher
::matches( const OverloadExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4177 InnerMatcher)namespace internal { class matcher_hasAnyDeclaration0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
OverloadExpr> { public: explicit matcher_hasAnyDeclaration0Matcher
( internal::Matcher<Decl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const OverloadExpr &Node,
::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
override; private: internal::Matcher<Decl> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<OverloadExpr
> hasAnyDeclaration( internal::Matcher<Decl> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_hasAnyDeclaration0Matcher(InnerMatcher
)); } typedef ::clang::ast_matchers::internal::Matcher<OverloadExpr
> ( &hasAnyDeclaration_Type0)(internal::Matcher<Decl
> const &InnerMatcher); inline bool internal::matcher_hasAnyDeclaration0Matcher
::matches( const OverloadExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
4178 return matchesFirstInPointerRange(InnerMatcher, Node.decls_begin(),
4179 Node.decls_end(), Finder,
4180 Builder) != Node.decls_end();
4181}
4182
4183/// Matches the Decl of a DeclStmt which has a single declaration.
4184///
4185/// Given
4186/// \code
4187/// int a, b;
4188/// int c;
4189/// \endcode
4190/// declStmt(hasSingleDecl(anything()))
4191/// matches 'int c;' but not 'int a, b;'.
4192AST_MATCHER_P(DeclStmt, hasSingleDecl, internal::Matcher<Decl>, InnerMatcher)namespace internal { class matcher_hasSingleDecl0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<DeclStmt
> { public: explicit matcher_hasSingleDecl0Matcher( internal
::Matcher<Decl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const DeclStmt &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Decl> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<DeclStmt> hasSingleDecl
( internal::Matcher<Decl> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasSingleDecl0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<DeclStmt> ( &hasSingleDecl_Type0
)(internal::Matcher<Decl> const &InnerMatcher); inline
bool internal::matcher_hasSingleDecl0Matcher::matches( const
DeclStmt &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
4193 if (Node.isSingleDecl()) {
4194 const Decl *FoundDecl = Node.getSingleDecl();
4195 return InnerMatcher.matches(*FoundDecl, Finder, Builder);
4196 }
4197 return false;
4198}
4199
4200/// Matches a variable declaration that has an initializer expression
4201/// that matches the given matcher.
4202///
4203/// Example matches x (matcher = varDecl(hasInitializer(callExpr())))
4204/// \code
4205/// bool y() { return true; }
4206/// bool x = y();
4207/// \endcode
4208AST_MATCHER_P(namespace internal { class matcher_hasInitializer0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<VarDecl
> { public: explicit matcher_hasInitializer0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const VarDecl &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<VarDecl> hasInitializer
( internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasInitializer0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<VarDecl> ( &hasInitializer_Type0
)(internal::Matcher<Expr> const &InnerMatcher); inline
bool internal::matcher_hasInitializer0Matcher::matches( const
VarDecl &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
4209 VarDecl, hasInitializer, internal::Matcher<Expr>,namespace internal { class matcher_hasInitializer0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<VarDecl
> { public: explicit matcher_hasInitializer0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const VarDecl &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<VarDecl> hasInitializer
( internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasInitializer0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<VarDecl> ( &hasInitializer_Type0
)(internal::Matcher<Expr> const &InnerMatcher); inline
bool internal::matcher_hasInitializer0Matcher::matches( const
VarDecl &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
4210 InnerMatcher)namespace internal { class matcher_hasInitializer0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<VarDecl
> { public: explicit matcher_hasInitializer0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const VarDecl &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<VarDecl> hasInitializer
( internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasInitializer0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<VarDecl> ( &hasInitializer_Type0
)(internal::Matcher<Expr> const &InnerMatcher); inline
bool internal::matcher_hasInitializer0Matcher::matches( const
VarDecl &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
4211 const Expr *Initializer = Node.getAnyInitializer();
4212 return (Initializer != nullptr &&
4213 InnerMatcher.matches(*Initializer, Finder, Builder));
4214}
4215
4216/// Matches a variable serving as the implicit variable for a lambda init-
4217/// capture.
4218///
4219/// Example matches x (matcher = varDecl(isInitCapture()))
4220/// \code
4221/// auto f = [x=3]() { return x; };
4222/// \endcode
4223AST_MATCHER(VarDecl, isInitCapture)namespace internal { class matcher_isInitCaptureMatcher : public
::clang::ast_matchers::internal::MatcherInterface<VarDecl
> { public: explicit matcher_isInitCaptureMatcher() = default
; bool matches(const VarDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<VarDecl> isInitCapture
() { return ::clang::ast_matchers::internal::makeMatcher( new
internal::matcher_isInitCaptureMatcher()); } inline bool internal
::matcher_isInitCaptureMatcher::matches( const VarDecl &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{ return Node.isInitCapture(); }
4224
4225/// Matches each lambda capture in a lambda expression.
4226///
4227/// Given
4228/// \code
4229/// int main() {
4230/// int x, y;
4231/// float z;
4232/// auto f = [=]() { return x + y + z; };
4233/// }
4234/// \endcode
4235/// lambdaExpr(forEachLambdaCapture(
4236/// lambdaCapture(capturesVar(varDecl(hasType(isInteger()))))))
4237/// will trigger two matches, binding for 'x' and 'y' respectively.
4238AST_MATCHER_P(LambdaExpr, forEachLambdaCapture,namespace internal { class matcher_forEachLambdaCapture0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
LambdaExpr> { public: explicit matcher_forEachLambdaCapture0Matcher
( internal::Matcher<LambdaCapture> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const LambdaExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<LambdaCapture
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<LambdaExpr> forEachLambdaCapture( internal::Matcher
<LambdaCapture> const &InnerMatcher) { return ::clang
::ast_matchers::internal::makeMatcher( new internal::matcher_forEachLambdaCapture0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<LambdaExpr> ( &forEachLambdaCapture_Type0)(internal
::Matcher<LambdaCapture> const &InnerMatcher); inline
bool internal::matcher_forEachLambdaCapture0Matcher::matches
( const LambdaExpr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
4239 internal::Matcher<LambdaCapture>, InnerMatcher)namespace internal { class matcher_forEachLambdaCapture0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
LambdaExpr> { public: explicit matcher_forEachLambdaCapture0Matcher
( internal::Matcher<LambdaCapture> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const LambdaExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<LambdaCapture
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<LambdaExpr> forEachLambdaCapture( internal::Matcher
<LambdaCapture> const &InnerMatcher) { return ::clang
::ast_matchers::internal::makeMatcher( new internal::matcher_forEachLambdaCapture0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<LambdaExpr> ( &forEachLambdaCapture_Type0)(internal
::Matcher<LambdaCapture> const &InnerMatcher); inline
bool internal::matcher_forEachLambdaCapture0Matcher::matches
( const LambdaExpr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
4240 BoundNodesTreeBuilder Result;
4241 bool Matched = false;
4242 for (const auto &Capture : Node.captures()) {
4243 if (Finder->isTraversalIgnoringImplicitNodes() && Capture.isImplicit())
4244 continue;
4245 BoundNodesTreeBuilder CaptureBuilder(*Builder);
4246 if (InnerMatcher.matches(Capture, Finder, &CaptureBuilder)) {
4247 Matched = true;
4248 Result.addMatch(CaptureBuilder);
4249 }
4250 }
4251 *Builder = std::move(Result);
4252 return Matched;
4253}
4254
4255/// \brief Matches a static variable with local scope.
4256///
4257/// Example matches y (matcher = varDecl(isStaticLocal()))
4258/// \code
4259/// void f() {
4260/// int x;
4261/// static int y;
4262/// }
4263/// static int z;
4264/// \endcode
4265AST_MATCHER(VarDecl, isStaticLocal)namespace internal { class matcher_isStaticLocalMatcher : public
::clang::ast_matchers::internal::MatcherInterface<VarDecl
> { public: explicit matcher_isStaticLocalMatcher() = default
; bool matches(const VarDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<VarDecl> isStaticLocal
() { return ::clang::ast_matchers::internal::makeMatcher( new
internal::matcher_isStaticLocalMatcher()); } inline bool internal
::matcher_isStaticLocalMatcher::matches( const VarDecl &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
4266 return Node.isStaticLocal();
4267}
4268
4269/// Matches a variable declaration that has function scope and is a
4270/// non-static local variable.
4271///
4272/// Example matches x (matcher = varDecl(hasLocalStorage())
4273/// \code
4274/// void f() {
4275/// int x;
4276/// static int y;
4277/// }
4278/// int z;
4279/// \endcode
4280AST_MATCHER(VarDecl, hasLocalStorage)namespace internal { class matcher_hasLocalStorageMatcher : public
::clang::ast_matchers::internal::MatcherInterface<VarDecl
> { public: explicit matcher_hasLocalStorageMatcher() = default
; bool matches(const VarDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<VarDecl> hasLocalStorage
() { return ::clang::ast_matchers::internal::makeMatcher( new
internal::matcher_hasLocalStorageMatcher()); } inline bool internal
::matcher_hasLocalStorageMatcher::matches( const VarDecl &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
4281 return Node.hasLocalStorage();
4282}
4283
4284/// Matches a variable declaration that does not have local storage.
4285///
4286/// Example matches y and z (matcher = varDecl(hasGlobalStorage())
4287/// \code
4288/// void f() {
4289/// int x;
4290/// static int y;
4291/// }
4292/// int z;
4293/// \endcode
4294AST_MATCHER(VarDecl, hasGlobalStorage)namespace internal { class matcher_hasGlobalStorageMatcher : public
::clang::ast_matchers::internal::MatcherInterface<VarDecl
> { public: explicit matcher_hasGlobalStorageMatcher() = default
; bool matches(const VarDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<VarDecl> hasGlobalStorage
() { return ::clang::ast_matchers::internal::makeMatcher( new
internal::matcher_hasGlobalStorageMatcher()); } inline bool internal
::matcher_hasGlobalStorageMatcher::matches( const VarDecl &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
4295 return Node.hasGlobalStorage();
4296}
4297
4298/// Matches a variable declaration that has automatic storage duration.
4299///
4300/// Example matches x, but not y, z, or a.
4301/// (matcher = varDecl(hasAutomaticStorageDuration())
4302/// \code
4303/// void f() {
4304/// int x;
4305/// static int y;
4306/// thread_local int z;
4307/// }
4308/// int a;
4309/// \endcode
4310AST_MATCHER(VarDecl, hasAutomaticStorageDuration)namespace internal { class matcher_hasAutomaticStorageDurationMatcher
: public ::clang::ast_matchers::internal::MatcherInterface<
VarDecl> { public: explicit matcher_hasAutomaticStorageDurationMatcher
() = default; bool matches(const VarDecl &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; }
; } inline ::clang::ast_matchers::internal::Matcher<VarDecl
> hasAutomaticStorageDuration() { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_hasAutomaticStorageDurationMatcher
()); } inline bool internal::matcher_hasAutomaticStorageDurationMatcher
::matches( const VarDecl &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
4311 return Node.getStorageDuration() == SD_Automatic;
4312}
4313
4314/// Matches a variable declaration that has static storage duration.
4315/// It includes the variable declared at namespace scope and those declared
4316/// with "static" and "extern" storage class specifiers.
4317///
4318/// \code
4319/// void f() {
4320/// int x;
4321/// static int y;
4322/// thread_local int z;
4323/// }
4324/// int a;
4325/// static int b;
4326/// extern int c;
4327/// varDecl(hasStaticStorageDuration())
4328/// matches the function declaration y, a, b and c.
4329/// \endcode
4330AST_MATCHER(VarDecl, hasStaticStorageDuration)namespace internal { class matcher_hasStaticStorageDurationMatcher
: public ::clang::ast_matchers::internal::MatcherInterface<
VarDecl> { public: explicit matcher_hasStaticStorageDurationMatcher
() = default; bool matches(const VarDecl &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; }
; } inline ::clang::ast_matchers::internal::Matcher<VarDecl
> hasStaticStorageDuration() { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_hasStaticStorageDurationMatcher
()); } inline bool internal::matcher_hasStaticStorageDurationMatcher
::matches( const VarDecl &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
4331 return Node.getStorageDuration() == SD_Static;
4332}
4333
4334/// Matches a variable declaration that has thread storage duration.
4335///
4336/// Example matches z, but not x, z, or a.
4337/// (matcher = varDecl(hasThreadStorageDuration())
4338/// \code
4339/// void f() {
4340/// int x;
4341/// static int y;
4342/// thread_local int z;
4343/// }
4344/// int a;
4345/// \endcode
4346AST_MATCHER(VarDecl, hasThreadStorageDuration)namespace internal { class matcher_hasThreadStorageDurationMatcher
: public ::clang::ast_matchers::internal::MatcherInterface<
VarDecl> { public: explicit matcher_hasThreadStorageDurationMatcher
() = default; bool matches(const VarDecl &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; }
; } inline ::clang::ast_matchers::internal::Matcher<VarDecl
> hasThreadStorageDuration() { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_hasThreadStorageDurationMatcher
()); } inline bool internal::matcher_hasThreadStorageDurationMatcher
::matches( const VarDecl &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
4347 return Node.getStorageDuration() == SD_Thread;
4348}
4349
4350/// Matches a variable declaration that is an exception variable from
4351/// a C++ catch block, or an Objective-C \@catch statement.
4352///
4353/// Example matches x (matcher = varDecl(isExceptionVariable())
4354/// \code
4355/// void f(int y) {
4356/// try {
4357/// } catch (int x) {
4358/// }
4359/// }
4360/// \endcode
4361AST_MATCHER(VarDecl, isExceptionVariable)namespace internal { class matcher_isExceptionVariableMatcher
: public ::clang::ast_matchers::internal::MatcherInterface<
VarDecl> { public: explicit matcher_isExceptionVariableMatcher
() = default; bool matches(const VarDecl &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; }
; } inline ::clang::ast_matchers::internal::Matcher<VarDecl
> isExceptionVariable() { return ::clang::ast_matchers::internal
::makeMatcher( new internal::matcher_isExceptionVariableMatcher
()); } inline bool internal::matcher_isExceptionVariableMatcher
::matches( const VarDecl &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
4362 return Node.isExceptionVariable();
4363}
4364
4365/// Checks that a call expression or a constructor call expression has
4366/// a specific number of arguments (including absent default arguments).
4367///
4368/// Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2)))
4369/// \code
4370/// void f(int x, int y);
4371/// f(0, 0);
4372/// \endcode
4373AST_POLYMORPHIC_MATCHER_P(argumentCountIs,namespace internal { template <typename NodeType, typename
ParamT> class matcher_argumentCountIs0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_argumentCountIs0Matcher( unsigned
const &AN) : N(AN) {} bool matches(const NodeType &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: unsigned N; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_argumentCountIs0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), unsigned> argumentCountIs(unsigned const &N) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_argumentCountIs0Matcher, void(::clang::ast_matchers
::internal::TypeList<CallExpr, CXXConstructExpr, CXXUnresolvedConstructExpr
, ObjCMessageExpr>), unsigned>(N); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_argumentCountIs0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), unsigned> (&argumentCountIs_Type0)(unsigned const
&N); template <typename NodeType, typename ParamT>
bool internal:: matcher_argumentCountIs0Matcher<NodeType,
ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4374 AST_POLYMORPHIC_SUPPORTED_TYPES(namespace internal { template <typename NodeType, typename
ParamT> class matcher_argumentCountIs0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_argumentCountIs0Matcher( unsigned
const &AN) : N(AN) {} bool matches(const NodeType &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: unsigned N; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_argumentCountIs0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), unsigned> argumentCountIs(unsigned const &N) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_argumentCountIs0Matcher, void(::clang::ast_matchers
::internal::TypeList<CallExpr, CXXConstructExpr, CXXUnresolvedConstructExpr
, ObjCMessageExpr>), unsigned>(N); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_argumentCountIs0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), unsigned> (&argumentCountIs_Type0)(unsigned const
&N); template <typename NodeType, typename ParamT>
bool internal:: matcher_argumentCountIs0Matcher<NodeType,
ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4375 CallExpr, CXXConstructExpr,namespace internal { template <typename NodeType, typename
ParamT> class matcher_argumentCountIs0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_argumentCountIs0Matcher( unsigned
const &AN) : N(AN) {} bool matches(const NodeType &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: unsigned N; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_argumentCountIs0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), unsigned> argumentCountIs(unsigned const &N) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_argumentCountIs0Matcher, void(::clang::ast_matchers
::internal::TypeList<CallExpr, CXXConstructExpr, CXXUnresolvedConstructExpr
, ObjCMessageExpr>), unsigned>(N); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_argumentCountIs0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), unsigned> (&argumentCountIs_Type0)(unsigned const
&N); template <typename NodeType, typename ParamT>
bool internal:: matcher_argumentCountIs0Matcher<NodeType,
ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4376 CXXUnresolvedConstructExpr, ObjCMessageExpr),namespace internal { template <typename NodeType, typename
ParamT> class matcher_argumentCountIs0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_argumentCountIs0Matcher( unsigned
const &AN) : N(AN) {} bool matches(const NodeType &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: unsigned N; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_argumentCountIs0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), unsigned> argumentCountIs(unsigned const &N) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_argumentCountIs0Matcher, void(::clang::ast_matchers
::internal::TypeList<CallExpr, CXXConstructExpr, CXXUnresolvedConstructExpr
, ObjCMessageExpr>), unsigned>(N); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_argumentCountIs0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), unsigned> (&argumentCountIs_Type0)(unsigned const
&N); template <typename NodeType, typename ParamT>
bool internal:: matcher_argumentCountIs0Matcher<NodeType,
ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4377 unsigned, N)namespace internal { template <typename NodeType, typename
ParamT> class matcher_argumentCountIs0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_argumentCountIs0Matcher( unsigned
const &AN) : N(AN) {} bool matches(const NodeType &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: unsigned N; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_argumentCountIs0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), unsigned> argumentCountIs(unsigned const &N) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_argumentCountIs0Matcher, void(::clang::ast_matchers
::internal::TypeList<CallExpr, CXXConstructExpr, CXXUnresolvedConstructExpr
, ObjCMessageExpr>), unsigned>(N); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_argumentCountIs0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), unsigned> (&argumentCountIs_Type0)(unsigned const
&N); template <typename NodeType, typename ParamT>
bool internal:: matcher_argumentCountIs0Matcher<NodeType,
ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
4378 unsigned NumArgs = Node.getNumArgs();
4379 if (!Finder->isTraversalIgnoringImplicitNodes())
4380 return NumArgs == N;
4381 while (NumArgs) {
4382 if (!isa<CXXDefaultArgExpr>(Node.getArg(NumArgs - 1)))
4383 break;
4384 --NumArgs;
4385 }
4386 return NumArgs == N;
4387}
4388
4389/// Matches the n'th argument of a call expression or a constructor
4390/// call expression.
4391///
4392/// Example matches y in x(y)
4393/// (matcher = callExpr(hasArgument(0, declRefExpr())))
4394/// \code
4395/// void x(int) { int y; x(y); }
4396/// \endcode
4397AST_POLYMORPHIC_MATCHER_P2(hasArgument,namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasArgument0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasArgument0Matcher(unsigned const
&AN, internal::Matcher<Expr> const &AInnerMatcher
) : N(AN), InnerMatcher(AInnerMatcher) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; internal::Matcher
<Expr> InnerMatcher; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_hasArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), unsigned, internal::Matcher<Expr> > hasArgument
(unsigned const &N, internal::Matcher<Expr> const &
InnerMatcher) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasArgument0Matcher, void(::clang::ast_matchers
::internal::TypeList<CallExpr, CXXConstructExpr, CXXUnresolvedConstructExpr
, ObjCMessageExpr>), unsigned, internal::Matcher<Expr>
>(N, InnerMatcher); } typedef ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), unsigned, internal::Matcher<Expr> > (&hasArgument_Type0
)( unsigned const &N, internal::Matcher<Expr> const
&InnerMatcher); template <typename NodeType, typename
ParamT1, typename ParamT2> bool internal::matcher_hasArgument0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
4398 AST_POLYMORPHIC_SUPPORTED_TYPES(namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasArgument0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasArgument0Matcher(unsigned const
&AN, internal::Matcher<Expr> const &AInnerMatcher
) : N(AN), InnerMatcher(AInnerMatcher) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; internal::Matcher
<Expr> InnerMatcher; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_hasArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), unsigned, internal::Matcher<Expr> > hasArgument
(unsigned const &N, internal::Matcher<Expr> const &
InnerMatcher) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasArgument0Matcher, void(::clang::ast_matchers
::internal::TypeList<CallExpr, CXXConstructExpr, CXXUnresolvedConstructExpr
, ObjCMessageExpr>), unsigned, internal::Matcher<Expr>
>(N, InnerMatcher); } typedef ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), unsigned, internal::Matcher<Expr> > (&hasArgument_Type0
)( unsigned const &N, internal::Matcher<Expr> const
&InnerMatcher); template <typename NodeType, typename
ParamT1, typename ParamT2> bool internal::matcher_hasArgument0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
4399 CallExpr, CXXConstructExpr,namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasArgument0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasArgument0Matcher(unsigned const
&AN, internal::Matcher<Expr> const &AInnerMatcher
) : N(AN), InnerMatcher(AInnerMatcher) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; internal::Matcher
<Expr> InnerMatcher; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_hasArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), unsigned, internal::Matcher<Expr> > hasArgument
(unsigned const &N, internal::Matcher<Expr> const &
InnerMatcher) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasArgument0Matcher, void(::clang::ast_matchers
::internal::TypeList<CallExpr, CXXConstructExpr, CXXUnresolvedConstructExpr
, ObjCMessageExpr>), unsigned, internal::Matcher<Expr>
>(N, InnerMatcher); } typedef ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), unsigned, internal::Matcher<Expr> > (&hasArgument_Type0
)( unsigned const &N, internal::Matcher<Expr> const
&InnerMatcher); template <typename NodeType, typename
ParamT1, typename ParamT2> bool internal::matcher_hasArgument0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
4400 CXXUnresolvedConstructExpr, ObjCMessageExpr),namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasArgument0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasArgument0Matcher(unsigned const
&AN, internal::Matcher<Expr> const &AInnerMatcher
) : N(AN), InnerMatcher(AInnerMatcher) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; internal::Matcher
<Expr> InnerMatcher; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_hasArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), unsigned, internal::Matcher<Expr> > hasArgument
(unsigned const &N, internal::Matcher<Expr> const &
InnerMatcher) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasArgument0Matcher, void(::clang::ast_matchers
::internal::TypeList<CallExpr, CXXConstructExpr, CXXUnresolvedConstructExpr
, ObjCMessageExpr>), unsigned, internal::Matcher<Expr>
>(N, InnerMatcher); } typedef ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), unsigned, internal::Matcher<Expr> > (&hasArgument_Type0
)( unsigned const &N, internal::Matcher<Expr> const
&InnerMatcher); template <typename NodeType, typename
ParamT1, typename ParamT2> bool internal::matcher_hasArgument0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
4401 unsigned, N, internal::Matcher<Expr>, InnerMatcher)namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasArgument0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasArgument0Matcher(unsigned const
&AN, internal::Matcher<Expr> const &AInnerMatcher
) : N(AN), InnerMatcher(AInnerMatcher) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; internal::Matcher
<Expr> InnerMatcher; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_hasArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), unsigned, internal::Matcher<Expr> > hasArgument
(unsigned const &N, internal::Matcher<Expr> const &
InnerMatcher) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasArgument0Matcher, void(::clang::ast_matchers
::internal::TypeList<CallExpr, CXXConstructExpr, CXXUnresolvedConstructExpr
, ObjCMessageExpr>), unsigned, internal::Matcher<Expr>
>(N, InnerMatcher); } typedef ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), unsigned, internal::Matcher<Expr> > (&hasArgument_Type0
)( unsigned const &N, internal::Matcher<Expr> const
&InnerMatcher); template <typename NodeType, typename
ParamT1, typename ParamT2> bool internal::matcher_hasArgument0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
4402 if (N >= Node.getNumArgs())
4403 return false;
4404 const Expr *Arg = Node.getArg(N);
4405 if (Finder->isTraversalIgnoringImplicitNodes() && isa<CXXDefaultArgExpr>(Arg))
4406 return false;
4407 return InnerMatcher.matches(*Arg->IgnoreParenImpCasts(), Finder, Builder);
4408}
4409
4410/// Matches the n'th item of an initializer list expression.
4411///
4412/// Example matches y.
4413/// (matcher = initListExpr(hasInit(0, expr())))
4414/// \code
4415/// int x{y}.
4416/// \endcode
4417AST_MATCHER_P2(InitListExpr, hasInit, unsigned, N,namespace internal { class matcher_hasInit0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<InitListExpr
> { public: matcher_hasInit0Matcher(unsigned const &AN
, ast_matchers::internal::Matcher<Expr> const &AInnerMatcher
) : N(AN), InnerMatcher(AInnerMatcher) {} bool matches(const InitListExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; ast_matchers::
internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<InitListExpr> hasInit
( unsigned const &N, ast_matchers::internal::Matcher<Expr
> const &InnerMatcher) { return ::clang::ast_matchers::
internal::makeMatcher( new internal::matcher_hasInit0Matcher(
N, InnerMatcher)); } typedef ::clang::ast_matchers::internal::
Matcher<InitListExpr> ( &hasInit_Type0)(unsigned const
&N, ast_matchers::internal::Matcher<Expr> const &
InnerMatcher); inline bool internal::matcher_hasInit0Matcher::
matches( const InitListExpr &Node, ::clang::ast_matchers::
internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4418 ast_matchers::internal::Matcher<Expr>, InnerMatcher)namespace internal { class matcher_hasInit0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<InitListExpr
> { public: matcher_hasInit0Matcher(unsigned const &AN
, ast_matchers::internal::Matcher<Expr> const &AInnerMatcher
) : N(AN), InnerMatcher(AInnerMatcher) {} bool matches(const InitListExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; ast_matchers::
internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<InitListExpr> hasInit
( unsigned const &N, ast_matchers::internal::Matcher<Expr
> const &InnerMatcher) { return ::clang::ast_matchers::
internal::makeMatcher( new internal::matcher_hasInit0Matcher(
N, InnerMatcher)); } typedef ::clang::ast_matchers::internal::
Matcher<InitListExpr> ( &hasInit_Type0)(unsigned const
&N, ast_matchers::internal::Matcher<Expr> const &
InnerMatcher); inline bool internal::matcher_hasInit0Matcher::
matches( const InitListExpr &Node, ::clang::ast_matchers::
internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
4419 return N < Node.getNumInits() &&
4420 InnerMatcher.matches(*Node.getInit(N), Finder, Builder);
4421}
4422
4423/// Matches declaration statements that contain a specific number of
4424/// declarations.
4425///
4426/// Example: Given
4427/// \code
4428/// int a, b;
4429/// int c;
4430/// int d = 2, e;
4431/// \endcode
4432/// declCountIs(2)
4433/// matches 'int a, b;' and 'int d = 2, e;', but not 'int c;'.
4434AST_MATCHER_P(DeclStmt, declCountIs, unsigned, N)namespace internal { class matcher_declCountIs0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<DeclStmt
> { public: explicit matcher_declCountIs0Matcher( unsigned
const &AN) : N(AN) {} bool matches(const DeclStmt &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: unsigned N; }; } inline ::clang::ast_matchers
::internal::Matcher<DeclStmt> declCountIs( unsigned const
&N) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_declCountIs0Matcher(N)); } typedef ::
clang::ast_matchers::internal::Matcher<DeclStmt> ( &
declCountIs_Type0)(unsigned const &N); inline bool internal
::matcher_declCountIs0Matcher::matches( const DeclStmt &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
4435 return std::distance(Node.decl_begin(), Node.decl_end()) == (ptrdiff_t)N;
4436}
4437
4438/// Matches the n'th declaration of a declaration statement.
4439///
4440/// Note that this does not work for global declarations because the AST
4441/// breaks up multiple-declaration DeclStmt's into multiple single-declaration
4442/// DeclStmt's.
4443/// Example: Given non-global declarations
4444/// \code
4445/// int a, b = 0;
4446/// int c;
4447/// int d = 2, e;
4448/// \endcode
4449/// declStmt(containsDeclaration(
4450/// 0, varDecl(hasInitializer(anything()))))
4451/// matches only 'int d = 2, e;', and
4452/// declStmt(containsDeclaration(1, varDecl()))
4453/// \code
4454/// matches 'int a, b = 0' as well as 'int d = 2, e;'
4455/// but 'int c;' is not matched.
4456/// \endcode
4457AST_MATCHER_P2(DeclStmt, containsDeclaration, unsigned, N,namespace internal { class matcher_containsDeclaration0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
DeclStmt> { public: matcher_containsDeclaration0Matcher(unsigned
const &AN, internal::Matcher<Decl> const &AInnerMatcher
) : N(AN), InnerMatcher(AInnerMatcher) {} bool matches(const DeclStmt
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; internal::Matcher
<Decl> InnerMatcher; }; } inline ::clang::ast_matchers::
internal::Matcher<DeclStmt> containsDeclaration( unsigned
const &N, internal::Matcher<Decl> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_containsDeclaration0Matcher(N, InnerMatcher)); } typedef
::clang::ast_matchers::internal::Matcher<DeclStmt> ( &
containsDeclaration_Type0)(unsigned const &N, internal::Matcher
<Decl> const &InnerMatcher); inline bool internal::
matcher_containsDeclaration0Matcher::matches( const DeclStmt &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
4458 internal::Matcher<Decl>, InnerMatcher)namespace internal { class matcher_containsDeclaration0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
DeclStmt> { public: matcher_containsDeclaration0Matcher(unsigned
const &AN, internal::Matcher<Decl> const &AInnerMatcher
) : N(AN), InnerMatcher(AInnerMatcher) {} bool matches(const DeclStmt
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; internal::Matcher
<Decl> InnerMatcher; }; } inline ::clang::ast_matchers::
internal::Matcher<DeclStmt> containsDeclaration( unsigned
const &N, internal::Matcher<Decl> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_containsDeclaration0Matcher(N, InnerMatcher)); } typedef
::clang::ast_matchers::internal::Matcher<DeclStmt> ( &
containsDeclaration_Type0)(unsigned const &N, internal::Matcher
<Decl> const &InnerMatcher); inline bool internal::
matcher_containsDeclaration0Matcher::matches( const DeclStmt &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
4459 const unsigned NumDecls = std::distance(Node.decl_begin(), Node.decl_end());
4460 if (N >= NumDecls)
4461 return false;
4462 DeclStmt::const_decl_iterator Iterator = Node.decl_begin();
4463 std::advance(Iterator, N);
4464 return InnerMatcher.matches(**Iterator, Finder, Builder);
4465}
4466
4467/// Matches a C++ catch statement that has a catch-all handler.
4468///
4469/// Given
4470/// \code
4471/// try {
4472/// // ...
4473/// } catch (int) {
4474/// // ...
4475/// } catch (...) {
4476/// // ...
4477/// }
4478/// \endcode
4479/// cxxCatchStmt(isCatchAll()) matches catch(...) but not catch(int).
4480AST_MATCHER(CXXCatchStmt, isCatchAll)namespace internal { class matcher_isCatchAllMatcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXCatchStmt
> { public: explicit matcher_isCatchAllMatcher() = default
; bool matches(const CXXCatchStmt &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<CXXCatchStmt>
isCatchAll() { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_isCatchAllMatcher()); } inline bool internal
::matcher_isCatchAllMatcher::matches( const CXXCatchStmt &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
4481 return Node.getExceptionDecl() == nullptr;
4482}
4483
4484/// Matches a constructor initializer.
4485///
4486/// Given
4487/// \code
4488/// struct Foo {
4489/// Foo() : foo_(1) { }
4490/// int foo_;
4491/// };
4492/// \endcode
4493/// cxxRecordDecl(has(cxxConstructorDecl(
4494/// hasAnyConstructorInitializer(anything())
4495/// )))
4496/// record matches Foo, hasAnyConstructorInitializer matches foo_(1)
4497AST_MATCHER_P(CXXConstructorDecl, hasAnyConstructorInitializer,namespace internal { class matcher_hasAnyConstructorInitializer0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
CXXConstructorDecl> { public: explicit matcher_hasAnyConstructorInitializer0Matcher
( internal::Matcher<CXXCtorInitializer> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const CXXConstructorDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<CXXCtorInitializer
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<CXXConstructorDecl> hasAnyConstructorInitializer
( internal::Matcher<CXXCtorInitializer> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_hasAnyConstructorInitializer0Matcher(InnerMatcher))
; } typedef ::clang::ast_matchers::internal::Matcher<CXXConstructorDecl
> ( &hasAnyConstructorInitializer_Type0)(internal::Matcher
<CXXCtorInitializer> const &InnerMatcher); inline bool
internal::matcher_hasAnyConstructorInitializer0Matcher::matches
( const CXXConstructorDecl &Node, ::clang::ast_matchers::
internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4498 internal::Matcher<CXXCtorInitializer>, InnerMatcher)namespace internal { class matcher_hasAnyConstructorInitializer0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
CXXConstructorDecl> { public: explicit matcher_hasAnyConstructorInitializer0Matcher
( internal::Matcher<CXXCtorInitializer> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const CXXConstructorDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<CXXCtorInitializer
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<CXXConstructorDecl> hasAnyConstructorInitializer
( internal::Matcher<CXXCtorInitializer> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_hasAnyConstructorInitializer0Matcher(InnerMatcher))
; } typedef ::clang::ast_matchers::internal::Matcher<CXXConstructorDecl
> ( &hasAnyConstructorInitializer_Type0)(internal::Matcher
<CXXCtorInitializer> const &InnerMatcher); inline bool
internal::matcher_hasAnyConstructorInitializer0Matcher::matches
( const CXXConstructorDecl &Node, ::clang::ast_matchers::
internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
4499 auto MatchIt = matchesFirstInPointerRange(InnerMatcher, Node.init_begin(),
4500 Node.init_end(), Finder, Builder);
4501 if (MatchIt == Node.init_end())
4502 return false;
4503 return (*MatchIt)->isWritten() || !Finder->isTraversalIgnoringImplicitNodes();
4504}
4505
4506/// Matches the field declaration of a constructor initializer.
4507///
4508/// Given
4509/// \code
4510/// struct Foo {
4511/// Foo() : foo_(1) { }
4512/// int foo_;
4513/// };
4514/// \endcode
4515/// cxxRecordDecl(has(cxxConstructorDecl(hasAnyConstructorInitializer(
4516/// forField(hasName("foo_"))))))
4517/// matches Foo
4518/// with forField matching foo_
4519AST_MATCHER_P(CXXCtorInitializer, forField,namespace internal { class matcher_forField0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<CXXCtorInitializer
> { public: explicit matcher_forField0Matcher( internal::Matcher
<FieldDecl> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const CXXCtorInitializer &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<FieldDecl> InnerMatcher; }; } inline
::clang::ast_matchers::internal::Matcher<CXXCtorInitializer
> forField( internal::Matcher<FieldDecl> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_forField0Matcher(InnerMatcher)); } typedef
::clang::ast_matchers::internal::Matcher<CXXCtorInitializer
> ( &forField_Type0)(internal::Matcher<FieldDecl>
const &InnerMatcher); inline bool internal::matcher_forField0Matcher
::matches( const CXXCtorInitializer &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4520 internal::Matcher<FieldDecl>, InnerMatcher)namespace internal { class matcher_forField0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<CXXCtorInitializer
> { public: explicit matcher_forField0Matcher( internal::Matcher
<FieldDecl> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const CXXCtorInitializer &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<FieldDecl> InnerMatcher; }; } inline
::clang::ast_matchers::internal::Matcher<CXXCtorInitializer
> forField( internal::Matcher<FieldDecl> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_forField0Matcher(InnerMatcher)); } typedef
::clang::ast_matchers::internal::Matcher<CXXCtorInitializer
> ( &forField_Type0)(internal::Matcher<FieldDecl>
const &InnerMatcher); inline bool internal::matcher_forField0Matcher
::matches( const CXXCtorInitializer &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
4521 const FieldDecl *NodeAsDecl = Node.getAnyMember();
4522 return (NodeAsDecl != nullptr &&
4523 InnerMatcher.matches(*NodeAsDecl, Finder, Builder));
4524}
4525
4526/// Matches the initializer expression of a constructor initializer.
4527///
4528/// Given
4529/// \code
4530/// struct Foo {
4531/// Foo() : foo_(1) { }
4532/// int foo_;
4533/// };
4534/// \endcode
4535/// cxxRecordDecl(has(cxxConstructorDecl(hasAnyConstructorInitializer(
4536/// withInitializer(integerLiteral(equals(1)))))))
4537/// matches Foo
4538/// with withInitializer matching (1)
4539AST_MATCHER_P(CXXCtorInitializer, withInitializer,namespace internal { class matcher_withInitializer0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXCtorInitializer
> { public: explicit matcher_withInitializer0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const CXXCtorInitializer &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<Expr> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<CXXCtorInitializer
> withInitializer( internal::Matcher<Expr> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_withInitializer0Matcher(InnerMatcher)
); } typedef ::clang::ast_matchers::internal::Matcher<CXXCtorInitializer
> ( &withInitializer_Type0)(internal::Matcher<Expr>
const &InnerMatcher); inline bool internal::matcher_withInitializer0Matcher
::matches( const CXXCtorInitializer &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4540 internal::Matcher<Expr>, InnerMatcher)namespace internal { class matcher_withInitializer0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXCtorInitializer
> { public: explicit matcher_withInitializer0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const CXXCtorInitializer &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<Expr> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<CXXCtorInitializer
> withInitializer( internal::Matcher<Expr> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_withInitializer0Matcher(InnerMatcher)
); } typedef ::clang::ast_matchers::internal::Matcher<CXXCtorInitializer
> ( &withInitializer_Type0)(internal::Matcher<Expr>
const &InnerMatcher); inline bool internal::matcher_withInitializer0Matcher
::matches( const CXXCtorInitializer &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
4541 const Expr* NodeAsExpr = Node.getInit();
4542 return (NodeAsExpr != nullptr &&
4543 InnerMatcher.matches(*NodeAsExpr, Finder, Builder));
4544}
4545
4546/// Matches a constructor initializer if it is explicitly written in
4547/// code (as opposed to implicitly added by the compiler).
4548///
4549/// Given
4550/// \code
4551/// struct Foo {
4552/// Foo() { }
4553/// Foo(int) : foo_("A") { }
4554/// string foo_;
4555/// };
4556/// \endcode
4557/// cxxConstructorDecl(hasAnyConstructorInitializer(isWritten()))
4558/// will match Foo(int), but not Foo()
4559AST_MATCHER(CXXCtorInitializer, isWritten)namespace internal { class matcher_isWrittenMatcher : public ::
clang::ast_matchers::internal::MatcherInterface<CXXCtorInitializer
> { public: explicit matcher_isWrittenMatcher() = default;
bool matches(const CXXCtorInitializer &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<CXXCtorInitializer
> isWritten() { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_isWrittenMatcher()); } inline bool internal
::matcher_isWrittenMatcher::matches( const CXXCtorInitializer
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
4560 return Node.isWritten();
4561}
4562
4563/// Matches a constructor initializer if it is initializing a base, as
4564/// opposed to a member.
4565///
4566/// Given
4567/// \code
4568/// struct B {};
4569/// struct D : B {
4570/// int I;
4571/// D(int i) : I(i) {}
4572/// };
4573/// struct E : B {
4574/// E() : B() {}
4575/// };
4576/// \endcode
4577/// cxxConstructorDecl(hasAnyConstructorInitializer(isBaseInitializer()))
4578/// will match E(), but not match D(int).
4579AST_MATCHER(CXXCtorInitializer, isBaseInitializer)namespace internal { class matcher_isBaseInitializerMatcher :
public ::clang::ast_matchers::internal::MatcherInterface<
CXXCtorInitializer> { public: explicit matcher_isBaseInitializerMatcher
() = default; bool matches(const CXXCtorInitializer &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; }; } inline ::clang::ast_matchers::internal
::Matcher<CXXCtorInitializer> isBaseInitializer() { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_isBaseInitializerMatcher()); } inline bool internal::
matcher_isBaseInitializerMatcher::matches( const CXXCtorInitializer
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
4580 return Node.isBaseInitializer();
4581}
4582
4583/// Matches a constructor initializer if it is initializing a member, as
4584/// opposed to a base.
4585///
4586/// Given
4587/// \code
4588/// struct B {};
4589/// struct D : B {
4590/// int I;
4591/// D(int i) : I(i) {}
4592/// };
4593/// struct E : B {
4594/// E() : B() {}
4595/// };
4596/// \endcode
4597/// cxxConstructorDecl(hasAnyConstructorInitializer(isMemberInitializer()))
4598/// will match D(int), but not match E().
4599AST_MATCHER(CXXCtorInitializer, isMemberInitializer)namespace internal { class matcher_isMemberInitializerMatcher
: public ::clang::ast_matchers::internal::MatcherInterface<
CXXCtorInitializer> { public: explicit matcher_isMemberInitializerMatcher
() = default; bool matches(const CXXCtorInitializer &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; }; } inline ::clang::ast_matchers::internal
::Matcher<CXXCtorInitializer> isMemberInitializer() { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_isMemberInitializerMatcher()); } inline bool internal
::matcher_isMemberInitializerMatcher::matches( const CXXCtorInitializer
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
4600 return Node.isMemberInitializer();
4601}
4602
4603/// Matches any argument of a call expression or a constructor call
4604/// expression, or an ObjC-message-send expression.
4605///
4606/// Given
4607/// \code
4608/// void x(int, int, int) { int y; x(1, y, 42); }
4609/// \endcode
4610/// callExpr(hasAnyArgument(declRefExpr()))
4611/// matches x(1, y, 42)
4612/// with hasAnyArgument(...)
4613/// matching y
4614///
4615/// For ObjectiveC, given
4616/// \code
4617/// @interface I - (void) f:(int) y; @end
4618/// void foo(I *i) { [i f:12]; }
4619/// \endcode
4620/// objcMessageExpr(hasAnyArgument(integerLiteral(equals(12))))
4621/// matches [i f:12]
4622AST_POLYMORPHIC_MATCHER_P(hasAnyArgument,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasAnyArgument0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_hasAnyArgument0Matcher( internal::Matcher<
Expr> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<Expr> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasAnyArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), internal::Matcher<Expr> > hasAnyArgument(internal
::Matcher<Expr> const &InnerMatcher) { return ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasAnyArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), internal::Matcher<Expr> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasAnyArgument0Matcher, void(::clang::ast_matchers::
internal::TypeList<CallExpr, CXXConstructExpr, CXXUnresolvedConstructExpr
, ObjCMessageExpr>), internal::Matcher<Expr> > (&
hasAnyArgument_Type0)(internal::Matcher<Expr> const &
InnerMatcher); template <typename NodeType, typename ParamT
> bool internal:: matcher_hasAnyArgument0Matcher<NodeType
, ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4623 AST_POLYMORPHIC_SUPPORTED_TYPES(namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasAnyArgument0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_hasAnyArgument0Matcher( internal::Matcher<
Expr> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<Expr> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasAnyArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), internal::Matcher<Expr> > hasAnyArgument(internal
::Matcher<Expr> const &InnerMatcher) { return ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasAnyArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), internal::Matcher<Expr> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasAnyArgument0Matcher, void(::clang::ast_matchers::
internal::TypeList<CallExpr, CXXConstructExpr, CXXUnresolvedConstructExpr
, ObjCMessageExpr>), internal::Matcher<Expr> > (&
hasAnyArgument_Type0)(internal::Matcher<Expr> const &
InnerMatcher); template <typename NodeType, typename ParamT
> bool internal:: matcher_hasAnyArgument0Matcher<NodeType
, ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4624 CallExpr, CXXConstructExpr,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasAnyArgument0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_hasAnyArgument0Matcher( internal::Matcher<
Expr> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<Expr> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasAnyArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), internal::Matcher<Expr> > hasAnyArgument(internal
::Matcher<Expr> const &InnerMatcher) { return ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasAnyArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), internal::Matcher<Expr> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasAnyArgument0Matcher, void(::clang::ast_matchers::
internal::TypeList<CallExpr, CXXConstructExpr, CXXUnresolvedConstructExpr
, ObjCMessageExpr>), internal::Matcher<Expr> > (&
hasAnyArgument_Type0)(internal::Matcher<Expr> const &
InnerMatcher); template <typename NodeType, typename ParamT
> bool internal:: matcher_hasAnyArgument0Matcher<NodeType
, ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4625 CXXUnresolvedConstructExpr, ObjCMessageExpr),namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasAnyArgument0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_hasAnyArgument0Matcher( internal::Matcher<
Expr> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<Expr> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasAnyArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), internal::Matcher<Expr> > hasAnyArgument(internal
::Matcher<Expr> const &InnerMatcher) { return ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasAnyArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), internal::Matcher<Expr> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasAnyArgument0Matcher, void(::clang::ast_matchers::
internal::TypeList<CallExpr, CXXConstructExpr, CXXUnresolvedConstructExpr
, ObjCMessageExpr>), internal::Matcher<Expr> > (&
hasAnyArgument_Type0)(internal::Matcher<Expr> const &
InnerMatcher); template <typename NodeType, typename ParamT
> bool internal:: matcher_hasAnyArgument0Matcher<NodeType
, ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4626 internal::Matcher<Expr>, InnerMatcher)namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasAnyArgument0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_hasAnyArgument0Matcher( internal::Matcher<
Expr> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<Expr> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasAnyArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), internal::Matcher<Expr> > hasAnyArgument(internal
::Matcher<Expr> const &InnerMatcher) { return ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasAnyArgument0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr, CXXUnresolvedConstructExpr, ObjCMessageExpr
>), internal::Matcher<Expr> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasAnyArgument0Matcher, void(::clang::ast_matchers::
internal::TypeList<CallExpr, CXXConstructExpr, CXXUnresolvedConstructExpr
, ObjCMessageExpr>), internal::Matcher<Expr> > (&
hasAnyArgument_Type0)(internal::Matcher<Expr> const &
InnerMatcher); template <typename NodeType, typename ParamT
> bool internal:: matcher_hasAnyArgument0Matcher<NodeType
, ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
4627 for (const Expr *Arg : Node.arguments()) {
4628 if (Finder->isTraversalIgnoringImplicitNodes() &&
4629 isa<CXXDefaultArgExpr>(Arg))
4630 break;
4631 BoundNodesTreeBuilder Result(*Builder);
4632 if (InnerMatcher.matches(*Arg, Finder, &Result)) {
4633 *Builder = std::move(Result);
4634 return true;
4635 }
4636 }
4637 return false;
4638}
4639
4640/// Matches lambda captures.
4641///
4642/// Given
4643/// \code
4644/// int main() {
4645/// int x;
4646/// auto f = [x](){};
4647/// auto g = [x = 1](){};
4648/// }
4649/// \endcode
4650/// In the matcher `lambdaExpr(hasAnyCapture(lambdaCapture()))`,
4651/// `lambdaCapture()` matches `x` and `x=1`.
4652extern const internal::VariadicAllOfMatcher<LambdaCapture> lambdaCapture;
4653
4654/// Matches any capture in a lambda expression.
4655///
4656/// Given
4657/// \code
4658/// void foo() {
4659/// int t = 5;
4660/// auto f = [=](){ return t; };
4661/// }
4662/// \endcode
4663/// lambdaExpr(hasAnyCapture(lambdaCapture())) and
4664/// lambdaExpr(hasAnyCapture(lambdaCapture(refersToVarDecl(hasName("t")))))
4665/// both match `[=](){ return t; }`.
4666AST_MATCHER_P(LambdaExpr, hasAnyCapture, internal::Matcher<LambdaCapture>,namespace internal { class matcher_hasAnyCapture0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<LambdaExpr
> { public: explicit matcher_hasAnyCapture0Matcher( internal
::Matcher<LambdaCapture> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const LambdaExpr &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
override; private: internal::Matcher<LambdaCapture> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<LambdaExpr
> hasAnyCapture( internal::Matcher<LambdaCapture> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
makeMatcher( new internal::matcher_hasAnyCapture0Matcher(InnerMatcher
)); } typedef ::clang::ast_matchers::internal::Matcher<LambdaExpr
> ( &hasAnyCapture_Type0)(internal::Matcher<LambdaCapture
> const &InnerMatcher); inline bool internal::matcher_hasAnyCapture0Matcher
::matches( const LambdaExpr &Node, ::clang::ast_matchers::
internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4667 InnerMatcher)namespace internal { class matcher_hasAnyCapture0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<LambdaExpr
> { public: explicit matcher_hasAnyCapture0Matcher( internal
::Matcher<LambdaCapture> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const LambdaExpr &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
override; private: internal::Matcher<LambdaCapture> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<LambdaExpr
> hasAnyCapture( internal::Matcher<LambdaCapture> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
makeMatcher( new internal::matcher_hasAnyCapture0Matcher(InnerMatcher
)); } typedef ::clang::ast_matchers::internal::Matcher<LambdaExpr
> ( &hasAnyCapture_Type0)(internal::Matcher<LambdaCapture
> const &InnerMatcher); inline bool internal::matcher_hasAnyCapture0Matcher
::matches( const LambdaExpr &Node, ::clang::ast_matchers::
internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
4668 for (const LambdaCapture &Capture : Node.captures()) {
4669 clang::ast_matchers::internal::BoundNodesTreeBuilder Result(*Builder);
4670 if (InnerMatcher.matches(Capture, Finder, &Result)) {
4671 *Builder = std::move(Result);
4672 return true;
4673 }
4674 }
4675 return false;
4676}
4677
4678/// Matches a `LambdaCapture` that refers to the specified `VarDecl`. The
4679/// `VarDecl` can be a separate variable that is captured by value or
4680/// reference, or a synthesized variable if the capture has an initializer.
4681///
4682/// Given
4683/// \code
4684/// void foo() {
4685/// int x;
4686/// auto f = [x](){};
4687/// auto g = [x = 1](){};
4688/// }
4689/// \endcode
4690/// In the matcher
4691/// lambdaExpr(hasAnyCapture(lambdaCapture(capturesVar(hasName("x")))),
4692/// capturesVar(hasName("x")) matches `x` and `x = 1`.
4693AST_MATCHER_P(LambdaCapture, capturesVar, internal::Matcher<VarDecl>,namespace internal { class matcher_capturesVar0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<LambdaCapture
> { public: explicit matcher_capturesVar0Matcher( internal
::Matcher<VarDecl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const LambdaCapture &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<VarDecl> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<LambdaCapture
> capturesVar( internal::Matcher<VarDecl> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_capturesVar0Matcher(InnerMatcher)); }
typedef ::clang::ast_matchers::internal::Matcher<LambdaCapture
> ( &capturesVar_Type0)(internal::Matcher<VarDecl>
const &InnerMatcher); inline bool internal::matcher_capturesVar0Matcher
::matches( const LambdaCapture &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4694 InnerMatcher)namespace internal { class matcher_capturesVar0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<LambdaCapture
> { public: explicit matcher_capturesVar0Matcher( internal
::Matcher<VarDecl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const LambdaCapture &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<VarDecl> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<LambdaCapture
> capturesVar( internal::Matcher<VarDecl> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_capturesVar0Matcher(InnerMatcher)); }
typedef ::clang::ast_matchers::internal::Matcher<LambdaCapture
> ( &capturesVar_Type0)(internal::Matcher<VarDecl>
const &InnerMatcher); inline bool internal::matcher_capturesVar0Matcher
::matches( const LambdaCapture &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
4695 auto *capturedVar = Node.getCapturedVar();
4696 return capturedVar && InnerMatcher.matches(*capturedVar, Finder, Builder);
4697}
4698
4699/// Matches a `LambdaCapture` that refers to 'this'.
4700///
4701/// Given
4702/// \code
4703/// class C {
4704/// int cc;
4705/// int f() {
4706/// auto l = [this]() { return cc; };
4707/// return l();
4708/// }
4709/// };
4710/// \endcode
4711/// lambdaExpr(hasAnyCapture(lambdaCapture(capturesThis())))
4712/// matches `[this]() { return cc; }`.
4713AST_MATCHER(LambdaCapture, capturesThis)namespace internal { class matcher_capturesThisMatcher : public
::clang::ast_matchers::internal::MatcherInterface<LambdaCapture
> { public: explicit matcher_capturesThisMatcher() = default
; bool matches(const LambdaCapture &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<LambdaCapture>
capturesThis() { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_capturesThisMatcher()); } inline bool
internal::matcher_capturesThisMatcher::matches( const LambdaCapture
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{ return Node.capturesThis(); }
4714
4715/// Matches a constructor call expression which uses list initialization.
4716AST_MATCHER(CXXConstructExpr, isListInitialization)namespace internal { class matcher_isListInitializationMatcher
: public ::clang::ast_matchers::internal::MatcherInterface<
CXXConstructExpr> { public: explicit matcher_isListInitializationMatcher
() = default; bool matches(const CXXConstructExpr &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
override; }; } inline ::clang::ast_matchers::internal::Matcher
<CXXConstructExpr> isListInitialization() { return ::clang
::ast_matchers::internal::makeMatcher( new internal::matcher_isListInitializationMatcher
()); } inline bool internal::matcher_isListInitializationMatcher
::matches( const CXXConstructExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
4717 return Node.isListInitialization();
4718}
4719
4720/// Matches a constructor call expression which requires
4721/// zero initialization.
4722///
4723/// Given
4724/// \code
4725/// void foo() {
4726/// struct point { double x; double y; };
4727/// point pt[2] = { { 1.0, 2.0 } };
4728/// }
4729/// \endcode
4730/// initListExpr(has(cxxConstructExpr(requiresZeroInitialization()))
4731/// will match the implicit array filler for pt[1].
4732AST_MATCHER(CXXConstructExpr, requiresZeroInitialization)namespace internal { class matcher_requiresZeroInitializationMatcher
: public ::clang::ast_matchers::internal::MatcherInterface<
CXXConstructExpr> { public: explicit matcher_requiresZeroInitializationMatcher
() = default; bool matches(const CXXConstructExpr &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
override; }; } inline ::clang::ast_matchers::internal::Matcher
<CXXConstructExpr> requiresZeroInitialization() { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_requiresZeroInitializationMatcher()); } inline bool internal
::matcher_requiresZeroInitializationMatcher::matches( const CXXConstructExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
4733 return Node.requiresZeroInitialization();
4734}
4735
4736/// Matches the n'th parameter of a function or an ObjC method
4737/// declaration or a block.
4738///
4739/// Given
4740/// \code
4741/// class X { void f(int x) {} };
4742/// \endcode
4743/// cxxMethodDecl(hasParameter(0, hasType(varDecl())))
4744/// matches f(int x) {}
4745/// with hasParameter(...)
4746/// matching int x
4747///
4748/// For ObjectiveC, given
4749/// \code
4750/// @interface I - (void) f:(int) y; @end
4751/// \endcode
4752//
4753/// the matcher objcMethodDecl(hasParameter(0, hasName("y")))
4754/// matches the declaration of method f with hasParameter
4755/// matching y.
4756AST_POLYMORPHIC_MATCHER_P2(hasParameter,namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasParameter0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasParameter0Matcher(unsigned const
&AN, internal::Matcher<ParmVarDecl> const &AInnerMatcher
) : N(AN), InnerMatcher(AInnerMatcher) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; internal::Matcher
<ParmVarDecl> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasParameter0Matcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, ObjCMethodDecl, BlockDecl>), unsigned, internal::Matcher
<ParmVarDecl> > hasParameter(unsigned const &N, internal
::Matcher<ParmVarDecl> const &InnerMatcher) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasParameter0Matcher, void(::clang::ast_matchers::internal
::TypeList<FunctionDecl, ObjCMethodDecl, BlockDecl>), unsigned
, internal::Matcher<ParmVarDecl> >(N, InnerMatcher);
} typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasParameter0Matcher, void(::clang::ast_matchers
::internal::TypeList<FunctionDecl, ObjCMethodDecl, BlockDecl
>), unsigned, internal::Matcher<ParmVarDecl> > (&
hasParameter_Type0)( unsigned const &N, internal::Matcher
<ParmVarDecl> const &InnerMatcher); template <typename
NodeType, typename ParamT1, typename ParamT2> bool internal
::matcher_hasParameter0Matcher< NodeType, ParamT1, ParamT2
>:: matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4757 AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasParameter0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasParameter0Matcher(unsigned const
&AN, internal::Matcher<ParmVarDecl> const &AInnerMatcher
) : N(AN), InnerMatcher(AInnerMatcher) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; internal::Matcher
<ParmVarDecl> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasParameter0Matcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, ObjCMethodDecl, BlockDecl>), unsigned, internal::Matcher
<ParmVarDecl> > hasParameter(unsigned const &N, internal
::Matcher<ParmVarDecl> const &InnerMatcher) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasParameter0Matcher, void(::clang::ast_matchers::internal
::TypeList<FunctionDecl, ObjCMethodDecl, BlockDecl>), unsigned
, internal::Matcher<ParmVarDecl> >(N, InnerMatcher);
} typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasParameter0Matcher, void(::clang::ast_matchers
::internal::TypeList<FunctionDecl, ObjCMethodDecl, BlockDecl
>), unsigned, internal::Matcher<ParmVarDecl> > (&
hasParameter_Type0)( unsigned const &N, internal::Matcher
<ParmVarDecl> const &InnerMatcher); template <typename
NodeType, typename ParamT1, typename ParamT2> bool internal
::matcher_hasParameter0Matcher< NodeType, ParamT1, ParamT2
>:: matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4758 ObjCMethodDecl,namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasParameter0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasParameter0Matcher(unsigned const
&AN, internal::Matcher<ParmVarDecl> const &AInnerMatcher
) : N(AN), InnerMatcher(AInnerMatcher) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; internal::Matcher
<ParmVarDecl> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasParameter0Matcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, ObjCMethodDecl, BlockDecl>), unsigned, internal::Matcher
<ParmVarDecl> > hasParameter(unsigned const &N, internal
::Matcher<ParmVarDecl> const &InnerMatcher) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasParameter0Matcher, void(::clang::ast_matchers::internal
::TypeList<FunctionDecl, ObjCMethodDecl, BlockDecl>), unsigned
, internal::Matcher<ParmVarDecl> >(N, InnerMatcher);
} typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasParameter0Matcher, void(::clang::ast_matchers
::internal::TypeList<FunctionDecl, ObjCMethodDecl, BlockDecl
>), unsigned, internal::Matcher<ParmVarDecl> > (&
hasParameter_Type0)( unsigned const &N, internal::Matcher
<ParmVarDecl> const &InnerMatcher); template <typename
NodeType, typename ParamT1, typename ParamT2> bool internal
::matcher_hasParameter0Matcher< NodeType, ParamT1, ParamT2
>:: matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4759 BlockDecl),namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasParameter0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasParameter0Matcher(unsigned const
&AN, internal::Matcher<ParmVarDecl> const &AInnerMatcher
) : N(AN), InnerMatcher(AInnerMatcher) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; internal::Matcher
<ParmVarDecl> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasParameter0Matcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, ObjCMethodDecl, BlockDecl>), unsigned, internal::Matcher
<ParmVarDecl> > hasParameter(unsigned const &N, internal
::Matcher<ParmVarDecl> const &InnerMatcher) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasParameter0Matcher, void(::clang::ast_matchers::internal
::TypeList<FunctionDecl, ObjCMethodDecl, BlockDecl>), unsigned
, internal::Matcher<ParmVarDecl> >(N, InnerMatcher);
} typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasParameter0Matcher, void(::clang::ast_matchers
::internal::TypeList<FunctionDecl, ObjCMethodDecl, BlockDecl
>), unsigned, internal::Matcher<ParmVarDecl> > (&
hasParameter_Type0)( unsigned const &N, internal::Matcher
<ParmVarDecl> const &InnerMatcher); template <typename
NodeType, typename ParamT1, typename ParamT2> bool internal
::matcher_hasParameter0Matcher< NodeType, ParamT1, ParamT2
>:: matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4760 unsigned, N, internal::Matcher<ParmVarDecl>,namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasParameter0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasParameter0Matcher(unsigned const
&AN, internal::Matcher<ParmVarDecl> const &AInnerMatcher
) : N(AN), InnerMatcher(AInnerMatcher) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; internal::Matcher
<ParmVarDecl> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasParameter0Matcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, ObjCMethodDecl, BlockDecl>), unsigned, internal::Matcher
<ParmVarDecl> > hasParameter(unsigned const &N, internal
::Matcher<ParmVarDecl> const &InnerMatcher) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasParameter0Matcher, void(::clang::ast_matchers::internal
::TypeList<FunctionDecl, ObjCMethodDecl, BlockDecl>), unsigned
, internal::Matcher<ParmVarDecl> >(N, InnerMatcher);
} typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasParameter0Matcher, void(::clang::ast_matchers
::internal::TypeList<FunctionDecl, ObjCMethodDecl, BlockDecl
>), unsigned, internal::Matcher<ParmVarDecl> > (&
hasParameter_Type0)( unsigned const &N, internal::Matcher
<ParmVarDecl> const &InnerMatcher); template <typename
NodeType, typename ParamT1, typename ParamT2> bool internal
::matcher_hasParameter0Matcher< NodeType, ParamT1, ParamT2
>:: matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4761 InnerMatcher)namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasParameter0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasParameter0Matcher(unsigned const
&AN, internal::Matcher<ParmVarDecl> const &AInnerMatcher
) : N(AN), InnerMatcher(AInnerMatcher) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; internal::Matcher
<ParmVarDecl> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasParameter0Matcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, ObjCMethodDecl, BlockDecl>), unsigned, internal::Matcher
<ParmVarDecl> > hasParameter(unsigned const &N, internal
::Matcher<ParmVarDecl> const &InnerMatcher) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasParameter0Matcher, void(::clang::ast_matchers::internal
::TypeList<FunctionDecl, ObjCMethodDecl, BlockDecl>), unsigned
, internal::Matcher<ParmVarDecl> >(N, InnerMatcher);
} typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasParameter0Matcher, void(::clang::ast_matchers
::internal::TypeList<FunctionDecl, ObjCMethodDecl, BlockDecl
>), unsigned, internal::Matcher<ParmVarDecl> > (&
hasParameter_Type0)( unsigned const &N, internal::Matcher
<ParmVarDecl> const &InnerMatcher); template <typename
NodeType, typename ParamT1, typename ParamT2> bool internal
::matcher_hasParameter0Matcher< NodeType, ParamT1, ParamT2
>:: matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
4762 return (N < Node.parameters().size()
4763 && InnerMatcher.matches(*Node.parameters()[N], Finder, Builder));
4764}
4765
4766/// Matches all arguments and their respective ParmVarDecl.
4767///
4768/// Given
4769/// \code
4770/// void f(int i);
4771/// int y;
4772/// f(y);
4773/// \endcode
4774/// callExpr(
4775/// forEachArgumentWithParam(
4776/// declRefExpr(to(varDecl(hasName("y")))),
4777/// parmVarDecl(hasType(isInteger()))
4778/// ))
4779/// matches f(y);
4780/// with declRefExpr(...)
4781/// matching int y
4782/// and parmVarDecl(...)
4783/// matching int i
4784AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParam,namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_forEachArgumentWithParam0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_forEachArgumentWithParam0Matcher
(internal::Matcher<Expr> const &AArgMatcher, internal
::Matcher<ParmVarDecl> const &AParamMatcher) : ArgMatcher
(AArgMatcher), ParamMatcher(AParamMatcher) {} bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> ArgMatcher; internal::Matcher<ParmVarDecl> ParamMatcher
; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_forEachArgumentWithParam0Matcher, void
(::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<ParmVarDecl
> > forEachArgumentWithParam(internal::Matcher<Expr>
const &ArgMatcher, internal::Matcher<ParmVarDecl> const
&ParamMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_forEachArgumentWithParam0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr>), internal::Matcher<Expr>, internal
::Matcher<ParmVarDecl> >(ArgMatcher, ParamMatcher); }
typedef ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_forEachArgumentWithParam0Matcher, void(::clang
::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<ParmVarDecl
> > (&forEachArgumentWithParam_Type0)( internal::Matcher
<Expr> const &ArgMatcher, internal::Matcher<ParmVarDecl
> const &ParamMatcher); template <typename NodeType
, typename ParamT1, typename ParamT2> bool internal::matcher_forEachArgumentWithParam0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
4785 AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_forEachArgumentWithParam0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_forEachArgumentWithParam0Matcher
(internal::Matcher<Expr> const &AArgMatcher, internal
::Matcher<ParmVarDecl> const &AParamMatcher) : ArgMatcher
(AArgMatcher), ParamMatcher(AParamMatcher) {} bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> ArgMatcher; internal::Matcher<ParmVarDecl> ParamMatcher
; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_forEachArgumentWithParam0Matcher, void
(::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<ParmVarDecl
> > forEachArgumentWithParam(internal::Matcher<Expr>
const &ArgMatcher, internal::Matcher<ParmVarDecl> const
&ParamMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_forEachArgumentWithParam0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr>), internal::Matcher<Expr>, internal
::Matcher<ParmVarDecl> >(ArgMatcher, ParamMatcher); }
typedef ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_forEachArgumentWithParam0Matcher, void(::clang
::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<ParmVarDecl
> > (&forEachArgumentWithParam_Type0)( internal::Matcher
<Expr> const &ArgMatcher, internal::Matcher<ParmVarDecl
> const &ParamMatcher); template <typename NodeType
, typename ParamT1, typename ParamT2> bool internal::matcher_forEachArgumentWithParam0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
4786 CXXConstructExpr),namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_forEachArgumentWithParam0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_forEachArgumentWithParam0Matcher
(internal::Matcher<Expr> const &AArgMatcher, internal
::Matcher<ParmVarDecl> const &AParamMatcher) : ArgMatcher
(AArgMatcher), ParamMatcher(AParamMatcher) {} bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> ArgMatcher; internal::Matcher<ParmVarDecl> ParamMatcher
; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_forEachArgumentWithParam0Matcher, void
(::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<ParmVarDecl
> > forEachArgumentWithParam(internal::Matcher<Expr>
const &ArgMatcher, internal::Matcher<ParmVarDecl> const
&ParamMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_forEachArgumentWithParam0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr>), internal::Matcher<Expr>, internal
::Matcher<ParmVarDecl> >(ArgMatcher, ParamMatcher); }
typedef ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_forEachArgumentWithParam0Matcher, void(::clang
::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<ParmVarDecl
> > (&forEachArgumentWithParam_Type0)( internal::Matcher
<Expr> const &ArgMatcher, internal::Matcher<ParmVarDecl
> const &ParamMatcher); template <typename NodeType
, typename ParamT1, typename ParamT2> bool internal::matcher_forEachArgumentWithParam0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
4787 internal::Matcher<Expr>, ArgMatcher,namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_forEachArgumentWithParam0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_forEachArgumentWithParam0Matcher
(internal::Matcher<Expr> const &AArgMatcher, internal
::Matcher<ParmVarDecl> const &AParamMatcher) : ArgMatcher
(AArgMatcher), ParamMatcher(AParamMatcher) {} bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> ArgMatcher; internal::Matcher<ParmVarDecl> ParamMatcher
; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_forEachArgumentWithParam0Matcher, void
(::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<ParmVarDecl
> > forEachArgumentWithParam(internal::Matcher<Expr>
const &ArgMatcher, internal::Matcher<ParmVarDecl> const
&ParamMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_forEachArgumentWithParam0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr>), internal::Matcher<Expr>, internal
::Matcher<ParmVarDecl> >(ArgMatcher, ParamMatcher); }
typedef ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_forEachArgumentWithParam0Matcher, void(::clang
::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<ParmVarDecl
> > (&forEachArgumentWithParam_Type0)( internal::Matcher
<Expr> const &ArgMatcher, internal::Matcher<ParmVarDecl
> const &ParamMatcher); template <typename NodeType
, typename ParamT1, typename ParamT2> bool internal::matcher_forEachArgumentWithParam0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
4788 internal::Matcher<ParmVarDecl>, ParamMatcher)namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_forEachArgumentWithParam0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_forEachArgumentWithParam0Matcher
(internal::Matcher<Expr> const &AArgMatcher, internal
::Matcher<ParmVarDecl> const &AParamMatcher) : ArgMatcher
(AArgMatcher), ParamMatcher(AParamMatcher) {} bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> ArgMatcher; internal::Matcher<ParmVarDecl> ParamMatcher
; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_forEachArgumentWithParam0Matcher, void
(::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<ParmVarDecl
> > forEachArgumentWithParam(internal::Matcher<Expr>
const &ArgMatcher, internal::Matcher<ParmVarDecl> const
&ParamMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_forEachArgumentWithParam0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr>), internal::Matcher<Expr>, internal
::Matcher<ParmVarDecl> >(ArgMatcher, ParamMatcher); }
typedef ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_forEachArgumentWithParam0Matcher, void(::clang
::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<ParmVarDecl
> > (&forEachArgumentWithParam_Type0)( internal::Matcher
<Expr> const &ArgMatcher, internal::Matcher<ParmVarDecl
> const &ParamMatcher); template <typename NodeType
, typename ParamT1, typename ParamT2> bool internal::matcher_forEachArgumentWithParam0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
4789 BoundNodesTreeBuilder Result;
4790 // The first argument of an overloaded member operator is the implicit object
4791 // argument of the method which should not be matched against a parameter, so
4792 // we skip over it here.
4793 BoundNodesTreeBuilder Matches;
4794 unsigned ArgIndex = cxxOperatorCallExpr(callee(cxxMethodDecl()))
4795 .matches(Node, Finder, &Matches)
4796 ? 1
4797 : 0;
4798 int ParamIndex = 0;
4799 bool Matched = false;
4800 for (; ArgIndex < Node.getNumArgs(); ++ArgIndex) {
4801 BoundNodesTreeBuilder ArgMatches(*Builder);
4802 if (ArgMatcher.matches(*(Node.getArg(ArgIndex)->IgnoreParenCasts()),
4803 Finder, &ArgMatches)) {
4804 BoundNodesTreeBuilder ParamMatches(ArgMatches);
4805 if (expr(anyOf(cxxConstructExpr(hasDeclaration(cxxConstructorDecl(
4806 hasParameter(ParamIndex, ParamMatcher)))),
4807 callExpr(callee(functionDecl(
4808 hasParameter(ParamIndex, ParamMatcher))))))
4809 .matches(Node, Finder, &ParamMatches)) {
4810 Result.addMatch(ParamMatches);
4811 Matched = true;
4812 }
4813 }
4814 ++ParamIndex;
4815 }
4816 *Builder = std::move(Result);
4817 return Matched;
4818}
4819
4820/// Matches all arguments and their respective types for a \c CallExpr or
4821/// \c CXXConstructExpr. It is very similar to \c forEachArgumentWithParam but
4822/// it works on calls through function pointers as well.
4823///
4824/// The difference is, that function pointers do not provide access to a
4825/// \c ParmVarDecl, but only the \c QualType for each argument.
4826///
4827/// Given
4828/// \code
4829/// void f(int i);
4830/// int y;
4831/// f(y);
4832/// void (*f_ptr)(int) = f;
4833/// f_ptr(y);
4834/// \endcode
4835/// callExpr(
4836/// forEachArgumentWithParamType(
4837/// declRefExpr(to(varDecl(hasName("y")))),
4838/// qualType(isInteger()).bind("type)
4839/// ))
4840/// matches f(y) and f_ptr(y)
4841/// with declRefExpr(...)
4842/// matching int y
4843/// and qualType(...)
4844/// matching int
4845AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParamType,namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_forEachArgumentWithParamType0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_forEachArgumentWithParamType0Matcher
(internal::Matcher<Expr> const &AArgMatcher, internal
::Matcher<QualType> const &AParamMatcher) : ArgMatcher
(AArgMatcher), ParamMatcher(AParamMatcher) {} bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> ArgMatcher; internal::Matcher<QualType> ParamMatcher
; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_forEachArgumentWithParamType0Matcher, void
(::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<QualType
> > forEachArgumentWithParamType(internal::Matcher<Expr
> const &ArgMatcher, internal::Matcher<QualType>
const &ParamMatcher) { return ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_forEachArgumentWithParamType0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr>), internal::Matcher<Expr>, internal
::Matcher<QualType> >(ArgMatcher, ParamMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_forEachArgumentWithParamType0Matcher, void(::clang::
ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<QualType
> > (&forEachArgumentWithParamType_Type0)( internal
::Matcher<Expr> const &ArgMatcher, internal::Matcher
<QualType> const &ParamMatcher); template <typename
NodeType, typename ParamT1, typename ParamT2> bool internal
::matcher_forEachArgumentWithParamType0Matcher< NodeType, ParamT1
, ParamT2>:: matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4846 AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_forEachArgumentWithParamType0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_forEachArgumentWithParamType0Matcher
(internal::Matcher<Expr> const &AArgMatcher, internal
::Matcher<QualType> const &AParamMatcher) : ArgMatcher
(AArgMatcher), ParamMatcher(AParamMatcher) {} bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> ArgMatcher; internal::Matcher<QualType> ParamMatcher
; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_forEachArgumentWithParamType0Matcher, void
(::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<QualType
> > forEachArgumentWithParamType(internal::Matcher<Expr
> const &ArgMatcher, internal::Matcher<QualType>
const &ParamMatcher) { return ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_forEachArgumentWithParamType0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr>), internal::Matcher<Expr>, internal
::Matcher<QualType> >(ArgMatcher, ParamMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_forEachArgumentWithParamType0Matcher, void(::clang::
ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<QualType
> > (&forEachArgumentWithParamType_Type0)( internal
::Matcher<Expr> const &ArgMatcher, internal::Matcher
<QualType> const &ParamMatcher); template <typename
NodeType, typename ParamT1, typename ParamT2> bool internal
::matcher_forEachArgumentWithParamType0Matcher< NodeType, ParamT1
, ParamT2>:: matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4847 CXXConstructExpr),namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_forEachArgumentWithParamType0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_forEachArgumentWithParamType0Matcher
(internal::Matcher<Expr> const &AArgMatcher, internal
::Matcher<QualType> const &AParamMatcher) : ArgMatcher
(AArgMatcher), ParamMatcher(AParamMatcher) {} bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> ArgMatcher; internal::Matcher<QualType> ParamMatcher
; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_forEachArgumentWithParamType0Matcher, void
(::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<QualType
> > forEachArgumentWithParamType(internal::Matcher<Expr
> const &ArgMatcher, internal::Matcher<QualType>
const &ParamMatcher) { return ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_forEachArgumentWithParamType0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr>), internal::Matcher<Expr>, internal
::Matcher<QualType> >(ArgMatcher, ParamMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_forEachArgumentWithParamType0Matcher, void(::clang::
ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<QualType
> > (&forEachArgumentWithParamType_Type0)( internal
::Matcher<Expr> const &ArgMatcher, internal::Matcher
<QualType> const &ParamMatcher); template <typename
NodeType, typename ParamT1, typename ParamT2> bool internal
::matcher_forEachArgumentWithParamType0Matcher< NodeType, ParamT1
, ParamT2>:: matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4848 internal::Matcher<Expr>, ArgMatcher,namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_forEachArgumentWithParamType0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_forEachArgumentWithParamType0Matcher
(internal::Matcher<Expr> const &AArgMatcher, internal
::Matcher<QualType> const &AParamMatcher) : ArgMatcher
(AArgMatcher), ParamMatcher(AParamMatcher) {} bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> ArgMatcher; internal::Matcher<QualType> ParamMatcher
; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_forEachArgumentWithParamType0Matcher, void
(::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<QualType
> > forEachArgumentWithParamType(internal::Matcher<Expr
> const &ArgMatcher, internal::Matcher<QualType>
const &ParamMatcher) { return ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_forEachArgumentWithParamType0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr>), internal::Matcher<Expr>, internal
::Matcher<QualType> >(ArgMatcher, ParamMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_forEachArgumentWithParamType0Matcher, void(::clang::
ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<QualType
> > (&forEachArgumentWithParamType_Type0)( internal
::Matcher<Expr> const &ArgMatcher, internal::Matcher
<QualType> const &ParamMatcher); template <typename
NodeType, typename ParamT1, typename ParamT2> bool internal
::matcher_forEachArgumentWithParamType0Matcher< NodeType, ParamT1
, ParamT2>:: matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
4849 internal::Matcher<QualType>, ParamMatcher)namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_forEachArgumentWithParamType0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_forEachArgumentWithParamType0Matcher
(internal::Matcher<Expr> const &AArgMatcher, internal
::Matcher<QualType> const &AParamMatcher) : ArgMatcher
(AArgMatcher), ParamMatcher(AParamMatcher) {} bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> ArgMatcher; internal::Matcher<QualType> ParamMatcher
; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_forEachArgumentWithParamType0Matcher, void
(::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<QualType
> > forEachArgumentWithParamType(internal::Matcher<Expr
> const &ArgMatcher, internal::Matcher<QualType>
const &ParamMatcher) { return ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_forEachArgumentWithParamType0Matcher
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr>), internal::Matcher<Expr>, internal
::Matcher<QualType> >(ArgMatcher, ParamMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_forEachArgumentWithParamType0Matcher, void(::clang::
ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>), internal::Matcher<Expr>, internal::Matcher<QualType
> > (&forEachArgumentWithParamType_Type0)( internal
::Matcher<Expr> const &ArgMatcher, internal::Matcher
<QualType> const &ParamMatcher); template <typename
NodeType, typename ParamT1, typename ParamT2> bool internal
::matcher_forEachArgumentWithParamType0Matcher< NodeType, ParamT1
, ParamT2>:: matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
4850 BoundNodesTreeBuilder Result;
4851 // The first argument of an overloaded member operator is the implicit object
4852 // argument of the method which should not be matched against a parameter, so
4853 // we skip over it here.
4854 BoundNodesTreeBuilder Matches;
4855 unsigned ArgIndex = cxxOperatorCallExpr(callee(cxxMethodDecl()))
4856 .matches(Node, Finder, &Matches)
4857 ? 1
4858 : 0;
4859
4860 const FunctionProtoType *FProto = nullptr;
4861
4862 if (const auto *Call = dyn_cast<CallExpr>(&Node)) {
4863 if (const auto *Value =
4864 dyn_cast_or_null<ValueDecl>(Call->getCalleeDecl())) {
4865 QualType QT = Value->getType().getCanonicalType();
4866
4867 // This does not necessarily lead to a `FunctionProtoType`,
4868 // e.g. K&R functions do not have a function prototype.
4869 if (QT->isFunctionPointerType())
4870 FProto = QT->getPointeeType()->getAs<FunctionProtoType>();
4871
4872 if (QT->isMemberFunctionPointerType()) {
4873 const auto *MP = QT->getAs<MemberPointerType>();
4874 assert(MP && "Must be member-pointer if its a memberfunctionpointer")(static_cast <bool> (MP && "Must be member-pointer if its a memberfunctionpointer"
) ? void (0) : __assert_fail ("MP && \"Must be member-pointer if its a memberfunctionpointer\""
, "clang/include/clang/ASTMatchers/ASTMatchers.h", 4874, __extension__
__PRETTY_FUNCTION__))
;
4875 FProto = MP->getPointeeType()->getAs<FunctionProtoType>();
4876 assert(FProto &&(static_cast <bool> (FProto && "The call must have happened through a member function "
"pointer") ? void (0) : __assert_fail ("FProto && \"The call must have happened through a member function \" \"pointer\""
, "clang/include/clang/ASTMatchers/ASTMatchers.h", 4878, __extension__
__PRETTY_FUNCTION__))
4877 "The call must have happened through a member function "(static_cast <bool> (FProto && "The call must have happened through a member function "
"pointer") ? void (0) : __assert_fail ("FProto && \"The call must have happened through a member function \" \"pointer\""
, "clang/include/clang/ASTMatchers/ASTMatchers.h", 4878, __extension__
__PRETTY_FUNCTION__))
4878 "pointer")(static_cast <bool> (FProto && "The call must have happened through a member function "
"pointer") ? void (0) : __assert_fail ("FProto && \"The call must have happened through a member function \" \"pointer\""
, "clang/include/clang/ASTMatchers/ASTMatchers.h", 4878, __extension__
__PRETTY_FUNCTION__))
;
4879 }
4880 }
4881 }
4882
4883 unsigned ParamIndex = 0;
4884 bool Matched = false;
4885 unsigned NumArgs = Node.getNumArgs();
4886 if (FProto && FProto->isVariadic())
4887 NumArgs = std::min(NumArgs, FProto->getNumParams());
4888
4889 for (; ArgIndex < NumArgs; ++ArgIndex, ++ParamIndex) {
4890 BoundNodesTreeBuilder ArgMatches(*Builder);
4891 if (ArgMatcher.matches(*(Node.getArg(ArgIndex)->IgnoreParenCasts()), Finder,
4892 &ArgMatches)) {
4893 BoundNodesTreeBuilder ParamMatches(ArgMatches);
4894
4895 // This test is cheaper compared to the big matcher in the next if.
4896 // Therefore, please keep this order.
4897 if (FProto && FProto->getNumParams() > ParamIndex) {
4898 QualType ParamType = FProto->getParamType(ParamIndex);
4899 if (ParamMatcher.matches(ParamType, Finder, &ParamMatches)) {
4900 Result.addMatch(ParamMatches);
4901 Matched = true;
4902 continue;
4903 }
4904 }
4905 if (expr(anyOf(cxxConstructExpr(hasDeclaration(cxxConstructorDecl(
4906 hasParameter(ParamIndex, hasType(ParamMatcher))))),
4907 callExpr(callee(functionDecl(
4908 hasParameter(ParamIndex, hasType(ParamMatcher)))))))
4909 .matches(Node, Finder, &ParamMatches)) {
4910 Result.addMatch(ParamMatches);
4911 Matched = true;
4912 continue;
4913 }
4914 }
4915 }
4916 *Builder = std::move(Result);
4917 return Matched;
4918}
4919
4920/// Matches the ParmVarDecl nodes that are at the N'th position in the parameter
4921/// list. The parameter list could be that of either a block, function, or
4922/// objc-method.
4923///
4924///
4925/// Given
4926///
4927/// \code
4928/// void f(int a, int b, int c) {
4929/// }
4930/// \endcode
4931///
4932/// ``parmVarDecl(isAtPosition(0))`` matches ``int a``.
4933///
4934/// ``parmVarDecl(isAtPosition(1))`` matches ``int b``.
4935AST_MATCHER_P(ParmVarDecl, isAtPosition, unsigned, N)namespace internal { class matcher_isAtPosition0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<ParmVarDecl
> { public: explicit matcher_isAtPosition0Matcher( unsigned
const &AN) : N(AN) {} bool matches(const ParmVarDecl &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: unsigned N; }; } inline ::clang::ast_matchers
::internal::Matcher<ParmVarDecl> isAtPosition( unsigned
const &N) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_isAtPosition0Matcher(N)); } typedef ::
clang::ast_matchers::internal::Matcher<ParmVarDecl> ( &
isAtPosition_Type0)(unsigned const &N); inline bool internal
::matcher_isAtPosition0Matcher::matches( const ParmVarDecl &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
4936 const clang::DeclContext *Context = Node.getParentFunctionOrMethod();
4937
4938 if (const auto *Decl = dyn_cast_or_null<FunctionDecl>(Context))
4939 return N < Decl->param_size() && Decl->getParamDecl(N) == &Node;
4940 if (const auto *Decl = dyn_cast_or_null<BlockDecl>(Context))
4941 return N < Decl->param_size() && Decl->getParamDecl(N) == &Node;
4942 if (const auto *Decl = dyn_cast_or_null<ObjCMethodDecl>(Context))
4943 return N < Decl->param_size() && Decl->getParamDecl(N) == &Node;
4944
4945 return false;
4946}
4947
4948/// Matches any parameter of a function or an ObjC method declaration or a
4949/// block.
4950///
4951/// Does not match the 'this' parameter of a method.
4952///
4953/// Given
4954/// \code
4955/// class X { void f(int x, int y, int z) {} };
4956/// \endcode
4957/// cxxMethodDecl(hasAnyParameter(hasName("y")))
4958/// matches f(int x, int y, int z) {}
4959/// with hasAnyParameter(...)
4960/// matching int y
4961///
4962/// For ObjectiveC, given
4963/// \code
4964/// @interface I - (void) f:(int) y; @end
4965/// \endcode
4966//
4967/// the matcher objcMethodDecl(hasAnyParameter(hasName("y")))
4968/// matches the declaration of method f with hasParameter
4969/// matching y.
4970///
4971/// For blocks, given
4972/// \code
4973/// b = ^(int y) { printf("%d", y) };
4974/// \endcode
4975///
4976/// the matcher blockDecl(hasAnyParameter(hasName("y")))
4977/// matches the declaration of the block b with hasParameter
4978/// matching y.
4979AST_POLYMORPHIC_MATCHER_P(hasAnyParameter,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasAnyParameter0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_hasAnyParameter0Matcher( internal
::Matcher<ParmVarDecl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<ParmVarDecl> InnerMatcher; }; } inline
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasAnyParameter0Matcher, void(::clang::ast_matchers
::internal::TypeList<FunctionDecl, ObjCMethodDecl, BlockDecl
>), internal::Matcher<ParmVarDecl> > hasAnyParameter
(internal::Matcher<ParmVarDecl> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasAnyParameter0Matcher, void(::clang::
ast_matchers::internal::TypeList<FunctionDecl, ObjCMethodDecl
, BlockDecl>), internal::Matcher<ParmVarDecl> >(InnerMatcher
); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasAnyParameter0Matcher, void(::clang::
ast_matchers::internal::TypeList<FunctionDecl, ObjCMethodDecl
, BlockDecl>), internal::Matcher<ParmVarDecl> > (
&hasAnyParameter_Type0)(internal::Matcher<ParmVarDecl>
const &InnerMatcher); template <typename NodeType, typename
ParamT> bool internal:: matcher_hasAnyParameter0Matcher<
NodeType, ParamT>::matches( const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
4980 AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasAnyParameter0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_hasAnyParameter0Matcher( internal
::Matcher<ParmVarDecl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<ParmVarDecl> InnerMatcher; }; } inline
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasAnyParameter0Matcher, void(::clang::ast_matchers
::internal::TypeList<FunctionDecl, ObjCMethodDecl, BlockDecl
>), internal::Matcher<ParmVarDecl> > hasAnyParameter
(internal::Matcher<ParmVarDecl> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasAnyParameter0Matcher, void(::clang::
ast_matchers::internal::TypeList<FunctionDecl, ObjCMethodDecl
, BlockDecl>), internal::Matcher<ParmVarDecl> >(InnerMatcher
); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasAnyParameter0Matcher, void(::clang::
ast_matchers::internal::TypeList<FunctionDecl, ObjCMethodDecl
, BlockDecl>), internal::Matcher<ParmVarDecl> > (
&hasAnyParameter_Type0)(internal::Matcher<ParmVarDecl>
const &InnerMatcher); template <typename NodeType, typename
ParamT> bool internal:: matcher_hasAnyParameter0Matcher<
NodeType, ParamT>::matches( const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
4981 ObjCMethodDecl,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasAnyParameter0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_hasAnyParameter0Matcher( internal
::Matcher<ParmVarDecl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<ParmVarDecl> InnerMatcher; }; } inline
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasAnyParameter0Matcher, void(::clang::ast_matchers
::internal::TypeList<FunctionDecl, ObjCMethodDecl, BlockDecl
>), internal::Matcher<ParmVarDecl> > hasAnyParameter
(internal::Matcher<ParmVarDecl> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasAnyParameter0Matcher, void(::clang::
ast_matchers::internal::TypeList<FunctionDecl, ObjCMethodDecl
, BlockDecl>), internal::Matcher<ParmVarDecl> >(InnerMatcher
); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasAnyParameter0Matcher, void(::clang::
ast_matchers::internal::TypeList<FunctionDecl, ObjCMethodDecl
, BlockDecl>), internal::Matcher<ParmVarDecl> > (
&hasAnyParameter_Type0)(internal::Matcher<ParmVarDecl>
const &InnerMatcher); template <typename NodeType, typename
ParamT> bool internal:: matcher_hasAnyParameter0Matcher<
NodeType, ParamT>::matches( const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
4982 BlockDecl),namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasAnyParameter0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_hasAnyParameter0Matcher( internal
::Matcher<ParmVarDecl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<ParmVarDecl> InnerMatcher; }; } inline
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasAnyParameter0Matcher, void(::clang::ast_matchers
::internal::TypeList<FunctionDecl, ObjCMethodDecl, BlockDecl
>), internal::Matcher<ParmVarDecl> > hasAnyParameter
(internal::Matcher<ParmVarDecl> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasAnyParameter0Matcher, void(::clang::
ast_matchers::internal::TypeList<FunctionDecl, ObjCMethodDecl
, BlockDecl>), internal::Matcher<ParmVarDecl> >(InnerMatcher
); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasAnyParameter0Matcher, void(::clang::
ast_matchers::internal::TypeList<FunctionDecl, ObjCMethodDecl
, BlockDecl>), internal::Matcher<ParmVarDecl> > (
&hasAnyParameter_Type0)(internal::Matcher<ParmVarDecl>
const &InnerMatcher); template <typename NodeType, typename
ParamT> bool internal:: matcher_hasAnyParameter0Matcher<
NodeType, ParamT>::matches( const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
4983 internal::Matcher<ParmVarDecl>,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasAnyParameter0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_hasAnyParameter0Matcher( internal
::Matcher<ParmVarDecl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<ParmVarDecl> InnerMatcher; }; } inline
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasAnyParameter0Matcher, void(::clang::ast_matchers
::internal::TypeList<FunctionDecl, ObjCMethodDecl, BlockDecl
>), internal::Matcher<ParmVarDecl> > hasAnyParameter
(internal::Matcher<ParmVarDecl> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasAnyParameter0Matcher, void(::clang::
ast_matchers::internal::TypeList<FunctionDecl, ObjCMethodDecl
, BlockDecl>), internal::Matcher<ParmVarDecl> >(InnerMatcher
); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasAnyParameter0Matcher, void(::clang::
ast_matchers::internal::TypeList<FunctionDecl, ObjCMethodDecl
, BlockDecl>), internal::Matcher<ParmVarDecl> > (
&hasAnyParameter_Type0)(internal::Matcher<ParmVarDecl>
const &InnerMatcher); template <typename NodeType, typename
ParamT> bool internal:: matcher_hasAnyParameter0Matcher<
NodeType, ParamT>::matches( const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
4984 InnerMatcher)namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasAnyParameter0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_hasAnyParameter0Matcher( internal
::Matcher<ParmVarDecl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<ParmVarDecl> InnerMatcher; }; } inline
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasAnyParameter0Matcher, void(::clang::ast_matchers
::internal::TypeList<FunctionDecl, ObjCMethodDecl, BlockDecl
>), internal::Matcher<ParmVarDecl> > hasAnyParameter
(internal::Matcher<ParmVarDecl> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasAnyParameter0Matcher, void(::clang::
ast_matchers::internal::TypeList<FunctionDecl, ObjCMethodDecl
, BlockDecl>), internal::Matcher<ParmVarDecl> >(InnerMatcher
); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasAnyParameter0Matcher, void(::clang::
ast_matchers::internal::TypeList<FunctionDecl, ObjCMethodDecl
, BlockDecl>), internal::Matcher<ParmVarDecl> > (
&hasAnyParameter_Type0)(internal::Matcher<ParmVarDecl>
const &InnerMatcher); template <typename NodeType, typename
ParamT> bool internal:: matcher_hasAnyParameter0Matcher<
NodeType, ParamT>::matches( const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
{
4985 return matchesFirstInPointerRange(InnerMatcher, Node.param_begin(),
4986 Node.param_end(), Finder,
4987 Builder) != Node.param_end();
4988}
4989
4990/// Matches \c FunctionDecls and \c FunctionProtoTypes that have a
4991/// specific parameter count.
4992///
4993/// Given
4994/// \code
4995/// void f(int i) {}
4996/// void g(int i, int j) {}
4997/// void h(int i, int j);
4998/// void j(int i);
4999/// void k(int x, int y, int z, ...);
5000/// \endcode
5001/// functionDecl(parameterCountIs(2))
5002/// matches \c g and \c h
5003/// functionProtoType(parameterCountIs(2))
5004/// matches \c g and \c h
5005/// functionProtoType(parameterCountIs(3))
5006/// matches \c k
5007AST_POLYMORPHIC_MATCHER_P(parameterCountIs,namespace internal { template <typename NodeType, typename
ParamT> class matcher_parameterCountIs0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_parameterCountIs0Matcher( unsigned
const &AN) : N(AN) {} bool matches(const NodeType &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: unsigned N; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_parameterCountIs0Matcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, FunctionProtoType>), unsigned> parameterCountIs(unsigned
const &N) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_parameterCountIs0Matcher, void(::clang
::ast_matchers::internal::TypeList<FunctionDecl, FunctionProtoType
>), unsigned>(N); } typedef ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_parameterCountIs0Matcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, FunctionProtoType>), unsigned> (&parameterCountIs_Type0
)(unsigned const &N); template <typename NodeType, typename
ParamT> bool internal:: matcher_parameterCountIs0Matcher<
NodeType, ParamT>::matches( const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
5008 AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,namespace internal { template <typename NodeType, typename
ParamT> class matcher_parameterCountIs0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_parameterCountIs0Matcher( unsigned
const &AN) : N(AN) {} bool matches(const NodeType &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: unsigned N; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_parameterCountIs0Matcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, FunctionProtoType>), unsigned> parameterCountIs(unsigned
const &N) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_parameterCountIs0Matcher, void(::clang
::ast_matchers::internal::TypeList<FunctionDecl, FunctionProtoType
>), unsigned>(N); } typedef ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_parameterCountIs0Matcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, FunctionProtoType>), unsigned> (&parameterCountIs_Type0
)(unsigned const &N); template <typename NodeType, typename
ParamT> bool internal:: matcher_parameterCountIs0Matcher<
NodeType, ParamT>::matches( const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
5009 FunctionProtoType),namespace internal { template <typename NodeType, typename
ParamT> class matcher_parameterCountIs0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_parameterCountIs0Matcher( unsigned
const &AN) : N(AN) {} bool matches(const NodeType &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: unsigned N; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_parameterCountIs0Matcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, FunctionProtoType>), unsigned> parameterCountIs(unsigned
const &N) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_parameterCountIs0Matcher, void(::clang
::ast_matchers::internal::TypeList<FunctionDecl, FunctionProtoType
>), unsigned>(N); } typedef ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_parameterCountIs0Matcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, FunctionProtoType>), unsigned> (&parameterCountIs_Type0
)(unsigned const &N); template <typename NodeType, typename
ParamT> bool internal:: matcher_parameterCountIs0Matcher<
NodeType, ParamT>::matches( const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
5010 unsigned, N)namespace internal { template <typename NodeType, typename
ParamT> class matcher_parameterCountIs0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_parameterCountIs0Matcher( unsigned
const &AN) : N(AN) {} bool matches(const NodeType &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: unsigned N; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_parameterCountIs0Matcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, FunctionProtoType>), unsigned> parameterCountIs(unsigned
const &N) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_parameterCountIs0Matcher, void(::clang
::ast_matchers::internal::TypeList<FunctionDecl, FunctionProtoType
>), unsigned>(N); } typedef ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_parameterCountIs0Matcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, FunctionProtoType>), unsigned> (&parameterCountIs_Type0
)(unsigned const &N); template <typename NodeType, typename
ParamT> bool internal:: matcher_parameterCountIs0Matcher<
NodeType, ParamT>::matches( const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
{
5011 return Node.getNumParams() == N;
5012}
5013
5014/// Matches \c FunctionDecls that have a noreturn attribute.
5015///
5016/// Given
5017/// \code
5018/// void nope();
5019/// [[noreturn]] void a();
5020/// __attribute__((noreturn)) void b();
5021/// struct c { [[noreturn]] c(); };
5022/// \endcode
5023/// functionDecl(isNoReturn())
5024/// matches all of those except
5025/// \code
5026/// void nope();
5027/// \endcode
5028AST_MATCHER(FunctionDecl, isNoReturn)namespace internal { class matcher_isNoReturnMatcher : public
::clang::ast_matchers::internal::MatcherInterface<FunctionDecl
> { public: explicit matcher_isNoReturnMatcher() = default
; bool matches(const FunctionDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<FunctionDecl>
isNoReturn() { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_isNoReturnMatcher()); } inline bool internal
::matcher_isNoReturnMatcher::matches( const FunctionDecl &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{ return Node.isNoReturn(); }
5029
5030/// Matches the return type of a function declaration.
5031///
5032/// Given:
5033/// \code
5034/// class X { int f() { return 1; } };
5035/// \endcode
5036/// cxxMethodDecl(returns(asString("int")))
5037/// matches int f() { return 1; }
5038AST_MATCHER_P(FunctionDecl, returns,namespace internal { class matcher_returns0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<FunctionDecl
> { public: explicit matcher_returns0Matcher( internal::Matcher
<QualType> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const FunctionDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<QualType> InnerMatcher; }; } inline ::clang::
ast_matchers::internal::Matcher<FunctionDecl> returns( internal
::Matcher<QualType> const &InnerMatcher) { return ::
clang::ast_matchers::internal::makeMatcher( new internal::matcher_returns0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<FunctionDecl> ( &returns_Type0)(internal::Matcher<
QualType> const &InnerMatcher); inline bool internal::
matcher_returns0Matcher::matches( const FunctionDecl &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
5039 internal::Matcher<QualType>, InnerMatcher)namespace internal { class matcher_returns0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<FunctionDecl
> { public: explicit matcher_returns0Matcher( internal::Matcher
<QualType> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const FunctionDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<QualType> InnerMatcher; }; } inline ::clang::
ast_matchers::internal::Matcher<FunctionDecl> returns( internal
::Matcher<QualType> const &InnerMatcher) { return ::
clang::ast_matchers::internal::makeMatcher( new internal::matcher_returns0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<FunctionDecl> ( &returns_Type0)(internal::Matcher<
QualType> const &InnerMatcher); inline bool internal::
matcher_returns0Matcher::matches( const FunctionDecl &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
5040 return InnerMatcher.matches(Node.getReturnType(), Finder, Builder);
5041}
5042
5043/// Matches extern "C" function or variable declarations.
5044///
5045/// Given:
5046/// \code
5047/// extern "C" void f() {}
5048/// extern "C" { void g() {} }
5049/// void h() {}
5050/// extern "C" int x = 1;
5051/// extern "C" int y = 2;
5052/// int z = 3;
5053/// \endcode
5054/// functionDecl(isExternC())
5055/// matches the declaration of f and g, but not the declaration of h.
5056/// varDecl(isExternC())
5057/// matches the declaration of x and y, but not the declaration of z.
5058AST_POLYMORPHIC_MATCHER(isExternC, AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,namespace internal { template <typename NodeType> class
matcher_isExternCMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isExternCMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, VarDecl>)> isExternC() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isExternCMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, VarDecl>)>(); } template <typename NodeType> bool
internal::matcher_isExternCMatcher<NodeType>::matches(
const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
5059 VarDecl))namespace internal { template <typename NodeType> class
matcher_isExternCMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isExternCMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, VarDecl>)> isExternC() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isExternCMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, VarDecl>)>(); } template <typename NodeType> bool
internal::matcher_isExternCMatcher<NodeType>::matches(
const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
5060 return Node.isExternC();
5061}
5062
5063/// Matches variable/function declarations that have "static" storage
5064/// class specifier ("static" keyword) written in the source.
5065///
5066/// Given:
5067/// \code
5068/// static void f() {}
5069/// static int i = 0;
5070/// extern int j;
5071/// int k;
5072/// \endcode
5073/// functionDecl(isStaticStorageClass())
5074/// matches the function declaration f.
5075/// varDecl(isStaticStorageClass())
5076/// matches the variable declaration i.
5077AST_POLYMORPHIC_MATCHER(isStaticStorageClass,namespace internal { template <typename NodeType> class
matcher_isStaticStorageClassMatcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isStaticStorageClassMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, VarDecl>)> isStaticStorageClass() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isStaticStorageClassMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, VarDecl>)>(); } template <typename NodeType> bool
internal::matcher_isStaticStorageClassMatcher<NodeType>
::matches( const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
5078 AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,namespace internal { template <typename NodeType> class
matcher_isStaticStorageClassMatcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isStaticStorageClassMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, VarDecl>)> isStaticStorageClass() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isStaticStorageClassMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, VarDecl>)>(); } template <typename NodeType> bool
internal::matcher_isStaticStorageClassMatcher<NodeType>
::matches( const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
5079 VarDecl))namespace internal { template <typename NodeType> class
matcher_isStaticStorageClassMatcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isStaticStorageClassMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, VarDecl>)> isStaticStorageClass() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isStaticStorageClassMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, VarDecl>)>(); } template <typename NodeType> bool
internal::matcher_isStaticStorageClassMatcher<NodeType>
::matches( const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
5080 return Node.getStorageClass() == SC_Static;
5081}
5082
5083/// Matches deleted function declarations.
5084///
5085/// Given:
5086/// \code
5087/// void Func();
5088/// void DeletedFunc() = delete;
5089/// \endcode
5090/// functionDecl(isDeleted())
5091/// matches the declaration of DeletedFunc, but not Func.
5092AST_MATCHER(FunctionDecl, isDeleted)namespace internal { class matcher_isDeletedMatcher : public ::
clang::ast_matchers::internal::MatcherInterface<FunctionDecl
> { public: explicit matcher_isDeletedMatcher() = default;
bool matches(const FunctionDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<FunctionDecl>
isDeleted() { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_isDeletedMatcher()); } inline bool internal
::matcher_isDeletedMatcher::matches( const FunctionDecl &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
5093 return Node.isDeleted();
5094}
5095
5096/// Matches defaulted function declarations.
5097///
5098/// Given:
5099/// \code
5100/// class A { ~A(); };
5101/// class B { ~B() = default; };
5102/// \endcode
5103/// functionDecl(isDefaulted())
5104/// matches the declaration of ~B, but not ~A.
5105AST_MATCHER(FunctionDecl, isDefaulted)namespace internal { class matcher_isDefaultedMatcher : public
::clang::ast_matchers::internal::MatcherInterface<FunctionDecl
> { public: explicit matcher_isDefaultedMatcher() = default
; bool matches(const FunctionDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<FunctionDecl>
isDefaulted() { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_isDefaultedMatcher()); } inline bool internal
::matcher_isDefaultedMatcher::matches( const FunctionDecl &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
5106 return Node.isDefaulted();
5107}
5108
5109/// Matches weak function declarations.
5110///
5111/// Given:
5112/// \code
5113/// void foo() __attribute__((__weakref__("__foo")));
5114/// void bar();
5115/// \endcode
5116/// functionDecl(isWeak())
5117/// matches the weak declaration "foo", but not "bar".
5118AST_MATCHER(FunctionDecl, isWeak)namespace internal { class matcher_isWeakMatcher : public ::clang
::ast_matchers::internal::MatcherInterface<FunctionDecl>
{ public: explicit matcher_isWeakMatcher() = default; bool matches
(const FunctionDecl &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::Matcher<FunctionDecl> isWeak() { return ::clang
::ast_matchers::internal::makeMatcher( new internal::matcher_isWeakMatcher
()); } inline bool internal::matcher_isWeakMatcher::matches( const
FunctionDecl &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{ return Node.isWeak(); }
5119
5120/// Matches functions that have a dynamic exception specification.
5121///
5122/// Given:
5123/// \code
5124/// void f();
5125/// void g() noexcept;
5126/// void h() noexcept(true);
5127/// void i() noexcept(false);
5128/// void j() throw();
5129/// void k() throw(int);
5130/// void l() throw(...);
5131/// \endcode
5132/// functionDecl(hasDynamicExceptionSpec()) and
5133/// functionProtoType(hasDynamicExceptionSpec())
5134/// match the declarations of j, k, and l, but not f, g, h, or i.
5135AST_POLYMORPHIC_MATCHER(hasDynamicExceptionSpec,namespace internal { template <typename NodeType> class
matcher_hasDynamicExceptionSpecMatcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_hasDynamicExceptionSpecMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, FunctionProtoType>)> hasDynamicExceptionSpec() { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasDynamicExceptionSpecMatcher, void(::clang::ast_matchers
::internal::TypeList<FunctionDecl, FunctionProtoType>)>
(); } template <typename NodeType> bool internal::matcher_hasDynamicExceptionSpecMatcher
<NodeType>::matches( const NodeType &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
5136 AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,namespace internal { template <typename NodeType> class
matcher_hasDynamicExceptionSpecMatcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_hasDynamicExceptionSpecMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, FunctionProtoType>)> hasDynamicExceptionSpec() { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasDynamicExceptionSpecMatcher, void(::clang::ast_matchers
::internal::TypeList<FunctionDecl, FunctionProtoType>)>
(); } template <typename NodeType> bool internal::matcher_hasDynamicExceptionSpecMatcher
<NodeType>::matches( const NodeType &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
5137 FunctionProtoType))namespace internal { template <typename NodeType> class
matcher_hasDynamicExceptionSpecMatcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_hasDynamicExceptionSpecMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, FunctionProtoType>)> hasDynamicExceptionSpec() { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasDynamicExceptionSpecMatcher, void(::clang::ast_matchers
::internal::TypeList<FunctionDecl, FunctionProtoType>)>
(); } template <typename NodeType> bool internal::matcher_hasDynamicExceptionSpecMatcher
<NodeType>::matches( const NodeType &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
{
5138 if (const FunctionProtoType *FnTy = internal::getFunctionProtoType(Node))
5139 return FnTy->hasDynamicExceptionSpec();
5140 return false;
5141}
5142
5143/// Matches functions that have a non-throwing exception specification.
5144///
5145/// Given:
5146/// \code
5147/// void f();
5148/// void g() noexcept;
5149/// void h() throw();
5150/// void i() throw(int);
5151/// void j() noexcept(false);
5152/// \endcode
5153/// functionDecl(isNoThrow()) and functionProtoType(isNoThrow())
5154/// match the declarations of g, and h, but not f, i or j.
5155AST_POLYMORPHIC_MATCHER(isNoThrow,namespace internal { template <typename NodeType> class
matcher_isNoThrowMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isNoThrowMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, FunctionProtoType>)> isNoThrow() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isNoThrowMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, FunctionProtoType>)>(); } template <typename NodeType
> bool internal::matcher_isNoThrowMatcher<NodeType>::
matches( const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
5156 AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,namespace internal { template <typename NodeType> class
matcher_isNoThrowMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isNoThrowMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, FunctionProtoType>)> isNoThrow() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isNoThrowMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, FunctionProtoType>)>(); } template <typename NodeType
> bool internal::matcher_isNoThrowMatcher<NodeType>::
matches( const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
5157 FunctionProtoType))namespace internal { template <typename NodeType> class
matcher_isNoThrowMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isNoThrowMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, FunctionProtoType>)> isNoThrow() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isNoThrowMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, FunctionProtoType>)>(); } template <typename NodeType
> bool internal::matcher_isNoThrowMatcher<NodeType>::
matches( const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
5158 const FunctionProtoType *FnTy = internal::getFunctionProtoType(Node);
5159
5160 // If the function does not have a prototype, then it is assumed to be a
5161 // throwing function (as it would if the function did not have any exception
5162 // specification).
5163 if (!FnTy)
5164 return false;
5165
5166 // Assume the best for any unresolved exception specification.
5167 if (isUnresolvedExceptionSpec(FnTy->getExceptionSpecType()))
5168 return true;
5169
5170 return FnTy->isNothrow();
5171}
5172
5173/// Matches consteval function declarations and if consteval/if ! consteval
5174/// statements.
5175///
5176/// Given:
5177/// \code
5178/// consteval int a();
5179/// void b() { if consteval {} }
5180/// void c() { if ! consteval {} }
5181/// void d() { if ! consteval {} else {} }
5182/// \endcode
5183/// functionDecl(isConsteval())
5184/// matches the declaration of "int a()".
5185/// ifStmt(isConsteval())
5186/// matches the if statement in "void b()", "void c()", "void d()".
5187AST_POLYMORPHIC_MATCHER(isConsteval,namespace internal { template <typename NodeType> class
matcher_isConstevalMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isConstevalMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, IfStmt>)> isConsteval() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isConstevalMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, IfStmt>)>(); } template <typename NodeType> bool
internal::matcher_isConstevalMatcher<NodeType>::matches
( const NodeType &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
5188 AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, IfStmt))namespace internal { template <typename NodeType> class
matcher_isConstevalMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isConstevalMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, IfStmt>)> isConsteval() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isConstevalMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, IfStmt>)>(); } template <typename NodeType> bool
internal::matcher_isConstevalMatcher<NodeType>::matches
( const NodeType &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
5189 return Node.isConsteval();
5190}
5191
5192/// Matches constexpr variable and function declarations,
5193/// and if constexpr.
5194///
5195/// Given:
5196/// \code
5197/// constexpr int foo = 42;
5198/// constexpr int bar();
5199/// void baz() { if constexpr(1 > 0) {} }
5200/// \endcode
5201/// varDecl(isConstexpr())
5202/// matches the declaration of foo.
5203/// functionDecl(isConstexpr())
5204/// matches the declaration of bar.
5205/// ifStmt(isConstexpr())
5206/// matches the if statement in baz.
5207AST_POLYMORPHIC_MATCHER(isConstexpr,namespace internal { template <typename NodeType> class
matcher_isConstexprMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isConstexprMatcher
, void(::clang::ast_matchers::internal::TypeList<VarDecl, FunctionDecl
, IfStmt>)> isConstexpr() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isConstexprMatcher
, void(::clang::ast_matchers::internal::TypeList<VarDecl, FunctionDecl
, IfStmt>)>(); } template <typename NodeType> bool
internal::matcher_isConstexprMatcher<NodeType>::matches
( const NodeType &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
5208 AST_POLYMORPHIC_SUPPORTED_TYPES(VarDecl,namespace internal { template <typename NodeType> class
matcher_isConstexprMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isConstexprMatcher
, void(::clang::ast_matchers::internal::TypeList<VarDecl, FunctionDecl
, IfStmt>)> isConstexpr() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isConstexprMatcher
, void(::clang::ast_matchers::internal::TypeList<VarDecl, FunctionDecl
, IfStmt>)>(); } template <typename NodeType> bool
internal::matcher_isConstexprMatcher<NodeType>::matches
( const NodeType &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
5209 FunctionDecl,namespace internal { template <typename NodeType> class
matcher_isConstexprMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isConstexprMatcher
, void(::clang::ast_matchers::internal::TypeList<VarDecl, FunctionDecl
, IfStmt>)> isConstexpr() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isConstexprMatcher
, void(::clang::ast_matchers::internal::TypeList<VarDecl, FunctionDecl
, IfStmt>)>(); } template <typename NodeType> bool
internal::matcher_isConstexprMatcher<NodeType>::matches
( const NodeType &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
5210 IfStmt))namespace internal { template <typename NodeType> class
matcher_isConstexprMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isConstexprMatcher
, void(::clang::ast_matchers::internal::TypeList<VarDecl, FunctionDecl
, IfStmt>)> isConstexpr() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isConstexprMatcher
, void(::clang::ast_matchers::internal::TypeList<VarDecl, FunctionDecl
, IfStmt>)>(); } template <typename NodeType> bool
internal::matcher_isConstexprMatcher<NodeType>::matches
( const NodeType &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
5211 return Node.isConstexpr();
5212}
5213
5214/// Matches constinit variable declarations.
5215///
5216/// Given:
5217/// \code
5218/// constinit int foo = 42;
5219/// constinit const char* bar = "bar";
5220/// int baz = 42;
5221/// [[clang::require_constant_initialization]] int xyz = 42;
5222/// \endcode
5223/// varDecl(isConstinit())
5224/// matches the declaration of `foo` and `bar`, but not `baz` and `xyz`.
5225AST_MATCHER(VarDecl, isConstinit)namespace internal { class matcher_isConstinitMatcher : public
::clang::ast_matchers::internal::MatcherInterface<VarDecl
> { public: explicit matcher_isConstinitMatcher() = default
; bool matches(const VarDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<VarDecl> isConstinit
() { return ::clang::ast_matchers::internal::makeMatcher( new
internal::matcher_isConstinitMatcher()); } inline bool internal
::matcher_isConstinitMatcher::matches( const VarDecl &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
5226 if (const auto *CIA = Node.getAttr<ConstInitAttr>())
5227 return CIA->isConstinit();
5228 return false;
5229}
5230
5231/// Matches selection statements with initializer.
5232///
5233/// Given:
5234/// \code
5235/// void foo() {
5236/// if (int i = foobar(); i > 0) {}
5237/// switch (int i = foobar(); i) {}
5238/// for (auto& a = get_range(); auto& x : a) {}
5239/// }
5240/// void bar() {
5241/// if (foobar() > 0) {}
5242/// switch (foobar()) {}
5243/// for (auto& x : get_range()) {}
5244/// }
5245/// \endcode
5246/// ifStmt(hasInitStatement(anything()))
5247/// matches the if statement in foo but not in bar.
5248/// switchStmt(hasInitStatement(anything()))
5249/// matches the switch statement in foo but not in bar.
5250/// cxxForRangeStmt(hasInitStatement(anything()))
5251/// matches the range for statement in foo but not in bar.
5252AST_POLYMORPHIC_MATCHER_P(hasInitStatement,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasInitStatement0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_hasInitStatement0Matcher( internal
::Matcher<Stmt> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Stmt> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasInitStatement0Matcher
, void(::clang::ast_matchers::internal::TypeList<IfStmt, SwitchStmt
, CXXForRangeStmt>), internal::Matcher<Stmt> > hasInitStatement
(internal::Matcher<Stmt> const &InnerMatcher) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasInitStatement0Matcher, void(::clang::ast_matchers
::internal::TypeList<IfStmt, SwitchStmt, CXXForRangeStmt>
), internal::Matcher<Stmt> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasInitStatement0Matcher, void(::clang::ast_matchers
::internal::TypeList<IfStmt, SwitchStmt, CXXForRangeStmt>
), internal::Matcher<Stmt> > (&hasInitStatement_Type0
)(internal::Matcher<Stmt> const &InnerMatcher); template
<typename NodeType, typename ParamT> bool internal:: matcher_hasInitStatement0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5253 AST_POLYMORPHIC_SUPPORTED_TYPES(IfStmt, SwitchStmt,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasInitStatement0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_hasInitStatement0Matcher( internal
::Matcher<Stmt> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Stmt> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasInitStatement0Matcher
, void(::clang::ast_matchers::internal::TypeList<IfStmt, SwitchStmt
, CXXForRangeStmt>), internal::Matcher<Stmt> > hasInitStatement
(internal::Matcher<Stmt> const &InnerMatcher) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasInitStatement0Matcher, void(::clang::ast_matchers
::internal::TypeList<IfStmt, SwitchStmt, CXXForRangeStmt>
), internal::Matcher<Stmt> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasInitStatement0Matcher, void(::clang::ast_matchers
::internal::TypeList<IfStmt, SwitchStmt, CXXForRangeStmt>
), internal::Matcher<Stmt> > (&hasInitStatement_Type0
)(internal::Matcher<Stmt> const &InnerMatcher); template
<typename NodeType, typename ParamT> bool internal:: matcher_hasInitStatement0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5254 CXXForRangeStmt),namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasInitStatement0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_hasInitStatement0Matcher( internal
::Matcher<Stmt> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Stmt> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasInitStatement0Matcher
, void(::clang::ast_matchers::internal::TypeList<IfStmt, SwitchStmt
, CXXForRangeStmt>), internal::Matcher<Stmt> > hasInitStatement
(internal::Matcher<Stmt> const &InnerMatcher) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasInitStatement0Matcher, void(::clang::ast_matchers
::internal::TypeList<IfStmt, SwitchStmt, CXXForRangeStmt>
), internal::Matcher<Stmt> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasInitStatement0Matcher, void(::clang::ast_matchers
::internal::TypeList<IfStmt, SwitchStmt, CXXForRangeStmt>
), internal::Matcher<Stmt> > (&hasInitStatement_Type0
)(internal::Matcher<Stmt> const &InnerMatcher); template
<typename NodeType, typename ParamT> bool internal:: matcher_hasInitStatement0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5255 internal::Matcher<Stmt>, InnerMatcher)namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasInitStatement0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_hasInitStatement0Matcher( internal
::Matcher<Stmt> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Stmt> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasInitStatement0Matcher
, void(::clang::ast_matchers::internal::TypeList<IfStmt, SwitchStmt
, CXXForRangeStmt>), internal::Matcher<Stmt> > hasInitStatement
(internal::Matcher<Stmt> const &InnerMatcher) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasInitStatement0Matcher, void(::clang::ast_matchers
::internal::TypeList<IfStmt, SwitchStmt, CXXForRangeStmt>
), internal::Matcher<Stmt> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasInitStatement0Matcher, void(::clang::ast_matchers
::internal::TypeList<IfStmt, SwitchStmt, CXXForRangeStmt>
), internal::Matcher<Stmt> > (&hasInitStatement_Type0
)(internal::Matcher<Stmt> const &InnerMatcher); template
<typename NodeType, typename ParamT> bool internal:: matcher_hasInitStatement0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
{
5256 const Stmt *Init = Node.getInit();
5257 return Init != nullptr && InnerMatcher.matches(*Init, Finder, Builder);
5258}
5259
5260/// Matches the condition expression of an if statement, for loop,
5261/// switch statement or conditional operator.
5262///
5263/// Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true))))
5264/// \code
5265/// if (true) {}
5266/// \endcode
5267AST_POLYMORPHIC_MATCHER_P(namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasCondition0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_hasCondition0Matcher( internal::Matcher<
Expr> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<Expr> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasCondition0Matcher
, void(::clang::ast_matchers::internal::TypeList<IfStmt, ForStmt
, WhileStmt, DoStmt, SwitchStmt, AbstractConditionalOperator>
), internal::Matcher<Expr> > hasCondition(internal::
Matcher<Expr> const &InnerMatcher) { return ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasCondition0Matcher
, void(::clang::ast_matchers::internal::TypeList<IfStmt, ForStmt
, WhileStmt, DoStmt, SwitchStmt, AbstractConditionalOperator>
), internal::Matcher<Expr> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasCondition0Matcher, void(::clang::ast_matchers::internal
::TypeList<IfStmt, ForStmt, WhileStmt, DoStmt, SwitchStmt,
AbstractConditionalOperator>), internal::Matcher<Expr>
> (&hasCondition_Type0)(internal::Matcher<Expr>
const &InnerMatcher); template <typename NodeType, typename
ParamT> bool internal:: matcher_hasCondition0Matcher<NodeType
, ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
5268 hasCondition,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasCondition0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_hasCondition0Matcher( internal::Matcher<
Expr> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<Expr> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasCondition0Matcher
, void(::clang::ast_matchers::internal::TypeList<IfStmt, ForStmt
, WhileStmt, DoStmt, SwitchStmt, AbstractConditionalOperator>
), internal::Matcher<Expr> > hasCondition(internal::
Matcher<Expr> const &InnerMatcher) { return ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasCondition0Matcher
, void(::clang::ast_matchers::internal::TypeList<IfStmt, ForStmt
, WhileStmt, DoStmt, SwitchStmt, AbstractConditionalOperator>
), internal::Matcher<Expr> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasCondition0Matcher, void(::clang::ast_matchers::internal
::TypeList<IfStmt, ForStmt, WhileStmt, DoStmt, SwitchStmt,
AbstractConditionalOperator>), internal::Matcher<Expr>
> (&hasCondition_Type0)(internal::Matcher<Expr>
const &InnerMatcher); template <typename NodeType, typename
ParamT> bool internal:: matcher_hasCondition0Matcher<NodeType
, ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
5269 AST_POLYMORPHIC_SUPPORTED_TYPES(IfStmt, ForStmt, WhileStmt, DoStmt,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasCondition0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_hasCondition0Matcher( internal::Matcher<
Expr> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<Expr> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasCondition0Matcher
, void(::clang::ast_matchers::internal::TypeList<IfStmt, ForStmt
, WhileStmt, DoStmt, SwitchStmt, AbstractConditionalOperator>
), internal::Matcher<Expr> > hasCondition(internal::
Matcher<Expr> const &InnerMatcher) { return ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasCondition0Matcher
, void(::clang::ast_matchers::internal::TypeList<IfStmt, ForStmt
, WhileStmt, DoStmt, SwitchStmt, AbstractConditionalOperator>
), internal::Matcher<Expr> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasCondition0Matcher, void(::clang::ast_matchers::internal
::TypeList<IfStmt, ForStmt, WhileStmt, DoStmt, SwitchStmt,
AbstractConditionalOperator>), internal::Matcher<Expr>
> (&hasCondition_Type0)(internal::Matcher<Expr>
const &InnerMatcher); template <typename NodeType, typename
ParamT> bool internal:: matcher_hasCondition0Matcher<NodeType
, ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
5270 SwitchStmt, AbstractConditionalOperator),namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasCondition0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_hasCondition0Matcher( internal::Matcher<
Expr> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<Expr> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasCondition0Matcher
, void(::clang::ast_matchers::internal::TypeList<IfStmt, ForStmt
, WhileStmt, DoStmt, SwitchStmt, AbstractConditionalOperator>
), internal::Matcher<Expr> > hasCondition(internal::
Matcher<Expr> const &InnerMatcher) { return ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasCondition0Matcher
, void(::clang::ast_matchers::internal::TypeList<IfStmt, ForStmt
, WhileStmt, DoStmt, SwitchStmt, AbstractConditionalOperator>
), internal::Matcher<Expr> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasCondition0Matcher, void(::clang::ast_matchers::internal
::TypeList<IfStmt, ForStmt, WhileStmt, DoStmt, SwitchStmt,
AbstractConditionalOperator>), internal::Matcher<Expr>
> (&hasCondition_Type0)(internal::Matcher<Expr>
const &InnerMatcher); template <typename NodeType, typename
ParamT> bool internal:: matcher_hasCondition0Matcher<NodeType
, ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
5271 internal::Matcher<Expr>, InnerMatcher)namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasCondition0Matcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: explicit matcher_hasCondition0Matcher( internal::Matcher<
Expr> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<Expr> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasCondition0Matcher
, void(::clang::ast_matchers::internal::TypeList<IfStmt, ForStmt
, WhileStmt, DoStmt, SwitchStmt, AbstractConditionalOperator>
), internal::Matcher<Expr> > hasCondition(internal::
Matcher<Expr> const &InnerMatcher) { return ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasCondition0Matcher
, void(::clang::ast_matchers::internal::TypeList<IfStmt, ForStmt
, WhileStmt, DoStmt, SwitchStmt, AbstractConditionalOperator>
), internal::Matcher<Expr> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasCondition0Matcher, void(::clang::ast_matchers::internal
::TypeList<IfStmt, ForStmt, WhileStmt, DoStmt, SwitchStmt,
AbstractConditionalOperator>), internal::Matcher<Expr>
> (&hasCondition_Type0)(internal::Matcher<Expr>
const &InnerMatcher); template <typename NodeType, typename
ParamT> bool internal:: matcher_hasCondition0Matcher<NodeType
, ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
5272 const Expr *const Condition = Node.getCond();
5273 return (Condition != nullptr &&
5274 InnerMatcher.matches(*Condition, Finder, Builder));
5275}
5276
5277/// Matches the then-statement of an if statement.
5278///
5279/// Examples matches the if statement
5280/// (matcher = ifStmt(hasThen(cxxBoolLiteral(equals(true)))))
5281/// \code
5282/// if (false) true; else false;
5283/// \endcode
5284AST_MATCHER_P(IfStmt, hasThen, internal::Matcher<Stmt>, InnerMatcher)namespace internal { class matcher_hasThen0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<IfStmt>
{ public: explicit matcher_hasThen0Matcher( internal::Matcher
<Stmt> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const IfStmt &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<Stmt> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::Matcher<IfStmt> hasThen( internal::Matcher<
Stmt> const &InnerMatcher) { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_hasThen0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<IfStmt> ( &hasThen_Type0)(internal::Matcher<Stmt
> const &InnerMatcher); inline bool internal::matcher_hasThen0Matcher
::matches( const IfStmt &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
5285 const Stmt *const Then = Node.getThen();
5286 return (Then != nullptr && InnerMatcher.matches(*Then, Finder, Builder));
5287}
5288
5289/// Matches the else-statement of an if statement.
5290///
5291/// Examples matches the if statement
5292/// (matcher = ifStmt(hasElse(cxxBoolLiteral(equals(true)))))
5293/// \code
5294/// if (false) false; else true;
5295/// \endcode
5296AST_MATCHER_P(IfStmt, hasElse, internal::Matcher<Stmt>, InnerMatcher)namespace internal { class matcher_hasElse0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<IfStmt>
{ public: explicit matcher_hasElse0Matcher( internal::Matcher
<Stmt> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const IfStmt &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<Stmt> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::Matcher<IfStmt> hasElse( internal::Matcher<
Stmt> const &InnerMatcher) { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_hasElse0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<IfStmt> ( &hasElse_Type0)(internal::Matcher<Stmt
> const &InnerMatcher); inline bool internal::matcher_hasElse0Matcher
::matches( const IfStmt &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
5297 const Stmt *const Else = Node.getElse();
5298 return (Else != nullptr && InnerMatcher.matches(*Else, Finder, Builder));
5299}
5300
5301/// Matches if a node equals a previously bound node.
5302///
5303/// Matches a node if it equals the node previously bound to \p ID.
5304///
5305/// Given
5306/// \code
5307/// class X { int a; int b; };
5308/// \endcode
5309/// cxxRecordDecl(
5310/// has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
5311/// has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))
5312/// matches the class \c X, as \c a and \c b have the same type.
5313///
5314/// Note that when multiple matches are involved via \c forEach* matchers,
5315/// \c equalsBoundNodes acts as a filter.
5316/// For example:
5317/// compoundStmt(
5318/// forEachDescendant(varDecl().bind("d")),
5319/// forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d"))))))
5320/// will trigger a match for each combination of variable declaration
5321/// and reference to that variable declaration within a compound statement.
5322AST_POLYMORPHIC_MATCHER_P(equalsBoundNode,namespace internal { template <typename NodeType, typename
ParamT> class matcher_equalsBoundNode0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_equalsBoundNode0Matcher( std::string
const &AID) : ID(AID) {} bool matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: std::string ID; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_equalsBoundNode0Matcher
, void(::clang::ast_matchers::internal::TypeList<Stmt, Decl
, Type, QualType>), std::string> equalsBoundNode(std::string
const &ID) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equalsBoundNode0Matcher, void(::clang::
ast_matchers::internal::TypeList<Stmt, Decl, Type, QualType
>), std::string>(ID); } typedef ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_equalsBoundNode0Matcher
, void(::clang::ast_matchers::internal::TypeList<Stmt, Decl
, Type, QualType>), std::string> (&equalsBoundNode_Type0
)(std::string const &ID); template <typename NodeType,
typename ParamT> bool internal:: matcher_equalsBoundNode0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5323 AST_POLYMORPHIC_SUPPORTED_TYPES(Stmt, Decl, Type,namespace internal { template <typename NodeType, typename
ParamT> class matcher_equalsBoundNode0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_equalsBoundNode0Matcher( std::string
const &AID) : ID(AID) {} bool matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: std::string ID; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_equalsBoundNode0Matcher
, void(::clang::ast_matchers::internal::TypeList<Stmt, Decl
, Type, QualType>), std::string> equalsBoundNode(std::string
const &ID) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equalsBoundNode0Matcher, void(::clang::
ast_matchers::internal::TypeList<Stmt, Decl, Type, QualType
>), std::string>(ID); } typedef ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_equalsBoundNode0Matcher
, void(::clang::ast_matchers::internal::TypeList<Stmt, Decl
, Type, QualType>), std::string> (&equalsBoundNode_Type0
)(std::string const &ID); template <typename NodeType,
typename ParamT> bool internal:: matcher_equalsBoundNode0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5324 QualType),namespace internal { template <typename NodeType, typename
ParamT> class matcher_equalsBoundNode0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_equalsBoundNode0Matcher( std::string
const &AID) : ID(AID) {} bool matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: std::string ID; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_equalsBoundNode0Matcher
, void(::clang::ast_matchers::internal::TypeList<Stmt, Decl
, Type, QualType>), std::string> equalsBoundNode(std::string
const &ID) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equalsBoundNode0Matcher, void(::clang::
ast_matchers::internal::TypeList<Stmt, Decl, Type, QualType
>), std::string>(ID); } typedef ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_equalsBoundNode0Matcher
, void(::clang::ast_matchers::internal::TypeList<Stmt, Decl
, Type, QualType>), std::string> (&equalsBoundNode_Type0
)(std::string const &ID); template <typename NodeType,
typename ParamT> bool internal:: matcher_equalsBoundNode0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5325 std::string, ID)namespace internal { template <typename NodeType, typename
ParamT> class matcher_equalsBoundNode0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_equalsBoundNode0Matcher( std::string
const &AID) : ID(AID) {} bool matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: std::string ID; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_equalsBoundNode0Matcher
, void(::clang::ast_matchers::internal::TypeList<Stmt, Decl
, Type, QualType>), std::string> equalsBoundNode(std::string
const &ID) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equalsBoundNode0Matcher, void(::clang::
ast_matchers::internal::TypeList<Stmt, Decl, Type, QualType
>), std::string>(ID); } typedef ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_equalsBoundNode0Matcher
, void(::clang::ast_matchers::internal::TypeList<Stmt, Decl
, Type, QualType>), std::string> (&equalsBoundNode_Type0
)(std::string const &ID); template <typename NodeType,
typename ParamT> bool internal:: matcher_equalsBoundNode0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
{
5326 // FIXME: Figure out whether it makes sense to allow this
5327 // on any other node types.
5328 // For *Loc it probably does not make sense, as those seem
5329 // unique. For NestedNameSepcifier it might make sense, as
5330 // those also have pointer identity, but I'm not sure whether
5331 // they're ever reused.
5332 internal::NotEqualsBoundNodePredicate Predicate;
5333 Predicate.ID = ID;
5334 Predicate.Node = DynTypedNode::create(Node);
5335 return Builder->removeBindings(Predicate);
5336}
5337
5338/// Matches the condition variable statement in an if statement.
5339///
5340/// Given
5341/// \code
5342/// if (A* a = GetAPointer()) {}
5343/// \endcode
5344/// hasConditionVariableStatement(...)
5345/// matches 'A* a = GetAPointer()'.
5346AST_MATCHER_P(IfStmt, hasConditionVariableStatement,namespace internal { class matcher_hasConditionVariableStatement0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
IfStmt> { public: explicit matcher_hasConditionVariableStatement0Matcher
( internal::Matcher<DeclStmt> const &AInnerMatcher)
: InnerMatcher(AInnerMatcher) {} bool matches(const IfStmt &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<DeclStmt> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<IfStmt
> hasConditionVariableStatement( internal::Matcher<DeclStmt
> const &InnerMatcher) { return ::clang::ast_matchers::
internal::makeMatcher( new internal::matcher_hasConditionVariableStatement0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<IfStmt> ( &hasConditionVariableStatement_Type0)(internal
::Matcher<DeclStmt> const &InnerMatcher); inline bool
internal::matcher_hasConditionVariableStatement0Matcher::matches
( const IfStmt &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
5347 internal::Matcher<DeclStmt>, InnerMatcher)namespace internal { class matcher_hasConditionVariableStatement0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
IfStmt> { public: explicit matcher_hasConditionVariableStatement0Matcher
( internal::Matcher<DeclStmt> const &AInnerMatcher)
: InnerMatcher(AInnerMatcher) {} bool matches(const IfStmt &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<DeclStmt> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<IfStmt
> hasConditionVariableStatement( internal::Matcher<DeclStmt
> const &InnerMatcher) { return ::clang::ast_matchers::
internal::makeMatcher( new internal::matcher_hasConditionVariableStatement0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<IfStmt> ( &hasConditionVariableStatement_Type0)(internal
::Matcher<DeclStmt> const &InnerMatcher); inline bool
internal::matcher_hasConditionVariableStatement0Matcher::matches
( const IfStmt &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
5348 const DeclStmt* const DeclarationStatement =
5349 Node.getConditionVariableDeclStmt();
5350 return DeclarationStatement != nullptr &&
5351 InnerMatcher.matches(*DeclarationStatement, Finder, Builder);
5352}
5353
5354/// Matches the index expression of an array subscript expression.
5355///
5356/// Given
5357/// \code
5358/// int i[5];
5359/// void f() { i[1] = 42; }
5360/// \endcode
5361/// arraySubscriptExpression(hasIndex(integerLiteral()))
5362/// matches \c i[1] with the \c integerLiteral() matching \c 1
5363AST_MATCHER_P(ArraySubscriptExpr, hasIndex,namespace internal { class matcher_hasIndex0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<ArraySubscriptExpr
> { public: explicit matcher_hasIndex0Matcher( internal::Matcher
<Expr> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const ArraySubscriptExpr &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<ArraySubscriptExpr> hasIndex
( internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasIndex0Matcher(InnerMatcher)); } typedef ::clang::ast_matchers
::internal::Matcher<ArraySubscriptExpr> ( &hasIndex_Type0
)(internal::Matcher<Expr> const &InnerMatcher); inline
bool internal::matcher_hasIndex0Matcher::matches( const ArraySubscriptExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
5364 internal::Matcher<Expr>, InnerMatcher)namespace internal { class matcher_hasIndex0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<ArraySubscriptExpr
> { public: explicit matcher_hasIndex0Matcher( internal::Matcher
<Expr> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const ArraySubscriptExpr &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<ArraySubscriptExpr> hasIndex
( internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasIndex0Matcher(InnerMatcher)); } typedef ::clang::ast_matchers
::internal::Matcher<ArraySubscriptExpr> ( &hasIndex_Type0
)(internal::Matcher<Expr> const &InnerMatcher); inline
bool internal::matcher_hasIndex0Matcher::matches( const ArraySubscriptExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
5365 if (const Expr* Expression = Node.getIdx())
5366 return InnerMatcher.matches(*Expression, Finder, Builder);
5367 return false;
5368}
5369
5370/// Matches the base expression of an array subscript expression.
5371///
5372/// Given
5373/// \code
5374/// int i[5];
5375/// void f() { i[1] = 42; }
5376/// \endcode
5377/// arraySubscriptExpression(hasBase(implicitCastExpr(
5378/// hasSourceExpression(declRefExpr()))))
5379/// matches \c i[1] with the \c declRefExpr() matching \c i
5380AST_MATCHER_P(ArraySubscriptExpr, hasBase,namespace internal { class matcher_hasBase0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<ArraySubscriptExpr
> { public: explicit matcher_hasBase0Matcher( internal::Matcher
<Expr> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const ArraySubscriptExpr &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<ArraySubscriptExpr> hasBase
( internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasBase0Matcher(InnerMatcher)); } typedef ::clang::ast_matchers
::internal::Matcher<ArraySubscriptExpr> ( &hasBase_Type0
)(internal::Matcher<Expr> const &InnerMatcher); inline
bool internal::matcher_hasBase0Matcher::matches( const ArraySubscriptExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
5381 internal::Matcher<Expr>, InnerMatcher)namespace internal { class matcher_hasBase0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<ArraySubscriptExpr
> { public: explicit matcher_hasBase0Matcher( internal::Matcher
<Expr> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const ArraySubscriptExpr &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<ArraySubscriptExpr> hasBase
( internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasBase0Matcher(InnerMatcher)); } typedef ::clang::ast_matchers
::internal::Matcher<ArraySubscriptExpr> ( &hasBase_Type0
)(internal::Matcher<Expr> const &InnerMatcher); inline
bool internal::matcher_hasBase0Matcher::matches( const ArraySubscriptExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
5382 if (const Expr* Expression = Node.getBase())
5383 return InnerMatcher.matches(*Expression, Finder, Builder);
5384 return false;
5385}
5386
5387/// Matches a 'for', 'while', 'do while' statement or a function
5388/// definition that has a given body. Note that in case of functions
5389/// this matcher only matches the definition itself and not the other
5390/// declarations of the same function.
5391///
5392/// Given
5393/// \code
5394/// for (;;) {}
5395/// \endcode
5396/// hasBody(compoundStmt())
5397/// matches 'for (;;) {}'
5398/// with compoundStmt()
5399/// matching '{}'
5400///
5401/// Given
5402/// \code
5403/// void f();
5404/// void f() {}
5405/// \endcode
5406/// hasBody(functionDecl())
5407/// matches 'void f() {}'
5408/// with compoundStmt()
5409/// matching '{}'
5410/// but does not match 'void f();'
5411
5412AST_POLYMORPHIC_MATCHER_P(hasBody,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasBody0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasBody0Matcher( internal::Matcher<Stmt> const
&AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Stmt
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasBody0Matcher, void
(::clang::ast_matchers::internal::TypeList<DoStmt, ForStmt
, WhileStmt, CXXForRangeStmt, FunctionDecl>), internal::Matcher
<Stmt> > hasBody(internal::Matcher<Stmt> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_hasBody0Matcher, void
(::clang::ast_matchers::internal::TypeList<DoStmt, ForStmt
, WhileStmt, CXXForRangeStmt, FunctionDecl>), internal::Matcher
<Stmt> >(InnerMatcher); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasBody0Matcher
, void(::clang::ast_matchers::internal::TypeList<DoStmt, ForStmt
, WhileStmt, CXXForRangeStmt, FunctionDecl>), internal::Matcher
<Stmt> > (&hasBody_Type0)(internal::Matcher<Stmt
> const &InnerMatcher); template <typename NodeType
, typename ParamT> bool internal:: matcher_hasBody0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5413 AST_POLYMORPHIC_SUPPORTED_TYPES(DoStmt, ForStmt,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasBody0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasBody0Matcher( internal::Matcher<Stmt> const
&AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Stmt
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasBody0Matcher, void
(::clang::ast_matchers::internal::TypeList<DoStmt, ForStmt
, WhileStmt, CXXForRangeStmt, FunctionDecl>), internal::Matcher
<Stmt> > hasBody(internal::Matcher<Stmt> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_hasBody0Matcher, void
(::clang::ast_matchers::internal::TypeList<DoStmt, ForStmt
, WhileStmt, CXXForRangeStmt, FunctionDecl>), internal::Matcher
<Stmt> >(InnerMatcher); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasBody0Matcher
, void(::clang::ast_matchers::internal::TypeList<DoStmt, ForStmt
, WhileStmt, CXXForRangeStmt, FunctionDecl>), internal::Matcher
<Stmt> > (&hasBody_Type0)(internal::Matcher<Stmt
> const &InnerMatcher); template <typename NodeType
, typename ParamT> bool internal:: matcher_hasBody0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5414 WhileStmt,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasBody0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasBody0Matcher( internal::Matcher<Stmt> const
&AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Stmt
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasBody0Matcher, void
(::clang::ast_matchers::internal::TypeList<DoStmt, ForStmt
, WhileStmt, CXXForRangeStmt, FunctionDecl>), internal::Matcher
<Stmt> > hasBody(internal::Matcher<Stmt> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_hasBody0Matcher, void
(::clang::ast_matchers::internal::TypeList<DoStmt, ForStmt
, WhileStmt, CXXForRangeStmt, FunctionDecl>), internal::Matcher
<Stmt> >(InnerMatcher); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasBody0Matcher
, void(::clang::ast_matchers::internal::TypeList<DoStmt, ForStmt
, WhileStmt, CXXForRangeStmt, FunctionDecl>), internal::Matcher
<Stmt> > (&hasBody_Type0)(internal::Matcher<Stmt
> const &InnerMatcher); template <typename NodeType
, typename ParamT> bool internal:: matcher_hasBody0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5415 CXXForRangeStmt,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasBody0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasBody0Matcher( internal::Matcher<Stmt> const
&AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Stmt
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasBody0Matcher, void
(::clang::ast_matchers::internal::TypeList<DoStmt, ForStmt
, WhileStmt, CXXForRangeStmt, FunctionDecl>), internal::Matcher
<Stmt> > hasBody(internal::Matcher<Stmt> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_hasBody0Matcher, void
(::clang::ast_matchers::internal::TypeList<DoStmt, ForStmt
, WhileStmt, CXXForRangeStmt, FunctionDecl>), internal::Matcher
<Stmt> >(InnerMatcher); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasBody0Matcher
, void(::clang::ast_matchers::internal::TypeList<DoStmt, ForStmt
, WhileStmt, CXXForRangeStmt, FunctionDecl>), internal::Matcher
<Stmt> > (&hasBody_Type0)(internal::Matcher<Stmt
> const &InnerMatcher); template <typename NodeType
, typename ParamT> bool internal:: matcher_hasBody0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5416 FunctionDecl),namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasBody0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasBody0Matcher( internal::Matcher<Stmt> const
&AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Stmt
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasBody0Matcher, void
(::clang::ast_matchers::internal::TypeList<DoStmt, ForStmt
, WhileStmt, CXXForRangeStmt, FunctionDecl>), internal::Matcher
<Stmt> > hasBody(internal::Matcher<Stmt> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_hasBody0Matcher, void
(::clang::ast_matchers::internal::TypeList<DoStmt, ForStmt
, WhileStmt, CXXForRangeStmt, FunctionDecl>), internal::Matcher
<Stmt> >(InnerMatcher); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasBody0Matcher
, void(::clang::ast_matchers::internal::TypeList<DoStmt, ForStmt
, WhileStmt, CXXForRangeStmt, FunctionDecl>), internal::Matcher
<Stmt> > (&hasBody_Type0)(internal::Matcher<Stmt
> const &InnerMatcher); template <typename NodeType
, typename ParamT> bool internal:: matcher_hasBody0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5417 internal::Matcher<Stmt>, InnerMatcher)namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasBody0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasBody0Matcher( internal::Matcher<Stmt> const
&AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Stmt
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasBody0Matcher, void
(::clang::ast_matchers::internal::TypeList<DoStmt, ForStmt
, WhileStmt, CXXForRangeStmt, FunctionDecl>), internal::Matcher
<Stmt> > hasBody(internal::Matcher<Stmt> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_hasBody0Matcher, void
(::clang::ast_matchers::internal::TypeList<DoStmt, ForStmt
, WhileStmt, CXXForRangeStmt, FunctionDecl>), internal::Matcher
<Stmt> >(InnerMatcher); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasBody0Matcher
, void(::clang::ast_matchers::internal::TypeList<DoStmt, ForStmt
, WhileStmt, CXXForRangeStmt, FunctionDecl>), internal::Matcher
<Stmt> > (&hasBody_Type0)(internal::Matcher<Stmt
> const &InnerMatcher); template <typename NodeType
, typename ParamT> bool internal:: matcher_hasBody0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
{
5418 if (Finder->isTraversalIgnoringImplicitNodes() && isDefaultedHelper(&Node))
5419 return false;
5420 const Stmt *const Statement = internal::GetBodyMatcher<NodeType>::get(Node);
5421 return (Statement != nullptr &&
5422 InnerMatcher.matches(*Statement, Finder, Builder));
5423}
5424
5425/// Matches a function declaration that has a given body present in the AST.
5426/// Note that this matcher matches all the declarations of a function whose
5427/// body is present in the AST.
5428///
5429/// Given
5430/// \code
5431/// void f();
5432/// void f() {}
5433/// void g();
5434/// \endcode
5435/// functionDecl(hasAnyBody(compoundStmt()))
5436/// matches both 'void f();'
5437/// and 'void f() {}'
5438/// with compoundStmt()
5439/// matching '{}'
5440/// but does not match 'void g();'
5441AST_MATCHER_P(FunctionDecl, hasAnyBody,namespace internal { class matcher_hasAnyBody0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<FunctionDecl
> { public: explicit matcher_hasAnyBody0Matcher( internal::
Matcher<Stmt> const &AInnerMatcher) : InnerMatcher(
AInnerMatcher) {} bool matches(const FunctionDecl &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
override; private: internal::Matcher<Stmt> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<FunctionDecl
> hasAnyBody( internal::Matcher<Stmt> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_hasAnyBody0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<FunctionDecl> ( &
hasAnyBody_Type0)(internal::Matcher<Stmt> const &InnerMatcher
); inline bool internal::matcher_hasAnyBody0Matcher::matches(
const FunctionDecl &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
5442 internal::Matcher<Stmt>, InnerMatcher)namespace internal { class matcher_hasAnyBody0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<FunctionDecl
> { public: explicit matcher_hasAnyBody0Matcher( internal::
Matcher<Stmt> const &AInnerMatcher) : InnerMatcher(
AInnerMatcher) {} bool matches(const FunctionDecl &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
override; private: internal::Matcher<Stmt> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<FunctionDecl
> hasAnyBody( internal::Matcher<Stmt> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_hasAnyBody0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<FunctionDecl> ( &
hasAnyBody_Type0)(internal::Matcher<Stmt> const &InnerMatcher
); inline bool internal::matcher_hasAnyBody0Matcher::matches(
const FunctionDecl &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
5443 const Stmt *const Statement = Node.getBody();
5444 return (Statement != nullptr &&
5445 InnerMatcher.matches(*Statement, Finder, Builder));
5446}
5447
5448
5449/// Matches compound statements where at least one substatement matches
5450/// a given matcher. Also matches StmtExprs that have CompoundStmt as children.
5451///
5452/// Given
5453/// \code
5454/// { {}; 1+2; }
5455/// \endcode
5456/// hasAnySubstatement(compoundStmt())
5457/// matches '{ {}; 1+2; }'
5458/// with compoundStmt()
5459/// matching '{}'
5460AST_POLYMORPHIC_MATCHER_P(hasAnySubstatement,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasAnySubstatement0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_hasAnySubstatement0Matcher( internal
::Matcher<Stmt> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Stmt> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasAnySubstatement0Matcher
, void(::clang::ast_matchers::internal::TypeList<CompoundStmt
, StmtExpr>), internal::Matcher<Stmt> > hasAnySubstatement
(internal::Matcher<Stmt> const &InnerMatcher) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasAnySubstatement0Matcher, void(::clang::ast_matchers
::internal::TypeList<CompoundStmt, StmtExpr>), internal
::Matcher<Stmt> >(InnerMatcher); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasAnySubstatement0Matcher
, void(::clang::ast_matchers::internal::TypeList<CompoundStmt
, StmtExpr>), internal::Matcher<Stmt> > (&hasAnySubstatement_Type0
)(internal::Matcher<Stmt> const &InnerMatcher); template
<typename NodeType, typename ParamT> bool internal:: matcher_hasAnySubstatement0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5461 AST_POLYMORPHIC_SUPPORTED_TYPES(CompoundStmt,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasAnySubstatement0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_hasAnySubstatement0Matcher( internal
::Matcher<Stmt> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Stmt> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasAnySubstatement0Matcher
, void(::clang::ast_matchers::internal::TypeList<CompoundStmt
, StmtExpr>), internal::Matcher<Stmt> > hasAnySubstatement
(internal::Matcher<Stmt> const &InnerMatcher) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasAnySubstatement0Matcher, void(::clang::ast_matchers
::internal::TypeList<CompoundStmt, StmtExpr>), internal
::Matcher<Stmt> >(InnerMatcher); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasAnySubstatement0Matcher
, void(::clang::ast_matchers::internal::TypeList<CompoundStmt
, StmtExpr>), internal::Matcher<Stmt> > (&hasAnySubstatement_Type0
)(internal::Matcher<Stmt> const &InnerMatcher); template
<typename NodeType, typename ParamT> bool internal:: matcher_hasAnySubstatement0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5462 StmtExpr),namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasAnySubstatement0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_hasAnySubstatement0Matcher( internal
::Matcher<Stmt> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Stmt> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasAnySubstatement0Matcher
, void(::clang::ast_matchers::internal::TypeList<CompoundStmt
, StmtExpr>), internal::Matcher<Stmt> > hasAnySubstatement
(internal::Matcher<Stmt> const &InnerMatcher) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasAnySubstatement0Matcher, void(::clang::ast_matchers
::internal::TypeList<CompoundStmt, StmtExpr>), internal
::Matcher<Stmt> >(InnerMatcher); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasAnySubstatement0Matcher
, void(::clang::ast_matchers::internal::TypeList<CompoundStmt
, StmtExpr>), internal::Matcher<Stmt> > (&hasAnySubstatement_Type0
)(internal::Matcher<Stmt> const &InnerMatcher); template
<typename NodeType, typename ParamT> bool internal:: matcher_hasAnySubstatement0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5463 internal::Matcher<Stmt>, InnerMatcher)namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasAnySubstatement0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_hasAnySubstatement0Matcher( internal
::Matcher<Stmt> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Stmt> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasAnySubstatement0Matcher
, void(::clang::ast_matchers::internal::TypeList<CompoundStmt
, StmtExpr>), internal::Matcher<Stmt> > hasAnySubstatement
(internal::Matcher<Stmt> const &InnerMatcher) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasAnySubstatement0Matcher, void(::clang::ast_matchers
::internal::TypeList<CompoundStmt, StmtExpr>), internal
::Matcher<Stmt> >(InnerMatcher); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasAnySubstatement0Matcher
, void(::clang::ast_matchers::internal::TypeList<CompoundStmt
, StmtExpr>), internal::Matcher<Stmt> > (&hasAnySubstatement_Type0
)(internal::Matcher<Stmt> const &InnerMatcher); template
<typename NodeType, typename ParamT> bool internal:: matcher_hasAnySubstatement0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
{
5464 const CompoundStmt *CS = CompoundStmtMatcher<NodeType>::get(Node);
5465 return CS && matchesFirstInPointerRange(InnerMatcher, CS->body_begin(),
5466 CS->body_end(), Finder,
5467 Builder) != CS->body_end();
5468}
5469
5470/// Checks that a compound statement contains a specific number of
5471/// child statements.
5472///
5473/// Example: Given
5474/// \code
5475/// { for (;;) {} }
5476/// \endcode
5477/// compoundStmt(statementCountIs(0)))
5478/// matches '{}'
5479/// but does not match the outer compound statement.
5480AST_MATCHER_P(CompoundStmt, statementCountIs, unsigned, N)namespace internal { class matcher_statementCountIs0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
CompoundStmt> { public: explicit matcher_statementCountIs0Matcher
( unsigned const &AN) : N(AN) {} bool matches(const CompoundStmt
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; }; } inline ::
clang::ast_matchers::internal::Matcher<CompoundStmt> statementCountIs
( unsigned const &N) { return ::clang::ast_matchers::internal
::makeMatcher( new internal::matcher_statementCountIs0Matcher
(N)); } typedef ::clang::ast_matchers::internal::Matcher<CompoundStmt
> ( &statementCountIs_Type0)(unsigned const &N); inline
bool internal::matcher_statementCountIs0Matcher::matches( const
CompoundStmt &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
5481 return Node.size() == N;
5482}
5483
5484/// Matches literals that are equal to the given value of type ValueT.
5485///
5486/// Given
5487/// \code
5488/// f('\0', false, 3.14, 42);
5489/// \endcode
5490/// characterLiteral(equals(0))
5491/// matches '\0'
5492/// cxxBoolLiteral(equals(false)) and cxxBoolLiteral(equals(0))
5493/// match false
5494/// floatLiteral(equals(3.14)) and floatLiteral(equals(314e-2))
5495/// match 3.14
5496/// integerLiteral(equals(42))
5497/// matches 42
5498///
5499/// Note that you cannot directly match a negative numeric literal because the
5500/// minus sign is not part of the literal: It is a unary operator whose operand
5501/// is the positive numeric literal. Instead, you must use a unaryOperator()
5502/// matcher to match the minus sign:
5503///
5504/// unaryOperator(hasOperatorName("-"),
5505/// hasUnaryOperand(integerLiteral(equals(13))))
5506///
5507/// Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteralExpr>,
5508/// Matcher<FloatingLiteral>, Matcher<IntegerLiteral>
5509template <typename ValueT>
5510internal::PolymorphicMatcher<internal::ValueEqualsMatcher,
5511 void(internal::AllNodeBaseTypes), ValueT>
5512equals(const ValueT &Value) {
5513 return internal::PolymorphicMatcher<internal::ValueEqualsMatcher,
5514 void(internal::AllNodeBaseTypes), ValueT>(
5515 Value);
5516}
5517
5518AST_POLYMORPHIC_MATCHER_P_OVERLOAD(equals,namespace internal { template <typename NodeType, typename
ParamT> class matcher_equals0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_equals0Matcher( bool const &AValue) : Value(AValue
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: bool
Value; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals0Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
IntegerLiteral>), bool> equals(bool const &Value) {
return ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_equals0Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
IntegerLiteral>), bool>(Value); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_equals0Matcher
, void(::clang::ast_matchers::internal::TypeList<CharacterLiteral
, CXXBoolLiteralExpr, IntegerLiteral>), bool> (&equals_Type0
)(bool const &Value); template <typename NodeType, typename
ParamT> bool internal:: matcher_equals0Matcher<NodeType
, ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
5519 AST_POLYMORPHIC_SUPPORTED_TYPES(CharacterLiteral,namespace internal { template <typename NodeType, typename
ParamT> class matcher_equals0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_equals0Matcher( bool const &AValue) : Value(AValue
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: bool
Value; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals0Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
IntegerLiteral>), bool> equals(bool const &Value) {
return ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_equals0Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
IntegerLiteral>), bool>(Value); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_equals0Matcher
, void(::clang::ast_matchers::internal::TypeList<CharacterLiteral
, CXXBoolLiteralExpr, IntegerLiteral>), bool> (&equals_Type0
)(bool const &Value); template <typename NodeType, typename
ParamT> bool internal:: matcher_equals0Matcher<NodeType
, ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
5520 CXXBoolLiteralExpr,namespace internal { template <typename NodeType, typename
ParamT> class matcher_equals0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_equals0Matcher( bool const &AValue) : Value(AValue
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: bool
Value; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals0Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
IntegerLiteral>), bool> equals(bool const &Value) {
return ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_equals0Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
IntegerLiteral>), bool>(Value); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_equals0Matcher
, void(::clang::ast_matchers::internal::TypeList<CharacterLiteral
, CXXBoolLiteralExpr, IntegerLiteral>), bool> (&equals_Type0
)(bool const &Value); template <typename NodeType, typename
ParamT> bool internal:: matcher_equals0Matcher<NodeType
, ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
5521 IntegerLiteral),namespace internal { template <typename NodeType, typename
ParamT> class matcher_equals0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_equals0Matcher( bool const &AValue) : Value(AValue
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: bool
Value; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals0Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
IntegerLiteral>), bool> equals(bool const &Value) {
return ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_equals0Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
IntegerLiteral>), bool>(Value); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_equals0Matcher
, void(::clang::ast_matchers::internal::TypeList<CharacterLiteral
, CXXBoolLiteralExpr, IntegerLiteral>), bool> (&equals_Type0
)(bool const &Value); template <typename NodeType, typename
ParamT> bool internal:: matcher_equals0Matcher<NodeType
, ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
5522 bool, Value, 0)namespace internal { template <typename NodeType, typename
ParamT> class matcher_equals0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_equals0Matcher( bool const &AValue) : Value(AValue
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: bool
Value; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals0Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
IntegerLiteral>), bool> equals(bool const &Value) {
return ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_equals0Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
IntegerLiteral>), bool>(Value); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_equals0Matcher
, void(::clang::ast_matchers::internal::TypeList<CharacterLiteral
, CXXBoolLiteralExpr, IntegerLiteral>), bool> (&equals_Type0
)(bool const &Value); template <typename NodeType, typename
ParamT> bool internal:: matcher_equals0Matcher<NodeType
, ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
5523 return internal::ValueEqualsMatcher<NodeType, ParamT>(Value)
5524 .matchesNode(Node);
5525}
5526
5527AST_POLYMORPHIC_MATCHER_P_OVERLOAD(equals,namespace internal { template <typename NodeType, typename
ParamT> class matcher_equals1Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_equals1Matcher( unsigned const &AValue) : Value(
AValue) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: unsigned
Value; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals1Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
IntegerLiteral>), unsigned> equals(unsigned const &
Value) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals1Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
IntegerLiteral>), unsigned>(Value); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_equals1Matcher
, void(::clang::ast_matchers::internal::TypeList<CharacterLiteral
, CXXBoolLiteralExpr, IntegerLiteral>), unsigned> (&
equals_Type1)(unsigned const &Value); template <typename
NodeType, typename ParamT> bool internal:: matcher_equals1Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5528 AST_POLYMORPHIC_SUPPORTED_TYPES(CharacterLiteral,namespace internal { template <typename NodeType, typename
ParamT> class matcher_equals1Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_equals1Matcher( unsigned const &AValue) : Value(
AValue) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: unsigned
Value; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals1Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
IntegerLiteral>), unsigned> equals(unsigned const &
Value) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals1Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
IntegerLiteral>), unsigned>(Value); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_equals1Matcher
, void(::clang::ast_matchers::internal::TypeList<CharacterLiteral
, CXXBoolLiteralExpr, IntegerLiteral>), unsigned> (&
equals_Type1)(unsigned const &Value); template <typename
NodeType, typename ParamT> bool internal:: matcher_equals1Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5529 CXXBoolLiteralExpr,namespace internal { template <typename NodeType, typename
ParamT> class matcher_equals1Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_equals1Matcher( unsigned const &AValue) : Value(
AValue) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: unsigned
Value; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals1Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
IntegerLiteral>), unsigned> equals(unsigned const &
Value) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals1Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
IntegerLiteral>), unsigned>(Value); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_equals1Matcher
, void(::clang::ast_matchers::internal::TypeList<CharacterLiteral
, CXXBoolLiteralExpr, IntegerLiteral>), unsigned> (&
equals_Type1)(unsigned const &Value); template <typename
NodeType, typename ParamT> bool internal:: matcher_equals1Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5530 IntegerLiteral),namespace internal { template <typename NodeType, typename
ParamT> class matcher_equals1Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_equals1Matcher( unsigned const &AValue) : Value(
AValue) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: unsigned
Value; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals1Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
IntegerLiteral>), unsigned> equals(unsigned const &
Value) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals1Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
IntegerLiteral>), unsigned>(Value); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_equals1Matcher
, void(::clang::ast_matchers::internal::TypeList<CharacterLiteral
, CXXBoolLiteralExpr, IntegerLiteral>), unsigned> (&
equals_Type1)(unsigned const &Value); template <typename
NodeType, typename ParamT> bool internal:: matcher_equals1Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5531 unsigned, Value, 1)namespace internal { template <typename NodeType, typename
ParamT> class matcher_equals1Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_equals1Matcher( unsigned const &AValue) : Value(
AValue) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: unsigned
Value; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals1Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
IntegerLiteral>), unsigned> equals(unsigned const &
Value) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals1Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
IntegerLiteral>), unsigned>(Value); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_equals1Matcher
, void(::clang::ast_matchers::internal::TypeList<CharacterLiteral
, CXXBoolLiteralExpr, IntegerLiteral>), unsigned> (&
equals_Type1)(unsigned const &Value); template <typename
NodeType, typename ParamT> bool internal:: matcher_equals1Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
{
5532 return internal::ValueEqualsMatcher<NodeType, ParamT>(Value)
5533 .matchesNode(Node);
5534}
5535
5536AST_POLYMORPHIC_MATCHER_P_OVERLOAD(equals,namespace internal { template <typename NodeType, typename
ParamT> class matcher_equals2Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_equals2Matcher( double const &AValue) : Value(AValue
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: double
Value; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals2Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
FloatingLiteral, IntegerLiteral>), double> equals(double
const &Value) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_equals2Matcher, void
(::clang::ast_matchers::internal::TypeList<CharacterLiteral
, CXXBoolLiteralExpr, FloatingLiteral, IntegerLiteral>), double
>(Value); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals2Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
FloatingLiteral, IntegerLiteral>), double> (&equals_Type2
)(double const &Value); template <typename NodeType, typename
ParamT> bool internal:: matcher_equals2Matcher<NodeType
, ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
5537 AST_POLYMORPHIC_SUPPORTED_TYPES(CharacterLiteral,namespace internal { template <typename NodeType, typename
ParamT> class matcher_equals2Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_equals2Matcher( double const &AValue) : Value(AValue
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: double
Value; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals2Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
FloatingLiteral, IntegerLiteral>), double> equals(double
const &Value) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_equals2Matcher, void
(::clang::ast_matchers::internal::TypeList<CharacterLiteral
, CXXBoolLiteralExpr, FloatingLiteral, IntegerLiteral>), double
>(Value); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals2Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
FloatingLiteral, IntegerLiteral>), double> (&equals_Type2
)(double const &Value); template <typename NodeType, typename
ParamT> bool internal:: matcher_equals2Matcher<NodeType
, ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
5538 CXXBoolLiteralExpr,namespace internal { template <typename NodeType, typename
ParamT> class matcher_equals2Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_equals2Matcher( double const &AValue) : Value(AValue
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: double
Value; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals2Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
FloatingLiteral, IntegerLiteral>), double> equals(double
const &Value) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_equals2Matcher, void
(::clang::ast_matchers::internal::TypeList<CharacterLiteral
, CXXBoolLiteralExpr, FloatingLiteral, IntegerLiteral>), double
>(Value); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals2Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
FloatingLiteral, IntegerLiteral>), double> (&equals_Type2
)(double const &Value); template <typename NodeType, typename
ParamT> bool internal:: matcher_equals2Matcher<NodeType
, ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
5539 FloatingLiteral,namespace internal { template <typename NodeType, typename
ParamT> class matcher_equals2Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_equals2Matcher( double const &AValue) : Value(AValue
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: double
Value; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals2Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
FloatingLiteral, IntegerLiteral>), double> equals(double
const &Value) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_equals2Matcher, void
(::clang::ast_matchers::internal::TypeList<CharacterLiteral
, CXXBoolLiteralExpr, FloatingLiteral, IntegerLiteral>), double
>(Value); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals2Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
FloatingLiteral, IntegerLiteral>), double> (&equals_Type2
)(double const &Value); template <typename NodeType, typename
ParamT> bool internal:: matcher_equals2Matcher<NodeType
, ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
5540 IntegerLiteral),namespace internal { template <typename NodeType, typename
ParamT> class matcher_equals2Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_equals2Matcher( double const &AValue) : Value(AValue
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: double
Value; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals2Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
FloatingLiteral, IntegerLiteral>), double> equals(double
const &Value) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_equals2Matcher, void
(::clang::ast_matchers::internal::TypeList<CharacterLiteral
, CXXBoolLiteralExpr, FloatingLiteral, IntegerLiteral>), double
>(Value); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals2Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
FloatingLiteral, IntegerLiteral>), double> (&equals_Type2
)(double const &Value); template <typename NodeType, typename
ParamT> bool internal:: matcher_equals2Matcher<NodeType
, ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
5541 double, Value, 2)namespace internal { template <typename NodeType, typename
ParamT> class matcher_equals2Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_equals2Matcher( double const &AValue) : Value(AValue
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: double
Value; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals2Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
FloatingLiteral, IntegerLiteral>), double> equals(double
const &Value) { return ::clang::ast_matchers::internal::
PolymorphicMatcher< internal::matcher_equals2Matcher, void
(::clang::ast_matchers::internal::TypeList<CharacterLiteral
, CXXBoolLiteralExpr, FloatingLiteral, IntegerLiteral>), double
>(Value); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_equals2Matcher, void(::clang::ast_matchers
::internal::TypeList<CharacterLiteral, CXXBoolLiteralExpr,
FloatingLiteral, IntegerLiteral>), double> (&equals_Type2
)(double const &Value); template <typename NodeType, typename
ParamT> bool internal:: matcher_equals2Matcher<NodeType
, ParamT>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
5542 return internal::ValueEqualsMatcher<NodeType, ParamT>(Value)
5543 .matchesNode(Node);
5544}
5545
5546/// Matches the operator Name of operator expressions (binary or
5547/// unary).
5548///
5549/// Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
5550/// \code
5551/// !(a || b)
5552/// \endcode
5553AST_POLYMORPHIC_MATCHER_P(namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasOperatorName0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_hasOperatorName0Matcher( std::string
const &AName) : Name(AName) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string Name; }; } inline
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasOperatorName0Matcher, void(::clang::ast_matchers
::internal::TypeList<BinaryOperator, CXXOperatorCallExpr, CXXRewrittenBinaryOperator
, UnaryOperator>), std::string> hasOperatorName(std::string
const &Name) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasOperatorName0Matcher, void(::clang::
ast_matchers::internal::TypeList<BinaryOperator, CXXOperatorCallExpr
, CXXRewrittenBinaryOperator, UnaryOperator>), std::string
>(Name); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasOperatorName0Matcher, void(::clang::
ast_matchers::internal::TypeList<BinaryOperator, CXXOperatorCallExpr
, CXXRewrittenBinaryOperator, UnaryOperator>), std::string
> (&hasOperatorName_Type0)(std::string const &Name
); template <typename NodeType, typename ParamT> bool internal
:: matcher_hasOperatorName0Matcher<NodeType, ParamT>::matches
( const NodeType &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
5554 hasOperatorName,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasOperatorName0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_hasOperatorName0Matcher( std::string
const &AName) : Name(AName) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string Name; }; } inline
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasOperatorName0Matcher, void(::clang::ast_matchers
::internal::TypeList<BinaryOperator, CXXOperatorCallExpr, CXXRewrittenBinaryOperator
, UnaryOperator>), std::string> hasOperatorName(std::string
const &Name) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasOperatorName0Matcher, void(::clang::
ast_matchers::internal::TypeList<BinaryOperator, CXXOperatorCallExpr
, CXXRewrittenBinaryOperator, UnaryOperator>), std::string
>(Name); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasOperatorName0Matcher, void(::clang::
ast_matchers::internal::TypeList<BinaryOperator, CXXOperatorCallExpr
, CXXRewrittenBinaryOperator, UnaryOperator>), std::string
> (&hasOperatorName_Type0)(std::string const &Name
); template <typename NodeType, typename ParamT> bool internal
:: matcher_hasOperatorName0Matcher<NodeType, ParamT>::matches
( const NodeType &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
5555 AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasOperatorName0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_hasOperatorName0Matcher( std::string
const &AName) : Name(AName) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string Name; }; } inline
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasOperatorName0Matcher, void(::clang::ast_matchers
::internal::TypeList<BinaryOperator, CXXOperatorCallExpr, CXXRewrittenBinaryOperator
, UnaryOperator>), std::string> hasOperatorName(std::string
const &Name) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasOperatorName0Matcher, void(::clang::
ast_matchers::internal::TypeList<BinaryOperator, CXXOperatorCallExpr
, CXXRewrittenBinaryOperator, UnaryOperator>), std::string
>(Name); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasOperatorName0Matcher, void(::clang::
ast_matchers::internal::TypeList<BinaryOperator, CXXOperatorCallExpr
, CXXRewrittenBinaryOperator, UnaryOperator>), std::string
> (&hasOperatorName_Type0)(std::string const &Name
); template <typename NodeType, typename ParamT> bool internal
:: matcher_hasOperatorName0Matcher<NodeType, ParamT>::matches
( const NodeType &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
5556 CXXRewrittenBinaryOperator, UnaryOperator),namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasOperatorName0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_hasOperatorName0Matcher( std::string
const &AName) : Name(AName) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string Name; }; } inline
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasOperatorName0Matcher, void(::clang::ast_matchers
::internal::TypeList<BinaryOperator, CXXOperatorCallExpr, CXXRewrittenBinaryOperator
, UnaryOperator>), std::string> hasOperatorName(std::string
const &Name) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasOperatorName0Matcher, void(::clang::
ast_matchers::internal::TypeList<BinaryOperator, CXXOperatorCallExpr
, CXXRewrittenBinaryOperator, UnaryOperator>), std::string
>(Name); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasOperatorName0Matcher, void(::clang::
ast_matchers::internal::TypeList<BinaryOperator, CXXOperatorCallExpr
, CXXRewrittenBinaryOperator, UnaryOperator>), std::string
> (&hasOperatorName_Type0)(std::string const &Name
); template <typename NodeType, typename ParamT> bool internal
:: matcher_hasOperatorName0Matcher<NodeType, ParamT>::matches
( const NodeType &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
5557 std::string, Name)namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasOperatorName0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_hasOperatorName0Matcher( std::string
const &AName) : Name(AName) {} bool matches(const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string Name; }; } inline
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasOperatorName0Matcher, void(::clang::ast_matchers
::internal::TypeList<BinaryOperator, CXXOperatorCallExpr, CXXRewrittenBinaryOperator
, UnaryOperator>), std::string> hasOperatorName(std::string
const &Name) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasOperatorName0Matcher, void(::clang::
ast_matchers::internal::TypeList<BinaryOperator, CXXOperatorCallExpr
, CXXRewrittenBinaryOperator, UnaryOperator>), std::string
>(Name); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasOperatorName0Matcher, void(::clang::
ast_matchers::internal::TypeList<BinaryOperator, CXXOperatorCallExpr
, CXXRewrittenBinaryOperator, UnaryOperator>), std::string
> (&hasOperatorName_Type0)(std::string const &Name
); template <typename NodeType, typename ParamT> bool internal
:: matcher_hasOperatorName0Matcher<NodeType, ParamT>::matches
( const NodeType &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
5558 if (Optional<StringRef> OpName = internal::getOpName(Node))
5559 return *OpName == Name;
5560 return false;
5561}
5562
5563/// Matches operator expressions (binary or unary) that have any of the
5564/// specified names.
5565///
5566/// hasAnyOperatorName("+", "-")
5567/// Is equivalent to
5568/// anyOf(hasOperatorName("+"), hasOperatorName("-"))
5569extern const internal::VariadicFunction<
5570 internal::PolymorphicMatcher<internal::HasAnyOperatorNameMatcher,
5571 AST_POLYMORPHIC_SUPPORTED_TYPES(void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator, UnaryOperator
>)
5572 BinaryOperator, CXXOperatorCallExpr,void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator, UnaryOperator
>)
5573 CXXRewrittenBinaryOperator, UnaryOperator)void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator, UnaryOperator
>)
,
5574 std::vector<std::string>>,
5575 StringRef, internal::hasAnyOperatorNameFunc>
5576 hasAnyOperatorName;
5577
5578/// Matches all kinds of assignment operators.
5579///
5580/// Example 1: matches a += b (matcher = binaryOperator(isAssignmentOperator()))
5581/// \code
5582/// if (a == b)
5583/// a += b;
5584/// \endcode
5585///
5586/// Example 2: matches s1 = s2
5587/// (matcher = cxxOperatorCallExpr(isAssignmentOperator()))
5588/// \code
5589/// struct S { S& operator=(const S&); };
5590/// void x() { S s1, s2; s1 = s2; }
5591/// \endcode
5592AST_POLYMORPHIC_MATCHER(namespace internal { template <typename NodeType> class
matcher_isAssignmentOperatorMatcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isAssignmentOperatorMatcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>)> isAssignmentOperator
() { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isAssignmentOperatorMatcher, void(::clang
::ast_matchers::internal::TypeList<BinaryOperator, CXXOperatorCallExpr
, CXXRewrittenBinaryOperator>)>(); } template <typename
NodeType> bool internal::matcher_isAssignmentOperatorMatcher
<NodeType>::matches( const NodeType &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
5593 isAssignmentOperator,namespace internal { template <typename NodeType> class
matcher_isAssignmentOperatorMatcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isAssignmentOperatorMatcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>)> isAssignmentOperator
() { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isAssignmentOperatorMatcher, void(::clang
::ast_matchers::internal::TypeList<BinaryOperator, CXXOperatorCallExpr
, CXXRewrittenBinaryOperator>)>(); } template <typename
NodeType> bool internal::matcher_isAssignmentOperatorMatcher
<NodeType>::matches( const NodeType &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
5594 AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,namespace internal { template <typename NodeType> class
matcher_isAssignmentOperatorMatcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isAssignmentOperatorMatcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>)> isAssignmentOperator
() { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isAssignmentOperatorMatcher, void(::clang
::ast_matchers::internal::TypeList<BinaryOperator, CXXOperatorCallExpr
, CXXRewrittenBinaryOperator>)>(); } template <typename
NodeType> bool internal::matcher_isAssignmentOperatorMatcher
<NodeType>::matches( const NodeType &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
5595 CXXRewrittenBinaryOperator))namespace internal { template <typename NodeType> class
matcher_isAssignmentOperatorMatcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isAssignmentOperatorMatcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>)> isAssignmentOperator
() { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isAssignmentOperatorMatcher, void(::clang
::ast_matchers::internal::TypeList<BinaryOperator, CXXOperatorCallExpr
, CXXRewrittenBinaryOperator>)>(); } template <typename
NodeType> bool internal::matcher_isAssignmentOperatorMatcher
<NodeType>::matches( const NodeType &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
{
5596 return Node.isAssignmentOp();
5597}
5598
5599/// Matches comparison operators.
5600///
5601/// Example 1: matches a == b (matcher = binaryOperator(isComparisonOperator()))
5602/// \code
5603/// if (a == b)
5604/// a += b;
5605/// \endcode
5606///
5607/// Example 2: matches s1 < s2
5608/// (matcher = cxxOperatorCallExpr(isComparisonOperator()))
5609/// \code
5610/// struct S { bool operator<(const S& other); };
5611/// void x(S s1, S s2) { bool b1 = s1 < s2; }
5612/// \endcode
5613AST_POLYMORPHIC_MATCHER(namespace internal { template <typename NodeType> class
matcher_isComparisonOperatorMatcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isComparisonOperatorMatcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>)> isComparisonOperator
() { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isComparisonOperatorMatcher, void(::clang
::ast_matchers::internal::TypeList<BinaryOperator, CXXOperatorCallExpr
, CXXRewrittenBinaryOperator>)>(); } template <typename
NodeType> bool internal::matcher_isComparisonOperatorMatcher
<NodeType>::matches( const NodeType &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
5614 isComparisonOperator,namespace internal { template <typename NodeType> class
matcher_isComparisonOperatorMatcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isComparisonOperatorMatcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>)> isComparisonOperator
() { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isComparisonOperatorMatcher, void(::clang
::ast_matchers::internal::TypeList<BinaryOperator, CXXOperatorCallExpr
, CXXRewrittenBinaryOperator>)>(); } template <typename
NodeType> bool internal::matcher_isComparisonOperatorMatcher
<NodeType>::matches( const NodeType &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
5615 AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,namespace internal { template <typename NodeType> class
matcher_isComparisonOperatorMatcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isComparisonOperatorMatcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>)> isComparisonOperator
() { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isComparisonOperatorMatcher, void(::clang
::ast_matchers::internal::TypeList<BinaryOperator, CXXOperatorCallExpr
, CXXRewrittenBinaryOperator>)>(); } template <typename
NodeType> bool internal::matcher_isComparisonOperatorMatcher
<NodeType>::matches( const NodeType &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
5616 CXXRewrittenBinaryOperator))namespace internal { template <typename NodeType> class
matcher_isComparisonOperatorMatcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isComparisonOperatorMatcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>)> isComparisonOperator
() { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isComparisonOperatorMatcher, void(::clang
::ast_matchers::internal::TypeList<BinaryOperator, CXXOperatorCallExpr
, CXXRewrittenBinaryOperator>)>(); } template <typename
NodeType> bool internal::matcher_isComparisonOperatorMatcher
<NodeType>::matches( const NodeType &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
{
5617 return Node.isComparisonOp();
5618}
5619
5620/// Matches the left hand side of binary operator expressions.
5621///
5622/// Example matches a (matcher = binaryOperator(hasLHS()))
5623/// \code
5624/// a || b
5625/// \endcode
5626AST_POLYMORPHIC_MATCHER_P(hasLHS,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasLHS0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasLHS0Matcher( internal::Matcher<Expr> const &
AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches(
const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasLHS0Matcher, void
(::clang::ast_matchers::internal::TypeList<BinaryOperator,
CXXOperatorCallExpr, CXXRewrittenBinaryOperator, ArraySubscriptExpr
>), internal::Matcher<Expr> > hasLHS(internal::Matcher
<Expr> const &InnerMatcher) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasLHS0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator, ArraySubscriptExpr
>), internal::Matcher<Expr> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasLHS0Matcher, void(::clang::ast_matchers::internal
::TypeList<BinaryOperator, CXXOperatorCallExpr, CXXRewrittenBinaryOperator
, ArraySubscriptExpr>), internal::Matcher<Expr> >
(&hasLHS_Type0)(internal::Matcher<Expr> const &
InnerMatcher); template <typename NodeType, typename ParamT
> bool internal:: matcher_hasLHS0Matcher<NodeType, ParamT
>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
5627 AST_POLYMORPHIC_SUPPORTED_TYPES(namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasLHS0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasLHS0Matcher( internal::Matcher<Expr> const &
AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches(
const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasLHS0Matcher, void
(::clang::ast_matchers::internal::TypeList<BinaryOperator,
CXXOperatorCallExpr, CXXRewrittenBinaryOperator, ArraySubscriptExpr
>), internal::Matcher<Expr> > hasLHS(internal::Matcher
<Expr> const &InnerMatcher) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasLHS0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator, ArraySubscriptExpr
>), internal::Matcher<Expr> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasLHS0Matcher, void(::clang::ast_matchers::internal
::TypeList<BinaryOperator, CXXOperatorCallExpr, CXXRewrittenBinaryOperator
, ArraySubscriptExpr>), internal::Matcher<Expr> >
(&hasLHS_Type0)(internal::Matcher<Expr> const &
InnerMatcher); template <typename NodeType, typename ParamT
> bool internal:: matcher_hasLHS0Matcher<NodeType, ParamT
>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
5628 BinaryOperator, CXXOperatorCallExpr,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasLHS0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasLHS0Matcher( internal::Matcher<Expr> const &
AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches(
const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasLHS0Matcher, void
(::clang::ast_matchers::internal::TypeList<BinaryOperator,
CXXOperatorCallExpr, CXXRewrittenBinaryOperator, ArraySubscriptExpr
>), internal::Matcher<Expr> > hasLHS(internal::Matcher
<Expr> const &InnerMatcher) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasLHS0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator, ArraySubscriptExpr
>), internal::Matcher<Expr> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasLHS0Matcher, void(::clang::ast_matchers::internal
::TypeList<BinaryOperator, CXXOperatorCallExpr, CXXRewrittenBinaryOperator
, ArraySubscriptExpr>), internal::Matcher<Expr> >
(&hasLHS_Type0)(internal::Matcher<Expr> const &
InnerMatcher); template <typename NodeType, typename ParamT
> bool internal:: matcher_hasLHS0Matcher<NodeType, ParamT
>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
5629 CXXRewrittenBinaryOperator, ArraySubscriptExpr),namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasLHS0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasLHS0Matcher( internal::Matcher<Expr> const &
AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches(
const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasLHS0Matcher, void
(::clang::ast_matchers::internal::TypeList<BinaryOperator,
CXXOperatorCallExpr, CXXRewrittenBinaryOperator, ArraySubscriptExpr
>), internal::Matcher<Expr> > hasLHS(internal::Matcher
<Expr> const &InnerMatcher) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasLHS0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator, ArraySubscriptExpr
>), internal::Matcher<Expr> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasLHS0Matcher, void(::clang::ast_matchers::internal
::TypeList<BinaryOperator, CXXOperatorCallExpr, CXXRewrittenBinaryOperator
, ArraySubscriptExpr>), internal::Matcher<Expr> >
(&hasLHS_Type0)(internal::Matcher<Expr> const &
InnerMatcher); template <typename NodeType, typename ParamT
> bool internal:: matcher_hasLHS0Matcher<NodeType, ParamT
>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
5630 internal::Matcher<Expr>, InnerMatcher)namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasLHS0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasLHS0Matcher( internal::Matcher<Expr> const &
AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches(
const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasLHS0Matcher, void
(::clang::ast_matchers::internal::TypeList<BinaryOperator,
CXXOperatorCallExpr, CXXRewrittenBinaryOperator, ArraySubscriptExpr
>), internal::Matcher<Expr> > hasLHS(internal::Matcher
<Expr> const &InnerMatcher) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasLHS0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator, ArraySubscriptExpr
>), internal::Matcher<Expr> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasLHS0Matcher, void(::clang::ast_matchers::internal
::TypeList<BinaryOperator, CXXOperatorCallExpr, CXXRewrittenBinaryOperator
, ArraySubscriptExpr>), internal::Matcher<Expr> >
(&hasLHS_Type0)(internal::Matcher<Expr> const &
InnerMatcher); template <typename NodeType, typename ParamT
> bool internal:: matcher_hasLHS0Matcher<NodeType, ParamT
>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
5631 const Expr *LeftHandSide = internal::getLHS(Node);
5632 return (LeftHandSide != nullptr &&
5633 InnerMatcher.matches(*LeftHandSide, Finder, Builder));
5634}
5635
5636/// Matches the right hand side of binary operator expressions.
5637///
5638/// Example matches b (matcher = binaryOperator(hasRHS()))
5639/// \code
5640/// a || b
5641/// \endcode
5642AST_POLYMORPHIC_MATCHER_P(hasRHS,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasRHS0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasRHS0Matcher( internal::Matcher<Expr> const &
AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches(
const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasRHS0Matcher, void
(::clang::ast_matchers::internal::TypeList<BinaryOperator,
CXXOperatorCallExpr, CXXRewrittenBinaryOperator, ArraySubscriptExpr
>), internal::Matcher<Expr> > hasRHS(internal::Matcher
<Expr> const &InnerMatcher) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasRHS0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator, ArraySubscriptExpr
>), internal::Matcher<Expr> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasRHS0Matcher, void(::clang::ast_matchers::internal
::TypeList<BinaryOperator, CXXOperatorCallExpr, CXXRewrittenBinaryOperator
, ArraySubscriptExpr>), internal::Matcher<Expr> >
(&hasRHS_Type0)(internal::Matcher<Expr> const &
InnerMatcher); template <typename NodeType, typename ParamT
> bool internal:: matcher_hasRHS0Matcher<NodeType, ParamT
>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
5643 AST_POLYMORPHIC_SUPPORTED_TYPES(namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasRHS0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasRHS0Matcher( internal::Matcher<Expr> const &
AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches(
const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasRHS0Matcher, void
(::clang::ast_matchers::internal::TypeList<BinaryOperator,
CXXOperatorCallExpr, CXXRewrittenBinaryOperator, ArraySubscriptExpr
>), internal::Matcher<Expr> > hasRHS(internal::Matcher
<Expr> const &InnerMatcher) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasRHS0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator, ArraySubscriptExpr
>), internal::Matcher<Expr> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasRHS0Matcher, void(::clang::ast_matchers::internal
::TypeList<BinaryOperator, CXXOperatorCallExpr, CXXRewrittenBinaryOperator
, ArraySubscriptExpr>), internal::Matcher<Expr> >
(&hasRHS_Type0)(internal::Matcher<Expr> const &
InnerMatcher); template <typename NodeType, typename ParamT
> bool internal:: matcher_hasRHS0Matcher<NodeType, ParamT
>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
5644 BinaryOperator, CXXOperatorCallExpr,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasRHS0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasRHS0Matcher( internal::Matcher<Expr> const &
AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches(
const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasRHS0Matcher, void
(::clang::ast_matchers::internal::TypeList<BinaryOperator,
CXXOperatorCallExpr, CXXRewrittenBinaryOperator, ArraySubscriptExpr
>), internal::Matcher<Expr> > hasRHS(internal::Matcher
<Expr> const &InnerMatcher) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasRHS0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator, ArraySubscriptExpr
>), internal::Matcher<Expr> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasRHS0Matcher, void(::clang::ast_matchers::internal
::TypeList<BinaryOperator, CXXOperatorCallExpr, CXXRewrittenBinaryOperator
, ArraySubscriptExpr>), internal::Matcher<Expr> >
(&hasRHS_Type0)(internal::Matcher<Expr> const &
InnerMatcher); template <typename NodeType, typename ParamT
> bool internal:: matcher_hasRHS0Matcher<NodeType, ParamT
>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
5645 CXXRewrittenBinaryOperator, ArraySubscriptExpr),namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasRHS0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasRHS0Matcher( internal::Matcher<Expr> const &
AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches(
const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasRHS0Matcher, void
(::clang::ast_matchers::internal::TypeList<BinaryOperator,
CXXOperatorCallExpr, CXXRewrittenBinaryOperator, ArraySubscriptExpr
>), internal::Matcher<Expr> > hasRHS(internal::Matcher
<Expr> const &InnerMatcher) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasRHS0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator, ArraySubscriptExpr
>), internal::Matcher<Expr> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasRHS0Matcher, void(::clang::ast_matchers::internal
::TypeList<BinaryOperator, CXXOperatorCallExpr, CXXRewrittenBinaryOperator
, ArraySubscriptExpr>), internal::Matcher<Expr> >
(&hasRHS_Type0)(internal::Matcher<Expr> const &
InnerMatcher); template <typename NodeType, typename ParamT
> bool internal:: matcher_hasRHS0Matcher<NodeType, ParamT
>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
5646 internal::Matcher<Expr>, InnerMatcher)namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasRHS0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasRHS0Matcher( internal::Matcher<Expr> const &
AInnerMatcher) : InnerMatcher(AInnerMatcher) {} bool matches(
const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasRHS0Matcher, void
(::clang::ast_matchers::internal::TypeList<BinaryOperator,
CXXOperatorCallExpr, CXXRewrittenBinaryOperator, ArraySubscriptExpr
>), internal::Matcher<Expr> > hasRHS(internal::Matcher
<Expr> const &InnerMatcher) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasRHS0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator, ArraySubscriptExpr
>), internal::Matcher<Expr> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasRHS0Matcher, void(::clang::ast_matchers::internal
::TypeList<BinaryOperator, CXXOperatorCallExpr, CXXRewrittenBinaryOperator
, ArraySubscriptExpr>), internal::Matcher<Expr> >
(&hasRHS_Type0)(internal::Matcher<Expr> const &
InnerMatcher); template <typename NodeType, typename ParamT
> bool internal:: matcher_hasRHS0Matcher<NodeType, ParamT
>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
5647 const Expr *RightHandSide = internal::getRHS(Node);
5648 return (RightHandSide != nullptr &&
5649 InnerMatcher.matches(*RightHandSide, Finder, Builder));
5650}
5651
5652/// Matches if either the left hand side or the right hand side of a
5653/// binary operator matches.
5654AST_POLYMORPHIC_MATCHER_P(namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasEitherOperand0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_hasEitherOperand0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasEitherOperand0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>), internal
::Matcher<Expr> > hasEitherOperand(internal::Matcher
<Expr> const &InnerMatcher) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasEitherOperand0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>), internal
::Matcher<Expr> >(InnerMatcher); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasEitherOperand0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>), internal
::Matcher<Expr> > (&hasEitherOperand_Type0)(internal
::Matcher<Expr> const &InnerMatcher); template <
typename NodeType, typename ParamT> bool internal:: matcher_hasEitherOperand0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5655 hasEitherOperand,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasEitherOperand0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_hasEitherOperand0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasEitherOperand0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>), internal
::Matcher<Expr> > hasEitherOperand(internal::Matcher
<Expr> const &InnerMatcher) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasEitherOperand0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>), internal
::Matcher<Expr> >(InnerMatcher); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasEitherOperand0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>), internal
::Matcher<Expr> > (&hasEitherOperand_Type0)(internal
::Matcher<Expr> const &InnerMatcher); template <
typename NodeType, typename ParamT> bool internal:: matcher_hasEitherOperand0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5656 AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasEitherOperand0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_hasEitherOperand0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasEitherOperand0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>), internal
::Matcher<Expr> > hasEitherOperand(internal::Matcher
<Expr> const &InnerMatcher) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasEitherOperand0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>), internal
::Matcher<Expr> >(InnerMatcher); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasEitherOperand0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>), internal
::Matcher<Expr> > (&hasEitherOperand_Type0)(internal
::Matcher<Expr> const &InnerMatcher); template <
typename NodeType, typename ParamT> bool internal:: matcher_hasEitherOperand0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5657 CXXRewrittenBinaryOperator),namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasEitherOperand0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_hasEitherOperand0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasEitherOperand0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>), internal
::Matcher<Expr> > hasEitherOperand(internal::Matcher
<Expr> const &InnerMatcher) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasEitherOperand0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>), internal
::Matcher<Expr> >(InnerMatcher); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasEitherOperand0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>), internal
::Matcher<Expr> > (&hasEitherOperand_Type0)(internal
::Matcher<Expr> const &InnerMatcher); template <
typename NodeType, typename ParamT> bool internal:: matcher_hasEitherOperand0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5658 internal::Matcher<Expr>, InnerMatcher)namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasEitherOperand0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_hasEitherOperand0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasEitherOperand0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>), internal
::Matcher<Expr> > hasEitherOperand(internal::Matcher
<Expr> const &InnerMatcher) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasEitherOperand0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>), internal
::Matcher<Expr> >(InnerMatcher); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasEitherOperand0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>), internal
::Matcher<Expr> > (&hasEitherOperand_Type0)(internal
::Matcher<Expr> const &InnerMatcher); template <
typename NodeType, typename ParamT> bool internal:: matcher_hasEitherOperand0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
{
5659 return internal::VariadicDynCastAllOfMatcher<Stmt, NodeType>()(
5660 anyOf(hasLHS(InnerMatcher), hasRHS(InnerMatcher)))
5661 .matches(Node, Finder, Builder);
5662}
5663
5664/// Matches if both matchers match with opposite sides of the binary operator.
5665///
5666/// Example matcher = binaryOperator(hasOperands(integerLiteral(equals(1),
5667/// integerLiteral(equals(2)))
5668/// \code
5669/// 1 + 2 // Match
5670/// 2 + 1 // Match
5671/// 1 + 1 // No match
5672/// 2 + 2 // No match
5673/// \endcode
5674AST_POLYMORPHIC_MATCHER_P2(namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasOperands0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasOperands0Matcher(internal::
Matcher<Expr> const &AMatcher1, internal::Matcher<
Expr> const &AMatcher2) : Matcher1(AMatcher1), Matcher2
(AMatcher2) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> Matcher1; internal::Matcher<
Expr> Matcher2; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasOperands0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>), internal
::Matcher<Expr>, internal::Matcher<Expr> > hasOperands
(internal::Matcher<Expr> const &Matcher1, internal::
Matcher<Expr> const &Matcher2) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasOperands0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>), internal
::Matcher<Expr>, internal::Matcher<Expr> >(Matcher1
, Matcher2); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasOperands0Matcher, void(::clang::ast_matchers
::internal::TypeList<BinaryOperator, CXXOperatorCallExpr, CXXRewrittenBinaryOperator
>), internal::Matcher<Expr>, internal::Matcher<Expr
> > (&hasOperands_Type0)( internal::Matcher<Expr
> const &Matcher1, internal::Matcher<Expr> const
&Matcher2); template <typename NodeType, typename ParamT1
, typename ParamT2> bool internal::matcher_hasOperands0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
5675 hasOperands,namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasOperands0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasOperands0Matcher(internal::
Matcher<Expr> const &AMatcher1, internal::Matcher<
Expr> const &AMatcher2) : Matcher1(AMatcher1), Matcher2
(AMatcher2) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> Matcher1; internal::Matcher<
Expr> Matcher2; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasOperands0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>), internal
::Matcher<Expr>, internal::Matcher<Expr> > hasOperands
(internal::Matcher<Expr> const &Matcher1, internal::
Matcher<Expr> const &Matcher2) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasOperands0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>), internal
::Matcher<Expr>, internal::Matcher<Expr> >(Matcher1
, Matcher2); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasOperands0Matcher, void(::clang::ast_matchers
::internal::TypeList<BinaryOperator, CXXOperatorCallExpr, CXXRewrittenBinaryOperator
>), internal::Matcher<Expr>, internal::Matcher<Expr
> > (&hasOperands_Type0)( internal::Matcher<Expr
> const &Matcher1, internal::Matcher<Expr> const
&Matcher2); template <typename NodeType, typename ParamT1
, typename ParamT2> bool internal::matcher_hasOperands0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
5676 AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasOperands0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasOperands0Matcher(internal::
Matcher<Expr> const &AMatcher1, internal::Matcher<
Expr> const &AMatcher2) : Matcher1(AMatcher1), Matcher2
(AMatcher2) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> Matcher1; internal::Matcher<
Expr> Matcher2; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasOperands0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>), internal
::Matcher<Expr>, internal::Matcher<Expr> > hasOperands
(internal::Matcher<Expr> const &Matcher1, internal::
Matcher<Expr> const &Matcher2) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasOperands0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>), internal
::Matcher<Expr>, internal::Matcher<Expr> >(Matcher1
, Matcher2); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasOperands0Matcher, void(::clang::ast_matchers
::internal::TypeList<BinaryOperator, CXXOperatorCallExpr, CXXRewrittenBinaryOperator
>), internal::Matcher<Expr>, internal::Matcher<Expr
> > (&hasOperands_Type0)( internal::Matcher<Expr
> const &Matcher1, internal::Matcher<Expr> const
&Matcher2); template <typename NodeType, typename ParamT1
, typename ParamT2> bool internal::matcher_hasOperands0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
5677 CXXRewrittenBinaryOperator),namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasOperands0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasOperands0Matcher(internal::
Matcher<Expr> const &AMatcher1, internal::Matcher<
Expr> const &AMatcher2) : Matcher1(AMatcher1), Matcher2
(AMatcher2) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> Matcher1; internal::Matcher<
Expr> Matcher2; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasOperands0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>), internal
::Matcher<Expr>, internal::Matcher<Expr> > hasOperands
(internal::Matcher<Expr> const &Matcher1, internal::
Matcher<Expr> const &Matcher2) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasOperands0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>), internal
::Matcher<Expr>, internal::Matcher<Expr> >(Matcher1
, Matcher2); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasOperands0Matcher, void(::clang::ast_matchers
::internal::TypeList<BinaryOperator, CXXOperatorCallExpr, CXXRewrittenBinaryOperator
>), internal::Matcher<Expr>, internal::Matcher<Expr
> > (&hasOperands_Type0)( internal::Matcher<Expr
> const &Matcher1, internal::Matcher<Expr> const
&Matcher2); template <typename NodeType, typename ParamT1
, typename ParamT2> bool internal::matcher_hasOperands0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
5678 internal::Matcher<Expr>, Matcher1, internal::Matcher<Expr>, Matcher2)namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasOperands0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasOperands0Matcher(internal::
Matcher<Expr> const &AMatcher1, internal::Matcher<
Expr> const &AMatcher2) : Matcher1(AMatcher1), Matcher2
(AMatcher2) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> Matcher1; internal::Matcher<
Expr> Matcher2; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcher< internal::matcher_hasOperands0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>), internal
::Matcher<Expr>, internal::Matcher<Expr> > hasOperands
(internal::Matcher<Expr> const &Matcher1, internal::
Matcher<Expr> const &Matcher2) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasOperands0Matcher
, void(::clang::ast_matchers::internal::TypeList<BinaryOperator
, CXXOperatorCallExpr, CXXRewrittenBinaryOperator>), internal
::Matcher<Expr>, internal::Matcher<Expr> >(Matcher1
, Matcher2); } typedef ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasOperands0Matcher, void(::clang::ast_matchers
::internal::TypeList<BinaryOperator, CXXOperatorCallExpr, CXXRewrittenBinaryOperator
>), internal::Matcher<Expr>, internal::Matcher<Expr
> > (&hasOperands_Type0)( internal::Matcher<Expr
> const &Matcher1, internal::Matcher<Expr> const
&Matcher2); template <typename NodeType, typename ParamT1
, typename ParamT2> bool internal::matcher_hasOperands0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
5679 return internal::VariadicDynCastAllOfMatcher<Stmt, NodeType>()(
5680 anyOf(allOf(hasLHS(Matcher1), hasRHS(Matcher2)),
5681 allOf(hasLHS(Matcher2), hasRHS(Matcher1))))
5682 .matches(Node, Finder, Builder);
5683}
5684
5685/// Matches if the operand of a unary operator matches.
5686///
5687/// Example matches true (matcher = hasUnaryOperand(
5688/// cxxBoolLiteral(equals(true))))
5689/// \code
5690/// !true
5691/// \endcode
5692AST_POLYMORPHIC_MATCHER_P(hasUnaryOperand,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasUnaryOperand0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_hasUnaryOperand0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasUnaryOperand0Matcher
, void(::clang::ast_matchers::internal::TypeList<UnaryOperator
, CXXOperatorCallExpr>), internal::Matcher<Expr> >
hasUnaryOperand(internal::Matcher<Expr> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasUnaryOperand0Matcher, void(::clang::
ast_matchers::internal::TypeList<UnaryOperator, CXXOperatorCallExpr
>), internal::Matcher<Expr> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasUnaryOperand0Matcher, void(::clang::ast_matchers
::internal::TypeList<UnaryOperator, CXXOperatorCallExpr>
), internal::Matcher<Expr> > (&hasUnaryOperand_Type0
)(internal::Matcher<Expr> const &InnerMatcher); template
<typename NodeType, typename ParamT> bool internal:: matcher_hasUnaryOperand0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5693 AST_POLYMORPHIC_SUPPORTED_TYPES(UnaryOperator,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasUnaryOperand0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_hasUnaryOperand0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasUnaryOperand0Matcher
, void(::clang::ast_matchers::internal::TypeList<UnaryOperator
, CXXOperatorCallExpr>), internal::Matcher<Expr> >
hasUnaryOperand(internal::Matcher<Expr> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasUnaryOperand0Matcher, void(::clang::
ast_matchers::internal::TypeList<UnaryOperator, CXXOperatorCallExpr
>), internal::Matcher<Expr> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasUnaryOperand0Matcher, void(::clang::ast_matchers
::internal::TypeList<UnaryOperator, CXXOperatorCallExpr>
), internal::Matcher<Expr> > (&hasUnaryOperand_Type0
)(internal::Matcher<Expr> const &InnerMatcher); template
<typename NodeType, typename ParamT> bool internal:: matcher_hasUnaryOperand0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5694 CXXOperatorCallExpr),namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasUnaryOperand0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_hasUnaryOperand0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasUnaryOperand0Matcher
, void(::clang::ast_matchers::internal::TypeList<UnaryOperator
, CXXOperatorCallExpr>), internal::Matcher<Expr> >
hasUnaryOperand(internal::Matcher<Expr> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasUnaryOperand0Matcher, void(::clang::
ast_matchers::internal::TypeList<UnaryOperator, CXXOperatorCallExpr
>), internal::Matcher<Expr> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasUnaryOperand0Matcher, void(::clang::ast_matchers
::internal::TypeList<UnaryOperator, CXXOperatorCallExpr>
), internal::Matcher<Expr> > (&hasUnaryOperand_Type0
)(internal::Matcher<Expr> const &InnerMatcher); template
<typename NodeType, typename ParamT> bool internal:: matcher_hasUnaryOperand0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5695 internal::Matcher<Expr>, InnerMatcher)namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasUnaryOperand0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_hasUnaryOperand0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasUnaryOperand0Matcher
, void(::clang::ast_matchers::internal::TypeList<UnaryOperator
, CXXOperatorCallExpr>), internal::Matcher<Expr> >
hasUnaryOperand(internal::Matcher<Expr> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasUnaryOperand0Matcher, void(::clang::
ast_matchers::internal::TypeList<UnaryOperator, CXXOperatorCallExpr
>), internal::Matcher<Expr> >(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasUnaryOperand0Matcher, void(::clang::ast_matchers
::internal::TypeList<UnaryOperator, CXXOperatorCallExpr>
), internal::Matcher<Expr> > (&hasUnaryOperand_Type0
)(internal::Matcher<Expr> const &InnerMatcher); template
<typename NodeType, typename ParamT> bool internal:: matcher_hasUnaryOperand0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
{
5696 const Expr *const Operand = internal::getSubExpr(Node);
5697 return (Operand != nullptr &&
5698 InnerMatcher.matches(*Operand, Finder, Builder));
5699}
5700
5701/// Matches if the cast's source expression
5702/// or opaque value's source expression matches the given matcher.
5703///
5704/// Example 1: matches "a string"
5705/// (matcher = castExpr(hasSourceExpression(cxxConstructExpr())))
5706/// \code
5707/// class URL { URL(string); };
5708/// URL url = "a string";
5709/// \endcode
5710///
5711/// Example 2: matches 'b' (matcher =
5712/// opaqueValueExpr(hasSourceExpression(implicitCastExpr(declRefExpr())))
5713/// \code
5714/// int a = b ?: 1;
5715/// \endcode
5716AST_POLYMORPHIC_MATCHER_P(hasSourceExpression,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasSourceExpression0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_hasSourceExpression0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasSourceExpression0Matcher
, void(::clang::ast_matchers::internal::TypeList<CastExpr,
OpaqueValueExpr>), internal::Matcher<Expr> > hasSourceExpression
(internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasSourceExpression0Matcher, void(::clang::ast_matchers
::internal::TypeList<CastExpr, OpaqueValueExpr>), internal
::Matcher<Expr> >(InnerMatcher); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasSourceExpression0Matcher
, void(::clang::ast_matchers::internal::TypeList<CastExpr,
OpaqueValueExpr>), internal::Matcher<Expr> > (&
hasSourceExpression_Type0)(internal::Matcher<Expr> const
&InnerMatcher); template <typename NodeType, typename
ParamT> bool internal:: matcher_hasSourceExpression0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5717 AST_POLYMORPHIC_SUPPORTED_TYPES(CastExpr,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasSourceExpression0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_hasSourceExpression0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasSourceExpression0Matcher
, void(::clang::ast_matchers::internal::TypeList<CastExpr,
OpaqueValueExpr>), internal::Matcher<Expr> > hasSourceExpression
(internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasSourceExpression0Matcher, void(::clang::ast_matchers
::internal::TypeList<CastExpr, OpaqueValueExpr>), internal
::Matcher<Expr> >(InnerMatcher); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasSourceExpression0Matcher
, void(::clang::ast_matchers::internal::TypeList<CastExpr,
OpaqueValueExpr>), internal::Matcher<Expr> > (&
hasSourceExpression_Type0)(internal::Matcher<Expr> const
&InnerMatcher); template <typename NodeType, typename
ParamT> bool internal:: matcher_hasSourceExpression0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5718 OpaqueValueExpr),namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasSourceExpression0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_hasSourceExpression0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasSourceExpression0Matcher
, void(::clang::ast_matchers::internal::TypeList<CastExpr,
OpaqueValueExpr>), internal::Matcher<Expr> > hasSourceExpression
(internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasSourceExpression0Matcher, void(::clang::ast_matchers
::internal::TypeList<CastExpr, OpaqueValueExpr>), internal
::Matcher<Expr> >(InnerMatcher); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasSourceExpression0Matcher
, void(::clang::ast_matchers::internal::TypeList<CastExpr,
OpaqueValueExpr>), internal::Matcher<Expr> > (&
hasSourceExpression_Type0)(internal::Matcher<Expr> const
&InnerMatcher); template <typename NodeType, typename
ParamT> bool internal:: matcher_hasSourceExpression0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
5719 internal::Matcher<Expr>, InnerMatcher)namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasSourceExpression0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_hasSourceExpression0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasSourceExpression0Matcher
, void(::clang::ast_matchers::internal::TypeList<CastExpr,
OpaqueValueExpr>), internal::Matcher<Expr> > hasSourceExpression
(internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasSourceExpression0Matcher, void(::clang::ast_matchers
::internal::TypeList<CastExpr, OpaqueValueExpr>), internal
::Matcher<Expr> >(InnerMatcher); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasSourceExpression0Matcher
, void(::clang::ast_matchers::internal::TypeList<CastExpr,
OpaqueValueExpr>), internal::Matcher<Expr> > (&
hasSourceExpression_Type0)(internal::Matcher<Expr> const
&InnerMatcher); template <typename NodeType, typename
ParamT> bool internal:: matcher_hasSourceExpression0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
{
5720 const Expr *const SubExpression =
5721 internal::GetSourceExpressionMatcher<NodeType>::get(Node);
5722 return (SubExpression != nullptr &&
5723 InnerMatcher.matches(*SubExpression, Finder, Builder));
5724}
5725
5726/// Matches casts that has a given cast kind.
5727///
5728/// Example: matches the implicit cast around \c 0
5729/// (matcher = castExpr(hasCastKind(CK_NullToPointer)))
5730/// \code
5731/// int *p = 0;
5732/// \endcode
5733///
5734/// If the matcher is use from clang-query, CastKind parameter
5735/// should be passed as a quoted string. e.g., hasCastKind("CK_NullToPointer").
5736AST_MATCHER_P(CastExpr, hasCastKind, CastKind, Kind)namespace internal { class matcher_hasCastKind0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CastExpr
> { public: explicit matcher_hasCastKind0Matcher( CastKind
const &AKind) : Kind(AKind) {} bool matches(const CastExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: CastKind Kind; }; } inline
::clang::ast_matchers::internal::Matcher<CastExpr> hasCastKind
( CastKind const &Kind) { return ::clang::ast_matchers::internal
::makeMatcher( new internal::matcher_hasCastKind0Matcher(Kind
)); } typedef ::clang::ast_matchers::internal::Matcher<CastExpr
> ( &hasCastKind_Type0)(CastKind const &Kind); inline
bool internal::matcher_hasCastKind0Matcher::matches( const CastExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
5737 return Node.getCastKind() == Kind;
5738}
5739
5740/// Matches casts whose destination type matches a given matcher.
5741///
5742/// (Note: Clang's AST refers to other conversions as "casts" too, and calls
5743/// actual casts "explicit" casts.)
5744AST_MATCHER_P(ExplicitCastExpr, hasDestinationType,namespace internal { class matcher_hasDestinationType0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
ExplicitCastExpr> { public: explicit matcher_hasDestinationType0Matcher
( internal::Matcher<QualType> const &AInnerMatcher)
: InnerMatcher(AInnerMatcher) {} bool matches(const ExplicitCastExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<QualType
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<ExplicitCastExpr> hasDestinationType( internal
::Matcher<QualType> const &InnerMatcher) { return ::
clang::ast_matchers::internal::makeMatcher( new internal::matcher_hasDestinationType0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<ExplicitCastExpr> ( &hasDestinationType_Type0)(internal
::Matcher<QualType> const &InnerMatcher); inline bool
internal::matcher_hasDestinationType0Matcher::matches( const
ExplicitCastExpr &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
5745 internal::Matcher<QualType>, InnerMatcher)namespace internal { class matcher_hasDestinationType0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
ExplicitCastExpr> { public: explicit matcher_hasDestinationType0Matcher
( internal::Matcher<QualType> const &AInnerMatcher)
: InnerMatcher(AInnerMatcher) {} bool matches(const ExplicitCastExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<QualType
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<ExplicitCastExpr> hasDestinationType( internal
::Matcher<QualType> const &InnerMatcher) { return ::
clang::ast_matchers::internal::makeMatcher( new internal::matcher_hasDestinationType0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<ExplicitCastExpr> ( &hasDestinationType_Type0)(internal
::Matcher<QualType> const &InnerMatcher); inline bool
internal::matcher_hasDestinationType0Matcher::matches( const
ExplicitCastExpr &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
5746 const QualType NodeType = Node.getTypeAsWritten();
5747 return InnerMatcher.matches(NodeType, Finder, Builder);
5748}
5749
5750/// Matches implicit casts whose destination type matches a given
5751/// matcher.
5752///
5753/// FIXME: Unit test this matcher
5754AST_MATCHER_P(ImplicitCastExpr, hasImplicitDestinationType,namespace internal { class matcher_hasImplicitDestinationType0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
ImplicitCastExpr> { public: explicit matcher_hasImplicitDestinationType0Matcher
( internal::Matcher<QualType> const &AInnerMatcher)
: InnerMatcher(AInnerMatcher) {} bool matches(const ImplicitCastExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<QualType
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<ImplicitCastExpr> hasImplicitDestinationType(
internal::Matcher<QualType> const &InnerMatcher) {
return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_hasImplicitDestinationType0Matcher(InnerMatcher)); }
typedef ::clang::ast_matchers::internal::Matcher<ImplicitCastExpr
> ( &hasImplicitDestinationType_Type0)(internal::Matcher
<QualType> const &InnerMatcher); inline bool internal
::matcher_hasImplicitDestinationType0Matcher::matches( const ImplicitCastExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
5755 internal::Matcher<QualType>, InnerMatcher)namespace internal { class matcher_hasImplicitDestinationType0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
ImplicitCastExpr> { public: explicit matcher_hasImplicitDestinationType0Matcher
( internal::Matcher<QualType> const &AInnerMatcher)
: InnerMatcher(AInnerMatcher) {} bool matches(const ImplicitCastExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<QualType
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<ImplicitCastExpr> hasImplicitDestinationType(
internal::Matcher<QualType> const &InnerMatcher) {
return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_hasImplicitDestinationType0Matcher(InnerMatcher)); }
typedef ::clang::ast_matchers::internal::Matcher<ImplicitCastExpr
> ( &hasImplicitDestinationType_Type0)(internal::Matcher
<QualType> const &InnerMatcher); inline bool internal
::matcher_hasImplicitDestinationType0Matcher::matches( const ImplicitCastExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
5756 return InnerMatcher.matches(Node.getType(), Finder, Builder);
5757}
5758
5759/// Matches TagDecl object that are spelled with "struct."
5760///
5761/// Example matches S, but not C, U or E.
5762/// \code
5763/// struct S {};
5764/// class C {};
5765/// union U {};
5766/// enum E {};
5767/// \endcode
5768AST_MATCHER(TagDecl, isStruct)namespace internal { class matcher_isStructMatcher : public ::
clang::ast_matchers::internal::MatcherInterface<TagDecl>
{ public: explicit matcher_isStructMatcher() = default; bool
matches(const TagDecl &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::Matcher<TagDecl> isStruct() { return ::clang::
ast_matchers::internal::makeMatcher( new internal::matcher_isStructMatcher
()); } inline bool internal::matcher_isStructMatcher::matches
( const TagDecl &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
5769 return Node.isStruct();
5770}
5771
5772/// Matches TagDecl object that are spelled with "union."
5773///
5774/// Example matches U, but not C, S or E.
5775/// \code
5776/// struct S {};
5777/// class C {};
5778/// union U {};
5779/// enum E {};
5780/// \endcode
5781AST_MATCHER(TagDecl, isUnion)namespace internal { class matcher_isUnionMatcher : public ::
clang::ast_matchers::internal::MatcherInterface<TagDecl>
{ public: explicit matcher_isUnionMatcher() = default; bool matches
(const TagDecl &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::Matcher<TagDecl> isUnion() { return ::clang::
ast_matchers::internal::makeMatcher( new internal::matcher_isUnionMatcher
()); } inline bool internal::matcher_isUnionMatcher::matches(
const TagDecl &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
5782 return Node.isUnion();
5783}
5784
5785/// Matches TagDecl object that are spelled with "class."
5786///
5787/// Example matches C, but not S, U or E.
5788/// \code
5789/// struct S {};
5790/// class C {};
5791/// union U {};
5792/// enum E {};
5793/// \endcode
5794AST_MATCHER(TagDecl, isClass)namespace internal { class matcher_isClassMatcher : public ::
clang::ast_matchers::internal::MatcherInterface<TagDecl>
{ public: explicit matcher_isClassMatcher() = default; bool matches
(const TagDecl &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::Matcher<TagDecl> isClass() { return ::clang::
ast_matchers::internal::makeMatcher( new internal::matcher_isClassMatcher
()); } inline bool internal::matcher_isClassMatcher::matches(
const TagDecl &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
5795 return Node.isClass();
5796}
5797
5798/// Matches TagDecl object that are spelled with "enum."
5799///
5800/// Example matches E, but not C, S or U.
5801/// \code
5802/// struct S {};
5803/// class C {};
5804/// union U {};
5805/// enum E {};
5806/// \endcode
5807AST_MATCHER(TagDecl, isEnum)namespace internal { class matcher_isEnumMatcher : public ::clang
::ast_matchers::internal::MatcherInterface<TagDecl> { public
: explicit matcher_isEnumMatcher() = default; bool matches(const
TagDecl &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::Matcher<TagDecl> isEnum() { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_isEnumMatcher(
)); } inline bool internal::matcher_isEnumMatcher::matches( const
TagDecl &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
5808 return Node.isEnum();
5809}
5810
5811/// Matches the true branch expression of a conditional operator.
5812///
5813/// Example 1 (conditional ternary operator): matches a
5814/// \code
5815/// condition ? a : b
5816/// \endcode
5817///
5818/// Example 2 (conditional binary operator): matches opaqueValueExpr(condition)
5819/// \code
5820/// condition ?: b
5821/// \endcode
5822AST_MATCHER_P(AbstractConditionalOperator, hasTrueExpression,namespace internal { class matcher_hasTrueExpression0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
AbstractConditionalOperator> { public: explicit matcher_hasTrueExpression0Matcher
( internal::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const AbstractConditionalOperator
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<AbstractConditionalOperator> hasTrueExpression
( internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasTrueExpression0Matcher(InnerMatcher)); } typedef ::
clang::ast_matchers::internal::Matcher<AbstractConditionalOperator
> ( &hasTrueExpression_Type0)(internal::Matcher<Expr
> const &InnerMatcher); inline bool internal::matcher_hasTrueExpression0Matcher
::matches( const AbstractConditionalOperator &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
5823 internal::Matcher<Expr>, InnerMatcher)namespace internal { class matcher_hasTrueExpression0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
AbstractConditionalOperator> { public: explicit matcher_hasTrueExpression0Matcher
( internal::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const AbstractConditionalOperator
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<AbstractConditionalOperator> hasTrueExpression
( internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasTrueExpression0Matcher(InnerMatcher)); } typedef ::
clang::ast_matchers::internal::Matcher<AbstractConditionalOperator
> ( &hasTrueExpression_Type0)(internal::Matcher<Expr
> const &InnerMatcher); inline bool internal::matcher_hasTrueExpression0Matcher
::matches( const AbstractConditionalOperator &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
{
5824 const Expr *Expression = Node.getTrueExpr();
5825 return (Expression != nullptr &&
5826 InnerMatcher.matches(*Expression, Finder, Builder));
5827}
5828
5829/// Matches the false branch expression of a conditional operator
5830/// (binary or ternary).
5831///
5832/// Example matches b
5833/// \code
5834/// condition ? a : b
5835/// condition ?: b
5836/// \endcode
5837AST_MATCHER_P(AbstractConditionalOperator, hasFalseExpression,namespace internal { class matcher_hasFalseExpression0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
AbstractConditionalOperator> { public: explicit matcher_hasFalseExpression0Matcher
( internal::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const AbstractConditionalOperator
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<AbstractConditionalOperator> hasFalseExpression
( internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasFalseExpression0Matcher(InnerMatcher)); } typedef ::
clang::ast_matchers::internal::Matcher<AbstractConditionalOperator
> ( &hasFalseExpression_Type0)(internal::Matcher<Expr
> const &InnerMatcher); inline bool internal::matcher_hasFalseExpression0Matcher
::matches( const AbstractConditionalOperator &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
5838 internal::Matcher<Expr>, InnerMatcher)namespace internal { class matcher_hasFalseExpression0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
AbstractConditionalOperator> { public: explicit matcher_hasFalseExpression0Matcher
( internal::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const AbstractConditionalOperator
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<Expr
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<AbstractConditionalOperator> hasFalseExpression
( internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasFalseExpression0Matcher(InnerMatcher)); } typedef ::
clang::ast_matchers::internal::Matcher<AbstractConditionalOperator
> ( &hasFalseExpression_Type0)(internal::Matcher<Expr
> const &InnerMatcher); inline bool internal::matcher_hasFalseExpression0Matcher
::matches( const AbstractConditionalOperator &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
{
5839 const Expr *Expression = Node.getFalseExpr();
5840 return (Expression != nullptr &&
5841 InnerMatcher.matches(*Expression, Finder, Builder));
5842}
5843
5844/// Matches if a declaration has a body attached.
5845///
5846/// Example matches A, va, fa
5847/// \code
5848/// class A {};
5849/// class B; // Doesn't match, as it has no body.
5850/// int va;
5851/// extern int vb; // Doesn't match, as it doesn't define the variable.
5852/// void fa() {}
5853/// void fb(); // Doesn't match, as it has no body.
5854/// @interface X
5855/// - (void)ma; // Doesn't match, interface is declaration.
5856/// @end
5857/// @implementation X
5858/// - (void)ma {}
5859/// @end
5860/// \endcode
5861///
5862/// Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>,
5863/// Matcher<ObjCMethodDecl>
5864AST_POLYMORPHIC_MATCHER(isDefinition,namespace internal { template <typename NodeType> class
matcher_isDefinitionMatcher : public ::clang::ast_matchers::
internal::MatcherInterface<NodeType> { public: bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isDefinitionMatcher
, void(::clang::ast_matchers::internal::TypeList<TagDecl, VarDecl
, ObjCMethodDecl, FunctionDecl>)> isDefinition() { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_isDefinitionMatcher, void(::clang::ast_matchers::internal
::TypeList<TagDecl, VarDecl, ObjCMethodDecl, FunctionDecl>
)>(); } template <typename NodeType> bool internal::
matcher_isDefinitionMatcher<NodeType>::matches( const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
5865 AST_POLYMORPHIC_SUPPORTED_TYPES(TagDecl, VarDecl,namespace internal { template <typename NodeType> class
matcher_isDefinitionMatcher : public ::clang::ast_matchers::
internal::MatcherInterface<NodeType> { public: bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isDefinitionMatcher
, void(::clang::ast_matchers::internal::TypeList<TagDecl, VarDecl
, ObjCMethodDecl, FunctionDecl>)> isDefinition() { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_isDefinitionMatcher, void(::clang::ast_matchers::internal
::TypeList<TagDecl, VarDecl, ObjCMethodDecl, FunctionDecl>
)>(); } template <typename NodeType> bool internal::
matcher_isDefinitionMatcher<NodeType>::matches( const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
5866 ObjCMethodDecl,namespace internal { template <typename NodeType> class
matcher_isDefinitionMatcher : public ::clang::ast_matchers::
internal::MatcherInterface<NodeType> { public: bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isDefinitionMatcher
, void(::clang::ast_matchers::internal::TypeList<TagDecl, VarDecl
, ObjCMethodDecl, FunctionDecl>)> isDefinition() { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_isDefinitionMatcher, void(::clang::ast_matchers::internal
::TypeList<TagDecl, VarDecl, ObjCMethodDecl, FunctionDecl>
)>(); } template <typename NodeType> bool internal::
matcher_isDefinitionMatcher<NodeType>::matches( const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
5867 FunctionDecl))namespace internal { template <typename NodeType> class
matcher_isDefinitionMatcher : public ::clang::ast_matchers::
internal::MatcherInterface<NodeType> { public: bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isDefinitionMatcher
, void(::clang::ast_matchers::internal::TypeList<TagDecl, VarDecl
, ObjCMethodDecl, FunctionDecl>)> isDefinition() { return
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_isDefinitionMatcher, void(::clang::ast_matchers::internal
::TypeList<TagDecl, VarDecl, ObjCMethodDecl, FunctionDecl>
)>(); } template <typename NodeType> bool internal::
matcher_isDefinitionMatcher<NodeType>::matches( const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
5868 return Node.isThisDeclarationADefinition();
5869}
5870
5871/// Matches if a function declaration is variadic.
5872///
5873/// Example matches f, but not g or h. The function i will not match, even when
5874/// compiled in C mode.
5875/// \code
5876/// void f(...);
5877/// void g(int);
5878/// template <typename... Ts> void h(Ts...);
5879/// void i();
5880/// \endcode
5881AST_MATCHER(FunctionDecl, isVariadic)namespace internal { class matcher_isVariadicMatcher : public
::clang::ast_matchers::internal::MatcherInterface<FunctionDecl
> { public: explicit matcher_isVariadicMatcher() = default
; bool matches(const FunctionDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<FunctionDecl>
isVariadic() { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_isVariadicMatcher()); } inline bool internal
::matcher_isVariadicMatcher::matches( const FunctionDecl &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
5882 return Node.isVariadic();
5883}
5884
5885/// Matches the class declaration that the given method declaration
5886/// belongs to.
5887///
5888/// FIXME: Generalize this for other kinds of declarations.
5889/// FIXME: What other kind of declarations would we need to generalize
5890/// this to?
5891///
5892/// Example matches A() in the last line
5893/// (matcher = cxxConstructExpr(hasDeclaration(cxxMethodDecl(
5894/// ofClass(hasName("A"))))))
5895/// \code
5896/// class A {
5897/// public:
5898/// A();
5899/// };
5900/// A a = A();
5901/// \endcode
5902AST_MATCHER_P(CXXMethodDecl, ofClass,namespace internal { class matcher_ofClass0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<CXXMethodDecl
> { public: explicit matcher_ofClass0Matcher( internal::Matcher
<CXXRecordDecl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const CXXMethodDecl &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<CXXRecordDecl
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<CXXMethodDecl> ofClass( internal::Matcher<
CXXRecordDecl> const &InnerMatcher) { return ::clang::
ast_matchers::internal::makeMatcher( new internal::matcher_ofClass0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<CXXMethodDecl> ( &ofClass_Type0)(internal::Matcher
<CXXRecordDecl> const &InnerMatcher); inline bool internal
::matcher_ofClass0Matcher::matches( const CXXMethodDecl &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
5903 internal::Matcher<CXXRecordDecl>, InnerMatcher)namespace internal { class matcher_ofClass0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<CXXMethodDecl
> { public: explicit matcher_ofClass0Matcher( internal::Matcher
<CXXRecordDecl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const CXXMethodDecl &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<CXXRecordDecl
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<CXXMethodDecl> ofClass( internal::Matcher<
CXXRecordDecl> const &InnerMatcher) { return ::clang::
ast_matchers::internal::makeMatcher( new internal::matcher_ofClass0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<CXXMethodDecl> ( &ofClass_Type0)(internal::Matcher
<CXXRecordDecl> const &InnerMatcher); inline bool internal
::matcher_ofClass0Matcher::matches( const CXXMethodDecl &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
5904
5905 ASTChildrenNotSpelledInSourceScope RAII(Finder, false);
5906
5907 const CXXRecordDecl *Parent = Node.getParent();
5908 return (Parent != nullptr &&
5909 InnerMatcher.matches(*Parent, Finder, Builder));
5910}
5911
5912/// Matches each method overridden by the given method. This matcher may
5913/// produce multiple matches.
5914///
5915/// Given
5916/// \code
5917/// class A { virtual void f(); };
5918/// class B : public A { void f(); };
5919/// class C : public B { void f(); };
5920/// \endcode
5921/// cxxMethodDecl(ofClass(hasName("C")),
5922/// forEachOverridden(cxxMethodDecl().bind("b"))).bind("d")
5923/// matches once, with "b" binding "A::f" and "d" binding "C::f" (Note
5924/// that B::f is not overridden by C::f).
5925///
5926/// The check can produce multiple matches in case of multiple inheritance, e.g.
5927/// \code
5928/// class A1 { virtual void f(); };
5929/// class A2 { virtual void f(); };
5930/// class C : public A1, public A2 { void f(); };
5931/// \endcode
5932/// cxxMethodDecl(ofClass(hasName("C")),
5933/// forEachOverridden(cxxMethodDecl().bind("b"))).bind("d")
5934/// matches twice, once with "b" binding "A1::f" and "d" binding "C::f", and
5935/// once with "b" binding "A2::f" and "d" binding "C::f".
5936AST_MATCHER_P(CXXMethodDecl, forEachOverridden,namespace internal { class matcher_forEachOverridden0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
CXXMethodDecl> { public: explicit matcher_forEachOverridden0Matcher
( internal::Matcher<CXXMethodDecl> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const CXXMethodDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<CXXMethodDecl
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<CXXMethodDecl> forEachOverridden( internal::Matcher
<CXXMethodDecl> const &InnerMatcher) { return ::clang
::ast_matchers::internal::makeMatcher( new internal::matcher_forEachOverridden0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<CXXMethodDecl> ( &forEachOverridden_Type0)(internal
::Matcher<CXXMethodDecl> const &InnerMatcher); inline
bool internal::matcher_forEachOverridden0Matcher::matches( const
CXXMethodDecl &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
5937 internal::Matcher<CXXMethodDecl>, InnerMatcher)namespace internal { class matcher_forEachOverridden0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
CXXMethodDecl> { public: explicit matcher_forEachOverridden0Matcher
( internal::Matcher<CXXMethodDecl> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const CXXMethodDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<CXXMethodDecl
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<CXXMethodDecl> forEachOverridden( internal::Matcher
<CXXMethodDecl> const &InnerMatcher) { return ::clang
::ast_matchers::internal::makeMatcher( new internal::matcher_forEachOverridden0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<CXXMethodDecl> ( &forEachOverridden_Type0)(internal
::Matcher<CXXMethodDecl> const &InnerMatcher); inline
bool internal::matcher_forEachOverridden0Matcher::matches( const
CXXMethodDecl &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
5938 BoundNodesTreeBuilder Result;
5939 bool Matched = false;
5940 for (const auto *Overridden : Node.overridden_methods()) {
5941 BoundNodesTreeBuilder OverriddenBuilder(*Builder);
5942 const bool OverriddenMatched =
5943 InnerMatcher.matches(*Overridden, Finder, &OverriddenBuilder);
5944 if (OverriddenMatched) {
5945 Matched = true;
5946 Result.addMatch(OverriddenBuilder);
5947 }
5948 }
5949 *Builder = std::move(Result);
5950 return Matched;
5951}
5952
5953/// Matches declarations of virtual methods and C++ base specifers that specify
5954/// virtual inheritance.
5955///
5956/// Example:
5957/// \code
5958/// class A {
5959/// public:
5960/// virtual void x(); // matches x
5961/// };
5962/// \endcode
5963///
5964/// Example:
5965/// \code
5966/// class Base {};
5967/// class DirectlyDerived : virtual Base {}; // matches Base
5968/// class IndirectlyDerived : DirectlyDerived, Base {}; // matches Base
5969/// \endcode
5970///
5971/// Usable as: Matcher<CXXMethodDecl>, Matcher<CXXBaseSpecifier>
5972AST_POLYMORPHIC_MATCHER(isVirtual,namespace internal { template <typename NodeType> class
matcher_isVirtualMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isVirtualMatcher
, void(::clang::ast_matchers::internal::TypeList<CXXMethodDecl
, CXXBaseSpecifier>)> isVirtual() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isVirtualMatcher
, void(::clang::ast_matchers::internal::TypeList<CXXMethodDecl
, CXXBaseSpecifier>)>(); } template <typename NodeType
> bool internal::matcher_isVirtualMatcher<NodeType>::
matches( const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
5973 AST_POLYMORPHIC_SUPPORTED_TYPES(CXXMethodDecl,namespace internal { template <typename NodeType> class
matcher_isVirtualMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isVirtualMatcher
, void(::clang::ast_matchers::internal::TypeList<CXXMethodDecl
, CXXBaseSpecifier>)> isVirtual() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isVirtualMatcher
, void(::clang::ast_matchers::internal::TypeList<CXXMethodDecl
, CXXBaseSpecifier>)>(); } template <typename NodeType
> bool internal::matcher_isVirtualMatcher<NodeType>::
matches( const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
5974 CXXBaseSpecifier))namespace internal { template <typename NodeType> class
matcher_isVirtualMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isVirtualMatcher
, void(::clang::ast_matchers::internal::TypeList<CXXMethodDecl
, CXXBaseSpecifier>)> isVirtual() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isVirtualMatcher
, void(::clang::ast_matchers::internal::TypeList<CXXMethodDecl
, CXXBaseSpecifier>)>(); } template <typename NodeType
> bool internal::matcher_isVirtualMatcher<NodeType>::
matches( const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
5975 return Node.isVirtual();
5976}
5977
5978/// Matches if the given method declaration has an explicit "virtual".
5979///
5980/// Given
5981/// \code
5982/// class A {
5983/// public:
5984/// virtual void x();
5985/// };
5986/// class B : public A {
5987/// public:
5988/// void x();
5989/// };
5990/// \endcode
5991/// matches A::x but not B::x
5992AST_MATCHER(CXXMethodDecl, isVirtualAsWritten)namespace internal { class matcher_isVirtualAsWrittenMatcher :
public ::clang::ast_matchers::internal::MatcherInterface<
CXXMethodDecl> { public: explicit matcher_isVirtualAsWrittenMatcher
() = default; bool matches(const CXXMethodDecl &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; }
; } inline ::clang::ast_matchers::internal::Matcher<CXXMethodDecl
> isVirtualAsWritten() { return ::clang::ast_matchers::internal
::makeMatcher( new internal::matcher_isVirtualAsWrittenMatcher
()); } inline bool internal::matcher_isVirtualAsWrittenMatcher
::matches( const CXXMethodDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
5993 return Node.isVirtualAsWritten();
5994}
5995
5996AST_MATCHER(CXXConstructorDecl, isInheritingConstructor)namespace internal { class matcher_isInheritingConstructorMatcher
: public ::clang::ast_matchers::internal::MatcherInterface<
CXXConstructorDecl> { public: explicit matcher_isInheritingConstructorMatcher
() = default; bool matches(const CXXConstructorDecl &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; }; } inline ::clang::ast_matchers::internal
::Matcher<CXXConstructorDecl> isInheritingConstructor()
{ return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_isInheritingConstructorMatcher()); } inline bool internal
::matcher_isInheritingConstructorMatcher::matches( const CXXConstructorDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
5997 return Node.isInheritingConstructor();
5998}
5999
6000/// Matches if the given method or class declaration is final.
6001///
6002/// Given:
6003/// \code
6004/// class A final {};
6005///
6006/// struct B {
6007/// virtual void f();
6008/// };
6009///
6010/// struct C : B {
6011/// void f() final;
6012/// };
6013/// \endcode
6014/// matches A and C::f, but not B, C, or B::f
6015AST_POLYMORPHIC_MATCHER(isFinal,namespace internal { template <typename NodeType> class
matcher_isFinalMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isFinalMatcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, CXXMethodDecl>)> isFinal() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isFinalMatcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, CXXMethodDecl>)>(); } template <typename NodeType>
bool internal::matcher_isFinalMatcher<NodeType>::matches
( const NodeType &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
6016 AST_POLYMORPHIC_SUPPORTED_TYPES(CXXRecordDecl,namespace internal { template <typename NodeType> class
matcher_isFinalMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isFinalMatcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, CXXMethodDecl>)> isFinal() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isFinalMatcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, CXXMethodDecl>)>(); } template <typename NodeType>
bool internal::matcher_isFinalMatcher<NodeType>::matches
( const NodeType &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
6017 CXXMethodDecl))namespace internal { template <typename NodeType> class
matcher_isFinalMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isFinalMatcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, CXXMethodDecl>)> isFinal() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isFinalMatcher
, void(::clang::ast_matchers::internal::TypeList<CXXRecordDecl
, CXXMethodDecl>)>(); } template <typename NodeType>
bool internal::matcher_isFinalMatcher<NodeType>::matches
( const NodeType &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
6018 return Node.template hasAttr<FinalAttr>();
6019}
6020
6021/// Matches if the given method declaration is pure.
6022///
6023/// Given
6024/// \code
6025/// class A {
6026/// public:
6027/// virtual void x() = 0;
6028/// };
6029/// \endcode
6030/// matches A::x
6031AST_MATCHER(CXXMethodDecl, isPure)namespace internal { class matcher_isPureMatcher : public ::clang
::ast_matchers::internal::MatcherInterface<CXXMethodDecl>
{ public: explicit matcher_isPureMatcher() = default; bool matches
(const CXXMethodDecl &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::Matcher<CXXMethodDecl> isPure() { return ::clang
::ast_matchers::internal::makeMatcher( new internal::matcher_isPureMatcher
()); } inline bool internal::matcher_isPureMatcher::matches( const
CXXMethodDecl &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
6032 return Node.isPure();
6033}
6034
6035/// Matches if the given method declaration is const.
6036///
6037/// Given
6038/// \code
6039/// struct A {
6040/// void foo() const;
6041/// void bar();
6042/// };
6043/// \endcode
6044///
6045/// cxxMethodDecl(isConst()) matches A::foo() but not A::bar()
6046AST_MATCHER(CXXMethodDecl, isConst)namespace internal { class matcher_isConstMatcher : public ::
clang::ast_matchers::internal::MatcherInterface<CXXMethodDecl
> { public: explicit matcher_isConstMatcher() = default; bool
matches(const CXXMethodDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<CXXMethodDecl>
isConst() { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_isConstMatcher()); } inline bool internal
::matcher_isConstMatcher::matches( const CXXMethodDecl &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
6047 return Node.isConst();
6048}
6049
6050/// Matches if the given method declaration declares a copy assignment
6051/// operator.
6052///
6053/// Given
6054/// \code
6055/// struct A {
6056/// A &operator=(const A &);
6057/// A &operator=(A &&);
6058/// };
6059/// \endcode
6060///
6061/// cxxMethodDecl(isCopyAssignmentOperator()) matches the first method but not
6062/// the second one.
6063AST_MATCHER(CXXMethodDecl, isCopyAssignmentOperator)namespace internal { class matcher_isCopyAssignmentOperatorMatcher
: public ::clang::ast_matchers::internal::MatcherInterface<
CXXMethodDecl> { public: explicit matcher_isCopyAssignmentOperatorMatcher
() = default; bool matches(const CXXMethodDecl &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; }
; } inline ::clang::ast_matchers::internal::Matcher<CXXMethodDecl
> isCopyAssignmentOperator() { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_isCopyAssignmentOperatorMatcher
()); } inline bool internal::matcher_isCopyAssignmentOperatorMatcher
::matches( const CXXMethodDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
6064 return Node.isCopyAssignmentOperator();
6065}
6066
6067/// Matches if the given method declaration declares a move assignment
6068/// operator.
6069///
6070/// Given
6071/// \code
6072/// struct A {
6073/// A &operator=(const A &);
6074/// A &operator=(A &&);
6075/// };
6076/// \endcode
6077///
6078/// cxxMethodDecl(isMoveAssignmentOperator()) matches the second method but not
6079/// the first one.
6080AST_MATCHER(CXXMethodDecl, isMoveAssignmentOperator)namespace internal { class matcher_isMoveAssignmentOperatorMatcher
: public ::clang::ast_matchers::internal::MatcherInterface<
CXXMethodDecl> { public: explicit matcher_isMoveAssignmentOperatorMatcher
() = default; bool matches(const CXXMethodDecl &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; }
; } inline ::clang::ast_matchers::internal::Matcher<CXXMethodDecl
> isMoveAssignmentOperator() { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_isMoveAssignmentOperatorMatcher
()); } inline bool internal::matcher_isMoveAssignmentOperatorMatcher
::matches( const CXXMethodDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
6081 return Node.isMoveAssignmentOperator();
6082}
6083
6084/// Matches if the given method declaration overrides another method.
6085///
6086/// Given
6087/// \code
6088/// class A {
6089/// public:
6090/// virtual void x();
6091/// };
6092/// class B : public A {
6093/// public:
6094/// virtual void x();
6095/// };
6096/// \endcode
6097/// matches B::x
6098AST_MATCHER(CXXMethodDecl, isOverride)namespace internal { class matcher_isOverrideMatcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXMethodDecl
> { public: explicit matcher_isOverrideMatcher() = default
; bool matches(const CXXMethodDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<CXXMethodDecl>
isOverride() { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_isOverrideMatcher()); } inline bool internal
::matcher_isOverrideMatcher::matches( const CXXMethodDecl &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
6099 return Node.size_overridden_methods() > 0 || Node.hasAttr<OverrideAttr>();
6100}
6101
6102/// Matches method declarations that are user-provided.
6103///
6104/// Given
6105/// \code
6106/// struct S {
6107/// S(); // #1
6108/// S(const S &) = default; // #2
6109/// S(S &&) = delete; // #3
6110/// };
6111/// \endcode
6112/// cxxConstructorDecl(isUserProvided()) will match #1, but not #2 or #3.
6113AST_MATCHER(CXXMethodDecl, isUserProvided)namespace internal { class matcher_isUserProvidedMatcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXMethodDecl
> { public: explicit matcher_isUserProvidedMatcher() = default
; bool matches(const CXXMethodDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<CXXMethodDecl>
isUserProvided() { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_isUserProvidedMatcher()); } inline bool
internal::matcher_isUserProvidedMatcher::matches( const CXXMethodDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
6114 return Node.isUserProvided();
6115}
6116
6117/// Matches member expressions that are called with '->' as opposed
6118/// to '.'.
6119///
6120/// Member calls on the implicit this pointer match as called with '->'.
6121///
6122/// Given
6123/// \code
6124/// class Y {
6125/// void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; }
6126/// template <class T> void f() { this->f<T>(); f<T>(); }
6127/// int a;
6128/// static int b;
6129/// };
6130/// template <class T>
6131/// class Z {
6132/// void x() { this->m; }
6133/// };
6134/// \endcode
6135/// memberExpr(isArrow())
6136/// matches this->x, x, y.x, a, this->b
6137/// cxxDependentScopeMemberExpr(isArrow())
6138/// matches this->m
6139/// unresolvedMemberExpr(isArrow())
6140/// matches this->f<T>, f<T>
6141AST_POLYMORPHIC_MATCHER(namespace internal { template <typename NodeType> class
matcher_isArrowMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isArrowMatcher
, void(::clang::ast_matchers::internal::TypeList<MemberExpr
, UnresolvedMemberExpr, CXXDependentScopeMemberExpr>)> isArrow
() { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isArrowMatcher, void(::clang::ast_matchers
::internal::TypeList<MemberExpr, UnresolvedMemberExpr, CXXDependentScopeMemberExpr
>)>(); } template <typename NodeType> bool internal
::matcher_isArrowMatcher<NodeType>::matches( const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
6142 isArrow, AST_POLYMORPHIC_SUPPORTED_TYPES(MemberExpr, UnresolvedMemberExpr,namespace internal { template <typename NodeType> class
matcher_isArrowMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isArrowMatcher
, void(::clang::ast_matchers::internal::TypeList<MemberExpr
, UnresolvedMemberExpr, CXXDependentScopeMemberExpr>)> isArrow
() { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isArrowMatcher, void(::clang::ast_matchers
::internal::TypeList<MemberExpr, UnresolvedMemberExpr, CXXDependentScopeMemberExpr
>)>(); } template <typename NodeType> bool internal
::matcher_isArrowMatcher<NodeType>::matches( const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
6143 CXXDependentScopeMemberExpr))namespace internal { template <typename NodeType> class
matcher_isArrowMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isArrowMatcher
, void(::clang::ast_matchers::internal::TypeList<MemberExpr
, UnresolvedMemberExpr, CXXDependentScopeMemberExpr>)> isArrow
() { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isArrowMatcher, void(::clang::ast_matchers
::internal::TypeList<MemberExpr, UnresolvedMemberExpr, CXXDependentScopeMemberExpr
>)>(); } template <typename NodeType> bool internal
::matcher_isArrowMatcher<NodeType>::matches( const NodeType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
6144 return Node.isArrow();
6145}
6146
6147/// Matches QualType nodes that are of integer type.
6148///
6149/// Given
6150/// \code
6151/// void a(int);
6152/// void b(long);
6153/// void c(double);
6154/// \endcode
6155/// functionDecl(hasAnyParameter(hasType(isInteger())))
6156/// matches "a(int)", "b(long)", but not "c(double)".
6157AST_MATCHER(QualType, isInteger)namespace internal { class matcher_isIntegerMatcher : public ::
clang::ast_matchers::internal::MatcherInterface<QualType>
{ public: explicit matcher_isIntegerMatcher() = default; bool
matches(const QualType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::Matcher<QualType> isInteger() { return ::clang
::ast_matchers::internal::makeMatcher( new internal::matcher_isIntegerMatcher
()); } inline bool internal::matcher_isIntegerMatcher::matches
( const QualType &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
6158 return Node->isIntegerType();
6159}
6160
6161/// Matches QualType nodes that are of unsigned integer type.
6162///
6163/// Given
6164/// \code
6165/// void a(int);
6166/// void b(unsigned long);
6167/// void c(double);
6168/// \endcode
6169/// functionDecl(hasAnyParameter(hasType(isUnsignedInteger())))
6170/// matches "b(unsigned long)", but not "a(int)" and "c(double)".
6171AST_MATCHER(QualType, isUnsignedInteger)namespace internal { class matcher_isUnsignedIntegerMatcher :
public ::clang::ast_matchers::internal::MatcherInterface<
QualType> { public: explicit matcher_isUnsignedIntegerMatcher
() = default; bool matches(const QualType &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; }
; } inline ::clang::ast_matchers::internal::Matcher<QualType
> isUnsignedInteger() { return ::clang::ast_matchers::internal
::makeMatcher( new internal::matcher_isUnsignedIntegerMatcher
()); } inline bool internal::matcher_isUnsignedIntegerMatcher
::matches( const QualType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
6172 return Node->isUnsignedIntegerType();
6173}
6174
6175/// Matches QualType nodes that are of signed integer type.
6176///
6177/// Given
6178/// \code
6179/// void a(int);
6180/// void b(unsigned long);
6181/// void c(double);
6182/// \endcode
6183/// functionDecl(hasAnyParameter(hasType(isSignedInteger())))
6184/// matches "a(int)", but not "b(unsigned long)" and "c(double)".
6185AST_MATCHER(QualType, isSignedInteger)namespace internal { class matcher_isSignedIntegerMatcher : public
::clang::ast_matchers::internal::MatcherInterface<QualType
> { public: explicit matcher_isSignedIntegerMatcher() = default
; bool matches(const QualType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<QualType> isSignedInteger
() { return ::clang::ast_matchers::internal::makeMatcher( new
internal::matcher_isSignedIntegerMatcher()); } inline bool internal
::matcher_isSignedIntegerMatcher::matches( const QualType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
6186 return Node->isSignedIntegerType();
6187}
6188
6189/// Matches QualType nodes that are of character type.
6190///
6191/// Given
6192/// \code
6193/// void a(char);
6194/// void b(wchar_t);
6195/// void c(double);
6196/// \endcode
6197/// functionDecl(hasAnyParameter(hasType(isAnyCharacter())))
6198/// matches "a(char)", "b(wchar_t)", but not "c(double)".
6199AST_MATCHER(QualType, isAnyCharacter)namespace internal { class matcher_isAnyCharacterMatcher : public
::clang::ast_matchers::internal::MatcherInterface<QualType
> { public: explicit matcher_isAnyCharacterMatcher() = default
; bool matches(const QualType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<QualType> isAnyCharacter
() { return ::clang::ast_matchers::internal::makeMatcher( new
internal::matcher_isAnyCharacterMatcher()); } inline bool internal
::matcher_isAnyCharacterMatcher::matches( const QualType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
6200 return Node->isAnyCharacterType();
6201}
6202
6203/// Matches QualType nodes that are of any pointer type; this includes
6204/// the Objective-C object pointer type, which is different despite being
6205/// syntactically similar.
6206///
6207/// Given
6208/// \code
6209/// int *i = nullptr;
6210///
6211/// @interface Foo
6212/// @end
6213/// Foo *f;
6214///
6215/// int j;
6216/// \endcode
6217/// varDecl(hasType(isAnyPointer()))
6218/// matches "int *i" and "Foo *f", but not "int j".
6219AST_MATCHER(QualType, isAnyPointer)namespace internal { class matcher_isAnyPointerMatcher : public
::clang::ast_matchers::internal::MatcherInterface<QualType
> { public: explicit matcher_isAnyPointerMatcher() = default
; bool matches(const QualType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<QualType> isAnyPointer
() { return ::clang::ast_matchers::internal::makeMatcher( new
internal::matcher_isAnyPointerMatcher()); } inline bool internal
::matcher_isAnyPointerMatcher::matches( const QualType &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
6220 return Node->isAnyPointerType();
6221}
6222
6223/// Matches QualType nodes that are const-qualified, i.e., that
6224/// include "top-level" const.
6225///
6226/// Given
6227/// \code
6228/// void a(int);
6229/// void b(int const);
6230/// void c(const int);
6231/// void d(const int*);
6232/// void e(int const) {};
6233/// \endcode
6234/// functionDecl(hasAnyParameter(hasType(isConstQualified())))
6235/// matches "void b(int const)", "void c(const int)" and
6236/// "void e(int const) {}". It does not match d as there
6237/// is no top-level const on the parameter type "const int *".
6238AST_MATCHER(QualType, isConstQualified)namespace internal { class matcher_isConstQualifiedMatcher : public
::clang::ast_matchers::internal::MatcherInterface<QualType
> { public: explicit matcher_isConstQualifiedMatcher() = default
; bool matches(const QualType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<QualType> isConstQualified
() { return ::clang::ast_matchers::internal::makeMatcher( new
internal::matcher_isConstQualifiedMatcher()); } inline bool internal
::matcher_isConstQualifiedMatcher::matches( const QualType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
6239 return Node.isConstQualified();
6240}
6241
6242/// Matches QualType nodes that are volatile-qualified, i.e., that
6243/// include "top-level" volatile.
6244///
6245/// Given
6246/// \code
6247/// void a(int);
6248/// void b(int volatile);
6249/// void c(volatile int);
6250/// void d(volatile int*);
6251/// void e(int volatile) {};
6252/// \endcode
6253/// functionDecl(hasAnyParameter(hasType(isVolatileQualified())))
6254/// matches "void b(int volatile)", "void c(volatile int)" and
6255/// "void e(int volatile) {}". It does not match d as there
6256/// is no top-level volatile on the parameter type "volatile int *".
6257AST_MATCHER(QualType, isVolatileQualified)namespace internal { class matcher_isVolatileQualifiedMatcher
: public ::clang::ast_matchers::internal::MatcherInterface<
QualType> { public: explicit matcher_isVolatileQualifiedMatcher
() = default; bool matches(const QualType &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; }
; } inline ::clang::ast_matchers::internal::Matcher<QualType
> isVolatileQualified() { return ::clang::ast_matchers::internal
::makeMatcher( new internal::matcher_isVolatileQualifiedMatcher
()); } inline bool internal::matcher_isVolatileQualifiedMatcher
::matches( const QualType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
6258 return Node.isVolatileQualified();
6259}
6260
6261/// Matches QualType nodes that have local CV-qualifiers attached to
6262/// the node, not hidden within a typedef.
6263///
6264/// Given
6265/// \code
6266/// typedef const int const_int;
6267/// const_int i;
6268/// int *const j;
6269/// int *volatile k;
6270/// int m;
6271/// \endcode
6272/// \c varDecl(hasType(hasLocalQualifiers())) matches only \c j and \c k.
6273/// \c i is const-qualified but the qualifier is not local.
6274AST_MATCHER(QualType, hasLocalQualifiers)namespace internal { class matcher_hasLocalQualifiersMatcher :
public ::clang::ast_matchers::internal::MatcherInterface<
QualType> { public: explicit matcher_hasLocalQualifiersMatcher
() = default; bool matches(const QualType &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; }
; } inline ::clang::ast_matchers::internal::Matcher<QualType
> hasLocalQualifiers() { return ::clang::ast_matchers::internal
::makeMatcher( new internal::matcher_hasLocalQualifiersMatcher
()); } inline bool internal::matcher_hasLocalQualifiersMatcher
::matches( const QualType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
6275 return Node.hasLocalQualifiers();
6276}
6277
6278/// Matches a member expression where the member is matched by a
6279/// given matcher.
6280///
6281/// Given
6282/// \code
6283/// struct { int first, second; } first, second;
6284/// int i(second.first);
6285/// int j(first.second);
6286/// \endcode
6287/// memberExpr(member(hasName("first")))
6288/// matches second.first
6289/// but not first.second (because the member name there is "second").
6290AST_MATCHER_P(MemberExpr, member,namespace internal { class matcher_member0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<MemberExpr
> { public: explicit matcher_member0Matcher( internal::Matcher
<ValueDecl> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const MemberExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<ValueDecl> InnerMatcher; }; } inline ::clang::
ast_matchers::internal::Matcher<MemberExpr> member( internal
::Matcher<ValueDecl> const &InnerMatcher) { return ::
clang::ast_matchers::internal::makeMatcher( new internal::matcher_member0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<MemberExpr> ( &member_Type0)(internal::Matcher<
ValueDecl> const &InnerMatcher); inline bool internal::
matcher_member0Matcher::matches( const MemberExpr &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
6291 internal::Matcher<ValueDecl>, InnerMatcher)namespace internal { class matcher_member0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<MemberExpr
> { public: explicit matcher_member0Matcher( internal::Matcher
<ValueDecl> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const MemberExpr &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<ValueDecl> InnerMatcher; }; } inline ::clang::
ast_matchers::internal::Matcher<MemberExpr> member( internal
::Matcher<ValueDecl> const &InnerMatcher) { return ::
clang::ast_matchers::internal::makeMatcher( new internal::matcher_member0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<MemberExpr> ( &member_Type0)(internal::Matcher<
ValueDecl> const &InnerMatcher); inline bool internal::
matcher_member0Matcher::matches( const MemberExpr &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
{
6292 return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
6293}
6294
6295/// Matches a member expression where the object expression is matched by a
6296/// given matcher. Implicit object expressions are included; that is, it matches
6297/// use of implicit `this`.
6298///
6299/// Given
6300/// \code
6301/// struct X {
6302/// int m;
6303/// int f(X x) { x.m; return m; }
6304/// };
6305/// \endcode
6306/// memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))))
6307/// matches `x.m`, but not `m`; however,
6308/// memberExpr(hasObjectExpression(hasType(pointsTo(
6309// cxxRecordDecl(hasName("X"))))))
6310/// matches `m` (aka. `this->m`), but not `x.m`.
6311AST_POLYMORPHIC_MATCHER_P(namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasObjectExpression0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_hasObjectExpression0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasObjectExpression0Matcher
, void(::clang::ast_matchers::internal::TypeList<MemberExpr
, UnresolvedMemberExpr, CXXDependentScopeMemberExpr>), internal
::Matcher<Expr> > hasObjectExpression(internal::Matcher
<Expr> const &InnerMatcher) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasObjectExpression0Matcher
, void(::clang::ast_matchers::internal::TypeList<MemberExpr
, UnresolvedMemberExpr, CXXDependentScopeMemberExpr>), internal
::Matcher<Expr> >(InnerMatcher); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasObjectExpression0Matcher
, void(::clang::ast_matchers::internal::TypeList<MemberExpr
, UnresolvedMemberExpr, CXXDependentScopeMemberExpr>), internal
::Matcher<Expr> > (&hasObjectExpression_Type0)(internal
::Matcher<Expr> const &InnerMatcher); template <
typename NodeType, typename ParamT> bool internal:: matcher_hasObjectExpression0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
6312 hasObjectExpression,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasObjectExpression0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_hasObjectExpression0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasObjectExpression0Matcher
, void(::clang::ast_matchers::internal::TypeList<MemberExpr
, UnresolvedMemberExpr, CXXDependentScopeMemberExpr>), internal
::Matcher<Expr> > hasObjectExpression(internal::Matcher
<Expr> const &InnerMatcher) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasObjectExpression0Matcher
, void(::clang::ast_matchers::internal::TypeList<MemberExpr
, UnresolvedMemberExpr, CXXDependentScopeMemberExpr>), internal
::Matcher<Expr> >(InnerMatcher); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasObjectExpression0Matcher
, void(::clang::ast_matchers::internal::TypeList<MemberExpr
, UnresolvedMemberExpr, CXXDependentScopeMemberExpr>), internal
::Matcher<Expr> > (&hasObjectExpression_Type0)(internal
::Matcher<Expr> const &InnerMatcher); template <
typename NodeType, typename ParamT> bool internal:: matcher_hasObjectExpression0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
6313 AST_POLYMORPHIC_SUPPORTED_TYPES(MemberExpr, UnresolvedMemberExpr,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasObjectExpression0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_hasObjectExpression0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasObjectExpression0Matcher
, void(::clang::ast_matchers::internal::TypeList<MemberExpr
, UnresolvedMemberExpr, CXXDependentScopeMemberExpr>), internal
::Matcher<Expr> > hasObjectExpression(internal::Matcher
<Expr> const &InnerMatcher) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasObjectExpression0Matcher
, void(::clang::ast_matchers::internal::TypeList<MemberExpr
, UnresolvedMemberExpr, CXXDependentScopeMemberExpr>), internal
::Matcher<Expr> >(InnerMatcher); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasObjectExpression0Matcher
, void(::clang::ast_matchers::internal::TypeList<MemberExpr
, UnresolvedMemberExpr, CXXDependentScopeMemberExpr>), internal
::Matcher<Expr> > (&hasObjectExpression_Type0)(internal
::Matcher<Expr> const &InnerMatcher); template <
typename NodeType, typename ParamT> bool internal:: matcher_hasObjectExpression0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
6314 CXXDependentScopeMemberExpr),namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasObjectExpression0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_hasObjectExpression0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasObjectExpression0Matcher
, void(::clang::ast_matchers::internal::TypeList<MemberExpr
, UnresolvedMemberExpr, CXXDependentScopeMemberExpr>), internal
::Matcher<Expr> > hasObjectExpression(internal::Matcher
<Expr> const &InnerMatcher) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasObjectExpression0Matcher
, void(::clang::ast_matchers::internal::TypeList<MemberExpr
, UnresolvedMemberExpr, CXXDependentScopeMemberExpr>), internal
::Matcher<Expr> >(InnerMatcher); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasObjectExpression0Matcher
, void(::clang::ast_matchers::internal::TypeList<MemberExpr
, UnresolvedMemberExpr, CXXDependentScopeMemberExpr>), internal
::Matcher<Expr> > (&hasObjectExpression_Type0)(internal
::Matcher<Expr> const &InnerMatcher); template <
typename NodeType, typename ParamT> bool internal:: matcher_hasObjectExpression0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
6315 internal::Matcher<Expr>, InnerMatcher)namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasObjectExpression0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NodeType
> { public: explicit matcher_hasObjectExpression0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasObjectExpression0Matcher
, void(::clang::ast_matchers::internal::TypeList<MemberExpr
, UnresolvedMemberExpr, CXXDependentScopeMemberExpr>), internal
::Matcher<Expr> > hasObjectExpression(internal::Matcher
<Expr> const &InnerMatcher) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasObjectExpression0Matcher
, void(::clang::ast_matchers::internal::TypeList<MemberExpr
, UnresolvedMemberExpr, CXXDependentScopeMemberExpr>), internal
::Matcher<Expr> >(InnerMatcher); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcher< internal::matcher_hasObjectExpression0Matcher
, void(::clang::ast_matchers::internal::TypeList<MemberExpr
, UnresolvedMemberExpr, CXXDependentScopeMemberExpr>), internal
::Matcher<Expr> > (&hasObjectExpression_Type0)(internal
::Matcher<Expr> const &InnerMatcher); template <
typename NodeType, typename ParamT> bool internal:: matcher_hasObjectExpression0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
{
6316 if (const auto *E = dyn_cast<UnresolvedMemberExpr>(&Node))
6317 if (E->isImplicitAccess())
6318 return false;
6319 if (const auto *E = dyn_cast<CXXDependentScopeMemberExpr>(&Node))
6320 if (E->isImplicitAccess())
6321 return false;
6322 return InnerMatcher.matches(*Node.getBase(), Finder, Builder);
6323}
6324
6325/// Matches any using shadow declaration.
6326///
6327/// Given
6328/// \code
6329/// namespace X { void b(); }
6330/// using X::b;
6331/// \endcode
6332/// usingDecl(hasAnyUsingShadowDecl(hasName("b"))))
6333/// matches \code using X::b \endcode
6334AST_MATCHER_P(BaseUsingDecl, hasAnyUsingShadowDecl,namespace internal { class matcher_hasAnyUsingShadowDecl0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
BaseUsingDecl> { public: explicit matcher_hasAnyUsingShadowDecl0Matcher
( internal::Matcher<UsingShadowDecl> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const BaseUsingDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<UsingShadowDecl
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<BaseUsingDecl> hasAnyUsingShadowDecl( internal
::Matcher<UsingShadowDecl> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasAnyUsingShadowDecl0Matcher(InnerMatcher)); } typedef
::clang::ast_matchers::internal::Matcher<BaseUsingDecl>
( &hasAnyUsingShadowDecl_Type0)(internal::Matcher<UsingShadowDecl
> const &InnerMatcher); inline bool internal::matcher_hasAnyUsingShadowDecl0Matcher
::matches( const BaseUsingDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
6335 internal::Matcher<UsingShadowDecl>, InnerMatcher)namespace internal { class matcher_hasAnyUsingShadowDecl0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
BaseUsingDecl> { public: explicit matcher_hasAnyUsingShadowDecl0Matcher
( internal::Matcher<UsingShadowDecl> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const BaseUsingDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<UsingShadowDecl
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<BaseUsingDecl> hasAnyUsingShadowDecl( internal
::Matcher<UsingShadowDecl> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasAnyUsingShadowDecl0Matcher(InnerMatcher)); } typedef
::clang::ast_matchers::internal::Matcher<BaseUsingDecl>
( &hasAnyUsingShadowDecl_Type0)(internal::Matcher<UsingShadowDecl
> const &InnerMatcher); inline bool internal::matcher_hasAnyUsingShadowDecl0Matcher
::matches( const BaseUsingDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
6336 return matchesFirstInPointerRange(InnerMatcher, Node.shadow_begin(),
6337 Node.shadow_end(), Finder,
6338 Builder) != Node.shadow_end();
6339}
6340
6341/// Matches a using shadow declaration where the target declaration is
6342/// matched by the given matcher.
6343///
6344/// Given
6345/// \code
6346/// namespace X { int a; void b(); }
6347/// using X::a;
6348/// using X::b;
6349/// \endcode
6350/// usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(functionDecl())))
6351/// matches \code using X::b \endcode
6352/// but not \code using X::a \endcode
6353AST_MATCHER_P(UsingShadowDecl, hasTargetDecl,namespace internal { class matcher_hasTargetDecl0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<UsingShadowDecl
> { public: explicit matcher_hasTargetDecl0Matcher( internal
::Matcher<NamedDecl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const UsingShadowDecl &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<NamedDecl>
InnerMatcher; }; } inline ::clang::ast_matchers::internal::Matcher
<UsingShadowDecl> hasTargetDecl( internal::Matcher<NamedDecl
> const &InnerMatcher) { return ::clang::ast_matchers::
internal::makeMatcher( new internal::matcher_hasTargetDecl0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<UsingShadowDecl> ( &hasTargetDecl_Type0)(internal::
Matcher<NamedDecl> const &InnerMatcher); inline bool
internal::matcher_hasTargetDecl0Matcher::matches( const UsingShadowDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
6354 internal::Matcher<NamedDecl>, InnerMatcher)namespace internal { class matcher_hasTargetDecl0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<UsingShadowDecl
> { public: explicit matcher_hasTargetDecl0Matcher( internal
::Matcher<NamedDecl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const UsingShadowDecl &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<NamedDecl>
InnerMatcher; }; } inline ::clang::ast_matchers::internal::Matcher
<UsingShadowDecl> hasTargetDecl( internal::Matcher<NamedDecl
> const &InnerMatcher) { return ::clang::ast_matchers::
internal::makeMatcher( new internal::matcher_hasTargetDecl0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<UsingShadowDecl> ( &hasTargetDecl_Type0)(internal::
Matcher<NamedDecl> const &InnerMatcher); inline bool
internal::matcher_hasTargetDecl0Matcher::matches( const UsingShadowDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
6355 return InnerMatcher.matches(*Node.getTargetDecl(), Finder, Builder);
6356}
6357
6358/// Matches template instantiations of function, class, or static
6359/// member variable template instantiations.
6360///
6361/// Given
6362/// \code
6363/// template <typename T> class X {}; class A {}; X<A> x;
6364/// \endcode
6365/// or
6366/// \code
6367/// template <typename T> class X {}; class A {}; template class X<A>;
6368/// \endcode
6369/// or
6370/// \code
6371/// template <typename T> class X {}; class A {}; extern template class X<A>;
6372/// \endcode
6373/// cxxRecordDecl(hasName("::X"), isTemplateInstantiation())
6374/// matches the template instantiation of X<A>.
6375///
6376/// But given
6377/// \code
6378/// template <typename T> class X {}; class A {};
6379/// template <> class X<A> {}; X<A> x;
6380/// \endcode
6381/// cxxRecordDecl(hasName("::X"), isTemplateInstantiation())
6382/// does not match, as X<A> is an explicit template specialization.
6383///
6384/// Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
6385AST_POLYMORPHIC_MATCHER(isTemplateInstantiation,namespace internal { template <typename NodeType> class
matcher_isTemplateInstantiationMatcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isTemplateInstantiationMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, VarDecl, CXXRecordDecl>)> isTemplateInstantiation() {
return ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_isTemplateInstantiationMatcher, void(::clang
::ast_matchers::internal::TypeList<FunctionDecl, VarDecl, CXXRecordDecl
>)>(); } template <typename NodeType> bool internal
::matcher_isTemplateInstantiationMatcher<NodeType>::matches
( const NodeType &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
6386 AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, VarDecl,namespace internal { template <typename NodeType> class
matcher_isTemplateInstantiationMatcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isTemplateInstantiationMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, VarDecl, CXXRecordDecl>)> isTemplateInstantiation() {
return ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_isTemplateInstantiationMatcher, void(::clang
::ast_matchers::internal::TypeList<FunctionDecl, VarDecl, CXXRecordDecl
>)>(); } template <typename NodeType> bool internal
::matcher_isTemplateInstantiationMatcher<NodeType>::matches
( const NodeType &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
6387 CXXRecordDecl))namespace internal { template <typename NodeType> class
matcher_isTemplateInstantiationMatcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isTemplateInstantiationMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, VarDecl, CXXRecordDecl>)> isTemplateInstantiation() {
return ::clang::ast_matchers::internal::PolymorphicMatcher<
internal::matcher_isTemplateInstantiationMatcher, void(::clang
::ast_matchers::internal::TypeList<FunctionDecl, VarDecl, CXXRecordDecl
>)>(); } template <typename NodeType> bool internal
::matcher_isTemplateInstantiationMatcher<NodeType>::matches
( const NodeType &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
6388 return (Node.getTemplateSpecializationKind() == TSK_ImplicitInstantiation ||
6389 Node.getTemplateSpecializationKind() ==
6390 TSK_ExplicitInstantiationDefinition ||
6391 Node.getTemplateSpecializationKind() ==
6392 TSK_ExplicitInstantiationDeclaration);
6393}
6394
6395/// Matches declarations that are template instantiations or are inside
6396/// template instantiations.
6397///
6398/// Given
6399/// \code
6400/// template<typename T> void A(T t) { T i; }
6401/// A(0);
6402/// A(0U);
6403/// \endcode
6404/// functionDecl(isInstantiated())
6405/// matches 'A(int) {...};' and 'A(unsigned) {...}'.
6406AST_MATCHER_FUNCTION(internal::Matcher<Decl>, isInstantiated)inline internal::Matcher<Decl> isInstantiated_getInstance
(); inline internal::Matcher<Decl> isInstantiated() { return
::clang::ast_matchers::internal::MemoizedMatcher< internal
::Matcher<Decl>, isInstantiated_getInstance>::getInstance
(); } inline internal::Matcher<Decl> isInstantiated_getInstance
()
{
6407 auto IsInstantiation = decl(anyOf(cxxRecordDecl(isTemplateInstantiation()),
6408 functionDecl(isTemplateInstantiation())));
6409 return decl(anyOf(IsInstantiation, hasAncestor(IsInstantiation)));
6410}
6411
6412/// Matches statements inside of a template instantiation.
6413///
6414/// Given
6415/// \code
6416/// int j;
6417/// template<typename T> void A(T t) { T i; j += 42;}
6418/// A(0);
6419/// A(0U);
6420/// \endcode
6421/// declStmt(isInTemplateInstantiation())
6422/// matches 'int i;' and 'unsigned i'.
6423/// unless(stmt(isInTemplateInstantiation()))
6424/// will NOT match j += 42; as it's shared between the template definition and
6425/// instantiation.
6426AST_MATCHER_FUNCTION(internal::Matcher<Stmt>, isInTemplateInstantiation)inline internal::Matcher<Stmt> isInTemplateInstantiation_getInstance
(); inline internal::Matcher<Stmt> isInTemplateInstantiation
() { return ::clang::ast_matchers::internal::MemoizedMatcher<
internal::Matcher<Stmt>, isInTemplateInstantiation_getInstance
>::getInstance(); } inline internal::Matcher<Stmt> isInTemplateInstantiation_getInstance
()
{
6427 return stmt(
6428 hasAncestor(decl(anyOf(cxxRecordDecl(isTemplateInstantiation()),
6429 functionDecl(isTemplateInstantiation())))));
6430}
6431
6432/// Matches explicit template specializations of function, class, or
6433/// static member variable template instantiations.
6434///
6435/// Given
6436/// \code
6437/// template<typename T> void A(T t) { }
6438/// template<> void A(int N) { }
6439/// \endcode
6440/// functionDecl(isExplicitTemplateSpecialization())
6441/// matches the specialization A<int>().
6442///
6443/// Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
6444AST_POLYMORPHIC_MATCHER(isExplicitTemplateSpecialization,namespace internal { template <typename NodeType> class
matcher_isExplicitTemplateSpecializationMatcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_isExplicitTemplateSpecializationMatcher, void(::clang
::ast_matchers::internal::TypeList<FunctionDecl, VarDecl, CXXRecordDecl
>)> isExplicitTemplateSpecialization() { return ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_isExplicitTemplateSpecializationMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, VarDecl, CXXRecordDecl>)>(); } template <typename NodeType
> bool internal::matcher_isExplicitTemplateSpecializationMatcher
<NodeType>::matches( const NodeType &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
6445 AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, VarDecl,namespace internal { template <typename NodeType> class
matcher_isExplicitTemplateSpecializationMatcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_isExplicitTemplateSpecializationMatcher, void(::clang
::ast_matchers::internal::TypeList<FunctionDecl, VarDecl, CXXRecordDecl
>)> isExplicitTemplateSpecialization() { return ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_isExplicitTemplateSpecializationMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, VarDecl, CXXRecordDecl>)>(); } template <typename NodeType
> bool internal::matcher_isExplicitTemplateSpecializationMatcher
<NodeType>::matches( const NodeType &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
6446 CXXRecordDecl))namespace internal { template <typename NodeType> class
matcher_isExplicitTemplateSpecializationMatcher : public ::clang
::ast_matchers::internal::MatcherInterface<NodeType> { public
: bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_isExplicitTemplateSpecializationMatcher, void(::clang
::ast_matchers::internal::TypeList<FunctionDecl, VarDecl, CXXRecordDecl
>)> isExplicitTemplateSpecialization() { return ::clang
::ast_matchers::internal::PolymorphicMatcher< internal::matcher_isExplicitTemplateSpecializationMatcher
, void(::clang::ast_matchers::internal::TypeList<FunctionDecl
, VarDecl, CXXRecordDecl>)>(); } template <typename NodeType
> bool internal::matcher_isExplicitTemplateSpecializationMatcher
<NodeType>::matches( const NodeType &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const
{
6447 return (Node.getTemplateSpecializationKind() == TSK_ExplicitSpecialization);
6448}
6449
6450/// Matches \c TypeLocs for which the given inner
6451/// QualType-matcher matches.
6452AST_MATCHER_FUNCTION_P_OVERLOAD(internal::BindableMatcher<TypeLoc>, loc,inline internal::BindableMatcher<TypeLoc> loc(internal::
Matcher<QualType> const &InnerMatcher); typedef internal
::BindableMatcher<TypeLoc> (&loc_Type0)(internal::Matcher
<QualType> const &); inline internal::BindableMatcher
<TypeLoc> loc(internal::Matcher<QualType> const &
InnerMatcher)
6453 internal::Matcher<QualType>, InnerMatcher, 0)inline internal::BindableMatcher<TypeLoc> loc(internal::
Matcher<QualType> const &InnerMatcher); typedef internal
::BindableMatcher<TypeLoc> (&loc_Type0)(internal::Matcher
<QualType> const &); inline internal::BindableMatcher
<TypeLoc> loc(internal::Matcher<QualType> const &
InnerMatcher)
{
6454 return internal::BindableMatcher<TypeLoc>(
6455 new internal::TypeLocTypeMatcher(InnerMatcher));
6456}
6457
6458/// Matches `QualifiedTypeLoc`s in the clang AST.
6459///
6460/// Given
6461/// \code
6462/// const int x = 0;
6463/// \endcode
6464/// qualifiedTypeLoc()
6465/// matches `const int`.
6466extern const internal::VariadicDynCastAllOfMatcher<TypeLoc, QualifiedTypeLoc>
6467 qualifiedTypeLoc;
6468
6469/// Matches `QualifiedTypeLoc`s that have an unqualified `TypeLoc` matching
6470/// `InnerMatcher`.
6471///
6472/// Given
6473/// \code
6474/// int* const x;
6475/// const int y;
6476/// \endcode
6477/// qualifiedTypeLoc(hasUnqualifiedLoc(pointerTypeLoc()))
6478/// matches the `TypeLoc` of the variable declaration of `x`, but not `y`.
6479AST_MATCHER_P(QualifiedTypeLoc, hasUnqualifiedLoc, internal::Matcher<TypeLoc>,namespace internal { class matcher_hasUnqualifiedLoc0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
QualifiedTypeLoc> { public: explicit matcher_hasUnqualifiedLoc0Matcher
( internal::Matcher<TypeLoc> const &AInnerMatcher) :
InnerMatcher(AInnerMatcher) {} bool matches(const QualifiedTypeLoc
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<TypeLoc
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<QualifiedTypeLoc> hasUnqualifiedLoc( internal
::Matcher<TypeLoc> const &InnerMatcher) { return ::
clang::ast_matchers::internal::makeMatcher( new internal::matcher_hasUnqualifiedLoc0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<QualifiedTypeLoc> ( &hasUnqualifiedLoc_Type0)(internal
::Matcher<TypeLoc> const &InnerMatcher); inline bool
internal::matcher_hasUnqualifiedLoc0Matcher::matches( const QualifiedTypeLoc
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
6480 InnerMatcher)namespace internal { class matcher_hasUnqualifiedLoc0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
QualifiedTypeLoc> { public: explicit matcher_hasUnqualifiedLoc0Matcher
( internal::Matcher<TypeLoc> const &AInnerMatcher) :
InnerMatcher(AInnerMatcher) {} bool matches(const QualifiedTypeLoc
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<TypeLoc
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<QualifiedTypeLoc> hasUnqualifiedLoc( internal
::Matcher<TypeLoc> const &InnerMatcher) { return ::
clang::ast_matchers::internal::makeMatcher( new internal::matcher_hasUnqualifiedLoc0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<QualifiedTypeLoc> ( &hasUnqualifiedLoc_Type0)(internal
::Matcher<TypeLoc> const &InnerMatcher); inline bool
internal::matcher_hasUnqualifiedLoc0Matcher::matches( const QualifiedTypeLoc
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
6481 return InnerMatcher.matches(Node.getUnqualifiedLoc(), Finder, Builder);
6482}
6483
6484/// Matches a function declared with the specified return `TypeLoc`.
6485///
6486/// Given
6487/// \code
6488/// int f() { return 5; }
6489/// void g() {}
6490/// \endcode
6491/// functionDecl(hasReturnTypeLoc(loc(asString("int"))))
6492/// matches the declaration of `f`, but not `g`.
6493AST_MATCHER_P(FunctionDecl, hasReturnTypeLoc, internal::Matcher<TypeLoc>,namespace internal { class matcher_hasReturnTypeLoc0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
FunctionDecl> { public: explicit matcher_hasReturnTypeLoc0Matcher
( internal::Matcher<TypeLoc> const &AReturnMatcher)
: ReturnMatcher(AReturnMatcher) {} bool matches(const FunctionDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<TypeLoc
> ReturnMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<FunctionDecl> hasReturnTypeLoc( internal::Matcher
<TypeLoc> const &ReturnMatcher) { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_hasReturnTypeLoc0Matcher
(ReturnMatcher)); } typedef ::clang::ast_matchers::internal::
Matcher<FunctionDecl> ( &hasReturnTypeLoc_Type0)(internal
::Matcher<TypeLoc> const &ReturnMatcher); inline bool
internal::matcher_hasReturnTypeLoc0Matcher::matches( const FunctionDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
6494 ReturnMatcher)namespace internal { class matcher_hasReturnTypeLoc0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
FunctionDecl> { public: explicit matcher_hasReturnTypeLoc0Matcher
( internal::Matcher<TypeLoc> const &AReturnMatcher)
: ReturnMatcher(AReturnMatcher) {} bool matches(const FunctionDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<TypeLoc
> ReturnMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<FunctionDecl> hasReturnTypeLoc( internal::Matcher
<TypeLoc> const &ReturnMatcher) { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_hasReturnTypeLoc0Matcher
(ReturnMatcher)); } typedef ::clang::ast_matchers::internal::
Matcher<FunctionDecl> ( &hasReturnTypeLoc_Type0)(internal
::Matcher<TypeLoc> const &ReturnMatcher); inline bool
internal::matcher_hasReturnTypeLoc0Matcher::matches( const FunctionDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
6495 auto Loc = Node.getFunctionTypeLoc();
6496 return Loc && ReturnMatcher.matches(Loc.getReturnLoc(), Finder, Builder);
6497}
6498
6499/// Matches pointer `TypeLoc`s.
6500///
6501/// Given
6502/// \code
6503/// int* x;
6504/// \endcode
6505/// pointerTypeLoc()
6506/// matches `int*`.
6507extern const internal::VariadicDynCastAllOfMatcher<TypeLoc, PointerTypeLoc>
6508 pointerTypeLoc;
6509
6510/// Matches pointer `TypeLoc`s that have a pointee `TypeLoc` matching
6511/// `PointeeMatcher`.
6512///
6513/// Given
6514/// \code
6515/// int* x;
6516/// \endcode
6517/// pointerTypeLoc(hasPointeeLoc(loc(asString("int"))))
6518/// matches `int*`.
6519AST_MATCHER_P(PointerTypeLoc, hasPointeeLoc, internal::Matcher<TypeLoc>,namespace internal { class matcher_hasPointeeLoc0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<PointerTypeLoc
> { public: explicit matcher_hasPointeeLoc0Matcher( internal
::Matcher<TypeLoc> const &APointeeMatcher) : PointeeMatcher
(APointeeMatcher) {} bool matches(const PointerTypeLoc &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<TypeLoc> PointeeMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<PointerTypeLoc
> hasPointeeLoc( internal::Matcher<TypeLoc> const &
PointeeMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_hasPointeeLoc0Matcher(PointeeMatcher)
); } typedef ::clang::ast_matchers::internal::Matcher<PointerTypeLoc
> ( &hasPointeeLoc_Type0)(internal::Matcher<TypeLoc
> const &PointeeMatcher); inline bool internal::matcher_hasPointeeLoc0Matcher
::matches( const PointerTypeLoc &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
6520 PointeeMatcher)namespace internal { class matcher_hasPointeeLoc0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<PointerTypeLoc
> { public: explicit matcher_hasPointeeLoc0Matcher( internal
::Matcher<TypeLoc> const &APointeeMatcher) : PointeeMatcher
(APointeeMatcher) {} bool matches(const PointerTypeLoc &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<TypeLoc> PointeeMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<PointerTypeLoc
> hasPointeeLoc( internal::Matcher<TypeLoc> const &
PointeeMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_hasPointeeLoc0Matcher(PointeeMatcher)
); } typedef ::clang::ast_matchers::internal::Matcher<PointerTypeLoc
> ( &hasPointeeLoc_Type0)(internal::Matcher<TypeLoc
> const &PointeeMatcher); inline bool internal::matcher_hasPointeeLoc0Matcher
::matches( const PointerTypeLoc &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
6521 return PointeeMatcher.matches(Node.getPointeeLoc(), Finder, Builder);
6522}
6523
6524/// Matches reference `TypeLoc`s.
6525///
6526/// Given
6527/// \code
6528/// int x = 3;
6529/// int& l = x;
6530/// int&& r = 3;
6531/// \endcode
6532/// referenceTypeLoc()
6533/// matches `int&` and `int&&`.
6534extern const internal::VariadicDynCastAllOfMatcher<TypeLoc, ReferenceTypeLoc>
6535 referenceTypeLoc;
6536
6537/// Matches reference `TypeLoc`s that have a referent `TypeLoc` matching
6538/// `ReferentMatcher`.
6539///
6540/// Given
6541/// \code
6542/// int x = 3;
6543/// int& xx = x;
6544/// \endcode
6545/// referenceTypeLoc(hasReferentLoc(loc(asString("int"))))
6546/// matches `int&`.
6547AST_MATCHER_P(ReferenceTypeLoc, hasReferentLoc, internal::Matcher<TypeLoc>,namespace internal { class matcher_hasReferentLoc0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<ReferenceTypeLoc
> { public: explicit matcher_hasReferentLoc0Matcher( internal
::Matcher<TypeLoc> const &AReferentMatcher) : ReferentMatcher
(AReferentMatcher) {} bool matches(const ReferenceTypeLoc &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<TypeLoc> ReferentMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<ReferenceTypeLoc
> hasReferentLoc( internal::Matcher<TypeLoc> const &
ReferentMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_hasReferentLoc0Matcher(ReferentMatcher
)); } typedef ::clang::ast_matchers::internal::Matcher<ReferenceTypeLoc
> ( &hasReferentLoc_Type0)(internal::Matcher<TypeLoc
> const &ReferentMatcher); inline bool internal::matcher_hasReferentLoc0Matcher
::matches( const ReferenceTypeLoc &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
6548 ReferentMatcher)namespace internal { class matcher_hasReferentLoc0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<ReferenceTypeLoc
> { public: explicit matcher_hasReferentLoc0Matcher( internal
::Matcher<TypeLoc> const &AReferentMatcher) : ReferentMatcher
(AReferentMatcher) {} bool matches(const ReferenceTypeLoc &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<TypeLoc> ReferentMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<ReferenceTypeLoc
> hasReferentLoc( internal::Matcher<TypeLoc> const &
ReferentMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_hasReferentLoc0Matcher(ReferentMatcher
)); } typedef ::clang::ast_matchers::internal::Matcher<ReferenceTypeLoc
> ( &hasReferentLoc_Type0)(internal::Matcher<TypeLoc
> const &ReferentMatcher); inline bool internal::matcher_hasReferentLoc0Matcher
::matches( const ReferenceTypeLoc &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
6549 return ReferentMatcher.matches(Node.getPointeeLoc(), Finder, Builder);
6550}
6551
6552/// Matches template specialization `TypeLoc`s.
6553///
6554/// Given
6555/// \code
6556/// template <typename T> class C {};
6557/// C<char> var;
6558/// \endcode
6559/// varDecl(hasTypeLoc(templateSpecializationTypeLoc(typeLoc())))
6560/// matches `C<char> var`.
6561extern const internal::VariadicDynCastAllOfMatcher<
6562 TypeLoc, TemplateSpecializationTypeLoc>
6563 templateSpecializationTypeLoc;
6564
6565/// Matches template specialization `TypeLoc`s that have at least one
6566/// `TemplateArgumentLoc` matching the given `InnerMatcher`.
6567///
6568/// Given
6569/// \code
6570/// template<typename T> class A {};
6571/// A<int> a;
6572/// \endcode
6573/// varDecl(hasTypeLoc(templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
6574/// hasTypeLoc(loc(asString("int")))))))
6575/// matches `A<int> a`.
6576AST_MATCHER_P(TemplateSpecializationTypeLoc, hasAnyTemplateArgumentLoc,namespace internal { class matcher_hasAnyTemplateArgumentLoc0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
TemplateSpecializationTypeLoc> { public: explicit matcher_hasAnyTemplateArgumentLoc0Matcher
( internal::Matcher<TemplateArgumentLoc> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const TemplateSpecializationTypeLoc
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<TemplateArgumentLoc
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<TemplateSpecializationTypeLoc> hasAnyTemplateArgumentLoc
( internal::Matcher<TemplateArgumentLoc> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_hasAnyTemplateArgumentLoc0Matcher(InnerMatcher)); }
typedef ::clang::ast_matchers::internal::Matcher<TemplateSpecializationTypeLoc
> ( &hasAnyTemplateArgumentLoc_Type0)(internal::Matcher
<TemplateArgumentLoc> const &InnerMatcher); inline bool
internal::matcher_hasAnyTemplateArgumentLoc0Matcher::matches
( const TemplateSpecializationTypeLoc &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
6577 internal::Matcher<TemplateArgumentLoc>, InnerMatcher)namespace internal { class matcher_hasAnyTemplateArgumentLoc0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
TemplateSpecializationTypeLoc> { public: explicit matcher_hasAnyTemplateArgumentLoc0Matcher
( internal::Matcher<TemplateArgumentLoc> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const TemplateSpecializationTypeLoc
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<TemplateArgumentLoc
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<TemplateSpecializationTypeLoc> hasAnyTemplateArgumentLoc
( internal::Matcher<TemplateArgumentLoc> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_hasAnyTemplateArgumentLoc0Matcher(InnerMatcher)); }
typedef ::clang::ast_matchers::internal::Matcher<TemplateSpecializationTypeLoc
> ( &hasAnyTemplateArgumentLoc_Type0)(internal::Matcher
<TemplateArgumentLoc> const &InnerMatcher); inline bool
internal::matcher_hasAnyTemplateArgumentLoc0Matcher::matches
( const TemplateSpecializationTypeLoc &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
6578 for (unsigned Index = 0, N = Node.getNumArgs(); Index < N; ++Index) {
6579 clang::ast_matchers::internal::BoundNodesTreeBuilder Result(*Builder);
6580 if (InnerMatcher.matches(Node.getArgLoc(Index), Finder, &Result)) {
6581 *Builder = std::move(Result);
6582 return true;
6583 }
6584 }
6585 return false;
6586}
6587
6588/// Matches template specialization `TypeLoc`s where the n'th
6589/// `TemplateArgumentLoc` matches the given `InnerMatcher`.
6590///
6591/// Given
6592/// \code
6593/// template<typename T, typename U> class A {};
6594/// A<double, int> b;
6595/// A<int, double> c;
6596/// \endcode
6597/// varDecl(hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(0,
6598/// hasTypeLoc(loc(asString("double")))))))
6599/// matches `A<double, int> b`, but not `A<int, double> c`.
6600AST_POLYMORPHIC_MATCHER_P2(namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasTemplateArgumentLoc0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasTemplateArgumentLoc0Matcher
(unsigned const &AIndex, internal::Matcher<TemplateArgumentLoc
> const &AInnerMatcher) : Index(AIndex), InnerMatcher(
AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: unsigned Index; internal::Matcher<TemplateArgumentLoc>
InnerMatcher; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasTemplateArgumentLoc0Matcher, void(::
clang::ast_matchers::internal::TypeList<DeclRefExpr, TemplateSpecializationTypeLoc
>), unsigned, internal::Matcher<TemplateArgumentLoc>
> hasTemplateArgumentLoc(unsigned const &Index, internal
::Matcher<TemplateArgumentLoc> const &InnerMatcher)
{ return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasTemplateArgumentLoc0Matcher, void(::
clang::ast_matchers::internal::TypeList<DeclRefExpr, TemplateSpecializationTypeLoc
>), unsigned, internal::Matcher<TemplateArgumentLoc>
>(Index, InnerMatcher); } typedef ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_hasTemplateArgumentLoc0Matcher
, void(::clang::ast_matchers::internal::TypeList<DeclRefExpr
, TemplateSpecializationTypeLoc>), unsigned, internal::Matcher
<TemplateArgumentLoc> > (&hasTemplateArgumentLoc_Type0
)( unsigned const &Index, internal::Matcher<TemplateArgumentLoc
> const &InnerMatcher); template <typename NodeType
, typename ParamT1, typename ParamT2> bool internal::matcher_hasTemplateArgumentLoc0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
6601 hasTemplateArgumentLoc,namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasTemplateArgumentLoc0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasTemplateArgumentLoc0Matcher
(unsigned const &AIndex, internal::Matcher<TemplateArgumentLoc
> const &AInnerMatcher) : Index(AIndex), InnerMatcher(
AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: unsigned Index; internal::Matcher<TemplateArgumentLoc>
InnerMatcher; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasTemplateArgumentLoc0Matcher, void(::
clang::ast_matchers::internal::TypeList<DeclRefExpr, TemplateSpecializationTypeLoc
>), unsigned, internal::Matcher<TemplateArgumentLoc>
> hasTemplateArgumentLoc(unsigned const &Index, internal
::Matcher<TemplateArgumentLoc> const &InnerMatcher)
{ return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasTemplateArgumentLoc0Matcher, void(::
clang::ast_matchers::internal::TypeList<DeclRefExpr, TemplateSpecializationTypeLoc
>), unsigned, internal::Matcher<TemplateArgumentLoc>
>(Index, InnerMatcher); } typedef ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_hasTemplateArgumentLoc0Matcher
, void(::clang::ast_matchers::internal::TypeList<DeclRefExpr
, TemplateSpecializationTypeLoc>), unsigned, internal::Matcher
<TemplateArgumentLoc> > (&hasTemplateArgumentLoc_Type0
)( unsigned const &Index, internal::Matcher<TemplateArgumentLoc
> const &InnerMatcher); template <typename NodeType
, typename ParamT1, typename ParamT2> bool internal::matcher_hasTemplateArgumentLoc0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
6602 AST_POLYMORPHIC_SUPPORTED_TYPES(DeclRefExpr, TemplateSpecializationTypeLoc),namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasTemplateArgumentLoc0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasTemplateArgumentLoc0Matcher
(unsigned const &AIndex, internal::Matcher<TemplateArgumentLoc
> const &AInnerMatcher) : Index(AIndex), InnerMatcher(
AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: unsigned Index; internal::Matcher<TemplateArgumentLoc>
InnerMatcher; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasTemplateArgumentLoc0Matcher, void(::
clang::ast_matchers::internal::TypeList<DeclRefExpr, TemplateSpecializationTypeLoc
>), unsigned, internal::Matcher<TemplateArgumentLoc>
> hasTemplateArgumentLoc(unsigned const &Index, internal
::Matcher<TemplateArgumentLoc> const &InnerMatcher)
{ return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasTemplateArgumentLoc0Matcher, void(::
clang::ast_matchers::internal::TypeList<DeclRefExpr, TemplateSpecializationTypeLoc
>), unsigned, internal::Matcher<TemplateArgumentLoc>
>(Index, InnerMatcher); } typedef ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_hasTemplateArgumentLoc0Matcher
, void(::clang::ast_matchers::internal::TypeList<DeclRefExpr
, TemplateSpecializationTypeLoc>), unsigned, internal::Matcher
<TemplateArgumentLoc> > (&hasTemplateArgumentLoc_Type0
)( unsigned const &Index, internal::Matcher<TemplateArgumentLoc
> const &InnerMatcher); template <typename NodeType
, typename ParamT1, typename ParamT2> bool internal::matcher_hasTemplateArgumentLoc0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
6603 unsigned, Index, internal::Matcher<TemplateArgumentLoc>, InnerMatcher)namespace internal { template <typename NodeType, typename
ParamT1, typename ParamT2> class matcher_hasTemplateArgumentLoc0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: matcher_hasTemplateArgumentLoc0Matcher
(unsigned const &AIndex, internal::Matcher<TemplateArgumentLoc
> const &AInnerMatcher) : Index(AIndex), InnerMatcher(
AInnerMatcher) {} bool matches(const NodeType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: unsigned Index; internal::Matcher<TemplateArgumentLoc>
InnerMatcher; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasTemplateArgumentLoc0Matcher, void(::
clang::ast_matchers::internal::TypeList<DeclRefExpr, TemplateSpecializationTypeLoc
>), unsigned, internal::Matcher<TemplateArgumentLoc>
> hasTemplateArgumentLoc(unsigned const &Index, internal
::Matcher<TemplateArgumentLoc> const &InnerMatcher)
{ return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_hasTemplateArgumentLoc0Matcher, void(::
clang::ast_matchers::internal::TypeList<DeclRefExpr, TemplateSpecializationTypeLoc
>), unsigned, internal::Matcher<TemplateArgumentLoc>
>(Index, InnerMatcher); } typedef ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_hasTemplateArgumentLoc0Matcher
, void(::clang::ast_matchers::internal::TypeList<DeclRefExpr
, TemplateSpecializationTypeLoc>), unsigned, internal::Matcher
<TemplateArgumentLoc> > (&hasTemplateArgumentLoc_Type0
)( unsigned const &Index, internal::Matcher<TemplateArgumentLoc
> const &InnerMatcher); template <typename NodeType
, typename ParamT1, typename ParamT2> bool internal::matcher_hasTemplateArgumentLoc0Matcher
< NodeType, ParamT1, ParamT2>:: matches(const NodeType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
6604 return internal::MatchTemplateArgLocAt(Node, Index, InnerMatcher, Finder,
6605 Builder);
6606}
6607
6608/// Matches C or C++ elaborated `TypeLoc`s.
6609///
6610/// Given
6611/// \code
6612/// struct s {};
6613/// struct s ss;
6614/// \endcode
6615/// elaboratedTypeLoc()
6616/// matches the `TypeLoc` of the variable declaration of `ss`.
6617extern const internal::VariadicDynCastAllOfMatcher<TypeLoc, ElaboratedTypeLoc>
6618 elaboratedTypeLoc;
6619
6620/// Matches elaborated `TypeLoc`s that have a named `TypeLoc` matching
6621/// `InnerMatcher`.
6622///
6623/// Given
6624/// \code
6625/// template <typename T>
6626/// class C {};
6627/// class C<int> c;
6628///
6629/// class D {};
6630/// class D d;
6631/// \endcode
6632/// elaboratedTypeLoc(hasNamedTypeLoc(templateSpecializationTypeLoc()));
6633/// matches the `TypeLoc` of the variable declaration of `c`, but not `d`.
6634AST_MATCHER_P(ElaboratedTypeLoc, hasNamedTypeLoc, internal::Matcher<TypeLoc>,namespace internal { class matcher_hasNamedTypeLoc0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<ElaboratedTypeLoc
> { public: explicit matcher_hasNamedTypeLoc0Matcher( internal
::Matcher<TypeLoc> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const ElaboratedTypeLoc &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<TypeLoc> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<ElaboratedTypeLoc
> hasNamedTypeLoc( internal::Matcher<TypeLoc> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_hasNamedTypeLoc0Matcher(InnerMatcher)
); } typedef ::clang::ast_matchers::internal::Matcher<ElaboratedTypeLoc
> ( &hasNamedTypeLoc_Type0)(internal::Matcher<TypeLoc
> const &InnerMatcher); inline bool internal::matcher_hasNamedTypeLoc0Matcher
::matches( const ElaboratedTypeLoc &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
6635 InnerMatcher)namespace internal { class matcher_hasNamedTypeLoc0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<ElaboratedTypeLoc
> { public: explicit matcher_hasNamedTypeLoc0Matcher( internal
::Matcher<TypeLoc> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const ElaboratedTypeLoc &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<TypeLoc> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<ElaboratedTypeLoc
> hasNamedTypeLoc( internal::Matcher<TypeLoc> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_hasNamedTypeLoc0Matcher(InnerMatcher)
); } typedef ::clang::ast_matchers::internal::Matcher<ElaboratedTypeLoc
> ( &hasNamedTypeLoc_Type0)(internal::Matcher<TypeLoc
> const &InnerMatcher); inline bool internal::matcher_hasNamedTypeLoc0Matcher
::matches( const ElaboratedTypeLoc &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
6636 return InnerMatcher.matches(Node.getNamedTypeLoc(), Finder, Builder);
6637}
6638
6639/// Matches type \c bool.
6640///
6641/// Given
6642/// \code
6643/// struct S { bool func(); };
6644/// \endcode
6645/// functionDecl(returns(booleanType()))
6646/// matches "bool func();"
6647AST_MATCHER(Type, booleanType)namespace internal { class matcher_booleanTypeMatcher : public
::clang::ast_matchers::internal::MatcherInterface<Type>
{ public: explicit matcher_booleanTypeMatcher() = default; bool
matches(const Type &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::Matcher<Type> booleanType() { return ::clang::
ast_matchers::internal::makeMatcher( new internal::matcher_booleanTypeMatcher
()); } inline bool internal::matcher_booleanTypeMatcher::matches
( const Type &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
6648 return Node.isBooleanType();
6649}
6650
6651/// Matches type \c void.
6652///
6653/// Given
6654/// \code
6655/// struct S { void func(); };
6656/// \endcode
6657/// functionDecl(returns(voidType()))
6658/// matches "void func();"
6659AST_MATCHER(Type, voidType)namespace internal { class matcher_voidTypeMatcher : public ::
clang::ast_matchers::internal::MatcherInterface<Type> {
public: explicit matcher_voidTypeMatcher() = default; bool matches
(const Type &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::Matcher<Type> voidType() { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_voidTypeMatcher
()); } inline bool internal::matcher_voidTypeMatcher::matches
( const Type &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
6660 return Node.isVoidType();
6661}
6662
6663template <typename NodeType>
6664using AstTypeMatcher = internal::VariadicDynCastAllOfMatcher<Type, NodeType>;
6665
6666/// Matches builtin Types.
6667///
6668/// Given
6669/// \code
6670/// struct A {};
6671/// A a;
6672/// int b;
6673/// float c;
6674/// bool d;
6675/// \endcode
6676/// builtinType()
6677/// matches "int b", "float c" and "bool d"
6678extern const AstTypeMatcher<BuiltinType> builtinType;
6679
6680/// Matches all kinds of arrays.
6681///
6682/// Given
6683/// \code
6684/// int a[] = { 2, 3 };
6685/// int b[4];
6686/// void f() { int c[a[0]]; }
6687/// \endcode
6688/// arrayType()
6689/// matches "int a[]", "int b[4]" and "int c[a[0]]";
6690extern const AstTypeMatcher<ArrayType> arrayType;
6691
6692/// Matches C99 complex types.
6693///
6694/// Given
6695/// \code
6696/// _Complex float f;
6697/// \endcode
6698/// complexType()
6699/// matches "_Complex float f"
6700extern const AstTypeMatcher<ComplexType> complexType;
6701
6702/// Matches any real floating-point type (float, double, long double).
6703///
6704/// Given
6705/// \code
6706/// int i;
6707/// float f;
6708/// \endcode
6709/// realFloatingPointType()
6710/// matches "float f" but not "int i"
6711AST_MATCHER(Type, realFloatingPointType)namespace internal { class matcher_realFloatingPointTypeMatcher
: public ::clang::ast_matchers::internal::MatcherInterface<
Type> { public: explicit matcher_realFloatingPointTypeMatcher
() = default; bool matches(const Type &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<Type> realFloatingPointType
() { return ::clang::ast_matchers::internal::makeMatcher( new
internal::matcher_realFloatingPointTypeMatcher()); } inline bool
internal::matcher_realFloatingPointTypeMatcher::matches( const
Type &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
6712 return Node.isRealFloatingType();
6713}
6714
6715/// Matches arrays and C99 complex types that have a specific element
6716/// type.
6717///
6718/// Given
6719/// \code
6720/// struct A {};
6721/// A a[7];
6722/// int b[7];
6723/// \endcode
6724/// arrayType(hasElementType(builtinType()))
6725/// matches "int b[7]"
6726///
6727/// Usable as: Matcher<ArrayType>, Matcher<ComplexType>
6728AST_TYPELOC_TRAVERSE_MATCHER_DECL(hasElementType, getElement,namespace internal { template <typename T> struct TypeLocMatcherhasElementTypeGetter
{ static TypeLoc (T::*value())() const { return &T::getElementLoc
; } }; } extern const ::clang::ast_matchers::internal:: TypeTraversePolymorphicMatcher
< TypeLoc, ::clang::ast_matchers::internal:: TypeLocMatcherhasElementTypeGetter
, ::clang::ast_matchers::internal::TypeLocTraverseMatcher, void
(::clang::ast_matchers::internal::TypeList<ArrayType, ComplexType
>)>::Func hasElementTypeLoc; namespace internal { template
<typename T> struct TypeMatcherhasElementTypeGetter { static
QualType (T::*value())() const { return &T::getElementType
; } }; } extern const ::clang::ast_matchers::internal:: TypeTraversePolymorphicMatcher
< QualType, ::clang::ast_matchers::internal::TypeMatcherhasElementTypeGetter
, ::clang::ast_matchers::internal::TypeTraverseMatcher, void(
::clang::ast_matchers::internal::TypeList<ArrayType, ComplexType
>)>::Func hasElementType
6729 AST_POLYMORPHIC_SUPPORTED_TYPES(ArrayType,namespace internal { template <typename T> struct TypeLocMatcherhasElementTypeGetter
{ static TypeLoc (T::*value())() const { return &T::getElementLoc
; } }; } extern const ::clang::ast_matchers::internal:: TypeTraversePolymorphicMatcher
< TypeLoc, ::clang::ast_matchers::internal:: TypeLocMatcherhasElementTypeGetter
, ::clang::ast_matchers::internal::TypeLocTraverseMatcher, void
(::clang::ast_matchers::internal::TypeList<ArrayType, ComplexType
>)>::Func hasElementTypeLoc; namespace internal { template
<typename T> struct TypeMatcherhasElementTypeGetter { static
QualType (T::*value())() const { return &T::getElementType
; } }; } extern const ::clang::ast_matchers::internal:: TypeTraversePolymorphicMatcher
< QualType, ::clang::ast_matchers::internal::TypeMatcherhasElementTypeGetter
, ::clang::ast_matchers::internal::TypeTraverseMatcher, void(
::clang::ast_matchers::internal::TypeList<ArrayType, ComplexType
>)>::Func hasElementType
6730 ComplexType))namespace internal { template <typename T> struct TypeLocMatcherhasElementTypeGetter
{ static TypeLoc (T::*value())() const { return &T::getElementLoc
; } }; } extern const ::clang::ast_matchers::internal:: TypeTraversePolymorphicMatcher
< TypeLoc, ::clang::ast_matchers::internal:: TypeLocMatcherhasElementTypeGetter
, ::clang::ast_matchers::internal::TypeLocTraverseMatcher, void
(::clang::ast_matchers::internal::TypeList<ArrayType, ComplexType
>)>::Func hasElementTypeLoc; namespace internal { template
<typename T> struct TypeMatcherhasElementTypeGetter { static
QualType (T::*value())() const { return &T::getElementType
; } }; } extern const ::clang::ast_matchers::internal:: TypeTraversePolymorphicMatcher
< QualType, ::clang::ast_matchers::internal::TypeMatcherhasElementTypeGetter
, ::clang::ast_matchers::internal::TypeTraverseMatcher, void(
::clang::ast_matchers::internal::TypeList<ArrayType, ComplexType
>)>::Func hasElementType
;
6731
6732/// Matches C arrays with a specified constant size.
6733///
6734/// Given
6735/// \code
6736/// void() {
6737/// int a[2];
6738/// int b[] = { 2, 3 };
6739/// int c[b[0]];
6740/// }
6741/// \endcode
6742/// constantArrayType()
6743/// matches "int a[2]"
6744extern const AstTypeMatcher<ConstantArrayType> constantArrayType;
6745
6746/// Matches nodes that have the specified size.
6747///
6748/// Given
6749/// \code
6750/// int a[42];
6751/// int b[2 * 21];
6752/// int c[41], d[43];
6753/// char *s = "abcd";
6754/// wchar_t *ws = L"abcd";
6755/// char *w = "a";
6756/// \endcode
6757/// constantArrayType(hasSize(42))
6758/// matches "int a[42]" and "int b[2 * 21]"
6759/// stringLiteral(hasSize(4))
6760/// matches "abcd", L"abcd"
6761AST_POLYMORPHIC_MATCHER_P(hasSize,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasSize0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasSize0Matcher( unsigned const &AN) : N(AN) {} bool
matches(const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; }; } inline ::
clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasSize0Matcher, void(::clang::ast_matchers::internal
::TypeList<ConstantArrayType, StringLiteral>), unsigned
> hasSize(unsigned const &N) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasSize0Matcher
, void(::clang::ast_matchers::internal::TypeList<ConstantArrayType
, StringLiteral>), unsigned>(N); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasSize0Matcher
, void(::clang::ast_matchers::internal::TypeList<ConstantArrayType
, StringLiteral>), unsigned> (&hasSize_Type0)(unsigned
const &N); template <typename NodeType, typename ParamT
> bool internal:: matcher_hasSize0Matcher<NodeType, ParamT
>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
6762 AST_POLYMORPHIC_SUPPORTED_TYPES(ConstantArrayType,namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasSize0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasSize0Matcher( unsigned const &AN) : N(AN) {} bool
matches(const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; }; } inline ::
clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasSize0Matcher, void(::clang::ast_matchers::internal
::TypeList<ConstantArrayType, StringLiteral>), unsigned
> hasSize(unsigned const &N) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasSize0Matcher
, void(::clang::ast_matchers::internal::TypeList<ConstantArrayType
, StringLiteral>), unsigned>(N); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasSize0Matcher
, void(::clang::ast_matchers::internal::TypeList<ConstantArrayType
, StringLiteral>), unsigned> (&hasSize_Type0)(unsigned
const &N); template <typename NodeType, typename ParamT
> bool internal:: matcher_hasSize0Matcher<NodeType, ParamT
>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
6763 StringLiteral),namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasSize0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasSize0Matcher( unsigned const &AN) : N(AN) {} bool
matches(const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; }; } inline ::
clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasSize0Matcher, void(::clang::ast_matchers::internal
::TypeList<ConstantArrayType, StringLiteral>), unsigned
> hasSize(unsigned const &N) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasSize0Matcher
, void(::clang::ast_matchers::internal::TypeList<ConstantArrayType
, StringLiteral>), unsigned>(N); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasSize0Matcher
, void(::clang::ast_matchers::internal::TypeList<ConstantArrayType
, StringLiteral>), unsigned> (&hasSize_Type0)(unsigned
const &N); template <typename NodeType, typename ParamT
> bool internal:: matcher_hasSize0Matcher<NodeType, ParamT
>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
6764 unsigned, N)namespace internal { template <typename NodeType, typename
ParamT> class matcher_hasSize0Matcher : public ::clang::ast_matchers
::internal::MatcherInterface<NodeType> { public: explicit
matcher_hasSize0Matcher( unsigned const &AN) : N(AN) {} bool
matches(const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; }; } inline ::
clang::ast_matchers::internal::PolymorphicMatcher< internal
::matcher_hasSize0Matcher, void(::clang::ast_matchers::internal
::TypeList<ConstantArrayType, StringLiteral>), unsigned
> hasSize(unsigned const &N) { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasSize0Matcher
, void(::clang::ast_matchers::internal::TypeList<ConstantArrayType
, StringLiteral>), unsigned>(N); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_hasSize0Matcher
, void(::clang::ast_matchers::internal::TypeList<ConstantArrayType
, StringLiteral>), unsigned> (&hasSize_Type0)(unsigned
const &N); template <typename NodeType, typename ParamT
> bool internal:: matcher_hasSize0Matcher<NodeType, ParamT
>::matches( const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
6765 return internal::HasSizeMatcher<NodeType>::hasSize(Node, N);
6766}
6767
6768/// Matches C++ arrays whose size is a value-dependent expression.
6769///
6770/// Given
6771/// \code
6772/// template<typename T, int Size>
6773/// class array {
6774/// T data[Size];
6775/// };
6776/// \endcode
6777/// dependentSizedArrayType
6778/// matches "T data[Size]"
6779extern const AstTypeMatcher<DependentSizedArrayType> dependentSizedArrayType;
6780
6781/// Matches C arrays with unspecified size.
6782///
6783/// Given
6784/// \code
6785/// int a[] = { 2, 3 };
6786/// int b[42];
6787/// void f(int c[]) { int d[a[0]]; };
6788/// \endcode
6789/// incompleteArrayType()
6790/// matches "int a[]" and "int c[]"
6791extern const AstTypeMatcher<IncompleteArrayType> incompleteArrayType;
6792
6793/// Matches C arrays with a specified size that is not an
6794/// integer-constant-expression.
6795///
6796/// Given
6797/// \code
6798/// void f() {
6799/// int a[] = { 2, 3 }
6800/// int b[42];
6801/// int c[a[0]];
6802/// }
6803/// \endcode
6804/// variableArrayType()
6805/// matches "int c[a[0]]"
6806extern const AstTypeMatcher<VariableArrayType> variableArrayType;
6807
6808/// Matches \c VariableArrayType nodes that have a specific size
6809/// expression.
6810///
6811/// Given
6812/// \code
6813/// void f(int b) {
6814/// int a[b];
6815/// }
6816/// \endcode
6817/// variableArrayType(hasSizeExpr(ignoringImpCasts(declRefExpr(to(
6818/// varDecl(hasName("b")))))))
6819/// matches "int a[b]"
6820AST_MATCHER_P(VariableArrayType, hasSizeExpr,namespace internal { class matcher_hasSizeExpr0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<VariableArrayType
> { public: explicit matcher_hasSizeExpr0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const VariableArrayType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<Expr> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<VariableArrayType
> hasSizeExpr( internal::Matcher<Expr> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_hasSizeExpr0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<VariableArrayType> ( &
hasSizeExpr_Type0)(internal::Matcher<Expr> const &InnerMatcher
); inline bool internal::matcher_hasSizeExpr0Matcher::matches
( const VariableArrayType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
6821 internal::Matcher<Expr>, InnerMatcher)namespace internal { class matcher_hasSizeExpr0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<VariableArrayType
> { public: explicit matcher_hasSizeExpr0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const VariableArrayType &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<Expr> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<VariableArrayType
> hasSizeExpr( internal::Matcher<Expr> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_hasSizeExpr0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<VariableArrayType> ( &
hasSizeExpr_Type0)(internal::Matcher<Expr> const &InnerMatcher
); inline bool internal::matcher_hasSizeExpr0Matcher::matches
( const VariableArrayType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
6822 return InnerMatcher.matches(*Node.getSizeExpr(), Finder, Builder);
6823}
6824
6825/// Matches atomic types.
6826///
6827/// Given
6828/// \code
6829/// _Atomic(int) i;
6830/// \endcode
6831/// atomicType()
6832/// matches "_Atomic(int) i"
6833extern const AstTypeMatcher<AtomicType> atomicType;
6834
6835/// Matches atomic types with a specific value type.
6836///
6837/// Given
6838/// \code
6839/// _Atomic(int) i;
6840/// _Atomic(float) f;
6841/// \endcode
6842/// atomicType(hasValueType(isInteger()))
6843/// matches "_Atomic(int) i"
6844///
6845/// Usable as: Matcher<AtomicType>
6846AST_TYPELOC_TRAVERSE_MATCHER_DECL(hasValueType, getValue,namespace internal { template <typename T> struct TypeLocMatcherhasValueTypeGetter
{ static TypeLoc (T::*value())() const { return &T::getValueLoc
; } }; } extern const ::clang::ast_matchers::internal:: TypeTraversePolymorphicMatcher
< TypeLoc, ::clang::ast_matchers::internal:: TypeLocMatcherhasValueTypeGetter
, ::clang::ast_matchers::internal::TypeLocTraverseMatcher, void
(::clang::ast_matchers::internal::TypeList<AtomicType>)
>::Func hasValueTypeLoc; namespace internal { template <
typename T> struct TypeMatcherhasValueTypeGetter { static QualType
(T::*value())() const { return &T::getValueType; } }; } extern
const ::clang::ast_matchers::internal:: TypeTraversePolymorphicMatcher
< QualType, ::clang::ast_matchers::internal::TypeMatcherhasValueTypeGetter
, ::clang::ast_matchers::internal::TypeTraverseMatcher, void(
::clang::ast_matchers::internal::TypeList<AtomicType>)>
::Func hasValueType
6847 AST_POLYMORPHIC_SUPPORTED_TYPES(AtomicType))namespace internal { template <typename T> struct TypeLocMatcherhasValueTypeGetter
{ static TypeLoc (T::*value())() const { return &T::getValueLoc
; } }; } extern const ::clang::ast_matchers::internal:: TypeTraversePolymorphicMatcher
< TypeLoc, ::clang::ast_matchers::internal:: TypeLocMatcherhasValueTypeGetter
, ::clang::ast_matchers::internal::TypeLocTraverseMatcher, void
(::clang::ast_matchers::internal::TypeList<AtomicType>)
>::Func hasValueTypeLoc; namespace internal { template <
typename T> struct TypeMatcherhasValueTypeGetter { static QualType
(T::*value())() const { return &T::getValueType; } }; } extern
const ::clang::ast_matchers::internal:: TypeTraversePolymorphicMatcher
< QualType, ::clang::ast_matchers::internal::TypeMatcherhasValueTypeGetter
, ::clang::ast_matchers::internal::TypeTraverseMatcher, void(
::clang::ast_matchers::internal::TypeList<AtomicType>)>
::Func hasValueType
;
6848
6849/// Matches types nodes representing C++11 auto types.
6850///
6851/// Given:
6852/// \code
6853/// auto n = 4;
6854/// int v[] = { 2, 3 }
6855/// for (auto i : v) { }
6856/// \endcode
6857/// autoType()
6858/// matches "auto n" and "auto i"
6859extern const AstTypeMatcher<AutoType> autoType;
6860
6861/// Matches types nodes representing C++11 decltype(<expr>) types.
6862///
6863/// Given:
6864/// \code
6865/// short i = 1;
6866/// int j = 42;
6867/// decltype(i + j) result = i + j;
6868/// \endcode
6869/// decltypeType()
6870/// matches "decltype(i + j)"
6871extern const AstTypeMatcher<DecltypeType> decltypeType;
6872
6873/// Matches \c AutoType nodes where the deduced type is a specific type.
6874///
6875/// Note: There is no \c TypeLoc for the deduced type and thus no
6876/// \c getDeducedLoc() matcher.
6877///
6878/// Given
6879/// \code
6880/// auto a = 1;
6881/// auto b = 2.0;
6882/// \endcode
6883/// autoType(hasDeducedType(isInteger()))
6884/// matches "auto a"
6885///
6886/// Usable as: Matcher<AutoType>
6887AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType,namespace internal { template <typename T> struct TypeMatcherhasDeducedTypeGetter
{ static QualType (T::*value())() const { return &T::getDeducedType
; } }; } const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher
< QualType, ::clang::ast_matchers::internal::TypeMatcherhasDeducedTypeGetter
, ::clang::ast_matchers::internal::TypeTraverseMatcher, void(
::clang::ast_matchers::internal::TypeList<AutoType>)>
::Func hasDeducedType
6888 AST_POLYMORPHIC_SUPPORTED_TYPES(AutoType))namespace internal { template <typename T> struct TypeMatcherhasDeducedTypeGetter
{ static QualType (T::*value())() const { return &T::getDeducedType
; } }; } const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher
< QualType, ::clang::ast_matchers::internal::TypeMatcherhasDeducedTypeGetter
, ::clang::ast_matchers::internal::TypeTraverseMatcher, void(
::clang::ast_matchers::internal::TypeList<AutoType>)>
::Func hasDeducedType
;
6889
6890/// Matches \c DecltypeType or \c UsingType nodes to find the underlying type.
6891///
6892/// Given
6893/// \code
6894/// decltype(1) a = 1;
6895/// decltype(2.0) b = 2.0;
6896/// \endcode
6897/// decltypeType(hasUnderlyingType(isInteger()))
6898/// matches the type of "a"
6899///
6900/// Usable as: Matcher<DecltypeType>, Matcher<UsingType>
6901AST_TYPE_TRAVERSE_MATCHER(hasUnderlyingType, getUnderlyingType,namespace internal { template <typename T> struct TypeMatcherhasUnderlyingTypeGetter
{ static QualType (T::*value())() const { return &T::getUnderlyingType
; } }; } const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher
< QualType, ::clang::ast_matchers::internal::TypeMatcherhasUnderlyingTypeGetter
, ::clang::ast_matchers::internal::TypeTraverseMatcher, void(
::clang::ast_matchers::internal::TypeList<DecltypeType, UsingType
>)>::Func hasUnderlyingType
6902 AST_POLYMORPHIC_SUPPORTED_TYPES(DecltypeType,namespace internal { template <typename T> struct TypeMatcherhasUnderlyingTypeGetter
{ static QualType (T::*value())() const { return &T::getUnderlyingType
; } }; } const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher
< QualType, ::clang::ast_matchers::internal::TypeMatcherhasUnderlyingTypeGetter
, ::clang::ast_matchers::internal::TypeTraverseMatcher, void(
::clang::ast_matchers::internal::TypeList<DecltypeType, UsingType
>)>::Func hasUnderlyingType
6903 UsingType))namespace internal { template <typename T> struct TypeMatcherhasUnderlyingTypeGetter
{ static QualType (T::*value())() const { return &T::getUnderlyingType
; } }; } const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher
< QualType, ::clang::ast_matchers::internal::TypeMatcherhasUnderlyingTypeGetter
, ::clang::ast_matchers::internal::TypeTraverseMatcher, void(
::clang::ast_matchers::internal::TypeList<DecltypeType, UsingType
>)>::Func hasUnderlyingType
;
6904
6905/// Matches \c FunctionType nodes.
6906///
6907/// Given
6908/// \code
6909/// int (*f)(int);
6910/// void g();
6911/// \endcode
6912/// functionType()
6913/// matches "int (*f)(int)" and the type of "g".
6914extern const AstTypeMatcher<FunctionType> functionType;
6915
6916/// Matches \c FunctionProtoType nodes.
6917///
6918/// Given
6919/// \code
6920/// int (*f)(int);
6921/// void g();
6922/// \endcode
6923/// functionProtoType()
6924/// matches "int (*f)(int)" and the type of "g" in C++ mode.
6925/// In C mode, "g" is not matched because it does not contain a prototype.
6926extern const AstTypeMatcher<FunctionProtoType> functionProtoType;
6927
6928/// Matches \c ParenType nodes.
6929///
6930/// Given
6931/// \code
6932/// int (*ptr_to_array)[4];
6933/// int *array_of_ptrs[4];
6934/// \endcode
6935///
6936/// \c varDecl(hasType(pointsTo(parenType()))) matches \c ptr_to_array but not
6937/// \c array_of_ptrs.
6938extern const AstTypeMatcher<ParenType> parenType;
6939
6940/// Matches \c ParenType nodes where the inner type is a specific type.
6941///
6942/// Given
6943/// \code
6944/// int (*ptr_to_array)[4];
6945/// int (*ptr_to_func)(int);
6946/// \endcode
6947///
6948/// \c varDecl(hasType(pointsTo(parenType(innerType(functionType()))))) matches
6949/// \c ptr_to_func but not \c ptr_to_array.
6950///
6951/// Usable as: Matcher<ParenType>
6952AST_TYPE_TRAVERSE_MATCHER(innerType, getInnerType,namespace internal { template <typename T> struct TypeMatcherinnerTypeGetter
{ static QualType (T::*value())() const { return &T::getInnerType
; } }; } const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher
< QualType, ::clang::ast_matchers::internal::TypeMatcherinnerTypeGetter
, ::clang::ast_matchers::internal::TypeTraverseMatcher, void(
::clang::ast_matchers::internal::TypeList<ParenType>)>
::Func innerType
6953 AST_POLYMORPHIC_SUPPORTED_TYPES(ParenType))namespace internal { template <typename T> struct TypeMatcherinnerTypeGetter
{ static QualType (T::*value())() const { return &T::getInnerType
; } }; } const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher
< QualType, ::clang::ast_matchers::internal::TypeMatcherinnerTypeGetter
, ::clang::ast_matchers::internal::TypeTraverseMatcher, void(
::clang::ast_matchers::internal::TypeList<ParenType>)>
::Func innerType
;
6954
6955/// Matches block pointer types, i.e. types syntactically represented as
6956/// "void (^)(int)".
6957///
6958/// The \c pointee is always required to be a \c FunctionType.
6959extern const AstTypeMatcher<BlockPointerType> blockPointerType;
6960
6961/// Matches member pointer types.
6962/// Given
6963/// \code
6964/// struct A { int i; }
6965/// A::* ptr = A::i;
6966/// \endcode
6967/// memberPointerType()
6968/// matches "A::* ptr"
6969extern const AstTypeMatcher<MemberPointerType> memberPointerType;
6970
6971/// Matches pointer types, but does not match Objective-C object pointer
6972/// types.
6973///
6974/// Given
6975/// \code
6976/// int *a;
6977/// int &b = *a;
6978/// int c = 5;
6979///
6980/// @interface Foo
6981/// @end
6982/// Foo *f;
6983/// \endcode
6984/// pointerType()
6985/// matches "int *a", but does not match "Foo *f".
6986extern const AstTypeMatcher<PointerType> pointerType;
6987
6988/// Matches an Objective-C object pointer type, which is different from
6989/// a pointer type, despite being syntactically similar.
6990///
6991/// Given
6992/// \code
6993/// int *a;
6994///
6995/// @interface Foo
6996/// @end
6997/// Foo *f;
6998/// \endcode
6999/// pointerType()
7000/// matches "Foo *f", but does not match "int *a".
7001extern const AstTypeMatcher<ObjCObjectPointerType> objcObjectPointerType;
7002
7003/// Matches both lvalue and rvalue reference types.
7004///
7005/// Given
7006/// \code
7007/// int *a;
7008/// int &b = *a;
7009/// int &&c = 1;
7010/// auto &d = b;
7011/// auto &&e = c;
7012/// auto &&f = 2;
7013/// int g = 5;
7014/// \endcode
7015///
7016/// \c referenceType() matches the types of \c b, \c c, \c d, \c e, and \c f.
7017extern const AstTypeMatcher<ReferenceType> referenceType;
7018
7019/// Matches lvalue reference types.
7020///
7021/// Given:
7022/// \code
7023/// int *a;
7024/// int &b = *a;
7025/// int &&c = 1;
7026/// auto &d = b;
7027/// auto &&e = c;
7028/// auto &&f = 2;
7029/// int g = 5;
7030/// \endcode
7031///
7032/// \c lValueReferenceType() matches the types of \c b, \c d, and \c e. \c e is
7033/// matched since the type is deduced as int& by reference collapsing rules.
7034extern const AstTypeMatcher<LValueReferenceType> lValueReferenceType;
7035
7036/// Matches rvalue reference types.
7037///
7038/// Given:
7039/// \code
7040/// int *a;
7041/// int &b = *a;
7042/// int &&c = 1;
7043/// auto &d = b;
7044/// auto &&e = c;
7045/// auto &&f = 2;
7046/// int g = 5;
7047/// \endcode
7048///
7049/// \c rValueReferenceType() matches the types of \c c and \c f. \c e is not
7050/// matched as it is deduced to int& by reference collapsing rules.
7051extern const AstTypeMatcher<RValueReferenceType> rValueReferenceType;
7052
7053/// Narrows PointerType (and similar) matchers to those where the
7054/// \c pointee matches a given matcher.
7055///
7056/// Given
7057/// \code
7058/// int *a;
7059/// int const *b;
7060/// float const *f;
7061/// \endcode
7062/// pointerType(pointee(isConstQualified(), isInteger()))
7063/// matches "int const *b"
7064///
7065/// Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>,
7066/// Matcher<PointerType>, Matcher<ReferenceType>
7067AST_TYPELOC_TRAVERSE_MATCHER_DECL(namespace internal { template <typename T> struct TypeLocMatcherpointeeGetter
{ static TypeLoc (T::*value())() const { return &T::getPointeeLoc
; } }; } extern const ::clang::ast_matchers::internal:: TypeTraversePolymorphicMatcher
< TypeLoc, ::clang::ast_matchers::internal:: TypeLocMatcherpointeeGetter
, ::clang::ast_matchers::internal::TypeLocTraverseMatcher, void
(::clang::ast_matchers::internal::TypeList<BlockPointerType
, MemberPointerType, PointerType, ReferenceType>)>::Func
pointeeLoc; namespace internal { template <typename T>
struct TypeMatcherpointeeGetter { static QualType (T::*value
())() const { return &T::getPointeeType; } }; } extern const
::clang::ast_matchers::internal:: TypeTraversePolymorphicMatcher
< QualType, ::clang::ast_matchers::internal::TypeMatcherpointeeGetter
, ::clang::ast_matchers::internal::TypeTraverseMatcher, void(
::clang::ast_matchers::internal::TypeList<BlockPointerType
, MemberPointerType, PointerType, ReferenceType>)>::Func
pointee
7068 pointee, getPointee,namespace internal { template <typename T> struct TypeLocMatcherpointeeGetter
{ static TypeLoc (T::*value())() const { return &T::getPointeeLoc
; } }; } extern const ::clang::ast_matchers::internal:: TypeTraversePolymorphicMatcher
< TypeLoc, ::clang::ast_matchers::internal:: TypeLocMatcherpointeeGetter
, ::clang::ast_matchers::internal::TypeLocTraverseMatcher, void
(::clang::ast_matchers::internal::TypeList<BlockPointerType
, MemberPointerType, PointerType, ReferenceType>)>::Func
pointeeLoc; namespace internal { template <typename T>
struct TypeMatcherpointeeGetter { static QualType (T::*value
())() const { return &T::getPointeeType; } }; } extern const
::clang::ast_matchers::internal:: TypeTraversePolymorphicMatcher
< QualType, ::clang::ast_matchers::internal::TypeMatcherpointeeGetter
, ::clang::ast_matchers::internal::TypeTraverseMatcher, void(
::clang::ast_matchers::internal::TypeList<BlockPointerType
, MemberPointerType, PointerType, ReferenceType>)>::Func
pointee
7069 AST_POLYMORPHIC_SUPPORTED_TYPES(BlockPointerType, MemberPointerType,namespace internal { template <typename T> struct TypeLocMatcherpointeeGetter
{ static TypeLoc (T::*value())() const { return &T::getPointeeLoc
; } }; } extern const ::clang::ast_matchers::internal:: TypeTraversePolymorphicMatcher
< TypeLoc, ::clang::ast_matchers::internal:: TypeLocMatcherpointeeGetter
, ::clang::ast_matchers::internal::TypeLocTraverseMatcher, void
(::clang::ast_matchers::internal::TypeList<BlockPointerType
, MemberPointerType, PointerType, ReferenceType>)>::Func
pointeeLoc; namespace internal { template <typename T>
struct TypeMatcherpointeeGetter { static QualType (T::*value
())() const { return &T::getPointeeType; } }; } extern const
::clang::ast_matchers::internal:: TypeTraversePolymorphicMatcher
< QualType, ::clang::ast_matchers::internal::TypeMatcherpointeeGetter
, ::clang::ast_matchers::internal::TypeTraverseMatcher, void(
::clang::ast_matchers::internal::TypeList<BlockPointerType
, MemberPointerType, PointerType, ReferenceType>)>::Func
pointee
7070 PointerType, ReferenceType))namespace internal { template <typename T> struct TypeLocMatcherpointeeGetter
{ static TypeLoc (T::*value())() const { return &T::getPointeeLoc
; } }; } extern const ::clang::ast_matchers::internal:: TypeTraversePolymorphicMatcher
< TypeLoc, ::clang::ast_matchers::internal:: TypeLocMatcherpointeeGetter
, ::clang::ast_matchers::internal::TypeLocTraverseMatcher, void
(::clang::ast_matchers::internal::TypeList<BlockPointerType
, MemberPointerType, PointerType, ReferenceType>)>::Func
pointeeLoc; namespace internal { template <typename T>
struct TypeMatcherpointeeGetter { static QualType (T::*value
())() const { return &T::getPointeeType; } }; } extern const
::clang::ast_matchers::internal:: TypeTraversePolymorphicMatcher
< QualType, ::clang::ast_matchers::internal::TypeMatcherpointeeGetter
, ::clang::ast_matchers::internal::TypeTraverseMatcher, void(
::clang::ast_matchers::internal::TypeList<BlockPointerType
, MemberPointerType, PointerType, ReferenceType>)>::Func
pointee
;
7071
7072/// Matches typedef types.
7073///
7074/// Given
7075/// \code
7076/// typedef int X;
7077/// \endcode
7078/// typedefType()
7079/// matches "typedef int X"
7080extern const AstTypeMatcher<TypedefType> typedefType;
7081
7082/// Matches enum types.
7083///
7084/// Given
7085/// \code
7086/// enum C { Green };
7087/// enum class S { Red };
7088///
7089/// C c;
7090/// S s;
7091/// \endcode
7092//
7093/// \c enumType() matches the type of the variable declarations of both \c c and
7094/// \c s.
7095extern const AstTypeMatcher<EnumType> enumType;
7096
7097/// Matches template specialization types.
7098///
7099/// Given
7100/// \code
7101/// template <typename T>
7102/// class C { };
7103///
7104/// template class C<int>; // A
7105/// C<char> var; // B
7106/// \endcode
7107///
7108/// \c templateSpecializationType() matches the type of the explicit
7109/// instantiation in \c A and the type of the variable declaration in \c B.
7110extern const AstTypeMatcher<TemplateSpecializationType>
7111 templateSpecializationType;
7112
7113/// Matches C++17 deduced template specialization types, e.g. deduced class
7114/// template types.
7115///
7116/// Given
7117/// \code
7118/// template <typename T>
7119/// class C { public: C(T); };
7120///
7121/// C c(123);
7122/// \endcode
7123/// \c deducedTemplateSpecializationType() matches the type in the declaration
7124/// of the variable \c c.
7125extern const AstTypeMatcher<DeducedTemplateSpecializationType>
7126 deducedTemplateSpecializationType;
7127
7128/// Matches types nodes representing unary type transformations.
7129///
7130/// Given:
7131/// \code
7132/// typedef __underlying_type(T) type;
7133/// \endcode
7134/// unaryTransformType()
7135/// matches "__underlying_type(T)"
7136extern const AstTypeMatcher<UnaryTransformType> unaryTransformType;
7137
7138/// Matches record types (e.g. structs, classes).
7139///
7140/// Given
7141/// \code
7142/// class C {};
7143/// struct S {};
7144///
7145/// C c;
7146/// S s;
7147/// \endcode
7148///
7149/// \c recordType() matches the type of the variable declarations of both \c c
7150/// and \c s.
7151extern const AstTypeMatcher<RecordType> recordType;
7152
7153/// Matches tag types (record and enum types).
7154///
7155/// Given
7156/// \code
7157/// enum E {};
7158/// class C {};
7159///
7160/// E e;
7161/// C c;
7162/// \endcode
7163///
7164/// \c tagType() matches the type of the variable declarations of both \c e
7165/// and \c c.
7166extern const AstTypeMatcher<TagType> tagType;
7167
7168/// Matches types specified with an elaborated type keyword or with a
7169/// qualified name.
7170///
7171/// Given
7172/// \code
7173/// namespace N {
7174/// namespace M {
7175/// class D {};
7176/// }
7177/// }
7178/// class C {};
7179///
7180/// class C c;
7181/// N::M::D d;
7182/// \endcode
7183///
7184/// \c elaboratedType() matches the type of the variable declarations of both
7185/// \c c and \c d.
7186extern const AstTypeMatcher<ElaboratedType> elaboratedType;
7187
7188/// Matches ElaboratedTypes whose qualifier, a NestedNameSpecifier,
7189/// matches \c InnerMatcher if the qualifier exists.
7190///
7191/// Given
7192/// \code
7193/// namespace N {
7194/// namespace M {
7195/// class D {};
7196/// }
7197/// }
7198/// N::M::D d;
7199/// \endcode
7200///
7201/// \c elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N"))))
7202/// matches the type of the variable declaration of \c d.
7203AST_MATCHER_P(ElaboratedType, hasQualifier,namespace internal { class matcher_hasQualifier0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<ElaboratedType
> { public: explicit matcher_hasQualifier0Matcher( internal
::Matcher<NestedNameSpecifier> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const ElaboratedType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<NestedNameSpecifier
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<ElaboratedType> hasQualifier( internal::Matcher
<NestedNameSpecifier> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasQualifier0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<ElaboratedType> ( &
hasQualifier_Type0)(internal::Matcher<NestedNameSpecifier>
const &InnerMatcher); inline bool internal::matcher_hasQualifier0Matcher
::matches( const ElaboratedType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
7204 internal::Matcher<NestedNameSpecifier>, InnerMatcher)namespace internal { class matcher_hasQualifier0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<ElaboratedType
> { public: explicit matcher_hasQualifier0Matcher( internal
::Matcher<NestedNameSpecifier> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const ElaboratedType
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<NestedNameSpecifier
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<ElaboratedType> hasQualifier( internal::Matcher
<NestedNameSpecifier> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasQualifier0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<ElaboratedType> ( &
hasQualifier_Type0)(internal::Matcher<NestedNameSpecifier>
const &InnerMatcher); inline bool internal::matcher_hasQualifier0Matcher
::matches( const ElaboratedType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
7205 if (const NestedNameSpecifier *Qualifier = Node.getQualifier())
7206 return InnerMatcher.matches(*Qualifier, Finder, Builder);
7207
7208 return false;
7209}
7210
7211/// Matches ElaboratedTypes whose named type matches \c InnerMatcher.
7212///
7213/// Given
7214/// \code
7215/// namespace N {
7216/// namespace M {
7217/// class D {};
7218/// }
7219/// }
7220/// N::M::D d;
7221/// \endcode
7222///
7223/// \c elaboratedType(namesType(recordType(
7224/// hasDeclaration(namedDecl(hasName("D")))))) matches the type of the variable
7225/// declaration of \c d.
7226AST_MATCHER_P(ElaboratedType, namesType, internal::Matcher<QualType>,namespace internal { class matcher_namesType0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<ElaboratedType
> { public: explicit matcher_namesType0Matcher( internal::
Matcher<QualType> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const ElaboratedType &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<QualType> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<ElaboratedType
> namesType( internal::Matcher<QualType> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_namesType0Matcher(InnerMatcher)); } typedef
::clang::ast_matchers::internal::Matcher<ElaboratedType>
( &namesType_Type0)(internal::Matcher<QualType> const
&InnerMatcher); inline bool internal::matcher_namesType0Matcher
::matches( const ElaboratedType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
7227 InnerMatcher)namespace internal { class matcher_namesType0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<ElaboratedType
> { public: explicit matcher_namesType0Matcher( internal::
Matcher<QualType> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const ElaboratedType &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<QualType> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<ElaboratedType
> namesType( internal::Matcher<QualType> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_namesType0Matcher(InnerMatcher)); } typedef
::clang::ast_matchers::internal::Matcher<ElaboratedType>
( &namesType_Type0)(internal::Matcher<QualType> const
&InnerMatcher); inline bool internal::matcher_namesType0Matcher
::matches( const ElaboratedType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
7228 return InnerMatcher.matches(Node.getNamedType(), Finder, Builder);
7229}
7230
7231/// Matches types specified through a using declaration.
7232///
7233/// Given
7234/// \code
7235/// namespace a { struct S {}; }
7236/// using a::S;
7237/// S s;
7238/// \endcode
7239///
7240/// \c usingType() matches the type of the variable declaration of \c s.
7241extern const AstTypeMatcher<UsingType> usingType;
7242
7243/// Matches types that represent the result of substituting a type for a
7244/// template type parameter.
7245///
7246/// Given
7247/// \code
7248/// template <typename T>
7249/// void F(T t) {
7250/// int i = 1 + t;
7251/// }
7252/// \endcode
7253///
7254/// \c substTemplateTypeParmType() matches the type of 't' but not '1'
7255extern const AstTypeMatcher<SubstTemplateTypeParmType>
7256 substTemplateTypeParmType;
7257
7258/// Matches template type parameter substitutions that have a replacement
7259/// type that matches the provided matcher.
7260///
7261/// Given
7262/// \code
7263/// template <typename T>
7264/// double F(T t);
7265/// int i;
7266/// double j = F(i);
7267/// \endcode
7268///
7269/// \c substTemplateTypeParmType(hasReplacementType(type())) matches int
7270AST_TYPE_TRAVERSE_MATCHER(namespace internal { template <typename T> struct TypeMatcherhasReplacementTypeGetter
{ static QualType (T::*value())() const { return &T::getReplacementType
; } }; } const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher
< QualType, ::clang::ast_matchers::internal::TypeMatcherhasReplacementTypeGetter
, ::clang::ast_matchers::internal::TypeTraverseMatcher, void(
::clang::ast_matchers::internal::TypeList<SubstTemplateTypeParmType
>)>::Func hasReplacementType
7271 hasReplacementType, getReplacementType,namespace internal { template <typename T> struct TypeMatcherhasReplacementTypeGetter
{ static QualType (T::*value())() const { return &T::getReplacementType
; } }; } const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher
< QualType, ::clang::ast_matchers::internal::TypeMatcherhasReplacementTypeGetter
, ::clang::ast_matchers::internal::TypeTraverseMatcher, void(
::clang::ast_matchers::internal::TypeList<SubstTemplateTypeParmType
>)>::Func hasReplacementType
7272 AST_POLYMORPHIC_SUPPORTED_TYPES(SubstTemplateTypeParmType))namespace internal { template <typename T> struct TypeMatcherhasReplacementTypeGetter
{ static QualType (T::*value())() const { return &T::getReplacementType
; } }; } const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher
< QualType, ::clang::ast_matchers::internal::TypeMatcherhasReplacementTypeGetter
, ::clang::ast_matchers::internal::TypeTraverseMatcher, void(
::clang::ast_matchers::internal::TypeList<SubstTemplateTypeParmType
>)>::Func hasReplacementType
;
7273
7274/// Matches template type parameter types.
7275///
7276/// Example matches T, but not int.
7277/// (matcher = templateTypeParmType())
7278/// \code
7279/// template <typename T> void f(int i);
7280/// \endcode
7281extern const AstTypeMatcher<TemplateTypeParmType> templateTypeParmType;
7282
7283/// Matches injected class name types.
7284///
7285/// Example matches S s, but not S<T> s.
7286/// (matcher = parmVarDecl(hasType(injectedClassNameType())))
7287/// \code
7288/// template <typename T> struct S {
7289/// void f(S s);
7290/// void g(S<T> s);
7291/// };
7292/// \endcode
7293extern const AstTypeMatcher<InjectedClassNameType> injectedClassNameType;
7294
7295/// Matches decayed type
7296/// Example matches i[] in declaration of f.
7297/// (matcher = valueDecl(hasType(decayedType(hasDecayedType(pointerType())))))
7298/// Example matches i[1].
7299/// (matcher = expr(hasType(decayedType(hasDecayedType(pointerType())))))
7300/// \code
7301/// void f(int i[]) {
7302/// i[1] = 0;
7303/// }
7304/// \endcode
7305extern const AstTypeMatcher<DecayedType> decayedType;
7306
7307/// Matches the decayed type, whoes decayed type matches \c InnerMatcher
7308AST_MATCHER_P(DecayedType, hasDecayedType, internal::Matcher<QualType>,namespace internal { class matcher_hasDecayedType0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<DecayedType
> { public: explicit matcher_hasDecayedType0Matcher( internal
::Matcher<QualType> const &AInnerType) : InnerType(
AInnerType) {} bool matches(const DecayedType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<QualType> InnerType; }; } inline ::
clang::ast_matchers::internal::Matcher<DecayedType> hasDecayedType
( internal::Matcher<QualType> const &InnerType) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasDecayedType0Matcher(InnerType)); } typedef ::clang
::ast_matchers::internal::Matcher<DecayedType> ( &hasDecayedType_Type0
)(internal::Matcher<QualType> const &InnerType); inline
bool internal::matcher_hasDecayedType0Matcher::matches( const
DecayedType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
7309 InnerType)namespace internal { class matcher_hasDecayedType0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<DecayedType
> { public: explicit matcher_hasDecayedType0Matcher( internal
::Matcher<QualType> const &AInnerType) : InnerType(
AInnerType) {} bool matches(const DecayedType &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<QualType> InnerType; }; } inline ::
clang::ast_matchers::internal::Matcher<DecayedType> hasDecayedType
( internal::Matcher<QualType> const &InnerType) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasDecayedType0Matcher(InnerType)); } typedef ::clang
::ast_matchers::internal::Matcher<DecayedType> ( &hasDecayedType_Type0
)(internal::Matcher<QualType> const &InnerType); inline
bool internal::matcher_hasDecayedType0Matcher::matches( const
DecayedType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
7310 return InnerType.matches(Node.getDecayedType(), Finder, Builder);
7311}
7312
7313/// Matches declarations whose declaration context, interpreted as a
7314/// Decl, matches \c InnerMatcher.
7315///
7316/// Given
7317/// \code
7318/// namespace N {
7319/// namespace M {
7320/// class D {};
7321/// }
7322/// }
7323/// \endcode
7324///
7325/// \c cxxRcordDecl(hasDeclContext(namedDecl(hasName("M")))) matches the
7326/// declaration of \c class \c D.
7327AST_MATCHER_P(Decl, hasDeclContext, internal::Matcher<Decl>, InnerMatcher)namespace internal { class matcher_hasDeclContext0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<Decl>
{ public: explicit matcher_hasDeclContext0Matcher( internal::
Matcher<Decl> const &AInnerMatcher) : InnerMatcher(
AInnerMatcher) {} bool matches(const Decl &Node, ::clang::
ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Decl> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<Decl> hasDeclContext(
internal::Matcher<Decl> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasDeclContext0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<Decl> ( &hasDeclContext_Type0
)(internal::Matcher<Decl> const &InnerMatcher); inline
bool internal::matcher_hasDeclContext0Matcher::matches( const
Decl &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
7328 const DeclContext *DC = Node.getDeclContext();
7329 if (!DC) return false;
7330 return InnerMatcher.matches(*Decl::castFromDeclContext(DC), Finder, Builder);
7331}
7332
7333/// Matches nested name specifiers.
7334///
7335/// Given
7336/// \code
7337/// namespace ns {
7338/// struct A { static void f(); };
7339/// void A::f() {}
7340/// void g() { A::f(); }
7341/// }
7342/// ns::A a;
7343/// \endcode
7344/// nestedNameSpecifier()
7345/// matches "ns::" and both "A::"
7346extern const internal::VariadicAllOfMatcher<NestedNameSpecifier>
7347 nestedNameSpecifier;
7348
7349/// Same as \c nestedNameSpecifier but matches \c NestedNameSpecifierLoc.
7350extern const internal::VariadicAllOfMatcher<NestedNameSpecifierLoc>
7351 nestedNameSpecifierLoc;
7352
7353/// Matches \c NestedNameSpecifierLocs for which the given inner
7354/// NestedNameSpecifier-matcher matches.
7355AST_MATCHER_FUNCTION_P_OVERLOAD(inline internal::BindableMatcher<NestedNameSpecifierLoc>
loc(internal::Matcher<NestedNameSpecifier> const &
InnerMatcher); typedef internal::BindableMatcher<NestedNameSpecifierLoc
> (&loc_Type1)(internal::Matcher<NestedNameSpecifier
> const &); inline internal::BindableMatcher<NestedNameSpecifierLoc
> loc(internal::Matcher<NestedNameSpecifier> const &
InnerMatcher)
7356 internal::BindableMatcher<NestedNameSpecifierLoc>, loc,inline internal::BindableMatcher<NestedNameSpecifierLoc>
loc(internal::Matcher<NestedNameSpecifier> const &
InnerMatcher); typedef internal::BindableMatcher<NestedNameSpecifierLoc
> (&loc_Type1)(internal::Matcher<NestedNameSpecifier
> const &); inline internal::BindableMatcher<NestedNameSpecifierLoc
> loc(internal::Matcher<NestedNameSpecifier> const &
InnerMatcher)
7357 internal::Matcher<NestedNameSpecifier>, InnerMatcher, 1)inline internal::BindableMatcher<NestedNameSpecifierLoc>
loc(internal::Matcher<NestedNameSpecifier> const &
InnerMatcher); typedef internal::BindableMatcher<NestedNameSpecifierLoc
> (&loc_Type1)(internal::Matcher<NestedNameSpecifier
> const &); inline internal::BindableMatcher<NestedNameSpecifierLoc
> loc(internal::Matcher<NestedNameSpecifier> const &
InnerMatcher)
{
7358 return internal::BindableMatcher<NestedNameSpecifierLoc>(
7359 new internal::LocMatcher<NestedNameSpecifierLoc, NestedNameSpecifier>(
7360 InnerMatcher));
7361}
7362
7363/// Matches nested name specifiers that specify a type matching the
7364/// given \c QualType matcher without qualifiers.
7365///
7366/// Given
7367/// \code
7368/// struct A { struct B { struct C {}; }; };
7369/// A::B::C c;
7370/// \endcode
7371/// nestedNameSpecifier(specifiesType(
7372/// hasDeclaration(cxxRecordDecl(hasName("A")))
7373/// ))
7374/// matches "A::"
7375AST_MATCHER_P(NestedNameSpecifier, specifiesType,namespace internal { class matcher_specifiesType0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NestedNameSpecifier
> { public: explicit matcher_specifiesType0Matcher( internal
::Matcher<QualType> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NestedNameSpecifier &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<QualType> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<NestedNameSpecifier
> specifiesType( internal::Matcher<QualType> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_specifiesType0Matcher(InnerMatcher));
} typedef ::clang::ast_matchers::internal::Matcher<NestedNameSpecifier
> ( &specifiesType_Type0)(internal::Matcher<QualType
> const &InnerMatcher); inline bool internal::matcher_specifiesType0Matcher
::matches( const NestedNameSpecifier &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
7376 internal::Matcher<QualType>, InnerMatcher)namespace internal { class matcher_specifiesType0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NestedNameSpecifier
> { public: explicit matcher_specifiesType0Matcher( internal
::Matcher<QualType> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const NestedNameSpecifier &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<QualType> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<NestedNameSpecifier
> specifiesType( internal::Matcher<QualType> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_specifiesType0Matcher(InnerMatcher));
} typedef ::clang::ast_matchers::internal::Matcher<NestedNameSpecifier
> ( &specifiesType_Type0)(internal::Matcher<QualType
> const &InnerMatcher); inline bool internal::matcher_specifiesType0Matcher
::matches( const NestedNameSpecifier &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
7377 if (!Node.getAsType())
7378 return false;
7379 return InnerMatcher.matches(QualType(Node.getAsType(), 0), Finder, Builder);
7380}
7381
7382/// Matches nested name specifier locs that specify a type matching the
7383/// given \c TypeLoc.
7384///
7385/// Given
7386/// \code
7387/// struct A { struct B { struct C {}; }; };
7388/// A::B::C c;
7389/// \endcode
7390/// nestedNameSpecifierLoc(specifiesTypeLoc(loc(type(
7391/// hasDeclaration(cxxRecordDecl(hasName("A")))))))
7392/// matches "A::"
7393AST_MATCHER_P(NestedNameSpecifierLoc, specifiesTypeLoc,namespace internal { class matcher_specifiesTypeLoc0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
NestedNameSpecifierLoc> { public: explicit matcher_specifiesTypeLoc0Matcher
( internal::Matcher<TypeLoc> const &AInnerMatcher) :
InnerMatcher(AInnerMatcher) {} bool matches(const NestedNameSpecifierLoc
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<TypeLoc
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<NestedNameSpecifierLoc> specifiesTypeLoc( internal
::Matcher<TypeLoc> const &InnerMatcher) { return ::
clang::ast_matchers::internal::makeMatcher( new internal::matcher_specifiesTypeLoc0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<NestedNameSpecifierLoc> ( &specifiesTypeLoc_Type0)
(internal::Matcher<TypeLoc> const &InnerMatcher); inline
bool internal::matcher_specifiesTypeLoc0Matcher::matches( const
NestedNameSpecifierLoc &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
7394 internal::Matcher<TypeLoc>, InnerMatcher)namespace internal { class matcher_specifiesTypeLoc0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
NestedNameSpecifierLoc> { public: explicit matcher_specifiesTypeLoc0Matcher
( internal::Matcher<TypeLoc> const &AInnerMatcher) :
InnerMatcher(AInnerMatcher) {} bool matches(const NestedNameSpecifierLoc
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<TypeLoc
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<NestedNameSpecifierLoc> specifiesTypeLoc( internal
::Matcher<TypeLoc> const &InnerMatcher) { return ::
clang::ast_matchers::internal::makeMatcher( new internal::matcher_specifiesTypeLoc0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<NestedNameSpecifierLoc> ( &specifiesTypeLoc_Type0)
(internal::Matcher<TypeLoc> const &InnerMatcher); inline
bool internal::matcher_specifiesTypeLoc0Matcher::matches( const
NestedNameSpecifierLoc &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
7395 return Node && Node.getNestedNameSpecifier()->getAsType() &&
7396 InnerMatcher.matches(Node.getTypeLoc(), Finder, Builder);
7397}
7398
7399/// Matches on the prefix of a \c NestedNameSpecifier.
7400///
7401/// Given
7402/// \code
7403/// struct A { struct B { struct C {}; }; };
7404/// A::B::C c;
7405/// \endcode
7406/// nestedNameSpecifier(hasPrefix(specifiesType(asString("struct A")))) and
7407/// matches "A::"
7408AST_MATCHER_P_OVERLOAD(NestedNameSpecifier, hasPrefix,namespace internal { class matcher_hasPrefix0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NestedNameSpecifier
> { public: explicit matcher_hasPrefix0Matcher( internal::
Matcher<NestedNameSpecifier> const &AInnerMatcher) :
InnerMatcher(AInnerMatcher) {} bool matches(const NestedNameSpecifier
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<NestedNameSpecifier
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<NestedNameSpecifier> hasPrefix( internal::Matcher
<NestedNameSpecifier> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasPrefix0Matcher(InnerMatcher)); } typedef ::clang::
ast_matchers::internal::Matcher<NestedNameSpecifier> ( &
hasPrefix_Type0)(internal::Matcher<NestedNameSpecifier>
const &InnerMatcher); inline bool internal::matcher_hasPrefix0Matcher
::matches( const NestedNameSpecifier &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
7409 internal::Matcher<NestedNameSpecifier>, InnerMatcher,namespace internal { class matcher_hasPrefix0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NestedNameSpecifier
> { public: explicit matcher_hasPrefix0Matcher( internal::
Matcher<NestedNameSpecifier> const &AInnerMatcher) :
InnerMatcher(AInnerMatcher) {} bool matches(const NestedNameSpecifier
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<NestedNameSpecifier
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<NestedNameSpecifier> hasPrefix( internal::Matcher
<NestedNameSpecifier> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasPrefix0Matcher(InnerMatcher)); } typedef ::clang::
ast_matchers::internal::Matcher<NestedNameSpecifier> ( &
hasPrefix_Type0)(internal::Matcher<NestedNameSpecifier>
const &InnerMatcher); inline bool internal::matcher_hasPrefix0Matcher
::matches( const NestedNameSpecifier &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
7410 0)namespace internal { class matcher_hasPrefix0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NestedNameSpecifier
> { public: explicit matcher_hasPrefix0Matcher( internal::
Matcher<NestedNameSpecifier> const &AInnerMatcher) :
InnerMatcher(AInnerMatcher) {} bool matches(const NestedNameSpecifier
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<NestedNameSpecifier
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<NestedNameSpecifier> hasPrefix( internal::Matcher
<NestedNameSpecifier> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasPrefix0Matcher(InnerMatcher)); } typedef ::clang::
ast_matchers::internal::Matcher<NestedNameSpecifier> ( &
hasPrefix_Type0)(internal::Matcher<NestedNameSpecifier>
const &InnerMatcher); inline bool internal::matcher_hasPrefix0Matcher
::matches( const NestedNameSpecifier &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
7411 const NestedNameSpecifier *NextNode = Node.getPrefix();
7412 if (!NextNode)
7413 return false;
7414 return InnerMatcher.matches(*NextNode, Finder, Builder);
7415}
7416
7417/// Matches on the prefix of a \c NestedNameSpecifierLoc.
7418///
7419/// Given
7420/// \code
7421/// struct A { struct B { struct C {}; }; };
7422/// A::B::C c;
7423/// \endcode
7424/// nestedNameSpecifierLoc(hasPrefix(loc(specifiesType(asString("struct A")))))
7425/// matches "A::"
7426AST_MATCHER_P_OVERLOAD(NestedNameSpecifierLoc, hasPrefix,namespace internal { class matcher_hasPrefix1Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NestedNameSpecifierLoc
> { public: explicit matcher_hasPrefix1Matcher( internal::
Matcher<NestedNameSpecifierLoc> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const NestedNameSpecifierLoc
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<NestedNameSpecifierLoc
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<NestedNameSpecifierLoc> hasPrefix( internal::
Matcher<NestedNameSpecifierLoc> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_hasPrefix1Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<NestedNameSpecifierLoc>
( &hasPrefix_Type1)(internal::Matcher<NestedNameSpecifierLoc
> const &InnerMatcher); inline bool internal::matcher_hasPrefix1Matcher
::matches( const NestedNameSpecifierLoc &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
7427 internal::Matcher<NestedNameSpecifierLoc>, InnerMatcher,namespace internal { class matcher_hasPrefix1Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NestedNameSpecifierLoc
> { public: explicit matcher_hasPrefix1Matcher( internal::
Matcher<NestedNameSpecifierLoc> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const NestedNameSpecifierLoc
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<NestedNameSpecifierLoc
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<NestedNameSpecifierLoc> hasPrefix( internal::
Matcher<NestedNameSpecifierLoc> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_hasPrefix1Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<NestedNameSpecifierLoc>
( &hasPrefix_Type1)(internal::Matcher<NestedNameSpecifierLoc
> const &InnerMatcher); inline bool internal::matcher_hasPrefix1Matcher
::matches( const NestedNameSpecifierLoc &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
7428 1)namespace internal { class matcher_hasPrefix1Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NestedNameSpecifierLoc
> { public: explicit matcher_hasPrefix1Matcher( internal::
Matcher<NestedNameSpecifierLoc> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const NestedNameSpecifierLoc
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<NestedNameSpecifierLoc
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<NestedNameSpecifierLoc> hasPrefix( internal::
Matcher<NestedNameSpecifierLoc> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_hasPrefix1Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<NestedNameSpecifierLoc>
( &hasPrefix_Type1)(internal::Matcher<NestedNameSpecifierLoc
> const &InnerMatcher); inline bool internal::matcher_hasPrefix1Matcher
::matches( const NestedNameSpecifierLoc &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
7429 NestedNameSpecifierLoc NextNode = Node.getPrefix();
7430 if (!NextNode)
7431 return false;
7432 return InnerMatcher.matches(NextNode, Finder, Builder);
7433}
7434
7435/// Matches nested name specifiers that specify a namespace matching the
7436/// given namespace matcher.
7437///
7438/// Given
7439/// \code
7440/// namespace ns { struct A {}; }
7441/// ns::A a;
7442/// \endcode
7443/// nestedNameSpecifier(specifiesNamespace(hasName("ns")))
7444/// matches "ns::"
7445AST_MATCHER_P(NestedNameSpecifier, specifiesNamespace,namespace internal { class matcher_specifiesNamespace0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NestedNameSpecifier> { public: explicit matcher_specifiesNamespace0Matcher
( internal::Matcher<NamespaceDecl> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const NestedNameSpecifier
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<NamespaceDecl
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<NestedNameSpecifier> specifiesNamespace( internal
::Matcher<NamespaceDecl> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_specifiesNamespace0Matcher(InnerMatcher)); } typedef ::
clang::ast_matchers::internal::Matcher<NestedNameSpecifier
> ( &specifiesNamespace_Type0)(internal::Matcher<NamespaceDecl
> const &InnerMatcher); inline bool internal::matcher_specifiesNamespace0Matcher
::matches( const NestedNameSpecifier &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
7446 internal::Matcher<NamespaceDecl>, InnerMatcher)namespace internal { class matcher_specifiesNamespace0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NestedNameSpecifier> { public: explicit matcher_specifiesNamespace0Matcher
( internal::Matcher<NamespaceDecl> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const NestedNameSpecifier
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<NamespaceDecl
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<NestedNameSpecifier> specifiesNamespace( internal
::Matcher<NamespaceDecl> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_specifiesNamespace0Matcher(InnerMatcher)); } typedef ::
clang::ast_matchers::internal::Matcher<NestedNameSpecifier
> ( &specifiesNamespace_Type0)(internal::Matcher<NamespaceDecl
> const &InnerMatcher); inline bool internal::matcher_specifiesNamespace0Matcher
::matches( const NestedNameSpecifier &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
7447 if (!Node.getAsNamespace())
7448 return false;
7449 return InnerMatcher.matches(*Node.getAsNamespace(), Finder, Builder);
7450}
7451
7452/// Matches attributes.
7453/// Attributes may be attached with a variety of different syntaxes (including
7454/// keywords, C++11 attributes, GNU ``__attribute``` and MSVC `__declspec``,
7455/// and ``#pragma``s). They may also be implicit.
7456///
7457/// Given
7458/// \code
7459/// struct [[nodiscard]] Foo{};
7460/// void bar(int * __attribute__((nonnull)) );
7461/// __declspec(noinline) void baz();
7462///
7463/// #pragma omp declare simd
7464/// int min();
7465/// \endcode
7466/// attr()
7467/// matches "nodiscard", "nonnull", "noinline", and the whole "#pragma" line.
7468extern const internal::VariadicAllOfMatcher<Attr> attr;
7469
7470/// Overloads for the \c equalsNode matcher.
7471/// FIXME: Implement for other node types.
7472/// @{
7473
7474/// Matches if a node equals another node.
7475///
7476/// \c Decl has pointer identity in the AST.
7477AST_MATCHER_P_OVERLOAD(Decl, equalsNode, const Decl*, Other, 0)namespace internal { class matcher_equalsNode0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<Decl>
{ public: explicit matcher_equalsNode0Matcher( const Decl* const
&AOther) : Other(AOther) {} bool matches(const Decl &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: const Decl* Other; }; } inline ::clang
::ast_matchers::internal::Matcher<Decl> equalsNode( const
Decl* const &Other) { return ::clang::ast_matchers::internal
::makeMatcher( new internal::matcher_equalsNode0Matcher(Other
)); } typedef ::clang::ast_matchers::internal::Matcher<Decl
> ( &equalsNode_Type0)(const Decl* const &Other); inline
bool internal::matcher_equalsNode0Matcher::matches( const Decl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
7478 return &Node == Other;
7479}
7480/// Matches if a node equals another node.
7481///
7482/// \c Stmt has pointer identity in the AST.
7483AST_MATCHER_P_OVERLOAD(Stmt, equalsNode, const Stmt*, Other, 1)namespace internal { class matcher_equalsNode1Matcher : public
::clang::ast_matchers::internal::MatcherInterface<Stmt>
{ public: explicit matcher_equalsNode1Matcher( const Stmt* const
&AOther) : Other(AOther) {} bool matches(const Stmt &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: const Stmt* Other; }; } inline ::clang
::ast_matchers::internal::Matcher<Stmt> equalsNode( const
Stmt* const &Other) { return ::clang::ast_matchers::internal
::makeMatcher( new internal::matcher_equalsNode1Matcher(Other
)); } typedef ::clang::ast_matchers::internal::Matcher<Stmt
> ( &equalsNode_Type1)(const Stmt* const &Other); inline
bool internal::matcher_equalsNode1Matcher::matches( const Stmt
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
7484 return &Node == Other;
7485}
7486/// Matches if a node equals another node.
7487///
7488/// \c Type has pointer identity in the AST.
7489AST_MATCHER_P_OVERLOAD(Type, equalsNode, const Type*, Other, 2)namespace internal { class matcher_equalsNode2Matcher : public
::clang::ast_matchers::internal::MatcherInterface<Type>
{ public: explicit matcher_equalsNode2Matcher( const Type* const
&AOther) : Other(AOther) {} bool matches(const Type &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: const Type* Other; }; } inline ::clang
::ast_matchers::internal::Matcher<Type> equalsNode( const
Type* const &Other) { return ::clang::ast_matchers::internal
::makeMatcher( new internal::matcher_equalsNode2Matcher(Other
)); } typedef ::clang::ast_matchers::internal::Matcher<Type
> ( &equalsNode_Type2)(const Type* const &Other); inline
bool internal::matcher_equalsNode2Matcher::matches( const Type
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
7490 return &Node == Other;
7491}
7492
7493/// @}
7494
7495/// Matches each case or default statement belonging to the given switch
7496/// statement. This matcher may produce multiple matches.
7497///
7498/// Given
7499/// \code
7500/// switch (1) { case 1: case 2: default: switch (2) { case 3: case 4: ; } }
7501/// \endcode
7502/// switchStmt(forEachSwitchCase(caseStmt().bind("c"))).bind("s")
7503/// matches four times, with "c" binding each of "case 1:", "case 2:",
7504/// "case 3:" and "case 4:", and "s" respectively binding "switch (1)",
7505/// "switch (1)", "switch (2)" and "switch (2)".
7506AST_MATCHER_P(SwitchStmt, forEachSwitchCase, internal::Matcher<SwitchCase>,namespace internal { class matcher_forEachSwitchCase0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
SwitchStmt> { public: explicit matcher_forEachSwitchCase0Matcher
( internal::Matcher<SwitchCase> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const SwitchStmt
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<SwitchCase
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<SwitchStmt> forEachSwitchCase( internal::Matcher
<SwitchCase> const &InnerMatcher) { return ::clang::
ast_matchers::internal::makeMatcher( new internal::matcher_forEachSwitchCase0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<SwitchStmt> ( &forEachSwitchCase_Type0)(internal::
Matcher<SwitchCase> const &InnerMatcher); inline bool
internal::matcher_forEachSwitchCase0Matcher::matches( const SwitchStmt
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
7507 InnerMatcher)namespace internal { class matcher_forEachSwitchCase0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
SwitchStmt> { public: explicit matcher_forEachSwitchCase0Matcher
( internal::Matcher<SwitchCase> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const SwitchStmt
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<SwitchCase
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<SwitchStmt> forEachSwitchCase( internal::Matcher
<SwitchCase> const &InnerMatcher) { return ::clang::
ast_matchers::internal::makeMatcher( new internal::matcher_forEachSwitchCase0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<SwitchStmt> ( &forEachSwitchCase_Type0)(internal::
Matcher<SwitchCase> const &InnerMatcher); inline bool
internal::matcher_forEachSwitchCase0Matcher::matches( const SwitchStmt
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
7508 BoundNodesTreeBuilder Result;
7509 // FIXME: getSwitchCaseList() does not necessarily guarantee a stable
7510 // iteration order. We should use the more general iterating matchers once
7511 // they are capable of expressing this matcher (for example, it should ignore
7512 // case statements belonging to nested switch statements).
7513 bool Matched = false;
7514 for (const SwitchCase *SC = Node.getSwitchCaseList(); SC;
7515 SC = SC->getNextSwitchCase()) {
7516 BoundNodesTreeBuilder CaseBuilder(*Builder);
7517 bool CaseMatched = InnerMatcher.matches(*SC, Finder, &CaseBuilder);
7518 if (CaseMatched) {
7519 Matched = true;
7520 Result.addMatch(CaseBuilder);
7521 }
7522 }
7523 *Builder = std::move(Result);
7524 return Matched;
7525}
7526
7527/// Matches each constructor initializer in a constructor definition.
7528///
7529/// Given
7530/// \code
7531/// class A { A() : i(42), j(42) {} int i; int j; };
7532/// \endcode
7533/// cxxConstructorDecl(forEachConstructorInitializer(
7534/// forField(decl().bind("x"))
7535/// ))
7536/// will trigger two matches, binding for 'i' and 'j' respectively.
7537AST_MATCHER_P(CXXConstructorDecl, forEachConstructorInitializer,namespace internal { class matcher_forEachConstructorInitializer0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
CXXConstructorDecl> { public: explicit matcher_forEachConstructorInitializer0Matcher
( internal::Matcher<CXXCtorInitializer> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const CXXConstructorDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<CXXCtorInitializer
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<CXXConstructorDecl> forEachConstructorInitializer
( internal::Matcher<CXXCtorInitializer> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_forEachConstructorInitializer0Matcher(InnerMatcher)
); } typedef ::clang::ast_matchers::internal::Matcher<CXXConstructorDecl
> ( &forEachConstructorInitializer_Type0)(internal::Matcher
<CXXCtorInitializer> const &InnerMatcher); inline bool
internal::matcher_forEachConstructorInitializer0Matcher::matches
( const CXXConstructorDecl &Node, ::clang::ast_matchers::
internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
7538 internal::Matcher<CXXCtorInitializer>, InnerMatcher)namespace internal { class matcher_forEachConstructorInitializer0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
CXXConstructorDecl> { public: explicit matcher_forEachConstructorInitializer0Matcher
( internal::Matcher<CXXCtorInitializer> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const CXXConstructorDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<CXXCtorInitializer
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<CXXConstructorDecl> forEachConstructorInitializer
( internal::Matcher<CXXCtorInitializer> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_forEachConstructorInitializer0Matcher(InnerMatcher)
); } typedef ::clang::ast_matchers::internal::Matcher<CXXConstructorDecl
> ( &forEachConstructorInitializer_Type0)(internal::Matcher
<CXXCtorInitializer> const &InnerMatcher); inline bool
internal::matcher_forEachConstructorInitializer0Matcher::matches
( const CXXConstructorDecl &Node, ::clang::ast_matchers::
internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
7539 BoundNodesTreeBuilder Result;
7540 bool Matched = false;
7541 for (const auto *I : Node.inits()) {
7542 if (Finder->isTraversalIgnoringImplicitNodes() && !I->isWritten())
7543 continue;
7544 BoundNodesTreeBuilder InitBuilder(*Builder);
7545 if (InnerMatcher.matches(*I, Finder, &InitBuilder)) {
7546 Matched = true;
7547 Result.addMatch(InitBuilder);
7548 }
7549 }
7550 *Builder = std::move(Result);
7551 return Matched;
7552}
7553
7554/// Matches constructor declarations that are copy constructors.
7555///
7556/// Given
7557/// \code
7558/// struct S {
7559/// S(); // #1
7560/// S(const S &); // #2
7561/// S(S &&); // #3
7562/// };
7563/// \endcode
7564/// cxxConstructorDecl(isCopyConstructor()) will match #2, but not #1 or #3.
7565AST_MATCHER(CXXConstructorDecl, isCopyConstructor)namespace internal { class matcher_isCopyConstructorMatcher :
public ::clang::ast_matchers::internal::MatcherInterface<
CXXConstructorDecl> { public: explicit matcher_isCopyConstructorMatcher
() = default; bool matches(const CXXConstructorDecl &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; }; } inline ::clang::ast_matchers::internal
::Matcher<CXXConstructorDecl> isCopyConstructor() { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_isCopyConstructorMatcher()); } inline bool internal::
matcher_isCopyConstructorMatcher::matches( const CXXConstructorDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
7566 return Node.isCopyConstructor();
7567}
7568
7569/// Matches constructor declarations that are move constructors.
7570///
7571/// Given
7572/// \code
7573/// struct S {
7574/// S(); // #1
7575/// S(const S &); // #2
7576/// S(S &&); // #3
7577/// };
7578/// \endcode
7579/// cxxConstructorDecl(isMoveConstructor()) will match #3, but not #1 or #2.
7580AST_MATCHER(CXXConstructorDecl, isMoveConstructor)namespace internal { class matcher_isMoveConstructorMatcher :
public ::clang::ast_matchers::internal::MatcherInterface<
CXXConstructorDecl> { public: explicit matcher_isMoveConstructorMatcher
() = default; bool matches(const CXXConstructorDecl &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; }; } inline ::clang::ast_matchers::internal
::Matcher<CXXConstructorDecl> isMoveConstructor() { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_isMoveConstructorMatcher()); } inline bool internal::
matcher_isMoveConstructorMatcher::matches( const CXXConstructorDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
7581 return Node.isMoveConstructor();
7582}
7583
7584/// Matches constructor declarations that are default constructors.
7585///
7586/// Given
7587/// \code
7588/// struct S {
7589/// S(); // #1
7590/// S(const S &); // #2
7591/// S(S &&); // #3
7592/// };
7593/// \endcode
7594/// cxxConstructorDecl(isDefaultConstructor()) will match #1, but not #2 or #3.
7595AST_MATCHER(CXXConstructorDecl, isDefaultConstructor)namespace internal { class matcher_isDefaultConstructorMatcher
: public ::clang::ast_matchers::internal::MatcherInterface<
CXXConstructorDecl> { public: explicit matcher_isDefaultConstructorMatcher
() = default; bool matches(const CXXConstructorDecl &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; }; } inline ::clang::ast_matchers::internal
::Matcher<CXXConstructorDecl> isDefaultConstructor() { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_isDefaultConstructorMatcher()); } inline bool internal
::matcher_isDefaultConstructorMatcher::matches( const CXXConstructorDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
7596 return Node.isDefaultConstructor();
7597}
7598
7599/// Matches constructors that delegate to another constructor.
7600///
7601/// Given
7602/// \code
7603/// struct S {
7604/// S(); // #1
7605/// S(int) {} // #2
7606/// S(S &&) : S() {} // #3
7607/// };
7608/// S::S() : S(0) {} // #4
7609/// \endcode
7610/// cxxConstructorDecl(isDelegatingConstructor()) will match #3 and #4, but not
7611/// #1 or #2.
7612AST_MATCHER(CXXConstructorDecl, isDelegatingConstructor)namespace internal { class matcher_isDelegatingConstructorMatcher
: public ::clang::ast_matchers::internal::MatcherInterface<
CXXConstructorDecl> { public: explicit matcher_isDelegatingConstructorMatcher
() = default; bool matches(const CXXConstructorDecl &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; }; } inline ::clang::ast_matchers::internal
::Matcher<CXXConstructorDecl> isDelegatingConstructor()
{ return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_isDelegatingConstructorMatcher()); } inline bool internal
::matcher_isDelegatingConstructorMatcher::matches( const CXXConstructorDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
7613 return Node.isDelegatingConstructor();
7614}
7615
7616/// Matches constructor, conversion function, and deduction guide declarations
7617/// that have an explicit specifier if this explicit specifier is resolved to
7618/// true.
7619///
7620/// Given
7621/// \code
7622/// template<bool b>
7623/// struct S {
7624/// S(int); // #1
7625/// explicit S(double); // #2
7626/// operator int(); // #3
7627/// explicit operator bool(); // #4
7628/// explicit(false) S(bool) // # 7
7629/// explicit(true) S(char) // # 8
7630/// explicit(b) S(S) // # 9
7631/// };
7632/// S(int) -> S<true> // #5
7633/// explicit S(double) -> S<false> // #6
7634/// \endcode
7635/// cxxConstructorDecl(isExplicit()) will match #2 and #8, but not #1, #7 or #9.
7636/// cxxConversionDecl(isExplicit()) will match #4, but not #3.
7637/// cxxDeductionGuideDecl(isExplicit()) will match #6, but not #5.
7638AST_POLYMORPHIC_MATCHER(isExplicit, AST_POLYMORPHIC_SUPPORTED_TYPES(namespace internal { template <typename NodeType> class
matcher_isExplicitMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isExplicitMatcher
, void(::clang::ast_matchers::internal::TypeList<CXXConstructorDecl
, CXXConversionDecl, CXXDeductionGuideDecl>)> isExplicit
() { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isExplicitMatcher, void(::clang::ast_matchers
::internal::TypeList<CXXConstructorDecl, CXXConversionDecl
, CXXDeductionGuideDecl>)>(); } template <typename NodeType
> bool internal::matcher_isExplicitMatcher<NodeType>
::matches( const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
7639 CXXConstructorDecl, CXXConversionDecl,namespace internal { template <typename NodeType> class
matcher_isExplicitMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isExplicitMatcher
, void(::clang::ast_matchers::internal::TypeList<CXXConstructorDecl
, CXXConversionDecl, CXXDeductionGuideDecl>)> isExplicit
() { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isExplicitMatcher, void(::clang::ast_matchers
::internal::TypeList<CXXConstructorDecl, CXXConversionDecl
, CXXDeductionGuideDecl>)>(); } template <typename NodeType
> bool internal::matcher_isExplicitMatcher<NodeType>
::matches( const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
7640 CXXDeductionGuideDecl))namespace internal { template <typename NodeType> class
matcher_isExplicitMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isExplicitMatcher
, void(::clang::ast_matchers::internal::TypeList<CXXConstructorDecl
, CXXConversionDecl, CXXDeductionGuideDecl>)> isExplicit
() { return ::clang::ast_matchers::internal::PolymorphicMatcher
< internal::matcher_isExplicitMatcher, void(::clang::ast_matchers
::internal::TypeList<CXXConstructorDecl, CXXConversionDecl
, CXXDeductionGuideDecl>)>(); } template <typename NodeType
> bool internal::matcher_isExplicitMatcher<NodeType>
::matches( const NodeType &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
7641 return Node.isExplicit();
7642}
7643
7644/// Matches the expression in an explicit specifier if present in the given
7645/// declaration.
7646///
7647/// Given
7648/// \code
7649/// template<bool b>
7650/// struct S {
7651/// S(int); // #1
7652/// explicit S(double); // #2
7653/// operator int(); // #3
7654/// explicit operator bool(); // #4
7655/// explicit(false) S(bool) // # 7
7656/// explicit(true) S(char) // # 8
7657/// explicit(b) S(S) // # 9
7658/// };
7659/// S(int) -> S<true> // #5
7660/// explicit S(double) -> S<false> // #6
7661/// \endcode
7662/// cxxConstructorDecl(hasExplicitSpecifier(constantExpr())) will match #7, #8 and #9, but not #1 or #2.
7663/// cxxConversionDecl(hasExplicitSpecifier(constantExpr())) will not match #3 or #4.
7664/// cxxDeductionGuideDecl(hasExplicitSpecifier(constantExpr())) will not match #5 or #6.
7665AST_MATCHER_P(FunctionDecl, hasExplicitSpecifier, internal::Matcher<Expr>,namespace internal { class matcher_hasExplicitSpecifier0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
FunctionDecl> { public: explicit matcher_hasExplicitSpecifier0Matcher
( internal::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const FunctionDecl &Node,
::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
override; private: internal::Matcher<Expr> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<FunctionDecl
> hasExplicitSpecifier( internal::Matcher<Expr> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
makeMatcher( new internal::matcher_hasExplicitSpecifier0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<FunctionDecl> ( &hasExplicitSpecifier_Type0)(internal
::Matcher<Expr> const &InnerMatcher); inline bool internal
::matcher_hasExplicitSpecifier0Matcher::matches( const FunctionDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
7666 InnerMatcher)namespace internal { class matcher_hasExplicitSpecifier0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
FunctionDecl> { public: explicit matcher_hasExplicitSpecifier0Matcher
( internal::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const FunctionDecl &Node,
::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
override; private: internal::Matcher<Expr> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<FunctionDecl
> hasExplicitSpecifier( internal::Matcher<Expr> const
&InnerMatcher) { return ::clang::ast_matchers::internal::
makeMatcher( new internal::matcher_hasExplicitSpecifier0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<FunctionDecl> ( &hasExplicitSpecifier_Type0)(internal
::Matcher<Expr> const &InnerMatcher); inline bool internal
::matcher_hasExplicitSpecifier0Matcher::matches( const FunctionDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
7667 ExplicitSpecifier ES = ExplicitSpecifier::getFromDecl(&Node);
7668 if (!ES.getExpr())
7669 return false;
7670
7671 ASTChildrenNotSpelledInSourceScope RAII(Finder, false);
7672
7673 return InnerMatcher.matches(*ES.getExpr(), Finder, Builder);
7674}
7675
7676/// Matches function and namespace declarations that are marked with
7677/// the inline keyword.
7678///
7679/// Given
7680/// \code
7681/// inline void f();
7682/// void g();
7683/// namespace n {
7684/// inline namespace m {}
7685/// }
7686/// \endcode
7687/// functionDecl(isInline()) will match ::f().
7688/// namespaceDecl(isInline()) will match n::m.
7689AST_POLYMORPHIC_MATCHER(isInline,namespace internal { template <typename NodeType> class
matcher_isInlineMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isInlineMatcher
, void(::clang::ast_matchers::internal::TypeList<NamespaceDecl
, FunctionDecl>)> isInline() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isInlineMatcher
, void(::clang::ast_matchers::internal::TypeList<NamespaceDecl
, FunctionDecl>)>(); } template <typename NodeType>
bool internal::matcher_isInlineMatcher<NodeType>::matches
( const NodeType &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
7690 AST_POLYMORPHIC_SUPPORTED_TYPES(NamespaceDecl,namespace internal { template <typename NodeType> class
matcher_isInlineMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isInlineMatcher
, void(::clang::ast_matchers::internal::TypeList<NamespaceDecl
, FunctionDecl>)> isInline() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isInlineMatcher
, void(::clang::ast_matchers::internal::TypeList<NamespaceDecl
, FunctionDecl>)>(); } template <typename NodeType>
bool internal::matcher_isInlineMatcher<NodeType>::matches
( const NodeType &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
7691 FunctionDecl))namespace internal { template <typename NodeType> class
matcher_isInlineMatcher : public ::clang::ast_matchers::internal
::MatcherInterface<NodeType> { public: bool matches(const
NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::PolymorphicMatcher< internal::matcher_isInlineMatcher
, void(::clang::ast_matchers::internal::TypeList<NamespaceDecl
, FunctionDecl>)> isInline() { return ::clang::ast_matchers
::internal::PolymorphicMatcher< internal::matcher_isInlineMatcher
, void(::clang::ast_matchers::internal::TypeList<NamespaceDecl
, FunctionDecl>)>(); } template <typename NodeType>
bool internal::matcher_isInlineMatcher<NodeType>::matches
( const NodeType &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
7692 // This is required because the spelling of the function used to determine
7693 // whether inline is specified or not differs between the polymorphic types.
7694 if (const auto *FD = dyn_cast<FunctionDecl>(&Node))
7695 return FD->isInlineSpecified();
7696 else if (const auto *NSD = dyn_cast<NamespaceDecl>(&Node))
7697 return NSD->isInline();
7698 llvm_unreachable("Not a valid polymorphic type")::llvm::llvm_unreachable_internal("Not a valid polymorphic type"
, "clang/include/clang/ASTMatchers/ASTMatchers.h", 7698)
;
7699}
7700
7701/// Matches anonymous namespace declarations.
7702///
7703/// Given
7704/// \code
7705/// namespace n {
7706/// namespace {} // #1
7707/// }
7708/// \endcode
7709/// namespaceDecl(isAnonymous()) will match #1 but not ::n.
7710AST_MATCHER(NamespaceDecl, isAnonymous)namespace internal { class matcher_isAnonymousMatcher : public
::clang::ast_matchers::internal::MatcherInterface<NamespaceDecl
> { public: explicit matcher_isAnonymousMatcher() = default
; bool matches(const NamespaceDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<NamespaceDecl>
isAnonymous() { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_isAnonymousMatcher()); } inline bool internal
::matcher_isAnonymousMatcher::matches( const NamespaceDecl &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
7711 return Node.isAnonymousNamespace();
7712}
7713
7714/// Matches declarations in the namespace `std`, but not in nested namespaces.
7715///
7716/// Given
7717/// \code
7718/// class vector {};
7719/// namespace foo {
7720/// class vector {};
7721/// namespace std {
7722/// class vector {};
7723/// }
7724/// }
7725/// namespace std {
7726/// inline namespace __1 {
7727/// class vector {}; // #1
7728/// namespace experimental {
7729/// class vector {};
7730/// }
7731/// }
7732/// }
7733/// \endcode
7734/// cxxRecordDecl(hasName("vector"), isInStdNamespace()) will match only #1.
7735AST_MATCHER(Decl, isInStdNamespace)namespace internal { class matcher_isInStdNamespaceMatcher : public
::clang::ast_matchers::internal::MatcherInterface<Decl>
{ public: explicit matcher_isInStdNamespaceMatcher() = default
; bool matches(const Decl &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::Matcher<Decl> isInStdNamespace() { return ::clang
::ast_matchers::internal::makeMatcher( new internal::matcher_isInStdNamespaceMatcher
()); } inline bool internal::matcher_isInStdNamespaceMatcher::
matches( const Decl &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{ return Node.isInStdNamespace(); }
7736
7737/// If the given case statement does not use the GNU case range
7738/// extension, matches the constant given in the statement.
7739///
7740/// Given
7741/// \code
7742/// switch (1) { case 1: case 1+1: case 3 ... 4: ; }
7743/// \endcode
7744/// caseStmt(hasCaseConstant(integerLiteral()))
7745/// matches "case 1:"
7746AST_MATCHER_P(CaseStmt, hasCaseConstant, internal::Matcher<Expr>,namespace internal { class matcher_hasCaseConstant0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CaseStmt
> { public: explicit matcher_hasCaseConstant0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const CaseStmt &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<CaseStmt> hasCaseConstant
( internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasCaseConstant0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<CaseStmt> ( &hasCaseConstant_Type0
)(internal::Matcher<Expr> const &InnerMatcher); inline
bool internal::matcher_hasCaseConstant0Matcher::matches( const
CaseStmt &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
7747 InnerMatcher)namespace internal { class matcher_hasCaseConstant0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CaseStmt
> { public: explicit matcher_hasCaseConstant0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const CaseStmt &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<Expr> InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<CaseStmt> hasCaseConstant
( internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasCaseConstant0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<CaseStmt> ( &hasCaseConstant_Type0
)(internal::Matcher<Expr> const &InnerMatcher); inline
bool internal::matcher_hasCaseConstant0Matcher::matches( const
CaseStmt &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
7748 if (Node.getRHS())
7749 return false;
7750
7751 return InnerMatcher.matches(*Node.getLHS(), Finder, Builder);
7752}
7753
7754/// Matches declaration that has a given attribute.
7755///
7756/// Given
7757/// \code
7758/// __attribute__((device)) void f() { ... }
7759/// \endcode
7760/// decl(hasAttr(clang::attr::CUDADevice)) matches the function declaration of
7761/// f. If the matcher is used from clang-query, attr::Kind parameter should be
7762/// passed as a quoted string. e.g., hasAttr("attr::CUDADevice").
7763AST_MATCHER_P(Decl, hasAttr, attr::Kind, AttrKind)namespace internal { class matcher_hasAttr0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<Decl> {
public: explicit matcher_hasAttr0Matcher( attr::Kind const &
AAttrKind) : AttrKind(AAttrKind) {} bool matches(const Decl &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: attr::Kind AttrKind; }; } inline ::
clang::ast_matchers::internal::Matcher<Decl> hasAttr( attr
::Kind const &AttrKind) { return ::clang::ast_matchers::internal
::makeMatcher( new internal::matcher_hasAttr0Matcher(AttrKind
)); } typedef ::clang::ast_matchers::internal::Matcher<Decl
> ( &hasAttr_Type0)(attr::Kind const &AttrKind); inline
bool internal::matcher_hasAttr0Matcher::matches( const Decl &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
7764 for (const auto *Attr : Node.attrs()) {
7765 if (Attr->getKind() == AttrKind)
7766 return true;
7767 }
7768 return false;
7769}
7770
7771/// Matches the return value expression of a return statement
7772///
7773/// Given
7774/// \code
7775/// return a + b;
7776/// \endcode
7777/// hasReturnValue(binaryOperator())
7778/// matches 'return a + b'
7779/// with binaryOperator()
7780/// matching 'a + b'
7781AST_MATCHER_P(ReturnStmt, hasReturnValue, internal::Matcher<Expr>,namespace internal { class matcher_hasReturnValue0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<ReturnStmt
> { public: explicit matcher_hasReturnValue0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const ReturnStmt &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
override; private: internal::Matcher<Expr> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<ReturnStmt
> hasReturnValue( internal::Matcher<Expr> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_hasReturnValue0Matcher(InnerMatcher))
; } typedef ::clang::ast_matchers::internal::Matcher<ReturnStmt
> ( &hasReturnValue_Type0)(internal::Matcher<Expr>
const &InnerMatcher); inline bool internal::matcher_hasReturnValue0Matcher
::matches( const ReturnStmt &Node, ::clang::ast_matchers::
internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
7782 InnerMatcher)namespace internal { class matcher_hasReturnValue0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<ReturnStmt
> { public: explicit matcher_hasReturnValue0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const ReturnStmt &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
override; private: internal::Matcher<Expr> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<ReturnStmt
> hasReturnValue( internal::Matcher<Expr> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_hasReturnValue0Matcher(InnerMatcher))
; } typedef ::clang::ast_matchers::internal::Matcher<ReturnStmt
> ( &hasReturnValue_Type0)(internal::Matcher<Expr>
const &InnerMatcher); inline bool internal::matcher_hasReturnValue0Matcher
::matches( const ReturnStmt &Node, ::clang::ast_matchers::
internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
7783 if (const auto *RetValue = Node.getRetValue())
7784 return InnerMatcher.matches(*RetValue, Finder, Builder);
7785 return false;
7786}
7787
7788/// Matches CUDA kernel call expression.
7789///
7790/// Example matches,
7791/// \code
7792/// kernel<<<i,j>>>();
7793/// \endcode
7794extern const internal::VariadicDynCastAllOfMatcher<Stmt, CUDAKernelCallExpr>
7795 cudaKernelCallExpr;
7796
7797/// Matches expressions that resolve to a null pointer constant, such as
7798/// GNU's __null, C++11's nullptr, or C's NULL macro.
7799///
7800/// Given:
7801/// \code
7802/// void *v1 = NULL;
7803/// void *v2 = nullptr;
7804/// void *v3 = __null; // GNU extension
7805/// char *cp = (char *)0;
7806/// int *ip = 0;
7807/// int i = 0;
7808/// \endcode
7809/// expr(nullPointerConstant())
7810/// matches the initializer for v1, v2, v3, cp, and ip. Does not match the
7811/// initializer for i.
7812AST_MATCHER_FUNCTION(internal::Matcher<Expr>, nullPointerConstant)inline internal::Matcher<Expr> nullPointerConstant_getInstance
(); inline internal::Matcher<Expr> nullPointerConstant(
) { return ::clang::ast_matchers::internal::MemoizedMatcher<
internal::Matcher<Expr>, nullPointerConstant_getInstance
>::getInstance(); } inline internal::Matcher<Expr> nullPointerConstant_getInstance
()
{
7813 return anyOf(
7814 gnuNullExpr(), cxxNullPtrLiteralExpr(),
7815 integerLiteral(equals(0), hasParent(expr(hasType(pointerType())))));
7816}
7817
7818/// Matches the DecompositionDecl the binding belongs to.
7819///
7820/// For example, in:
7821/// \code
7822/// void foo()
7823/// {
7824/// int arr[3];
7825/// auto &[f, s, t] = arr;
7826///
7827/// f = 42;
7828/// }
7829/// \endcode
7830/// The matcher:
7831/// \code
7832/// bindingDecl(hasName("f"),
7833/// forDecomposition(decompositionDecl())
7834/// \endcode
7835/// matches 'f' in 'auto &[f, s, t]'.
7836AST_MATCHER_P(BindingDecl, forDecomposition, internal::Matcher<ValueDecl>,namespace internal { class matcher_forDecomposition0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
BindingDecl> { public: explicit matcher_forDecomposition0Matcher
( internal::Matcher<ValueDecl> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const BindingDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<ValueDecl
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<BindingDecl> forDecomposition( internal::Matcher
<ValueDecl> const &InnerMatcher) { return ::clang::
ast_matchers::internal::makeMatcher( new internal::matcher_forDecomposition0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<BindingDecl> ( &forDecomposition_Type0)(internal::
Matcher<ValueDecl> const &InnerMatcher); inline bool
internal::matcher_forDecomposition0Matcher::matches( const BindingDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
7837 InnerMatcher)namespace internal { class matcher_forDecomposition0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
BindingDecl> { public: explicit matcher_forDecomposition0Matcher
( internal::Matcher<ValueDecl> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const BindingDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: internal::Matcher<ValueDecl
> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<BindingDecl> forDecomposition( internal::Matcher
<ValueDecl> const &InnerMatcher) { return ::clang::
ast_matchers::internal::makeMatcher( new internal::matcher_forDecomposition0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<BindingDecl> ( &forDecomposition_Type0)(internal::
Matcher<ValueDecl> const &InnerMatcher); inline bool
internal::matcher_forDecomposition0Matcher::matches( const BindingDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
7838 if (const ValueDecl *VD = Node.getDecomposedDecl())
7839 return InnerMatcher.matches(*VD, Finder, Builder);
7840 return false;
7841}
7842
7843/// Matches the Nth binding of a DecompositionDecl.
7844///
7845/// For example, in:
7846/// \code
7847/// void foo()
7848/// {
7849/// int arr[3];
7850/// auto &[f, s, t] = arr;
7851///
7852/// f = 42;
7853/// }
7854/// \endcode
7855/// The matcher:
7856/// \code
7857/// decompositionDecl(hasBinding(0,
7858/// bindingDecl(hasName("f").bind("fBinding"))))
7859/// \endcode
7860/// matches the decomposition decl with 'f' bound to "fBinding".
7861AST_MATCHER_P2(DecompositionDecl, hasBinding, unsigned, N,namespace internal { class matcher_hasBinding0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<DecompositionDecl
> { public: matcher_hasBinding0Matcher(unsigned const &
AN, internal::Matcher<BindingDecl> const &AInnerMatcher
) : N(AN), InnerMatcher(AInnerMatcher) {} bool matches(const DecompositionDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; internal::Matcher
<BindingDecl> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::Matcher<DecompositionDecl> hasBinding( unsigned
const &N, internal::Matcher<BindingDecl> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_hasBinding0Matcher(N, InnerMatcher));
} typedef ::clang::ast_matchers::internal::Matcher<DecompositionDecl
> ( &hasBinding_Type0)(unsigned const &N, internal
::Matcher<BindingDecl> const &InnerMatcher); inline
bool internal::matcher_hasBinding0Matcher::matches( const DecompositionDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
7862 internal::Matcher<BindingDecl>, InnerMatcher)namespace internal { class matcher_hasBinding0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<DecompositionDecl
> { public: matcher_hasBinding0Matcher(unsigned const &
AN, internal::Matcher<BindingDecl> const &AInnerMatcher
) : N(AN), InnerMatcher(AInnerMatcher) {} bool matches(const DecompositionDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned N; internal::Matcher
<BindingDecl> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::Matcher<DecompositionDecl> hasBinding( unsigned
const &N, internal::Matcher<BindingDecl> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_hasBinding0Matcher(N, InnerMatcher));
} typedef ::clang::ast_matchers::internal::Matcher<DecompositionDecl
> ( &hasBinding_Type0)(unsigned const &N, internal
::Matcher<BindingDecl> const &InnerMatcher); inline
bool internal::matcher_hasBinding0Matcher::matches( const DecompositionDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
7863 if (Node.bindings().size() <= N)
7864 return false;
7865 return InnerMatcher.matches(*Node.bindings()[N], Finder, Builder);
7866}
7867
7868/// Matches any binding of a DecompositionDecl.
7869///
7870/// For example, in:
7871/// \code
7872/// void foo()
7873/// {
7874/// int arr[3];
7875/// auto &[f, s, t] = arr;
7876///
7877/// f = 42;
7878/// }
7879/// \endcode
7880/// The matcher:
7881/// \code
7882/// decompositionDecl(hasAnyBinding(bindingDecl(hasName("f").bind("fBinding"))))
7883/// \endcode
7884/// matches the decomposition decl with 'f' bound to "fBinding".
7885AST_MATCHER_P(DecompositionDecl, hasAnyBinding, internal::Matcher<BindingDecl>,namespace internal { class matcher_hasAnyBinding0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<DecompositionDecl
> { public: explicit matcher_hasAnyBinding0Matcher( internal
::Matcher<BindingDecl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const DecompositionDecl &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<BindingDecl>
InnerMatcher; }; } inline ::clang::ast_matchers::internal::Matcher
<DecompositionDecl> hasAnyBinding( internal::Matcher<
BindingDecl> const &InnerMatcher) { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_hasAnyBinding0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<DecompositionDecl> ( &hasAnyBinding_Type0)(internal
::Matcher<BindingDecl> const &InnerMatcher); inline
bool internal::matcher_hasAnyBinding0Matcher::matches( const
DecompositionDecl &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
7886 InnerMatcher)namespace internal { class matcher_hasAnyBinding0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<DecompositionDecl
> { public: explicit matcher_hasAnyBinding0Matcher( internal
::Matcher<BindingDecl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const DecompositionDecl &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<BindingDecl>
InnerMatcher; }; } inline ::clang::ast_matchers::internal::Matcher
<DecompositionDecl> hasAnyBinding( internal::Matcher<
BindingDecl> const &InnerMatcher) { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_hasAnyBinding0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<DecompositionDecl> ( &hasAnyBinding_Type0)(internal
::Matcher<BindingDecl> const &InnerMatcher); inline
bool internal::matcher_hasAnyBinding0Matcher::matches( const
DecompositionDecl &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
7887 return llvm::any_of(Node.bindings(), [&](const auto *Binding) {
7888 return InnerMatcher.matches(*Binding, Finder, Builder);
7889 });
7890}
7891
7892/// Matches declaration of the function the statement belongs to.
7893///
7894/// Deprecated. Use forCallable() to correctly handle the situation when
7895/// the declaration is not a function (but a block or an Objective-C method).
7896/// forFunction() not only fails to take non-functions into account but also
7897/// may match the wrong declaration in their presence.
7898///
7899/// Given:
7900/// \code
7901/// F& operator=(const F& o) {
7902/// std::copy_if(o.begin(), o.end(), begin(), [](V v) { return v > 0; });
7903/// return *this;
7904/// }
7905/// \endcode
7906/// returnStmt(forFunction(hasName("operator=")))
7907/// matches 'return *this'
7908/// but does not match 'return v > 0'
7909AST_MATCHER_P(Stmt, forFunction, internal::Matcher<FunctionDecl>,namespace internal { class matcher_forFunction0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<Stmt>
{ public: explicit matcher_forFunction0Matcher( internal::Matcher
<FunctionDecl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const Stmt &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<FunctionDecl> InnerMatcher; }; } inline
::clang::ast_matchers::internal::Matcher<Stmt> forFunction
( internal::Matcher<FunctionDecl> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_forFunction0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<Stmt> ( &forFunction_Type0
)(internal::Matcher<FunctionDecl> const &InnerMatcher
); inline bool internal::matcher_forFunction0Matcher::matches
( const Stmt &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
7910 InnerMatcher)namespace internal { class matcher_forFunction0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<Stmt>
{ public: explicit matcher_forFunction0Matcher( internal::Matcher
<FunctionDecl> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const Stmt &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<FunctionDecl> InnerMatcher; }; } inline
::clang::ast_matchers::internal::Matcher<Stmt> forFunction
( internal::Matcher<FunctionDecl> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_forFunction0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<Stmt> ( &forFunction_Type0
)(internal::Matcher<FunctionDecl> const &InnerMatcher
); inline bool internal::matcher_forFunction0Matcher::matches
( const Stmt &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
7911 const auto &Parents = Finder->getASTContext().getParents(Node);
7912
7913 llvm::SmallVector<DynTypedNode, 8> Stack(Parents.begin(), Parents.end());
7914 while (!Stack.empty()) {
7915 const auto &CurNode = Stack.back();
7916 Stack.pop_back();
7917 if (const auto *FuncDeclNode = CurNode.get<FunctionDecl>()) {
7918 if (InnerMatcher.matches(*FuncDeclNode, Finder, Builder)) {
7919 return true;
7920 }
7921 } else if (const auto *LambdaExprNode = CurNode.get<LambdaExpr>()) {
7922 if (InnerMatcher.matches(*LambdaExprNode->getCallOperator(), Finder,
7923 Builder)) {
7924 return true;
7925 }
7926 } else {
7927 for (const auto &Parent : Finder->getASTContext().getParents(CurNode))
7928 Stack.push_back(Parent);
7929 }
7930 }
7931 return false;
7932}
7933
7934/// Matches declaration of the function, method, or block the statement
7935/// belongs to.
7936///
7937/// Given:
7938/// \code
7939/// F& operator=(const F& o) {
7940/// std::copy_if(o.begin(), o.end(), begin(), [](V v) { return v > 0; });
7941/// return *this;
7942/// }
7943/// \endcode
7944/// returnStmt(forCallable(functionDecl(hasName("operator="))))
7945/// matches 'return *this'
7946/// but does not match 'return v > 0'
7947///
7948/// Given:
7949/// \code
7950/// -(void) foo {
7951/// int x = 1;
7952/// dispatch_sync(queue, ^{ int y = 2; });
7953/// }
7954/// \endcode
7955/// declStmt(forCallable(objcMethodDecl()))
7956/// matches 'int x = 1'
7957/// but does not match 'int y = 2'.
7958/// whereas declStmt(forCallable(blockDecl()))
7959/// matches 'int y = 2'
7960/// but does not match 'int x = 1'.
7961AST_MATCHER_P(Stmt, forCallable, internal::Matcher<Decl>, InnerMatcher)namespace internal { class matcher_forCallable0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<Stmt>
{ public: explicit matcher_forCallable0Matcher( internal::Matcher
<Decl> const &AInnerMatcher) : InnerMatcher(AInnerMatcher
) {} bool matches(const Stmt &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<Decl> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::Matcher<Stmt> forCallable( internal::Matcher
<Decl> const &InnerMatcher) { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_forCallable0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<Stmt> ( &forCallable_Type0)(internal::Matcher<Decl
> const &InnerMatcher); inline bool internal::matcher_forCallable0Matcher
::matches( const Stmt &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
7962 const auto &Parents = Finder->getASTContext().getParents(Node);
7963
7964 llvm::SmallVector<DynTypedNode, 8> Stack(Parents.begin(), Parents.end());
7965 while (!Stack.empty()) {
7966 const auto &CurNode = Stack.back();
7967 Stack.pop_back();
7968 if (const auto *FuncDeclNode = CurNode.get<FunctionDecl>()) {
7969 if (InnerMatcher.matches(*FuncDeclNode, Finder, Builder)) {
7970 return true;
7971 }
7972 } else if (const auto *LambdaExprNode = CurNode.get<LambdaExpr>()) {
7973 if (InnerMatcher.matches(*LambdaExprNode->getCallOperator(), Finder,
7974 Builder)) {
7975 return true;
7976 }
7977 } else if (const auto *ObjCMethodDeclNode = CurNode.get<ObjCMethodDecl>()) {
7978 if (InnerMatcher.matches(*ObjCMethodDeclNode, Finder, Builder)) {
7979 return true;
7980 }
7981 } else if (const auto *BlockDeclNode = CurNode.get<BlockDecl>()) {
7982 if (InnerMatcher.matches(*BlockDeclNode, Finder, Builder)) {
7983 return true;
7984 }
7985 } else {
7986 for (const auto &Parent : Finder->getASTContext().getParents(CurNode))
7987 Stack.push_back(Parent);
7988 }
7989 }
7990 return false;
7991}
7992
7993/// Matches a declaration that has external formal linkage.
7994///
7995/// Example matches only z (matcher = varDecl(hasExternalFormalLinkage()))
7996/// \code
7997/// void f() {
7998/// int x;
7999/// static int y;
8000/// }
8001/// int z;
8002/// \endcode
8003///
8004/// Example matches f() because it has external formal linkage despite being
8005/// unique to the translation unit as though it has internal likage
8006/// (matcher = functionDecl(hasExternalFormalLinkage()))
8007///
8008/// \code
8009/// namespace {
8010/// void f() {}
8011/// }
8012/// \endcode
8013AST_MATCHER(NamedDecl, hasExternalFormalLinkage)namespace internal { class matcher_hasExternalFormalLinkageMatcher
: public ::clang::ast_matchers::internal::MatcherInterface<
NamedDecl> { public: explicit matcher_hasExternalFormalLinkageMatcher
() = default; bool matches(const NamedDecl &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; }
; } inline ::clang::ast_matchers::internal::Matcher<NamedDecl
> hasExternalFormalLinkage() { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_hasExternalFormalLinkageMatcher
()); } inline bool internal::matcher_hasExternalFormalLinkageMatcher
::matches( const NamedDecl &Node, ::clang::ast_matchers::
internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
8014 return Node.hasExternalFormalLinkage();
8015}
8016
8017/// Matches a declaration that has default arguments.
8018///
8019/// Example matches y (matcher = parmVarDecl(hasDefaultArgument()))
8020/// \code
8021/// void x(int val) {}
8022/// void y(int val = 0) {}
8023/// \endcode
8024///
8025/// Deprecated. Use hasInitializer() instead to be able to
8026/// match on the contents of the default argument. For example:
8027///
8028/// \code
8029/// void x(int val = 7) {}
8030/// void y(int val = 42) {}
8031/// \endcode
8032/// parmVarDecl(hasInitializer(integerLiteral(equals(42))))
8033/// matches the parameter of y
8034///
8035/// A matcher such as
8036/// parmVarDecl(hasInitializer(anything()))
8037/// is equivalent to parmVarDecl(hasDefaultArgument()).
8038AST_MATCHER(ParmVarDecl, hasDefaultArgument)namespace internal { class matcher_hasDefaultArgumentMatcher :
public ::clang::ast_matchers::internal::MatcherInterface<
ParmVarDecl> { public: explicit matcher_hasDefaultArgumentMatcher
() = default; bool matches(const ParmVarDecl &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; }
; } inline ::clang::ast_matchers::internal::Matcher<ParmVarDecl
> hasDefaultArgument() { return ::clang::ast_matchers::internal
::makeMatcher( new internal::matcher_hasDefaultArgumentMatcher
()); } inline bool internal::matcher_hasDefaultArgumentMatcher
::matches( const ParmVarDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
8039 return Node.hasDefaultArg();
8040}
8041
8042/// Matches array new expressions.
8043///
8044/// Given:
8045/// \code
8046/// MyClass *p1 = new MyClass[10];
8047/// \endcode
8048/// cxxNewExpr(isArray())
8049/// matches the expression 'new MyClass[10]'.
8050AST_MATCHER(CXXNewExpr, isArray)namespace internal { class matcher_isArrayMatcher : public ::
clang::ast_matchers::internal::MatcherInterface<CXXNewExpr
> { public: explicit matcher_isArrayMatcher() = default; bool
matches(const CXXNewExpr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::Matcher<CXXNewExpr> isArray() { return ::clang
::ast_matchers::internal::makeMatcher( new internal::matcher_isArrayMatcher
()); } inline bool internal::matcher_isArrayMatcher::matches(
const CXXNewExpr &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
8051 return Node.isArray();
8052}
8053
8054/// Matches placement new expression arguments.
8055///
8056/// Given:
8057/// \code
8058/// MyClass *p1 = new (Storage, 16) MyClass();
8059/// \endcode
8060/// cxxNewExpr(hasPlacementArg(1, integerLiteral(equals(16))))
8061/// matches the expression 'new (Storage, 16) MyClass()'.
8062AST_MATCHER_P2(CXXNewExpr, hasPlacementArg, unsigned, Index,namespace internal { class matcher_hasPlacementArg0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXNewExpr
> { public: matcher_hasPlacementArg0Matcher(unsigned const
&AIndex, internal::Matcher<Expr> const &AInnerMatcher
) : Index(AIndex), InnerMatcher(AInnerMatcher) {} bool matches
(const CXXNewExpr &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned Index; internal::
Matcher<Expr> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::Matcher<CXXNewExpr> hasPlacementArg( unsigned
const &Index, internal::Matcher<Expr> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_hasPlacementArg0Matcher(Index, InnerMatcher)); } typedef
::clang::ast_matchers::internal::Matcher<CXXNewExpr> (
&hasPlacementArg_Type0)(unsigned const &Index, internal
::Matcher<Expr> const &InnerMatcher); inline bool internal
::matcher_hasPlacementArg0Matcher::matches( const CXXNewExpr &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
8063 internal::Matcher<Expr>, InnerMatcher)namespace internal { class matcher_hasPlacementArg0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXNewExpr
> { public: matcher_hasPlacementArg0Matcher(unsigned const
&AIndex, internal::Matcher<Expr> const &AInnerMatcher
) : Index(AIndex), InnerMatcher(AInnerMatcher) {} bool matches
(const CXXNewExpr &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned Index; internal::
Matcher<Expr> InnerMatcher; }; } inline ::clang::ast_matchers
::internal::Matcher<CXXNewExpr> hasPlacementArg( unsigned
const &Index, internal::Matcher<Expr> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_hasPlacementArg0Matcher(Index, InnerMatcher)); } typedef
::clang::ast_matchers::internal::Matcher<CXXNewExpr> (
&hasPlacementArg_Type0)(unsigned const &Index, internal
::Matcher<Expr> const &InnerMatcher); inline bool internal
::matcher_hasPlacementArg0Matcher::matches( const CXXNewExpr &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
8064 return Node.getNumPlacementArgs() > Index &&
8065 InnerMatcher.matches(*Node.getPlacementArg(Index), Finder, Builder);
8066}
8067
8068/// Matches any placement new expression arguments.
8069///
8070/// Given:
8071/// \code
8072/// MyClass *p1 = new (Storage) MyClass();
8073/// \endcode
8074/// cxxNewExpr(hasAnyPlacementArg(anything()))
8075/// matches the expression 'new (Storage, 16) MyClass()'.
8076AST_MATCHER_P(CXXNewExpr, hasAnyPlacementArg, internal::Matcher<Expr>,namespace internal { class matcher_hasAnyPlacementArg0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
CXXNewExpr> { public: explicit matcher_hasAnyPlacementArg0Matcher
( internal::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const CXXNewExpr &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
override; private: internal::Matcher<Expr> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<CXXNewExpr
> hasAnyPlacementArg( internal::Matcher<Expr> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_hasAnyPlacementArg0Matcher(InnerMatcher
)); } typedef ::clang::ast_matchers::internal::Matcher<CXXNewExpr
> ( &hasAnyPlacementArg_Type0)(internal::Matcher<Expr
> const &InnerMatcher); inline bool internal::matcher_hasAnyPlacementArg0Matcher
::matches( const CXXNewExpr &Node, ::clang::ast_matchers::
internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
8077 InnerMatcher)namespace internal { class matcher_hasAnyPlacementArg0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
CXXNewExpr> { public: explicit matcher_hasAnyPlacementArg0Matcher
( internal::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const CXXNewExpr &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
override; private: internal::Matcher<Expr> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<CXXNewExpr
> hasAnyPlacementArg( internal::Matcher<Expr> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_hasAnyPlacementArg0Matcher(InnerMatcher
)); } typedef ::clang::ast_matchers::internal::Matcher<CXXNewExpr
> ( &hasAnyPlacementArg_Type0)(internal::Matcher<Expr
> const &InnerMatcher); inline bool internal::matcher_hasAnyPlacementArg0Matcher
::matches( const CXXNewExpr &Node, ::clang::ast_matchers::
internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
8078 return llvm::any_of(Node.placement_arguments(), [&](const Expr *Arg) {
8079 return InnerMatcher.matches(*Arg, Finder, Builder);
8080 });
8081}
8082
8083/// Matches array new expressions with a given array size.
8084///
8085/// Given:
8086/// \code
8087/// MyClass *p1 = new MyClass[10];
8088/// \endcode
8089/// cxxNewExpr(hasArraySize(integerLiteral(equals(10))))
8090/// matches the expression 'new MyClass[10]'.
8091AST_MATCHER_P(CXXNewExpr, hasArraySize, internal::Matcher<Expr>, InnerMatcher)namespace internal { class matcher_hasArraySize0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXNewExpr
> { public: explicit matcher_hasArraySize0Matcher( internal
::Matcher<Expr> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const CXXNewExpr &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
override; private: internal::Matcher<Expr> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<CXXNewExpr
> hasArraySize( internal::Matcher<Expr> const &InnerMatcher
) { return ::clang::ast_matchers::internal::makeMatcher( new internal
::matcher_hasArraySize0Matcher(InnerMatcher)); } typedef ::clang
::ast_matchers::internal::Matcher<CXXNewExpr> ( &hasArraySize_Type0
)(internal::Matcher<Expr> const &InnerMatcher); inline
bool internal::matcher_hasArraySize0Matcher::matches( const CXXNewExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
8092 return Node.isArray() && *Node.getArraySize() &&
8093 InnerMatcher.matches(**Node.getArraySize(), Finder, Builder);
8094}
8095
8096/// Matches a class declaration that is defined.
8097///
8098/// Example matches x (matcher = cxxRecordDecl(hasDefinition()))
8099/// \code
8100/// class x {};
8101/// class y;
8102/// \endcode
8103AST_MATCHER(CXXRecordDecl, hasDefinition)namespace internal { class matcher_hasDefinitionMatcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXRecordDecl
> { public: explicit matcher_hasDefinitionMatcher() = default
; bool matches(const CXXRecordDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<CXXRecordDecl>
hasDefinition() { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_hasDefinitionMatcher()); } inline bool
internal::matcher_hasDefinitionMatcher::matches( const CXXRecordDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
8104 return Node.hasDefinition();
8105}
8106
8107/// Matches C++11 scoped enum declaration.
8108///
8109/// Example matches Y (matcher = enumDecl(isScoped()))
8110/// \code
8111/// enum X {};
8112/// enum class Y {};
8113/// \endcode
8114AST_MATCHER(EnumDecl, isScoped)namespace internal { class matcher_isScopedMatcher : public ::
clang::ast_matchers::internal::MatcherInterface<EnumDecl>
{ public: explicit matcher_isScopedMatcher() = default; bool
matches(const EnumDecl &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; }; } inline ::clang::ast_matchers::
internal::Matcher<EnumDecl> isScoped() { return ::clang
::ast_matchers::internal::makeMatcher( new internal::matcher_isScopedMatcher
()); } inline bool internal::matcher_isScopedMatcher::matches
( const EnumDecl &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
8115 return Node.isScoped();
8116}
8117
8118/// Matches a function declared with a trailing return type.
8119///
8120/// Example matches Y (matcher = functionDecl(hasTrailingReturn()))
8121/// \code
8122/// int X() {}
8123/// auto Y() -> int {}
8124/// \endcode
8125AST_MATCHER(FunctionDecl, hasTrailingReturn)namespace internal { class matcher_hasTrailingReturnMatcher :
public ::clang::ast_matchers::internal::MatcherInterface<
FunctionDecl> { public: explicit matcher_hasTrailingReturnMatcher
() = default; bool matches(const FunctionDecl &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; }
; } inline ::clang::ast_matchers::internal::Matcher<FunctionDecl
> hasTrailingReturn() { return ::clang::ast_matchers::internal
::makeMatcher( new internal::matcher_hasTrailingReturnMatcher
()); } inline bool internal::matcher_hasTrailingReturnMatcher
::matches( const FunctionDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
8126 if (const auto *F = Node.getType()->getAs<FunctionProtoType>())
8127 return F->hasTrailingReturn();
8128 return false;
8129}
8130
8131/// Matches expressions that match InnerMatcher that are possibly wrapped in an
8132/// elidable constructor and other corresponding bookkeeping nodes.
8133///
8134/// In C++17, elidable copy constructors are no longer being generated in the
8135/// AST as it is not permitted by the standard. They are, however, part of the
8136/// AST in C++14 and earlier. So, a matcher must abstract over these differences
8137/// to work in all language modes. This matcher skips elidable constructor-call
8138/// AST nodes, `ExprWithCleanups` nodes wrapping elidable constructor-calls and
8139/// various implicit nodes inside the constructor calls, all of which will not
8140/// appear in the C++17 AST.
8141///
8142/// Given
8143///
8144/// \code
8145/// struct H {};
8146/// H G();
8147/// void f() {
8148/// H D = G();
8149/// }
8150/// \endcode
8151///
8152/// ``varDecl(hasInitializer(ignoringElidableConstructorCall(callExpr())))``
8153/// matches ``H D = G()`` in C++11 through C++17 (and beyond).
8154AST_MATCHER_P(Expr, ignoringElidableConstructorCall,namespace internal { class matcher_ignoringElidableConstructorCall0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
Expr> { public: explicit matcher_ignoringElidableConstructorCall0Matcher
( ast_matchers::internal::Matcher<Expr> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const Expr &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: ast_matchers::internal::Matcher<
Expr> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<Expr> ignoringElidableConstructorCall( ast_matchers
::internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_ignoringElidableConstructorCall0Matcher(InnerMatcher)
); } typedef ::clang::ast_matchers::internal::Matcher<Expr
> ( &ignoringElidableConstructorCall_Type0)(ast_matchers
::internal::Matcher<Expr> const &InnerMatcher); inline
bool internal::matcher_ignoringElidableConstructorCall0Matcher
::matches( const Expr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
8155 ast_matchers::internal::Matcher<Expr>, InnerMatcher)namespace internal { class matcher_ignoringElidableConstructorCall0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
Expr> { public: explicit matcher_ignoringElidableConstructorCall0Matcher
( ast_matchers::internal::Matcher<Expr> const &AInnerMatcher
) : InnerMatcher(AInnerMatcher) {} bool matches(const Expr &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: ast_matchers::internal::Matcher<
Expr> InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<Expr> ignoringElidableConstructorCall( ast_matchers
::internal::Matcher<Expr> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_ignoringElidableConstructorCall0Matcher(InnerMatcher)
); } typedef ::clang::ast_matchers::internal::Matcher<Expr
> ( &ignoringElidableConstructorCall_Type0)(ast_matchers
::internal::Matcher<Expr> const &InnerMatcher); inline
bool internal::matcher_ignoringElidableConstructorCall0Matcher
::matches( const Expr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
8156 // E tracks the node that we are examining.
8157 const Expr *E = &Node;
8158 // If present, remove an outer `ExprWithCleanups` corresponding to the
8159 // underlying `CXXConstructExpr`. This check won't cover all cases of added
8160 // `ExprWithCleanups` corresponding to `CXXConstructExpr` nodes (because the
8161 // EWC is placed on the outermost node of the expression, which this may not
8162 // be), but, it still improves the coverage of this matcher.
8163 if (const auto *CleanupsExpr = dyn_cast<ExprWithCleanups>(&Node))
8164 E = CleanupsExpr->getSubExpr();
8165 if (const auto *CtorExpr = dyn_cast<CXXConstructExpr>(E)) {
8166 if (CtorExpr->isElidable()) {
8167 if (const auto *MaterializeTemp =
8168 dyn_cast<MaterializeTemporaryExpr>(CtorExpr->getArg(0))) {
8169 return InnerMatcher.matches(*MaterializeTemp->getSubExpr(), Finder,
8170 Builder);
8171 }
8172 }
8173 }
8174 return InnerMatcher.matches(Node, Finder, Builder);
8175}
8176
8177//----------------------------------------------------------------------------//
8178// OpenMP handling.
8179//----------------------------------------------------------------------------//
8180
8181/// Matches any ``#pragma omp`` executable directive.
8182///
8183/// Given
8184///
8185/// \code
8186/// #pragma omp parallel
8187/// #pragma omp parallel default(none)
8188/// #pragma omp taskyield
8189/// \endcode
8190///
8191/// ``ompExecutableDirective()`` matches ``omp parallel``,
8192/// ``omp parallel default(none)`` and ``omp taskyield``.
8193extern const internal::VariadicDynCastAllOfMatcher<Stmt, OMPExecutableDirective>
8194 ompExecutableDirective;
8195
8196/// Matches standalone OpenMP directives,
8197/// i.e., directives that can't have a structured block.
8198///
8199/// Given
8200///
8201/// \code
8202/// #pragma omp parallel
8203/// {}
8204/// #pragma omp taskyield
8205/// \endcode
8206///
8207/// ``ompExecutableDirective(isStandaloneDirective()))`` matches
8208/// ``omp taskyield``.
8209AST_MATCHER(OMPExecutableDirective, isStandaloneDirective)namespace internal { class matcher_isStandaloneDirectiveMatcher
: public ::clang::ast_matchers::internal::MatcherInterface<
OMPExecutableDirective> { public: explicit matcher_isStandaloneDirectiveMatcher
() = default; bool matches(const OMPExecutableDirective &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; }; } inline ::clang::ast_matchers::internal
::Matcher<OMPExecutableDirective> isStandaloneDirective
() { return ::clang::ast_matchers::internal::makeMatcher( new
internal::matcher_isStandaloneDirectiveMatcher()); } inline bool
internal::matcher_isStandaloneDirectiveMatcher::matches( const
OMPExecutableDirective &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
8210 return Node.isStandaloneDirective();
8211}
8212
8213/// Matches the structured-block of the OpenMP executable directive
8214///
8215/// Prerequisite: the executable directive must not be standalone directive.
8216/// If it is, it will never match.
8217///
8218/// Given
8219///
8220/// \code
8221/// #pragma omp parallel
8222/// ;
8223/// #pragma omp parallel
8224/// {}
8225/// \endcode
8226///
8227/// ``ompExecutableDirective(hasStructuredBlock(nullStmt()))`` will match ``;``
8228AST_MATCHER_P(OMPExecutableDirective, hasStructuredBlock,namespace internal { class matcher_hasStructuredBlock0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
OMPExecutableDirective> { public: explicit matcher_hasStructuredBlock0Matcher
( internal::Matcher<Stmt> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const OMPExecutableDirective &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<Stmt> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<OMPExecutableDirective
> hasStructuredBlock( internal::Matcher<Stmt> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_hasStructuredBlock0Matcher(InnerMatcher
)); } typedef ::clang::ast_matchers::internal::Matcher<OMPExecutableDirective
> ( &hasStructuredBlock_Type0)(internal::Matcher<Stmt
> const &InnerMatcher); inline bool internal::matcher_hasStructuredBlock0Matcher
::matches( const OMPExecutableDirective &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
8229 internal::Matcher<Stmt>, InnerMatcher)namespace internal { class matcher_hasStructuredBlock0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
OMPExecutableDirective> { public: explicit matcher_hasStructuredBlock0Matcher
( internal::Matcher<Stmt> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const OMPExecutableDirective &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<Stmt> InnerMatcher
; }; } inline ::clang::ast_matchers::internal::Matcher<OMPExecutableDirective
> hasStructuredBlock( internal::Matcher<Stmt> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_hasStructuredBlock0Matcher(InnerMatcher
)); } typedef ::clang::ast_matchers::internal::Matcher<OMPExecutableDirective
> ( &hasStructuredBlock_Type0)(internal::Matcher<Stmt
> const &InnerMatcher); inline bool internal::matcher_hasStructuredBlock0Matcher
::matches( const OMPExecutableDirective &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
8230 if (Node.isStandaloneDirective())
8231 return false; // Standalone directives have no structured blocks.
8232 return InnerMatcher.matches(*Node.getStructuredBlock(), Finder, Builder);
8233}
8234
8235/// Matches any clause in an OpenMP directive.
8236///
8237/// Given
8238///
8239/// \code
8240/// #pragma omp parallel
8241/// #pragma omp parallel default(none)
8242/// \endcode
8243///
8244/// ``ompExecutableDirective(hasAnyClause(anything()))`` matches
8245/// ``omp parallel default(none)``.
8246AST_MATCHER_P(OMPExecutableDirective, hasAnyClause,namespace internal { class matcher_hasAnyClause0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<OMPExecutableDirective
> { public: explicit matcher_hasAnyClause0Matcher( internal
::Matcher<OMPClause> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const OMPExecutableDirective &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<OMPClause>
InnerMatcher; }; } inline ::clang::ast_matchers::internal::Matcher
<OMPExecutableDirective> hasAnyClause( internal::Matcher
<OMPClause> const &InnerMatcher) { return ::clang::
ast_matchers::internal::makeMatcher( new internal::matcher_hasAnyClause0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<OMPExecutableDirective> ( &hasAnyClause_Type0)(internal
::Matcher<OMPClause> const &InnerMatcher); inline bool
internal::matcher_hasAnyClause0Matcher::matches( const OMPExecutableDirective
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
8247 internal::Matcher<OMPClause>, InnerMatcher)namespace internal { class matcher_hasAnyClause0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<OMPExecutableDirective
> { public: explicit matcher_hasAnyClause0Matcher( internal
::Matcher<OMPClause> const &AInnerMatcher) : InnerMatcher
(AInnerMatcher) {} bool matches(const OMPExecutableDirective &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const override; private: internal::Matcher<OMPClause>
InnerMatcher; }; } inline ::clang::ast_matchers::internal::Matcher
<OMPExecutableDirective> hasAnyClause( internal::Matcher
<OMPClause> const &InnerMatcher) { return ::clang::
ast_matchers::internal::makeMatcher( new internal::matcher_hasAnyClause0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<OMPExecutableDirective> ( &hasAnyClause_Type0)(internal
::Matcher<OMPClause> const &InnerMatcher); inline bool
internal::matcher_hasAnyClause0Matcher::matches( const OMPExecutableDirective
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
8248 ArrayRef<OMPClause *> Clauses = Node.clauses();
8249 return matchesFirstInPointerRange(InnerMatcher, Clauses.begin(),
8250 Clauses.end(), Finder,
8251 Builder) != Clauses.end();
8252}
8253
8254/// Matches OpenMP ``default`` clause.
8255///
8256/// Given
8257///
8258/// \code
8259/// #pragma omp parallel default(none)
8260/// #pragma omp parallel default(shared)
8261/// #pragma omp parallel default(firstprivate)
8262/// #pragma omp parallel
8263/// \endcode
8264///
8265/// ``ompDefaultClause()`` matches ``default(none)``, ``default(shared)``, and
8266/// ``default(firstprivate)``
8267extern const internal::VariadicDynCastAllOfMatcher<OMPClause, OMPDefaultClause>
8268 ompDefaultClause;
8269
8270/// Matches if the OpenMP ``default`` clause has ``none`` kind specified.
8271///
8272/// Given
8273///
8274/// \code
8275/// #pragma omp parallel
8276/// #pragma omp parallel default(none)
8277/// #pragma omp parallel default(shared)
8278/// #pragma omp parallel default(firstprivate)
8279/// \endcode
8280///
8281/// ``ompDefaultClause(isNoneKind())`` matches only ``default(none)``.
8282AST_MATCHER(OMPDefaultClause, isNoneKind)namespace internal { class matcher_isNoneKindMatcher : public
::clang::ast_matchers::internal::MatcherInterface<OMPDefaultClause
> { public: explicit matcher_isNoneKindMatcher() = default
; bool matches(const OMPDefaultClause &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<OMPDefaultClause
> isNoneKind() { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_isNoneKindMatcher()); } inline bool internal
::matcher_isNoneKindMatcher::matches( const OMPDefaultClause &
Node, ::clang::ast_matchers::internal::ASTMatchFinder *Finder
, ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{
8283 return Node.getDefaultKind() == llvm::omp::OMP_DEFAULT_none;
8284}
8285
8286/// Matches if the OpenMP ``default`` clause has ``shared`` kind specified.
8287///
8288/// Given
8289///
8290/// \code
8291/// #pragma omp parallel
8292/// #pragma omp parallel default(none)
8293/// #pragma omp parallel default(shared)
8294/// #pragma omp parallel default(firstprivate)
8295/// \endcode
8296///
8297/// ``ompDefaultClause(isSharedKind())`` matches only ``default(shared)``.
8298AST_MATCHER(OMPDefaultClause, isSharedKind)namespace internal { class matcher_isSharedKindMatcher : public
::clang::ast_matchers::internal::MatcherInterface<OMPDefaultClause
> { public: explicit matcher_isSharedKindMatcher() = default
; bool matches(const OMPDefaultClause &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; }; } inline
::clang::ast_matchers::internal::Matcher<OMPDefaultClause
> isSharedKind() { return ::clang::ast_matchers::internal::
makeMatcher( new internal::matcher_isSharedKindMatcher()); } inline
bool internal::matcher_isSharedKindMatcher::matches( const OMPDefaultClause
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
8299 return Node.getDefaultKind() == llvm::omp::OMP_DEFAULT_shared;
8300}
8301
8302/// Matches if the OpenMP ``default`` clause has ``firstprivate`` kind
8303/// specified.
8304///
8305/// Given
8306///
8307/// \code
8308/// #pragma omp parallel
8309/// #pragma omp parallel default(none)
8310/// #pragma omp parallel default(shared)
8311/// #pragma omp parallel default(firstprivate)
8312/// \endcode
8313///
8314/// ``ompDefaultClause(isFirstPrivateKind())`` matches only
8315/// ``default(firstprivate)``.
8316AST_MATCHER(OMPDefaultClause, isFirstPrivateKind)namespace internal { class matcher_isFirstPrivateKindMatcher :
public ::clang::ast_matchers::internal::MatcherInterface<
OMPDefaultClause> { public: explicit matcher_isFirstPrivateKindMatcher
() = default; bool matches(const OMPDefaultClause &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
override; }; } inline ::clang::ast_matchers::internal::Matcher
<OMPDefaultClause> isFirstPrivateKind() { return ::clang
::ast_matchers::internal::makeMatcher( new internal::matcher_isFirstPrivateKindMatcher
()); } inline bool internal::matcher_isFirstPrivateKindMatcher
::matches( const OMPDefaultClause &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
8317 return Node.getDefaultKind() == llvm::omp::OMP_DEFAULT_firstprivate;
8318}
8319
8320/// Matches if the OpenMP directive is allowed to contain the specified OpenMP
8321/// clause kind.
8322///
8323/// Given
8324///
8325/// \code
8326/// #pragma omp parallel
8327/// #pragma omp parallel for
8328/// #pragma omp for
8329/// \endcode
8330///
8331/// `ompExecutableDirective(isAllowedToContainClause(OMPC_default))`` matches
8332/// ``omp parallel`` and ``omp parallel for``.
8333///
8334/// If the matcher is use from clang-query, ``OpenMPClauseKind`` parameter
8335/// should be passed as a quoted string. e.g.,
8336/// ``isAllowedToContainClauseKind("OMPC_default").``
8337AST_MATCHER_P(OMPExecutableDirective, isAllowedToContainClauseKind,namespace internal { class matcher_isAllowedToContainClauseKind0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
OMPExecutableDirective> { public: explicit matcher_isAllowedToContainClauseKind0Matcher
( OpenMPClauseKind const &ACKind) : CKind(ACKind) {} bool
matches(const OMPExecutableDirective &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: OpenMPClauseKind
CKind; }; } inline ::clang::ast_matchers::internal::Matcher<
OMPExecutableDirective> isAllowedToContainClauseKind( OpenMPClauseKind
const &CKind) { return ::clang::ast_matchers::internal::
makeMatcher( new internal::matcher_isAllowedToContainClauseKind0Matcher
(CKind)); } typedef ::clang::ast_matchers::internal::Matcher<
OMPExecutableDirective> ( &isAllowedToContainClauseKind_Type0
)(OpenMPClauseKind const &CKind); inline bool internal::matcher_isAllowedToContainClauseKind0Matcher
::matches( const OMPExecutableDirective &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
8338 OpenMPClauseKind, CKind)namespace internal { class matcher_isAllowedToContainClauseKind0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
OMPExecutableDirective> { public: explicit matcher_isAllowedToContainClauseKind0Matcher
( OpenMPClauseKind const &ACKind) : CKind(ACKind) {} bool
matches(const OMPExecutableDirective &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: OpenMPClauseKind
CKind; }; } inline ::clang::ast_matchers::internal::Matcher<
OMPExecutableDirective> isAllowedToContainClauseKind( OpenMPClauseKind
const &CKind) { return ::clang::ast_matchers::internal::
makeMatcher( new internal::matcher_isAllowedToContainClauseKind0Matcher
(CKind)); } typedef ::clang::ast_matchers::internal::Matcher<
OMPExecutableDirective> ( &isAllowedToContainClauseKind_Type0
)(OpenMPClauseKind const &CKind); inline bool internal::matcher_isAllowedToContainClauseKind0Matcher
::matches( const OMPExecutableDirective &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
8339 return llvm::omp::isAllowedClauseForDirective(
8340 Node.getDirectiveKind(), CKind,
8341 Finder->getASTContext().getLangOpts().OpenMP);
8342}
8343
8344//----------------------------------------------------------------------------//
8345// End OpenMP handling.
8346//----------------------------------------------------------------------------//
8347
8348} // namespace ast_matchers
8349} // namespace clang
8350
8351#endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERS_H

/build/llvm-toolchain-snapshot-15~++20220212111237+869c066ca8a4/clang/include/clang/ASTMatchers/ASTMatchersInternal.h

1//===- ASTMatchersInternal.h - Structural query framework -------*- C++ -*-===//
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// Matchers are methods that return a Matcher<T> which provides a method
12// Matches(...) which is a predicate on an AST node. The Matches method's
13// parameters define the context of the match, which allows matchers to recurse
14// or store the current node as bound to a specific string, so that it can be
15// retrieved later.
16//
17// In general, matchers have two parts:
18// 1. A function Matcher<T> MatcherName(<arguments>) which returns a Matcher<T>
19// based on the arguments and optionally on template type deduction based
20// on the arguments. Matcher<T>s form an implicit reverse hierarchy
21// to clang's AST class hierarchy, meaning that you can use a Matcher<Base>
22// everywhere a Matcher<Derived> is required.
23// 2. An implementation of a class derived from MatcherInterface<T>.
24//
25// The matcher functions are defined in ASTMatchers.h. To make it possible
26// to implement both the matcher function and the implementation of the matcher
27// interface in one place, ASTMatcherMacros.h defines macros that allow
28// implementing a matcher in a single place.
29//
30// This file contains the base classes needed to construct the actual matchers.
31//
32//===----------------------------------------------------------------------===//
33
34#ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H
35#define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H
36
37#include "clang/AST/ASTTypeTraits.h"
38#include "clang/AST/Decl.h"
39#include "clang/AST/DeclCXX.h"
40#include "clang/AST/DeclFriend.h"
41#include "clang/AST/DeclTemplate.h"
42#include "clang/AST/Expr.h"
43#include "clang/AST/ExprCXX.h"
44#include "clang/AST/ExprObjC.h"
45#include "clang/AST/NestedNameSpecifier.h"
46#include "clang/AST/Stmt.h"
47#include "clang/AST/TemplateName.h"
48#include "clang/AST/Type.h"
49#include "clang/AST/TypeLoc.h"
50#include "clang/Basic/LLVM.h"
51#include "clang/Basic/OperatorKinds.h"
52#include "llvm/ADT/APFloat.h"
53#include "llvm/ADT/ArrayRef.h"
54#include "llvm/ADT/IntrusiveRefCntPtr.h"
55#include "llvm/ADT/None.h"
56#include "llvm/ADT/Optional.h"
57#include "llvm/ADT/STLExtras.h"
58#include "llvm/ADT/SmallVector.h"
59#include "llvm/ADT/StringRef.h"
60#include "llvm/ADT/iterator.h"
61#include "llvm/Support/Casting.h"
62#include "llvm/Support/ManagedStatic.h"
63#include "llvm/Support/Regex.h"
64#include <algorithm>
65#include <cassert>
66#include <cstddef>
67#include <cstdint>
68#include <map>
69#include <memory>
70#include <string>
71#include <tuple>
72#include <type_traits>
73#include <utility>
74#include <vector>
75
76namespace clang {
77
78class ASTContext;
79
80namespace ast_matchers {
81
82class BoundNodes;
83
84namespace internal {
85
86/// A type-list implementation.
87///
88/// A "linked list" of types, accessible by using the ::head and ::tail
89/// typedefs.
90template <typename... Ts> struct TypeList {}; // Empty sentinel type list.
91
92template <typename T1, typename... Ts> struct TypeList<T1, Ts...> {
93 /// The first type on the list.
94 using head = T1;
95
96 /// A sublist with the tail. ie everything but the head.
97 ///
98 /// This type is used to do recursion. TypeList<>/EmptyTypeList indicates the
99 /// end of the list.
100 using tail = TypeList<Ts...>;
101};
102
103/// The empty type list.
104using EmptyTypeList = TypeList<>;
105
106/// Helper meta-function to determine if some type \c T is present or
107/// a parent type in the list.
108template <typename AnyTypeList, typename T> struct TypeListContainsSuperOf {
109 static const bool value =
110 std::is_base_of<typename AnyTypeList::head, T>::value ||
111 TypeListContainsSuperOf<typename AnyTypeList::tail, T>::value;
112};
113template <typename T> struct TypeListContainsSuperOf<EmptyTypeList, T> {
114 static const bool value = false;
115};
116
117/// Variadic function object.
118///
119/// Most of the functions below that use VariadicFunction could be implemented
120/// using plain C++11 variadic functions, but the function object allows us to
121/// capture it on the dynamic matcher registry.
122template <typename ResultT, typename ArgT,
123 ResultT (*Func)(ArrayRef<const ArgT *>)>
124struct VariadicFunction {
125 ResultT operator()() const { return Func(None); }
126
127 template <typename... ArgsT>
128 ResultT operator()(const ArgT &Arg1, const ArgsT &... Args) const {
129 return Execute(Arg1, static_cast<const ArgT &>(Args)...);
130 }
131
132 // We also allow calls with an already created array, in case the caller
133 // already had it.
134 ResultT operator()(ArrayRef<ArgT> Args) const {
135 SmallVector<const ArgT*, 8> InnerArgs;
136 for (const ArgT &Arg : Args)
137 InnerArgs.push_back(&Arg);
138 return Func(InnerArgs);
139 }
140
141private:
142 // Trampoline function to allow for implicit conversions to take place
143 // before we make the array.
144 template <typename... ArgsT> ResultT Execute(const ArgsT &... Args) const {
145 const ArgT *const ArgsArray[] = {&Args...};
146 return Func(ArrayRef<const ArgT *>(ArgsArray, sizeof...(ArgsT)));
147 }
148};
149
150/// Unifies obtaining the underlying type of a regular node through
151/// `getType` and a TypedefNameDecl node through `getUnderlyingType`.
152inline QualType getUnderlyingType(const Expr &Node) { return Node.getType(); }
153
154inline QualType getUnderlyingType(const ValueDecl &Node) {
155 return Node.getType();
156}
157inline QualType getUnderlyingType(const TypedefNameDecl &Node) {
158 return Node.getUnderlyingType();
159}
160inline QualType getUnderlyingType(const FriendDecl &Node) {
161 if (const TypeSourceInfo *TSI = Node.getFriendType())
162 return TSI->getType();
163 return QualType();
164}
165inline QualType getUnderlyingType(const CXXBaseSpecifier &Node) {
166 return Node.getType();
167}
168
169/// Unifies obtaining a `TypeSourceInfo` from different node types.
170template <typename T,
171 std::enable_if_t<TypeListContainsSuperOf<
172 TypeList<CXXBaseSpecifier, CXXCtorInitializer,
173 CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr,
174 CompoundLiteralExpr, DeclaratorDecl, ObjCPropertyDecl,
175 TemplateArgumentLoc, TypedefNameDecl>,
176 T>::value> * = nullptr>
177inline TypeSourceInfo *GetTypeSourceInfo(const T &Node) {
178 return Node.getTypeSourceInfo();
179}
180template <typename T,
181 std::enable_if_t<TypeListContainsSuperOf<
182 TypeList<CXXFunctionalCastExpr, ExplicitCastExpr>, T>::value> * =
183 nullptr>
184inline TypeSourceInfo *GetTypeSourceInfo(const T &Node) {
185 return Node.getTypeInfoAsWritten();
186}
187inline TypeSourceInfo *GetTypeSourceInfo(const BlockDecl &Node) {
188 return Node.getSignatureAsWritten();
189}
190inline TypeSourceInfo *GetTypeSourceInfo(const CXXNewExpr &Node) {
191 return Node.getAllocatedTypeSourceInfo();
192}
193inline TypeSourceInfo *
194GetTypeSourceInfo(const ClassTemplateSpecializationDecl &Node) {
195 return Node.getTypeAsWritten();
196}
197
198/// Unifies obtaining the FunctionProtoType pointer from both
199/// FunctionProtoType and FunctionDecl nodes..
200inline const FunctionProtoType *
201getFunctionProtoType(const FunctionProtoType &Node) {
202 return &Node;
203}
204
205inline const FunctionProtoType *getFunctionProtoType(const FunctionDecl &Node) {
206 return Node.getType()->getAs<FunctionProtoType>();
207}
208
209/// Unifies obtaining the access specifier from Decl and CXXBaseSpecifier nodes.
210inline clang::AccessSpecifier getAccessSpecifier(const Decl &Node) {
211 return Node.getAccess();
212}
213
214inline clang::AccessSpecifier getAccessSpecifier(const CXXBaseSpecifier &Node) {
215 return Node.getAccessSpecifier();
216}
217
218/// Internal version of BoundNodes. Holds all the bound nodes.
219class BoundNodesMap {
220public:
221 /// Adds \c Node to the map with key \c ID.
222 ///
223 /// The node's base type should be in NodeBaseType or it will be unaccessible.
224 void addNode(StringRef ID, const DynTypedNode &DynNode) {
225 NodeMap[std::string(ID)] = DynNode;
226 }
227
228 /// Returns the AST node bound to \c ID.
229 ///
230 /// Returns NULL if there was no node bound to \c ID or if there is a node but
231 /// it cannot be converted to the specified type.
232 template <typename T>
233 const T *getNodeAs(StringRef ID) const {
234 IDToNodeMap::const_iterator It = NodeMap.find(ID);
235 if (It == NodeMap.end()) {
3
Calling 'operator=='
6
Returning from 'operator=='
7
Taking false branch
22
Calling 'operator=='
25
Returning from 'operator=='
26
Taking false branch
41
Calling 'operator=='
44
Returning from 'operator=='
45
Taking false branch
60
Calling 'operator=='
63
Returning from 'operator=='
64
Taking false branch
236 return nullptr;
237 }
238 return It->second.get<T>();
8
Calling 'DynTypedNode::get'
15
Returning from 'DynTypedNode::get'
16
Returning null pointer, which participates in a condition later
27
Calling 'DynTypedNode::get'
34
Returning from 'DynTypedNode::get'
35
Returning null pointer, which participates in a condition later
46
Calling 'DynTypedNode::get'
53
Returning from 'DynTypedNode::get'
54
Returning null pointer, which participates in a condition later
65
Calling 'DynTypedNode::get'
72
Returning from 'DynTypedNode::get'
73
Returning pointer, which participates in a condition later
239 }
240
241 DynTypedNode getNode(StringRef ID) const {
242 IDToNodeMap::const_iterator It = NodeMap.find(ID);
243 if (It == NodeMap.end()) {
244 return DynTypedNode();
245 }
246 return It->second;
247 }
248
249 /// Imposes an order on BoundNodesMaps.
250 bool operator<(const BoundNodesMap &Other) const {
251 return NodeMap < Other.NodeMap;
252 }
253
254 /// A map from IDs to the bound nodes.
255 ///
256 /// Note that we're using std::map here, as for memoization:
257 /// - we need a comparison operator
258 /// - we need an assignment operator
259 using IDToNodeMap = std::map<std::string, DynTypedNode, std::less<>>;
260
261 const IDToNodeMap &getMap() const {
262 return NodeMap;
263 }
264
265 /// Returns \c true if this \c BoundNodesMap can be compared, i.e. all
266 /// stored nodes have memoization data.
267 bool isComparable() const {
268 for (const auto &IDAndNode : NodeMap) {
269 if (!IDAndNode.second.getMemoizationData())
270 return false;
271 }
272 return true;
273 }
274
275private:
276 IDToNodeMap NodeMap;
277};
278
279/// Creates BoundNodesTree objects.
280///
281/// The tree builder is used during the matching process to insert the bound
282/// nodes from the Id matcher.
283class BoundNodesTreeBuilder {
284public:
285 /// A visitor interface to visit all BoundNodes results for a
286 /// BoundNodesTree.
287 class Visitor {
288 public:
289 virtual ~Visitor() = default;
290
291 /// Called multiple times during a single call to VisitMatches(...).
292 ///
293 /// 'BoundNodesView' contains the bound nodes for a single match.
294 virtual void visitMatch(const BoundNodes& BoundNodesView) = 0;
295 };
296
297 /// Add a binding from an id to a node.
298 void setBinding(StringRef Id, const DynTypedNode &DynNode) {
299 if (Bindings.empty())
300 Bindings.emplace_back();
301 for (BoundNodesMap &Binding : Bindings)
302 Binding.addNode(Id, DynNode);
303 }
304
305 /// Adds a branch in the tree.
306 void addMatch(const BoundNodesTreeBuilder &Bindings);
307
308 /// Visits all matches that this BoundNodesTree represents.
309 ///
310 /// The ownership of 'ResultVisitor' remains at the caller.
311 void visitMatches(Visitor* ResultVisitor);
312
313 template <typename ExcludePredicate>
314 bool removeBindings(const ExcludePredicate &Predicate) {
315 llvm::erase_if(Bindings, Predicate);
316 return !Bindings.empty();
317 }
318
319 /// Imposes an order on BoundNodesTreeBuilders.
320 bool operator<(const BoundNodesTreeBuilder &Other) const {
321 return Bindings < Other.Bindings;
322 }
323
324 /// Returns \c true if this \c BoundNodesTreeBuilder can be compared,
325 /// i.e. all stored node maps have memoization data.
326 bool isComparable() const {
327 for (const BoundNodesMap &NodesMap : Bindings) {
328 if (!NodesMap.isComparable())
329 return false;
330 }
331 return true;
332 }
333
334private:
335 SmallVector<BoundNodesMap, 1> Bindings;
336};
337
338class ASTMatchFinder;
339
340/// Generic interface for all matchers.
341///
342/// Used by the implementation of Matcher<T> and DynTypedMatcher.
343/// In general, implement MatcherInterface<T> or SingleNodeMatcherInterface<T>
344/// instead.
345class DynMatcherInterface
346 : public llvm::ThreadSafeRefCountedBase<DynMatcherInterface> {
347public:
348 virtual ~DynMatcherInterface() = default;
349
350 /// Returns true if \p DynNode can be matched.
351 ///
352 /// May bind \p DynNode to an ID via \p Builder, or recurse into
353 /// the AST via \p Finder.
354 virtual bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
355 BoundNodesTreeBuilder *Builder) const = 0;
356
357 virtual llvm::Optional<clang::TraversalKind> TraversalKind() const {
358 return llvm::None;
359 }
360};
361
362/// Generic interface for matchers on an AST node of type T.
363///
364/// Implement this if your matcher may need to inspect the children or
365/// descendants of the node or bind matched nodes to names. If you are
366/// writing a simple matcher that only inspects properties of the
367/// current node and doesn't care about its children or descendants,
368/// implement SingleNodeMatcherInterface instead.
369template <typename T>
370class MatcherInterface : public DynMatcherInterface {
371public:
372 /// Returns true if 'Node' can be matched.
373 ///
374 /// May bind 'Node' to an ID via 'Builder', or recurse into
375 /// the AST via 'Finder'.
376 virtual bool matches(const T &Node,
377 ASTMatchFinder *Finder,
378 BoundNodesTreeBuilder *Builder) const = 0;
379
380 bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
381 BoundNodesTreeBuilder *Builder) const override {
382 return matches(DynNode.getUnchecked<T>(), Finder, Builder);
383 }
384};
385
386/// Interface for matchers that only evaluate properties on a single
387/// node.
388template <typename T>
389class SingleNodeMatcherInterface : public MatcherInterface<T> {
390public:
391 /// Returns true if the matcher matches the provided node.
392 ///
393 /// A subclass must implement this instead of Matches().
394 virtual bool matchesNode(const T &Node) const = 0;
395
396private:
397 /// Implements MatcherInterface::Matches.
398 bool matches(const T &Node,
399 ASTMatchFinder * /* Finder */,
400 BoundNodesTreeBuilder * /* Builder */) const override {
401 return matchesNode(Node);
402 }
403};
404
405template <typename> class Matcher;
406
407/// Matcher that works on a \c DynTypedNode.
408///
409/// It is constructed from a \c Matcher<T> object and redirects most calls to
410/// underlying matcher.
411/// It checks whether the \c DynTypedNode is convertible into the type of the
412/// underlying matcher and then do the actual match on the actual node, or
413/// return false if it is not convertible.
414class DynTypedMatcher {
415public:
416 /// Takes ownership of the provided implementation pointer.
417 template <typename T>
418 DynTypedMatcher(MatcherInterface<T> *Implementation)
419 : SupportedKind(ASTNodeKind::getFromNodeKind<T>()),
420 RestrictKind(SupportedKind), Implementation(Implementation) {}
421
422 /// Construct from a variadic function.
423 enum VariadicOperator {
424 /// Matches nodes for which all provided matchers match.
425 VO_AllOf,
426
427 /// Matches nodes for which at least one of the provided matchers
428 /// matches.
429 VO_AnyOf,
430
431 /// Matches nodes for which at least one of the provided matchers
432 /// matches, but doesn't stop at the first match.
433 VO_EachOf,
434
435 /// Matches any node but executes all inner matchers to find result
436 /// bindings.
437 VO_Optionally,
438
439 /// Matches nodes that do not match the provided matcher.
440 ///
441 /// Uses the variadic matcher interface, but fails if
442 /// InnerMatchers.size() != 1.
443 VO_UnaryNot
444 };
445
446 static DynTypedMatcher
447 constructVariadic(VariadicOperator Op, ASTNodeKind SupportedKind,
448 std::vector<DynTypedMatcher> InnerMatchers);
449
450 static DynTypedMatcher
451 constructRestrictedWrapper(const DynTypedMatcher &InnerMatcher,
452 ASTNodeKind RestrictKind);
453
454 /// Get a "true" matcher for \p NodeKind.
455 ///
456 /// It only checks that the node is of the right kind.
457 static DynTypedMatcher trueMatcher(ASTNodeKind NodeKind);
458
459 void setAllowBind(bool AB) { AllowBind = AB; }
460
461 /// Check whether this matcher could ever match a node of kind \p Kind.
462 /// \return \c false if this matcher will never match such a node. Otherwise,
463 /// return \c true.
464 bool canMatchNodesOfKind(ASTNodeKind Kind) const;
465
466 /// Return a matcher that points to the same implementation, but
467 /// restricts the node types for \p Kind.
468 DynTypedMatcher dynCastTo(const ASTNodeKind Kind) const;
469
470 /// Return a matcher that that points to the same implementation, but sets the
471 /// traversal kind.
472 ///
473 /// If the traversal kind is already set, then \c TK overrides it.
474 DynTypedMatcher withTraversalKind(TraversalKind TK);
475
476 /// Returns true if the matcher matches the given \c DynNode.
477 bool matches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
478 BoundNodesTreeBuilder *Builder) const;
479
480 /// Same as matches(), but skips the kind check.
481 ///
482 /// It is faster, but the caller must ensure the node is valid for the
483 /// kind of this matcher.
484 bool matchesNoKindCheck(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
485 BoundNodesTreeBuilder *Builder) const;
486
487 /// Bind the specified \p ID to the matcher.
488 /// \return A new matcher with the \p ID bound to it if this matcher supports
489 /// binding. Otherwise, returns an empty \c Optional<>.
490 llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const;
491
492 /// Returns a unique \p ID for the matcher.
493 ///
494 /// Casting a Matcher<T> to Matcher<U> creates a matcher that has the
495 /// same \c Implementation pointer, but different \c RestrictKind. We need to
496 /// include both in the ID to make it unique.
497 ///
498 /// \c MatcherIDType supports operator< and provides strict weak ordering.
499 using MatcherIDType = std::pair<ASTNodeKind, uint64_t>;
500 MatcherIDType getID() const {
501 /// FIXME: Document the requirements this imposes on matcher
502 /// implementations (no new() implementation_ during a Matches()).
503 return std::make_pair(RestrictKind,
504 reinterpret_cast<uint64_t>(Implementation.get()));
505 }
506
507 /// Returns the type this matcher works on.
508 ///
509 /// \c matches() will always return false unless the node passed is of this
510 /// or a derived type.
511 ASTNodeKind getSupportedKind() const { return SupportedKind; }
512
513 /// Returns \c true if the passed \c DynTypedMatcher can be converted
514 /// to a \c Matcher<T>.
515 ///
516 /// This method verifies that the underlying matcher in \c Other can process
517 /// nodes of types T.
518 template <typename T> bool canConvertTo() const {
519 return canConvertTo(ASTNodeKind::getFromNodeKind<T>());
520 }
521 bool canConvertTo(ASTNodeKind To) const;
522
523 /// Construct a \c Matcher<T> interface around the dynamic matcher.
524 ///
525 /// This method asserts that \c canConvertTo() is \c true. Callers
526 /// should call \c canConvertTo() first to make sure that \c this is
527 /// compatible with T.
528 template <typename T> Matcher<T> convertTo() const {
529 assert(canConvertTo<T>())(static_cast <bool> (canConvertTo<T>()) ? void (0
) : __assert_fail ("canConvertTo<T>()", "clang/include/clang/ASTMatchers/ASTMatchersInternal.h"
, 529, __extension__ __PRETTY_FUNCTION__))
;
530 return unconditionalConvertTo<T>();
531 }
532
533 /// Same as \c convertTo(), but does not check that the underlying
534 /// matcher can handle a value of T.
535 ///
536 /// If it is not compatible, then this matcher will never match anything.
537 template <typename T> Matcher<T> unconditionalConvertTo() const;
538
539 /// Returns the \c TraversalKind respected by calls to `match()`, if any.
540 ///
541 /// Most matchers will not have a traversal kind set, instead relying on the
542 /// surrounding context. For those, \c llvm::None is returned.
543 llvm::Optional<clang::TraversalKind> getTraversalKind() const {
544 return Implementation->TraversalKind();
545 }
546
547private:
548 DynTypedMatcher(ASTNodeKind SupportedKind, ASTNodeKind RestrictKind,
549 IntrusiveRefCntPtr<DynMatcherInterface> Implementation)
550 : SupportedKind(SupportedKind), RestrictKind(RestrictKind),
551 Implementation(std::move(Implementation)) {}
552
553 bool AllowBind = false;
554 ASTNodeKind SupportedKind;
555
556 /// A potentially stricter node kind.
557 ///
558 /// It allows to perform implicit and dynamic cast of matchers without
559 /// needing to change \c Implementation.
560 ASTNodeKind RestrictKind;
561 IntrusiveRefCntPtr<DynMatcherInterface> Implementation;
562};
563
564/// Wrapper of a MatcherInterface<T> *that allows copying.
565///
566/// A Matcher<Base> can be used anywhere a Matcher<Derived> is
567/// required. This establishes an is-a relationship which is reverse
568/// to the AST hierarchy. In other words, Matcher<T> is contravariant
569/// with respect to T. The relationship is built via a type conversion
570/// operator rather than a type hierarchy to be able to templatize the
571/// type hierarchy instead of spelling it out.
572template <typename T>
573class Matcher {
574public:
575 /// Takes ownership of the provided implementation pointer.
576 explicit Matcher(MatcherInterface<T> *Implementation)
577 : Implementation(Implementation) {}
578
579 /// Implicitly converts \c Other to a Matcher<T>.
580 ///
581 /// Requires \c T to be derived from \c From.
582 template <typename From>
583 Matcher(const Matcher<From> &Other,
584 std::enable_if_t<std::is_base_of<From, T>::value &&
585 !std::is_same<From, T>::value> * = nullptr)
586 : Implementation(restrictMatcher(Other.Implementation)) {
587 assert(Implementation.getSupportedKind().isSame((static_cast <bool> (Implementation.getSupportedKind().
isSame( ASTNodeKind::getFromNodeKind<T>())) ? void (0) :
__assert_fail ("Implementation.getSupportedKind().isSame( ASTNodeKind::getFromNodeKind<T>())"
, "clang/include/clang/ASTMatchers/ASTMatchersInternal.h", 588
, __extension__ __PRETTY_FUNCTION__))
588 ASTNodeKind::getFromNodeKind<T>()))(static_cast <bool> (Implementation.getSupportedKind().
isSame( ASTNodeKind::getFromNodeKind<T>())) ? void (0) :
__assert_fail ("Implementation.getSupportedKind().isSame( ASTNodeKind::getFromNodeKind<T>())"
, "clang/include/clang/ASTMatchers/ASTMatchersInternal.h", 588
, __extension__ __PRETTY_FUNCTION__))
;
589 }
590
591 /// Implicitly converts \c Matcher<Type> to \c Matcher<QualType>.
592 ///
593 /// The resulting matcher is not strict, i.e. ignores qualifiers.
594 template <typename TypeT>
595 Matcher(const Matcher<TypeT> &Other,
596 std::enable_if_t<std::is_same<T, QualType>::value &&
597 std::is_same<TypeT, Type>::value> * = nullptr)
598 : Implementation(new TypeToQualType<TypeT>(Other)) {}
599
600 /// Convert \c this into a \c Matcher<T> by applying dyn_cast<> to the
601 /// argument.
602 /// \c To must be a base class of \c T.
603 template <typename To> Matcher<To> dynCastTo() const & {
604 static_assert(std::is_base_of<To, T>::value, "Invalid dynCast call.");
605 return Matcher<To>(Implementation);
606 }
607
608 template <typename To> Matcher<To> dynCastTo() && {
609 static_assert(std::is_base_of<To, T>::value, "Invalid dynCast call.");
610 return Matcher<To>(std::move(Implementation));
611 }
612
613 /// Forwards the call to the underlying MatcherInterface<T> pointer.
614 bool matches(const T &Node,
615 ASTMatchFinder *Finder,
616 BoundNodesTreeBuilder *Builder) const {
617 return Implementation.matches(DynTypedNode::create(Node), Finder, Builder);
618 }
619
620 /// Returns an ID that uniquely identifies the matcher.
621 DynTypedMatcher::MatcherIDType getID() const {
622 return Implementation.getID();
623 }
624
625 /// Extract the dynamic matcher.
626 ///
627 /// The returned matcher keeps the same restrictions as \c this and remembers
628 /// that it is meant to support nodes of type \c T.
629 operator DynTypedMatcher() const & { return Implementation; }
630
631 operator DynTypedMatcher() && { return std::move(Implementation); }
632
633 /// Allows the conversion of a \c Matcher<Type> to a \c
634 /// Matcher<QualType>.
635 ///
636 /// Depending on the constructor argument, the matcher is either strict, i.e.
637 /// does only matches in the absence of qualifiers, or not, i.e. simply
638 /// ignores any qualifiers.
639 template <typename TypeT>
640 class TypeToQualType : public MatcherInterface<QualType> {
641 const DynTypedMatcher InnerMatcher;
642
643 public:
644 TypeToQualType(const Matcher<TypeT> &InnerMatcher)
645 : InnerMatcher(InnerMatcher) {}
646
647 bool matches(const QualType &Node, ASTMatchFinder *Finder,
648 BoundNodesTreeBuilder *Builder) const override {
649 if (Node.isNull())
650 return false;
651 return this->InnerMatcher.matches(DynTypedNode::create(*Node), Finder,
652 Builder);
653 }
654
655 llvm::Optional<clang::TraversalKind> TraversalKind() const override {
656 return this->InnerMatcher.getTraversalKind();
657 }
658 };
659
660private:
661 // For Matcher<T> <=> Matcher<U> conversions.
662 template <typename U> friend class Matcher;
663
664 // For DynTypedMatcher::unconditionalConvertTo<T>.
665 friend class DynTypedMatcher;
666
667 static DynTypedMatcher restrictMatcher(const DynTypedMatcher &Other) {
668 return Other.dynCastTo(ASTNodeKind::getFromNodeKind<T>());
669 }
670
671 explicit Matcher(const DynTypedMatcher &Implementation)
672 : Implementation(restrictMatcher(Implementation)) {
673 assert(this->Implementation.getSupportedKind().isSame((static_cast <bool> (this->Implementation.getSupportedKind
().isSame( ASTNodeKind::getFromNodeKind<T>())) ? void (
0) : __assert_fail ("this->Implementation.getSupportedKind().isSame( ASTNodeKind::getFromNodeKind<T>())"
, "clang/include/clang/ASTMatchers/ASTMatchersInternal.h", 674
, __extension__ __PRETTY_FUNCTION__))
674 ASTNodeKind::getFromNodeKind<T>()))(static_cast <bool> (this->Implementation.getSupportedKind
().isSame( ASTNodeKind::getFromNodeKind<T>())) ? void (
0) : __assert_fail ("this->Implementation.getSupportedKind().isSame( ASTNodeKind::getFromNodeKind<T>())"
, "clang/include/clang/ASTMatchers/ASTMatchersInternal.h", 674
, __extension__ __PRETTY_FUNCTION__))
;
675 }
676
677 DynTypedMatcher Implementation;
678}; // class Matcher
679
680/// A convenient helper for creating a Matcher<T> without specifying
681/// the template type argument.
682template <typename T>
683inline Matcher<T> makeMatcher(MatcherInterface<T> *Implementation) {
684 return Matcher<T>(Implementation);
685}
686
687/// Interface that allows matchers to traverse the AST.
688/// FIXME: Find a better name.
689///
690/// This provides three entry methods for each base node type in the AST:
691/// - \c matchesChildOf:
692/// Matches a matcher on every child node of the given node. Returns true
693/// if at least one child node could be matched.
694/// - \c matchesDescendantOf:
695/// Matches a matcher on all descendant nodes of the given node. Returns true
696/// if at least one descendant matched.
697/// - \c matchesAncestorOf:
698/// Matches a matcher on all ancestors of the given node. Returns true if
699/// at least one ancestor matched.
700///
701/// FIXME: Currently we only allow Stmt and Decl nodes to start a traversal.
702/// In the future, we want to implement this for all nodes for which it makes
703/// sense. In the case of matchesAncestorOf, we'll want to implement it for
704/// all nodes, as all nodes have ancestors.
705class ASTMatchFinder {
706public:
707 /// Defines how bindings are processed on recursive matches.
708 enum BindKind {
709 /// Stop at the first match and only bind the first match.
710 BK_First,
711
712 /// Create results for all combinations of bindings that match.
713 BK_All
714 };
715
716 /// Defines which ancestors are considered for a match.
717 enum AncestorMatchMode {
718 /// All ancestors.
719 AMM_All,
720
721 /// Direct parent only.
722 AMM_ParentOnly
723 };
724
725 virtual ~ASTMatchFinder() = default;
726
727 /// Returns true if the given C++ class is directly or indirectly derived
728 /// from a base type matching \c base.
729 ///
730 /// A class is not considered to be derived from itself.
731 virtual bool classIsDerivedFrom(const CXXRecordDecl *Declaration,
732 const Matcher<NamedDecl> &Base,
733 BoundNodesTreeBuilder *Builder,
734 bool Directly) = 0;
735
736 /// Returns true if the given Objective-C class is directly or indirectly
737 /// derived from a base class matching \c base.
738 ///
739 /// A class is not considered to be derived from itself.
740 virtual bool objcClassIsDerivedFrom(const ObjCInterfaceDecl *Declaration,
741 const Matcher<NamedDecl> &Base,
742 BoundNodesTreeBuilder *Builder,
743 bool Directly) = 0;
744
745 template <typename T>
746 bool matchesChildOf(const T &Node, const DynTypedMatcher &Matcher,
747 BoundNodesTreeBuilder *Builder, BindKind Bind) {
748 static_assert(std::is_base_of<Decl, T>::value ||
749 std::is_base_of<Stmt, T>::value ||
750 std::is_base_of<NestedNameSpecifier, T>::value ||
751 std::is_base_of<NestedNameSpecifierLoc, T>::value ||
752 std::is_base_of<TypeLoc, T>::value ||
753 std::is_base_of<QualType, T>::value ||
754 std::is_base_of<Attr, T>::value,
755 "unsupported type for recursive matching");
756 return matchesChildOf(DynTypedNode::create(Node), getASTContext(), Matcher,
757 Builder, Bind);
758 }
759
760 template <typename T>
761 bool matchesDescendantOf(const T &Node, const DynTypedMatcher &Matcher,
762 BoundNodesTreeBuilder *Builder, BindKind Bind) {
763 static_assert(std::is_base_of<Decl, T>::value ||
764 std::is_base_of<Stmt, T>::value ||
765 std::is_base_of<NestedNameSpecifier, T>::value ||
766 std::is_base_of<NestedNameSpecifierLoc, T>::value ||
767 std::is_base_of<TypeLoc, T>::value ||
768 std::is_base_of<QualType, T>::value ||
769 std::is_base_of<Attr, T>::value,
770 "unsupported type for recursive matching");
771 return matchesDescendantOf(DynTypedNode::create(Node), getASTContext(),
772 Matcher, Builder, Bind);
773 }
774
775 // FIXME: Implement support for BindKind.
776 template <typename T>
777 bool matchesAncestorOf(const T &Node, const DynTypedMatcher &Matcher,
778 BoundNodesTreeBuilder *Builder,
779 AncestorMatchMode MatchMode) {
780 static_assert(std::is_base_of<Decl, T>::value ||
781 std::is_base_of<NestedNameSpecifierLoc, T>::value ||
782 std::is_base_of<Stmt, T>::value ||
783 std::is_base_of<TypeLoc, T>::value ||
784 std::is_base_of<Attr, T>::value,
785 "type not allowed for recursive matching");
786 return matchesAncestorOf(DynTypedNode::create(Node), getASTContext(),
787 Matcher, Builder, MatchMode);
788 }
789
790 virtual ASTContext &getASTContext() const = 0;
791
792 virtual bool IsMatchingInASTNodeNotSpelledInSource() const = 0;
793
794 virtual bool IsMatchingInASTNodeNotAsIs() const = 0;
795
796 bool isTraversalIgnoringImplicitNodes() const;
797
798protected:
799 virtual bool matchesChildOf(const DynTypedNode &Node, ASTContext &Ctx,
800 const DynTypedMatcher &Matcher,
801 BoundNodesTreeBuilder *Builder,
802 BindKind Bind) = 0;
803
804 virtual bool matchesDescendantOf(const DynTypedNode &Node, ASTContext &Ctx,
805 const DynTypedMatcher &Matcher,
806 BoundNodesTreeBuilder *Builder,
807 BindKind Bind) = 0;
808
809 virtual bool matchesAncestorOf(const DynTypedNode &Node, ASTContext &Ctx,
810 const DynTypedMatcher &Matcher,
811 BoundNodesTreeBuilder *Builder,
812 AncestorMatchMode MatchMode) = 0;
813private:
814 friend struct ASTChildrenNotSpelledInSourceScope;
815 virtual bool isMatchingChildrenNotSpelledInSource() const = 0;
816 virtual void setMatchingChildrenNotSpelledInSource(bool Set) = 0;
817};
818
819struct ASTChildrenNotSpelledInSourceScope {
820 ASTChildrenNotSpelledInSourceScope(ASTMatchFinder *V, bool B)
821 : MV(V), MB(V->isMatchingChildrenNotSpelledInSource()) {
822 V->setMatchingChildrenNotSpelledInSource(B);
823 }
824 ~ASTChildrenNotSpelledInSourceScope() {
825 MV->setMatchingChildrenNotSpelledInSource(MB);
826 }
827
828private:
829 ASTMatchFinder *MV;
830 bool MB;
831};
832
833/// Specialization of the conversion functions for QualType.
834///
835/// This specialization provides the Matcher<Type>->Matcher<QualType>
836/// conversion that the static API does.
837template <>
838inline Matcher<QualType> DynTypedMatcher::convertTo<QualType>() const {
839 assert(canConvertTo<QualType>())(static_cast <bool> (canConvertTo<QualType>()) ? void
(0) : __assert_fail ("canConvertTo<QualType>()", "clang/include/clang/ASTMatchers/ASTMatchersInternal.h"
, 839, __extension__ __PRETTY_FUNCTION__))
;
840 const ASTNodeKind SourceKind = getSupportedKind();
841 if (SourceKind.isSame(ASTNodeKind::getFromNodeKind<Type>())) {
842 // We support implicit conversion from Matcher<Type> to Matcher<QualType>
843 return unconditionalConvertTo<Type>();
844 }
845 return unconditionalConvertTo<QualType>();
846}
847
848/// Finds the first node in a range that matches the given matcher.
849template <typename MatcherT, typename IteratorT>
850IteratorT matchesFirstInRange(const MatcherT &Matcher, IteratorT Start,
851 IteratorT End, ASTMatchFinder *Finder,
852 BoundNodesTreeBuilder *Builder) {
853 for (IteratorT I = Start; I != End; ++I) {
854 BoundNodesTreeBuilder Result(*Builder);
855 if (Matcher.matches(*I, Finder, &Result)) {
856 *Builder = std::move(Result);
857 return I;
858 }
859 }
860 return End;
861}
862
863/// Finds the first node in a pointer range that matches the given
864/// matcher.
865template <typename MatcherT, typename IteratorT>
866IteratorT matchesFirstInPointerRange(const MatcherT &Matcher, IteratorT Start,
867 IteratorT End, ASTMatchFinder *Finder,
868 BoundNodesTreeBuilder *Builder) {
869 for (IteratorT I = Start; I != End; ++I) {
870 BoundNodesTreeBuilder Result(*Builder);
871 if (Matcher.matches(**I, Finder, &Result)) {
872 *Builder = std::move(Result);
873 return I;
874 }
875 }
876 return End;
877}
878
879template <typename T, std::enable_if_t<!std::is_base_of<FunctionDecl, T>::value>
880 * = nullptr>
881inline bool isDefaultedHelper(const T *) {
882 return false;
883}
884inline bool isDefaultedHelper(const FunctionDecl *FD) {
885 return FD->isDefaulted();
886}
887
888// Metafunction to determine if type T has a member called getDecl.
889template <typename Ty>
890class has_getDecl {
891 using yes = char[1];
892 using no = char[2];
893
894 template <typename Inner>
895 static yes& test(Inner *I, decltype(I->getDecl()) * = nullptr);
896
897 template <typename>
898 static no& test(...);
899
900public:
901 static const bool value = sizeof(test<Ty>(nullptr)) == sizeof(yes);
902};
903
904/// Matches overloaded operators with a specific name.
905///
906/// The type argument ArgT is not used by this matcher but is used by
907/// PolymorphicMatcher and should be StringRef.
908template <typename T, typename ArgT>
909class HasOverloadedOperatorNameMatcher : public SingleNodeMatcherInterface<T> {
910 static_assert(std::is_same<T, CXXOperatorCallExpr>::value ||
911 std::is_base_of<FunctionDecl, T>::value,
912 "unsupported class for matcher");
913 static_assert(std::is_same<ArgT, std::vector<std::string>>::value,
914 "argument type must be std::vector<std::string>");
915
916public:
917 explicit HasOverloadedOperatorNameMatcher(std::vector<std::string> Names)
918 : SingleNodeMatcherInterface<T>(), Names(std::move(Names)) {}
919
920 bool matchesNode(const T &Node) const override {
921 return matchesSpecialized(Node);
922 }
923
924private:
925
926 /// CXXOperatorCallExpr exist only for calls to overloaded operators
927 /// so this function returns true if the call is to an operator of the given
928 /// name.
929 bool matchesSpecialized(const CXXOperatorCallExpr &Node) const {
930 return llvm::is_contained(Names, getOperatorSpelling(Node.getOperator()));
931 }
932
933 /// Returns true only if CXXMethodDecl represents an overloaded
934 /// operator and has the given operator name.
935 bool matchesSpecialized(const FunctionDecl &Node) const {
936 return Node.isOverloadedOperator() &&
937 llvm::is_contained(
938 Names, getOperatorSpelling(Node.getOverloadedOperator()));
939 }
940
941 std::vector<std::string> Names;
942};
943
944/// Matches named declarations with a specific name.
945///
946/// See \c hasName() and \c hasAnyName() in ASTMatchers.h for details.
947class HasNameMatcher : public SingleNodeMatcherInterface<NamedDecl> {
948 public:
949 explicit HasNameMatcher(std::vector<std::string> Names);
950
951 bool matchesNode(const NamedDecl &Node) const override;
952
953private:
954 /// Unqualified match routine.
955 ///
956 /// It is much faster than the full match, but it only works for unqualified
957 /// matches.
958 bool matchesNodeUnqualified(const NamedDecl &Node) const;
959
960 /// Full match routine
961 ///
962 /// Fast implementation for the simple case of a named declaration at
963 /// namespace or RecordDecl scope.
964 /// It is slower than matchesNodeUnqualified, but faster than
965 /// matchesNodeFullSlow.
966 bool matchesNodeFullFast(const NamedDecl &Node) const;
967
968 /// Full match routine
969 ///
970 /// It generates the fully qualified name of the declaration (which is
971 /// expensive) before trying to match.
972 /// It is slower but simple and works on all cases.
973 bool matchesNodeFullSlow(const NamedDecl &Node) const;
974
975 bool UseUnqualifiedMatch;
976 std::vector<std::string> Names;
977};
978
979/// Trampoline function to use VariadicFunction<> to construct a
980/// HasNameMatcher.
981Matcher<NamedDecl> hasAnyNameFunc(ArrayRef<const StringRef *> NameRefs);
982
983/// Trampoline function to use VariadicFunction<> to construct a
984/// hasAnySelector matcher.
985Matcher<ObjCMessageExpr> hasAnySelectorFunc(
986 ArrayRef<const StringRef *> NameRefs);
987
988/// Matches declarations for QualType and CallExpr.
989///
990/// Type argument DeclMatcherT is required by PolymorphicMatcher but
991/// not actually used.
992template <typename T, typename DeclMatcherT>
993class HasDeclarationMatcher : public MatcherInterface<T> {
994 static_assert(std::is_same<DeclMatcherT, Matcher<Decl>>::value,
995 "instantiated with wrong types");
996
997 DynTypedMatcher InnerMatcher;
998
999public:
1000 explicit HasDeclarationMatcher(const Matcher<Decl> &InnerMatcher)
1001 : InnerMatcher(InnerMatcher) {}
1002
1003 bool matches(const T &Node, ASTMatchFinder *Finder,
1004 BoundNodesTreeBuilder *Builder) const override {
1005 return matchesSpecialized(Node, Finder, Builder);
1006 }
1007
1008private:
1009 /// Forwards to matching on the underlying type of the QualType.
1010 bool matchesSpecialized(const QualType &Node, ASTMatchFinder *Finder,
1011 BoundNodesTreeBuilder *Builder) const {
1012 if (Node.isNull())
1013 return false;
1014
1015 return matchesSpecialized(*Node, Finder, Builder);
1016 }
1017
1018 /// Finds the best declaration for a type and returns whether the inner
1019 /// matcher matches on it.
1020 bool matchesSpecialized(const Type &Node, ASTMatchFinder *Finder,
1021 BoundNodesTreeBuilder *Builder) const {
1022 // DeducedType does not have declarations of its own, so
1023 // match the deduced type instead.
1024 if (const auto *S = dyn_cast<DeducedType>(&Node)) {
1025 QualType DT = S->getDeducedType();
1026 return !DT.isNull() ? matchesSpecialized(*DT, Finder, Builder) : false;
1027 }
1028
1029 // First, for any types that have a declaration, extract the declaration and
1030 // match on it.
1031 if (const auto *S = dyn_cast<TagType>(&Node)) {
1032 return matchesDecl(S->getDecl(), Finder, Builder);
1033 }
1034 if (const auto *S = dyn_cast<InjectedClassNameType>(&Node)) {
1035 return matchesDecl(S->getDecl(), Finder, Builder);
1036 }
1037 if (const auto *S = dyn_cast<TemplateTypeParmType>(&Node)) {
1038 return matchesDecl(S->getDecl(), Finder, Builder);
1039 }
1040 if (const auto *S = dyn_cast<TypedefType>(&Node)) {
1041 return matchesDecl(S->getDecl(), Finder, Builder);
1042 }
1043 if (const auto *S = dyn_cast<UnresolvedUsingType>(&Node)) {
1044 return matchesDecl(S->getDecl(), Finder, Builder);
1045 }
1046 if (const auto *S = dyn_cast<ObjCObjectType>(&Node)) {
1047 return matchesDecl(S->getInterface(), Finder, Builder);
1048 }
1049
1050 // A SubstTemplateTypeParmType exists solely to mark a type substitution
1051 // on the instantiated template. As users usually want to match the
1052 // template parameter on the uninitialized template, we can always desugar
1053 // one level without loss of expressivness.
1054 // For example, given:
1055 // template<typename T> struct X { T t; } class A {}; X<A> a;
1056 // The following matcher will match, which otherwise would not:
1057 // fieldDecl(hasType(pointerType())).
1058 if (const auto *S = dyn_cast<SubstTemplateTypeParmType>(&Node)) {
1059 return matchesSpecialized(S->getReplacementType(), Finder, Builder);
1060 }
1061
1062 // For template specialization types, we want to match the template
1063 // declaration, as long as the type is still dependent, and otherwise the
1064 // declaration of the instantiated tag type.
1065 if (const auto *S = dyn_cast<TemplateSpecializationType>(&Node)) {
1066 if (!S->isTypeAlias() && S->isSugared()) {
1067 // If the template is non-dependent, we want to match the instantiated
1068 // tag type.
1069 // For example, given:
1070 // template<typename T> struct X {}; X<int> a;
1071 // The following matcher will match, which otherwise would not:
1072 // templateSpecializationType(hasDeclaration(cxxRecordDecl())).
1073 return matchesSpecialized(*S->desugar(), Finder, Builder);
1074 }
1075 // If the template is dependent or an alias, match the template
1076 // declaration.
1077 return matchesDecl(S->getTemplateName().getAsTemplateDecl(), Finder,
1078 Builder);
1079 }
1080
1081 // FIXME: We desugar elaborated types. This makes the assumption that users
1082 // do never want to match on whether a type is elaborated - there are
1083 // arguments for both sides; for now, continue desugaring.
1084 if (const auto *S = dyn_cast<ElaboratedType>(&Node)) {
1085 return matchesSpecialized(S->desugar(), Finder, Builder);
1086 }
1087 // Similarly types found via using declarations.
1088 // These are *usually* meaningless sugar, and this matches the historical
1089 // behavior prior to the introduction of UsingType.
1090 if (const auto *S = dyn_cast<UsingType>(&Node)) {
1091 return matchesSpecialized(S->desugar(), Finder, Builder);
1092 }
1093 return false;
1094 }
1095
1096 /// Extracts the Decl the DeclRefExpr references and returns whether
1097 /// the inner matcher matches on it.
1098 bool matchesSpecialized(const DeclRefExpr &Node, ASTMatchFinder *Finder,
1099 BoundNodesTreeBuilder *Builder) const {
1100 return matchesDecl(Node.getDecl(), Finder, Builder);
1101 }
1102
1103 /// Extracts the Decl of the callee of a CallExpr and returns whether
1104 /// the inner matcher matches on it.
1105 bool matchesSpecialized(const CallExpr &Node, ASTMatchFinder *Finder,
1106 BoundNodesTreeBuilder *Builder) const {
1107 return matchesDecl(Node.getCalleeDecl(), Finder, Builder);
1108 }
1109
1110 /// Extracts the Decl of the constructor call and returns whether the
1111 /// inner matcher matches on it.
1112 bool matchesSpecialized(const CXXConstructExpr &Node,
1113 ASTMatchFinder *Finder,
1114 BoundNodesTreeBuilder *Builder) const {
1115 return matchesDecl(Node.getConstructor(), Finder, Builder);
1116 }
1117
1118 bool matchesSpecialized(const ObjCIvarRefExpr &Node,
1119 ASTMatchFinder *Finder,
1120 BoundNodesTreeBuilder *Builder) const {
1121 return matchesDecl(Node.getDecl(), Finder, Builder);
1122 }
1123
1124 /// Extracts the operator new of the new call and returns whether the
1125 /// inner matcher matches on it.
1126 bool matchesSpecialized(const CXXNewExpr &Node,
1127 ASTMatchFinder *Finder,
1128 BoundNodesTreeBuilder *Builder) const {
1129 return matchesDecl(Node.getOperatorNew(), Finder, Builder);
1130 }
1131
1132 /// Extracts the \c ValueDecl a \c MemberExpr refers to and returns
1133 /// whether the inner matcher matches on it.
1134 bool matchesSpecialized(const MemberExpr &Node,
1135 ASTMatchFinder *Finder,
1136 BoundNodesTreeBuilder *Builder) const {
1137 return matchesDecl(Node.getMemberDecl(), Finder, Builder);
1138 }
1139
1140 /// Extracts the \c LabelDecl a \c AddrLabelExpr refers to and returns
1141 /// whether the inner matcher matches on it.
1142 bool matchesSpecialized(const AddrLabelExpr &Node,
1143 ASTMatchFinder *Finder,
1144 BoundNodesTreeBuilder *Builder) const {
1145 return matchesDecl(Node.getLabel(), Finder, Builder);
1146 }
1147
1148 /// Extracts the declaration of a LabelStmt and returns whether the
1149 /// inner matcher matches on it.
1150 bool matchesSpecialized(const LabelStmt &Node, ASTMatchFinder *Finder,
1151 BoundNodesTreeBuilder *Builder) const {
1152 return matchesDecl(Node.getDecl(), Finder, Builder);
1153 }
1154
1155 /// Returns whether the inner matcher \c Node. Returns false if \c Node
1156 /// is \c NULL.
1157 bool matchesDecl(const Decl *Node, ASTMatchFinder *Finder,
1158 BoundNodesTreeBuilder *Builder) const {
1159 return Node != nullptr &&
1160 !(Finder->isTraversalIgnoringImplicitNodes() &&
1161 Node->isImplicit()) &&
1162 this->InnerMatcher.matches(DynTypedNode::create(*Node), Finder,
1163 Builder);
1164 }
1165};
1166
1167/// IsBaseType<T>::value is true if T is a "base" type in the AST
1168/// node class hierarchies.
1169template <typename T>
1170struct IsBaseType {
1171 static const bool value =
1172 std::is_same<T, Decl>::value || std::is_same<T, Stmt>::value ||
1173 std::is_same<T, QualType>::value || std::is_same<T, Type>::value ||
1174 std::is_same<T, TypeLoc>::value ||
1175 std::is_same<T, NestedNameSpecifier>::value ||
1176 std::is_same<T, NestedNameSpecifierLoc>::value ||
1177 std::is_same<T, CXXCtorInitializer>::value ||
1178 std::is_same<T, TemplateArgumentLoc>::value ||
1179 std::is_same<T, Attr>::value;
1180};
1181template <typename T>
1182const bool IsBaseType<T>::value;
1183
1184/// A "type list" that contains all types.
1185///
1186/// Useful for matchers like \c anything and \c unless.
1187using AllNodeBaseTypes =
1188 TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, QualType,
1189 Type, TypeLoc, CXXCtorInitializer, Attr>;
1190
1191/// Helper meta-function to extract the argument out of a function of
1192/// type void(Arg).
1193///
1194/// See AST_POLYMORPHIC_SUPPORTED_TYPES for details.
1195template <class T> struct ExtractFunctionArgMeta;
1196template <class T> struct ExtractFunctionArgMeta<void(T)> {
1197 using type = T;
1198};
1199
1200template <class T, class Tuple, std::size_t... I>
1201constexpr T *new_from_tuple_impl(Tuple &&t, std::index_sequence<I...>) {
1202 return new T(std::get<I>(std::forward<Tuple>(t))...);
1203}
1204
1205template <class T, class Tuple> constexpr T *new_from_tuple(Tuple &&t) {
1206 return new_from_tuple_impl<T>(
1207 std::forward<Tuple>(t),
1208 std::make_index_sequence<
1209 std::tuple_size<std::remove_reference_t<Tuple>>::value>{});
1210}
1211
1212/// Default type lists for ArgumentAdaptingMatcher matchers.
1213using AdaptativeDefaultFromTypes = AllNodeBaseTypes;
1214using AdaptativeDefaultToTypes =
1215 TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, TypeLoc,
1216 QualType, Attr>;
1217
1218/// All types that are supported by HasDeclarationMatcher above.
1219using HasDeclarationSupportedTypes =
1220 TypeList<CallExpr, CXXConstructExpr, CXXNewExpr, DeclRefExpr, EnumType,
1221 ElaboratedType, InjectedClassNameType, LabelStmt, AddrLabelExpr,
1222 MemberExpr, QualType, RecordType, TagType,
1223 TemplateSpecializationType, TemplateTypeParmType, TypedefType,
1224 UnresolvedUsingType, ObjCIvarRefExpr>;
1225
1226/// A Matcher that allows binding the node it matches to an id.
1227///
1228/// BindableMatcher provides a \a bind() method that allows binding the
1229/// matched node to an id if the match was successful.
1230template <typename T> class BindableMatcher : public Matcher<T> {
1231public:
1232 explicit BindableMatcher(const Matcher<T> &M) : Matcher<T>(M) {}
1233 explicit BindableMatcher(MatcherInterface<T> *Implementation)
1234 : Matcher<T>(Implementation) {}
1235
1236 /// Returns a matcher that will bind the matched node on a match.
1237 ///
1238 /// The returned matcher is equivalent to this matcher, but will
1239 /// bind the matched node on a match.
1240 Matcher<T> bind(StringRef ID) const {
1241 return DynTypedMatcher(*this)
1242 .tryBind(ID)
1243 ->template unconditionalConvertTo<T>();
1244 }
1245
1246 /// Same as Matcher<T>'s conversion operator, but enables binding on
1247 /// the returned matcher.
1248 operator DynTypedMatcher() const {
1249 DynTypedMatcher Result = static_cast<const Matcher<T> &>(*this);
1250 Result.setAllowBind(true);
1251 return Result;
1252 }
1253};
1254
1255/// Matches any instance of the given NodeType.
1256///
1257/// This is useful when a matcher syntactically requires a child matcher,
1258/// but the context doesn't care. See for example: anything().
1259class TrueMatcher {
1260public:
1261 using ReturnTypes = AllNodeBaseTypes;
1262
1263 template <typename T> operator Matcher<T>() const {
1264 return DynTypedMatcher::trueMatcher(ASTNodeKind::getFromNodeKind<T>())
1265 .template unconditionalConvertTo<T>();
1266 }
1267};
1268
1269/// Creates a Matcher<T> that matches if all inner matchers match.
1270template <typename T>
1271BindableMatcher<T>
1272makeAllOfComposite(ArrayRef<const Matcher<T> *> InnerMatchers) {
1273 // For the size() == 0 case, we return a "true" matcher.
1274 if (InnerMatchers.empty()) {
1275 return BindableMatcher<T>(TrueMatcher());
1276 }
1277 // For the size() == 1 case, we simply return that one matcher.
1278 // No need to wrap it in a variadic operation.
1279 if (InnerMatchers.size() == 1) {
1280 return BindableMatcher<T>(*InnerMatchers[0]);
1281 }
1282
1283 using PI = llvm::pointee_iterator<const Matcher<T> *const *>;
1284
1285 std::vector<DynTypedMatcher> DynMatchers(PI(InnerMatchers.begin()),
1286 PI(InnerMatchers.end()));
1287 return BindableMatcher<T>(
1288 DynTypedMatcher::constructVariadic(DynTypedMatcher::VO_AllOf,
1289 ASTNodeKind::getFromNodeKind<T>(),
1290 std::move(DynMatchers))
1291 .template unconditionalConvertTo<T>());
1292}
1293
1294/// Creates a Matcher<T> that matches if
1295/// T is dyn_cast'able into InnerT and all inner matchers match.
1296///
1297/// Returns BindableMatcher, as matchers that use dyn_cast have
1298/// the same object both to match on and to run submatchers on,
1299/// so there is no ambiguity with what gets bound.
1300template <typename T, typename InnerT>
1301BindableMatcher<T>
1302makeDynCastAllOfComposite(ArrayRef<const Matcher<InnerT> *> InnerMatchers) {
1303 return BindableMatcher<T>(
1304 makeAllOfComposite(InnerMatchers).template dynCastTo<T>());
1305}
1306
1307/// A VariadicDynCastAllOfMatcher<SourceT, TargetT> object is a
1308/// variadic functor that takes a number of Matcher<TargetT> and returns a
1309/// Matcher<SourceT> that matches TargetT nodes that are matched by all of the
1310/// given matchers, if SourceT can be dynamically casted into TargetT.
1311///
1312/// For example:
1313/// const VariadicDynCastAllOfMatcher<Decl, CXXRecordDecl> record;
1314/// Creates a functor record(...) that creates a Matcher<Decl> given
1315/// a variable number of arguments of type Matcher<CXXRecordDecl>.
1316/// The returned matcher matches if the given Decl can by dynamically
1317/// casted to CXXRecordDecl and all given matchers match.
1318template <typename SourceT, typename TargetT>
1319class VariadicDynCastAllOfMatcher
1320 : public VariadicFunction<BindableMatcher<SourceT>, Matcher<TargetT>,
1321 makeDynCastAllOfComposite<SourceT, TargetT>> {
1322public:
1323 VariadicDynCastAllOfMatcher() {}
1324};
1325
1326/// A \c VariadicAllOfMatcher<T> object is a variadic functor that takes
1327/// a number of \c Matcher<T> and returns a \c Matcher<T> that matches \c T
1328/// nodes that are matched by all of the given matchers.
1329///
1330/// For example:
1331/// const VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier;
1332/// Creates a functor nestedNameSpecifier(...) that creates a
1333/// \c Matcher<NestedNameSpecifier> given a variable number of arguments of type
1334/// \c Matcher<NestedNameSpecifier>.
1335/// The returned matcher matches if all given matchers match.
1336template <typename T>
1337class VariadicAllOfMatcher
1338 : public VariadicFunction<BindableMatcher<T>, Matcher<T>,
1339 makeAllOfComposite<T>> {
1340public:
1341 VariadicAllOfMatcher() {}
1342};
1343
1344/// VariadicOperatorMatcher related types.
1345/// @{
1346
1347/// Polymorphic matcher object that uses a \c
1348/// DynTypedMatcher::VariadicOperator operator.
1349///
1350/// Input matchers can have any type (including other polymorphic matcher
1351/// types), and the actual Matcher<T> is generated on demand with an implicit
1352/// conversion operator.
1353template <typename... Ps> class VariadicOperatorMatcher {
1354public:
1355 VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, Ps &&... Params)
1356 : Op(Op), Params(std::forward<Ps>(Params)...) {}
1357
1358 template <typename T> operator Matcher<T>() const & {
1359 return DynTypedMatcher::constructVariadic(
1360 Op, ASTNodeKind::getFromNodeKind<T>(),
1361 getMatchers<T>(std::index_sequence_for<Ps...>()))
1362 .template unconditionalConvertTo<T>();
1363 }
1364
1365 template <typename T> operator Matcher<T>() && {
1366 return DynTypedMatcher::constructVariadic(
1367 Op, ASTNodeKind::getFromNodeKind<T>(),
1368 getMatchers<T>(std::index_sequence_for<Ps...>()))
1369 .template unconditionalConvertTo<T>();
1370 }
1371
1372private:
1373 // Helper method to unpack the tuple into a vector.
1374 template <typename T, std::size_t... Is>
1375 std::vector<DynTypedMatcher> getMatchers(std::index_sequence<Is...>) const & {
1376 return {Matcher<T>(std::get<Is>(Params))...};
1377 }
1378
1379 template <typename T, std::size_t... Is>
1380 std::vector<DynTypedMatcher> getMatchers(std::index_sequence<Is...>) && {
1381 return {Matcher<T>(std::get<Is>(std::move(Params)))...};
1382 }
1383
1384 const DynTypedMatcher::VariadicOperator Op;
1385 std::tuple<Ps...> Params;
1386};
1387
1388/// Overloaded function object to generate VariadicOperatorMatcher
1389/// objects from arbitrary matchers.
1390template <unsigned MinCount, unsigned MaxCount>
1391struct VariadicOperatorMatcherFunc {
1392 DynTypedMatcher::VariadicOperator Op;
1393
1394 template <typename... Ms>
1395 VariadicOperatorMatcher<Ms...> operator()(Ms &&... Ps) const {
1396 static_assert(MinCount <= sizeof...(Ms) && sizeof...(Ms) <= MaxCount,
1397 "invalid number of parameters for variadic matcher");
1398 return VariadicOperatorMatcher<Ms...>(Op, std::forward<Ms>(Ps)...);
1399 }
1400};
1401
1402template <typename F, typename Tuple, std::size_t... I>
1403constexpr auto applyMatcherImpl(F &&f, Tuple &&args,
1404 std::index_sequence<I...>) {
1405 return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(args))...);
1406}
1407
1408template <typename F, typename Tuple>
1409constexpr auto applyMatcher(F &&f, Tuple &&args) {
1410 return applyMatcherImpl(
1411 std::forward<F>(f), std::forward<Tuple>(args),
1412 std::make_index_sequence<
1413 std::tuple_size<typename std::decay<Tuple>::type>::value>());
1414}
1415
1416template <typename T, bool IsBaseOf, typename Head, typename Tail>
1417struct GetCladeImpl {
1418 using Type = Head;
1419};
1420template <typename T, typename Head, typename Tail>
1421struct GetCladeImpl<T, false, Head, Tail>
1422 : GetCladeImpl<T, std::is_base_of<typename Tail::head, T>::value,
1423 typename Tail::head, typename Tail::tail> {};
1424
1425template <typename T, typename... U>
1426struct GetClade : GetCladeImpl<T, false, T, AllNodeBaseTypes> {};
1427
1428template <typename CladeType, typename... MatcherTypes>
1429struct MapAnyOfMatcherImpl {
1430
1431 template <typename... InnerMatchers>
1432 BindableMatcher<CladeType>
1433 operator()(InnerMatchers &&... InnerMatcher) const {
1434 // TODO: Use std::apply from c++17
1435 return VariadicAllOfMatcher<CladeType>()(applyMatcher(
1436 internal::VariadicOperatorMatcherFunc<
1437 0, std::numeric_limits<unsigned>::max()>{
1438 internal::DynTypedMatcher::VO_AnyOf},
1439 applyMatcher(
1440 [&](auto... Matcher) {
1441 return std::make_tuple(Matcher(InnerMatcher...)...);
1442 },
1443 std::tuple<
1444 VariadicDynCastAllOfMatcher<CladeType, MatcherTypes>...>())));
1445 }
1446};
1447
1448template <typename... MatcherTypes>
1449using MapAnyOfMatcher =
1450 MapAnyOfMatcherImpl<typename GetClade<MatcherTypes...>::Type,
1451 MatcherTypes...>;
1452
1453template <typename... MatcherTypes> struct MapAnyOfHelper {
1454 using CladeType = typename GetClade<MatcherTypes...>::Type;
1455
1456 MapAnyOfMatcher<MatcherTypes...> with;
1457
1458 operator BindableMatcher<CladeType>() const { return with(); }
1459
1460 Matcher<CladeType> bind(StringRef ID) const { return with().bind(ID); }
1461};
1462
1463template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
1464 typename T, typename ToTypes>
1465class ArgumentAdaptingMatcherFuncAdaptor {
1466public:
1467 explicit ArgumentAdaptingMatcherFuncAdaptor(const Matcher<T> &InnerMatcher)
1468 : InnerMatcher(InnerMatcher) {}
1469
1470 using ReturnTypes = ToTypes;
1471
1472 template <typename To> operator Matcher<To>() const & {
1473 return Matcher<To>(new ArgumentAdapterT<To, T>(InnerMatcher));
1474 }
1475
1476 template <typename To> operator Matcher<To>() && {
1477 return Matcher<To>(new ArgumentAdapterT<To, T>(std::move(InnerMatcher)));
1478 }
1479
1480private:
1481 Matcher<T> InnerMatcher;
1482};
1483
1484/// Converts a \c Matcher<T> to a matcher of desired type \c To by
1485/// "adapting" a \c To into a \c T.
1486///
1487/// The \c ArgumentAdapterT argument specifies how the adaptation is done.
1488///
1489/// For example:
1490/// \c ArgumentAdaptingMatcher<HasMatcher, T>(InnerMatcher);
1491/// Given that \c InnerMatcher is of type \c Matcher<T>, this returns a matcher
1492/// that is convertible into any matcher of type \c To by constructing
1493/// \c HasMatcher<To, T>(InnerMatcher).
1494///
1495/// If a matcher does not need knowledge about the inner type, prefer to use
1496/// PolymorphicMatcher.
1497template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
1498 typename FromTypes = AdaptativeDefaultFromTypes,
1499 typename ToTypes = AdaptativeDefaultToTypes>
1500struct ArgumentAdaptingMatcherFunc {
1501 template <typename T>
1502 static ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>
1503 create(const Matcher<T> &InnerMatcher) {
1504 return ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>(
1505 InnerMatcher);
1506 }
1507
1508 template <typename T>
1509 ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>
1510 operator()(const Matcher<T> &InnerMatcher) const {
1511 return create(InnerMatcher);
1512 }
1513
1514 template <typename... T>
1515 ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT,
1516 typename GetClade<T...>::Type, ToTypes>
1517 operator()(const MapAnyOfHelper<T...> &InnerMatcher) const {
1518 return create(InnerMatcher.with());
1519 }
1520};
1521
1522template <typename T> class TraversalMatcher : public MatcherInterface<T> {
1523 DynTypedMatcher InnerMatcher;
1524 clang::TraversalKind Traversal;
1525
1526public:
1527 explicit TraversalMatcher(clang::TraversalKind TK,
1528 const Matcher<T> &InnerMatcher)
1529 : InnerMatcher(InnerMatcher), Traversal(TK) {}
1530
1531 bool matches(const T &Node, ASTMatchFinder *Finder,
1532 BoundNodesTreeBuilder *Builder) const override {
1533 return this->InnerMatcher.matches(DynTypedNode::create(Node), Finder,
1534 Builder);
1535 }
1536
1537 llvm::Optional<clang::TraversalKind> TraversalKind() const override {
1538 if (auto NestedKind = this->InnerMatcher.getTraversalKind())
1539 return NestedKind;
1540 return Traversal;
1541 }
1542};
1543
1544template <typename MatcherType> class TraversalWrapper {
1545public:
1546 TraversalWrapper(TraversalKind TK, const MatcherType &InnerMatcher)
1547 : TK(TK), InnerMatcher(InnerMatcher) {}
1548
1549 template <typename T> operator Matcher<T>() const & {
1550 return internal::DynTypedMatcher::constructRestrictedWrapper(
1551 new internal::TraversalMatcher<T>(TK, InnerMatcher),
1552 ASTNodeKind::getFromNodeKind<T>())
1553 .template unconditionalConvertTo<T>();
1554 }
1555
1556 template <typename T> operator Matcher<T>() && {
1557 return internal::DynTypedMatcher::constructRestrictedWrapper(
1558 new internal::TraversalMatcher<T>(TK, std::move(InnerMatcher)),
1559 ASTNodeKind::getFromNodeKind<T>())
1560 .template unconditionalConvertTo<T>();
1561 }
1562
1563private:
1564 TraversalKind TK;
1565 MatcherType InnerMatcher;
1566};
1567
1568/// A PolymorphicMatcher<MatcherT, P1, ..., PN> object can be
1569/// created from N parameters p1, ..., pN (of type P1, ..., PN) and
1570/// used as a Matcher<T> where a MatcherT<T, P1, ..., PN>(p1, ..., pN)
1571/// can be constructed.
1572///
1573/// For example:
1574/// - PolymorphicMatcher<IsDefinitionMatcher>()
1575/// creates an object that can be used as a Matcher<T> for any type T
1576/// where an IsDefinitionMatcher<T>() can be constructed.
1577/// - PolymorphicMatcher<ValueEqualsMatcher, int>(42)
1578/// creates an object that can be used as a Matcher<T> for any type T
1579/// where a ValueEqualsMatcher<T, int>(42) can be constructed.
1580template <template <typename T, typename... Params> class MatcherT,
1581 typename ReturnTypesF, typename... ParamTypes>
1582class PolymorphicMatcher {
1583public:
1584 PolymorphicMatcher(const ParamTypes &... Params) : Params(Params...) {}
1585
1586 using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
1587
1588 template <typename T> operator Matcher<T>() const & {
1589 static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
1590 "right polymorphic conversion");
1591 return Matcher<T>(new_from_tuple<MatcherT<T, ParamTypes...>>(Params));
1592 }
1593
1594 template <typename T> operator Matcher<T>() && {
1595 static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
1596 "right polymorphic conversion");
1597 return Matcher<T>(
1598 new_from_tuple<MatcherT<T, ParamTypes...>>(std::move(Params)));
1599 }
1600
1601private:
1602 std::tuple<ParamTypes...> Params;
1603};
1604
1605/// Matches nodes of type T that have child nodes of type ChildT for
1606/// which a specified child matcher matches.
1607///
1608/// ChildT must be an AST base type.
1609template <typename T, typename ChildT>
1610class HasMatcher : public MatcherInterface<T> {
1611 DynTypedMatcher InnerMatcher;
1612
1613public:
1614 explicit HasMatcher(const Matcher<ChildT> &InnerMatcher)
1615 : InnerMatcher(InnerMatcher) {}
1616
1617 bool matches(const T &Node, ASTMatchFinder *Finder,
1618 BoundNodesTreeBuilder *Builder) const override {
1619 return Finder->matchesChildOf(Node, this->InnerMatcher, Builder,
1620 ASTMatchFinder::BK_First);
1621 }
1622};
1623
1624/// Matches nodes of type T that have child nodes of type ChildT for
1625/// which a specified child matcher matches. ChildT must be an AST base
1626/// type.
1627/// As opposed to the HasMatcher, the ForEachMatcher will produce a match
1628/// for each child that matches.
1629template <typename T, typename ChildT>
1630class ForEachMatcher : public MatcherInterface<T> {
1631 static_assert(IsBaseType<ChildT>::value,
1632 "for each only accepts base type matcher");
1633
1634 DynTypedMatcher InnerMatcher;
1635
1636public:
1637 explicit ForEachMatcher(const Matcher<ChildT> &InnerMatcher)
1638 : InnerMatcher(InnerMatcher) {}
1639
1640 bool matches(const T &Node, ASTMatchFinder *Finder,
1641 BoundNodesTreeBuilder *Builder) const override {
1642 return Finder->matchesChildOf(
1643 Node, this->InnerMatcher, Builder,
1644 ASTMatchFinder::BK_All);
1645 }
1646};
1647
1648/// @}
1649
1650template <typename T>
1651inline Matcher<T> DynTypedMatcher::unconditionalConvertTo() const {
1652 return Matcher<T>(*this);
1653}
1654
1655/// Matches nodes of type T that have at least one descendant node of
1656/// type DescendantT for which the given inner matcher matches.
1657///
1658/// DescendantT must be an AST base type.
1659template <typename T, typename DescendantT>
1660class HasDescendantMatcher : public MatcherInterface<T> {
1661 static_assert(IsBaseType<DescendantT>::value,
1662 "has descendant only accepts base type matcher");
1663
1664 DynTypedMatcher DescendantMatcher;
1665
1666public:
1667 explicit HasDescendantMatcher(const Matcher<DescendantT> &DescendantMatcher)
1668 : DescendantMatcher(DescendantMatcher) {}
1669
1670 bool matches(const T &Node, ASTMatchFinder *Finder,
1671 BoundNodesTreeBuilder *Builder) const override {
1672 return Finder->matchesDescendantOf(Node, this->DescendantMatcher, Builder,
1673 ASTMatchFinder::BK_First);
1674 }
1675};
1676
1677/// Matches nodes of type \c T that have a parent node of type \c ParentT
1678/// for which the given inner matcher matches.
1679///
1680/// \c ParentT must be an AST base type.
1681template <typename T, typename ParentT>
1682class HasParentMatcher : public MatcherInterface<T> {
1683 static_assert(IsBaseType<ParentT>::value,
1684 "has parent only accepts base type matcher");
1685
1686 DynTypedMatcher ParentMatcher;
1687
1688public:
1689 explicit HasParentMatcher(const Matcher<ParentT> &ParentMatcher)
1690 : ParentMatcher(ParentMatcher) {}
1691
1692 bool matches(const T &Node, ASTMatchFinder *Finder,
1693 BoundNodesTreeBuilder *Builder) const override {
1694 return Finder->matchesAncestorOf(Node, this->ParentMatcher, Builder,
1695 ASTMatchFinder::AMM_ParentOnly);
1696 }
1697};
1698
1699/// Matches nodes of type \c T that have at least one ancestor node of
1700/// type \c AncestorT for which the given inner matcher matches.
1701///
1702/// \c AncestorT must be an AST base type.
1703template <typename T, typename AncestorT>
1704class HasAncestorMatcher : public MatcherInterface<T> {
1705 static_assert(IsBaseType<AncestorT>::value,
1706 "has ancestor only accepts base type matcher");
1707
1708 DynTypedMatcher AncestorMatcher;
1709
1710public:
1711 explicit HasAncestorMatcher(const Matcher<AncestorT> &AncestorMatcher)
1712 : AncestorMatcher(AncestorMatcher) {}
1713
1714 bool matches(const T &Node, ASTMatchFinder *Finder,
1715 BoundNodesTreeBuilder *Builder) const override {
1716 return Finder->matchesAncestorOf(Node, this->AncestorMatcher, Builder,
1717 ASTMatchFinder::AMM_All);
1718 }
1719};
1720
1721/// Matches nodes of type T that have at least one descendant node of
1722/// type DescendantT for which the given inner matcher matches.
1723///
1724/// DescendantT must be an AST base type.
1725/// As opposed to HasDescendantMatcher, ForEachDescendantMatcher will match
1726/// for each descendant node that matches instead of only for the first.
1727template <typename T, typename DescendantT>
1728class ForEachDescendantMatcher : public MatcherInterface<T> {
1729 static_assert(IsBaseType<DescendantT>::value,
1730 "for each descendant only accepts base type matcher");
1731
1732 DynTypedMatcher DescendantMatcher;
1733
1734public:
1735 explicit ForEachDescendantMatcher(
1736 const Matcher<DescendantT> &DescendantMatcher)
1737 : DescendantMatcher(DescendantMatcher) {}
1738
1739 bool matches(const T &Node, ASTMatchFinder *Finder,
1740 BoundNodesTreeBuilder *Builder) const override {
1741 return Finder->matchesDescendantOf(Node, this->DescendantMatcher, Builder,
1742 ASTMatchFinder::BK_All);
1743 }
1744};
1745
1746/// Matches on nodes that have a getValue() method if getValue() equals
1747/// the value the ValueEqualsMatcher was constructed with.
1748template <typename T, typename ValueT>
1749class ValueEqualsMatcher : public SingleNodeMatcherInterface<T> {
1750 static_assert(std::is_base_of<CharacterLiteral, T>::value ||
1751 std::is_base_of<CXXBoolLiteralExpr, T>::value ||
1752 std::is_base_of<FloatingLiteral, T>::value ||
1753 std::is_base_of<IntegerLiteral, T>::value,
1754 "the node must have a getValue method");
1755
1756public:
1757 explicit ValueEqualsMatcher(const ValueT &ExpectedValue)
1758 : ExpectedValue(ExpectedValue) {}
1759
1760 bool matchesNode(const T &Node) const override {
1761 return Node.getValue() == ExpectedValue;
1762 }
1763
1764private:
1765 ValueT ExpectedValue;
1766};
1767
1768/// Template specializations to easily write matchers for floating point
1769/// literals.
1770template <>
1771inline bool ValueEqualsMatcher<FloatingLiteral, double>::matchesNode(
1772 const FloatingLiteral &Node) const {
1773 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle())
1774 return Node.getValue().convertToFloat() == ExpectedValue;
1775 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble())
1776 return Node.getValue().convertToDouble() == ExpectedValue;
1777 return false;
1778}
1779template <>
1780inline bool ValueEqualsMatcher<FloatingLiteral, float>::matchesNode(
1781 const FloatingLiteral &Node) const {
1782 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle())
1783 return Node.getValue().convertToFloat() == ExpectedValue;
1784 if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble())
1785 return Node.getValue().convertToDouble() == ExpectedValue;
1786 return false;
1787}
1788template <>
1789inline bool ValueEqualsMatcher<FloatingLiteral, llvm::APFloat>::matchesNode(
1790 const FloatingLiteral &Node) const {
1791 return ExpectedValue.compare(Node.getValue()) == llvm::APFloat::cmpEqual;
1792}
1793
1794/// Matches nodes of type \c TLoc for which the inner
1795/// \c Matcher<T> matches.
1796template <typename TLoc, typename T>
1797class LocMatcher : public MatcherInterface<TLoc> {
1798 DynTypedMatcher InnerMatcher;
1799
1800public:
1801 explicit LocMatcher(const Matcher<T> &InnerMatcher)
1802 : InnerMatcher(InnerMatcher) {}
1803
1804 bool matches(const TLoc &Node, ASTMatchFinder *Finder,
1805 BoundNodesTreeBuilder *Builder) const override {
1806 if (!Node)
1807 return false;
1808 return this->InnerMatcher.matches(extract(Node), Finder, Builder);
1809 }
1810
1811private:
1812 static DynTypedNode extract(const NestedNameSpecifierLoc &Loc) {
1813 return DynTypedNode::create(*Loc.getNestedNameSpecifier());
1814 }
1815};
1816
1817/// Matches \c TypeLocs based on an inner matcher matching a certain
1818/// \c QualType.
1819///
1820/// Used to implement the \c loc() matcher.
1821class TypeLocTypeMatcher : public MatcherInterface<TypeLoc> {
1822 DynTypedMatcher InnerMatcher;
1823
1824public:
1825 explicit TypeLocTypeMatcher(const Matcher<QualType> &InnerMatcher)
1826 : InnerMatcher(InnerMatcher) {}
1827
1828 bool matches(const TypeLoc &Node, ASTMatchFinder *Finder,
1829 BoundNodesTreeBuilder *Builder) const override {
1830 if (!Node)
1831 return false;
1832 return this->InnerMatcher.matches(DynTypedNode::create(Node.getType()),
1833 Finder, Builder);
1834 }
1835};
1836
1837/// Matches nodes of type \c T for which the inner matcher matches on a
1838/// another node of type \c T that can be reached using a given traverse
1839/// function.
1840template <typename T> class TypeTraverseMatcher : public MatcherInterface<T> {
1841 DynTypedMatcher InnerMatcher;
1842
1843public:
1844 explicit TypeTraverseMatcher(const Matcher<QualType> &InnerMatcher,
1845 QualType (T::*TraverseFunction)() const)
1846 : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {}
1847
1848 bool matches(const T &Node, ASTMatchFinder *Finder,
1849 BoundNodesTreeBuilder *Builder) const override {
1850 QualType NextNode = (Node.*TraverseFunction)();
1851 if (NextNode.isNull())
1852 return false;
1853 return this->InnerMatcher.matches(DynTypedNode::create(NextNode), Finder,
1854 Builder);
1855 }
1856
1857private:
1858 QualType (T::*TraverseFunction)() const;
1859};
1860
1861/// Matches nodes of type \c T in a ..Loc hierarchy, for which the inner
1862/// matcher matches on a another node of type \c T that can be reached using a
1863/// given traverse function.
1864template <typename T>
1865class TypeLocTraverseMatcher : public MatcherInterface<T> {
1866 DynTypedMatcher InnerMatcher;
1867
1868public:
1869 explicit TypeLocTraverseMatcher(const Matcher<TypeLoc> &InnerMatcher,
1870 TypeLoc (T::*TraverseFunction)() const)
1871 : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {}
1872
1873 bool matches(const T &Node, ASTMatchFinder *Finder,
1874 BoundNodesTreeBuilder *Builder) const override {
1875 TypeLoc NextNode = (Node.*TraverseFunction)();
1876 if (!NextNode)
1877 return false;
1878 return this->InnerMatcher.matches(DynTypedNode::create(NextNode), Finder,
1879 Builder);
1880 }
1881
1882private:
1883 TypeLoc (T::*TraverseFunction)() const;
1884};
1885
1886/// Converts a \c Matcher<InnerT> to a \c Matcher<OuterT>, where
1887/// \c OuterT is any type that is supported by \c Getter.
1888///
1889/// \code Getter<OuterT>::value() \endcode returns a
1890/// \code InnerTBase (OuterT::*)() \endcode, which is used to adapt a \c OuterT
1891/// object into a \c InnerT
1892template <typename InnerTBase,
1893 template <typename OuterT> class Getter,
1894 template <typename OuterT> class MatcherImpl,
1895 typename ReturnTypesF>
1896class TypeTraversePolymorphicMatcher {
1897private:
1898 using Self = TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl,
1899 ReturnTypesF>;
1900
1901 static Self create(ArrayRef<const Matcher<InnerTBase> *> InnerMatchers);
1902
1903public:
1904 using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
1905
1906 explicit TypeTraversePolymorphicMatcher(
1907 ArrayRef<const Matcher<InnerTBase> *> InnerMatchers)
1908 : InnerMatcher(makeAllOfComposite(InnerMatchers)) {}
1909
1910 template <typename OuterT> operator Matcher<OuterT>() const {
1911 return Matcher<OuterT>(
1912 new MatcherImpl<OuterT>(InnerMatcher, Getter<OuterT>::value()));
1913 }
1914
1915 struct Func
1916 : public VariadicFunction<Self, Matcher<InnerTBase>, &Self::create> {
1917 Func() {}
1918 };
1919
1920private:
1921 Matcher<InnerTBase> InnerMatcher;
1922};
1923
1924/// A simple memoizer of T(*)() functions.
1925///
1926/// It will call the passed 'Func' template parameter at most once.
1927/// Used to support AST_MATCHER_FUNCTION() macro.
1928template <typename Matcher, Matcher (*Func)()> class MemoizedMatcher {
1929 struct Wrapper {
1930 Wrapper() : M(Func()) {}
1931
1932 Matcher M;
1933 };
1934
1935public:
1936 static const Matcher &getInstance() {
1937 static llvm::ManagedStatic<Wrapper> Instance;
1938 return Instance->M;
1939 }
1940};
1941
1942// Define the create() method out of line to silence a GCC warning about
1943// the struct "Func" having greater visibility than its base, which comes from
1944// using the flag -fvisibility-inlines-hidden.
1945template <typename InnerTBase, template <typename OuterT> class Getter,
1946 template <typename OuterT> class MatcherImpl, typename ReturnTypesF>
1947TypeTraversePolymorphicMatcher<InnerTBase, Getter, MatcherImpl, ReturnTypesF>
1948TypeTraversePolymorphicMatcher<
1949 InnerTBase, Getter, MatcherImpl,
1950 ReturnTypesF>::create(ArrayRef<const Matcher<InnerTBase> *> InnerMatchers) {
1951 return Self(InnerMatchers);
1952}
1953
1954// FIXME: unify ClassTemplateSpecializationDecl and TemplateSpecializationType's
1955// APIs for accessing the template argument list.
1956inline ArrayRef<TemplateArgument>
1957getTemplateSpecializationArgs(const ClassTemplateSpecializationDecl &D) {
1958 return D.getTemplateArgs().asArray();
1959}
1960
1961inline ArrayRef<TemplateArgument>
1962getTemplateSpecializationArgs(const TemplateSpecializationType &T) {
1963 return llvm::makeArrayRef(T.getArgs(), T.getNumArgs());
1964}
1965
1966inline ArrayRef<TemplateArgument>
1967getTemplateSpecializationArgs(const FunctionDecl &FD) {
1968 if (const auto* TemplateArgs = FD.getTemplateSpecializationArgs())
1969 return TemplateArgs->asArray();
1970 return ArrayRef<TemplateArgument>();
1971}
1972
1973struct NotEqualsBoundNodePredicate {
1974 bool operator()(const internal::BoundNodesMap &Nodes) const {
1975 return Nodes.getNode(ID) != Node;
1976 }
1977
1978 std::string ID;
1979 DynTypedNode Node;
1980};
1981
1982template <typename Ty, typename Enable = void> struct GetBodyMatcher {
1983 static const Stmt *get(const Ty &Node) { return Node.getBody(); }
1984};
1985
1986template <typename Ty>
1987struct GetBodyMatcher<Ty, typename std::enable_if<
1988 std::is_base_of<FunctionDecl, Ty>::value>::type> {
1989 static const Stmt *get(const Ty &Node) {
1990 return Node.doesThisDeclarationHaveABody() ? Node.getBody() : nullptr;
1991 }
1992};
1993
1994template <typename NodeType>
1995inline Optional<BinaryOperatorKind>
1996equivalentBinaryOperator(const NodeType &Node) {
1997 return Node.getOpcode();
1998}
1999
2000template <>
2001inline Optional<BinaryOperatorKind>
2002equivalentBinaryOperator<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
2003 if (Node.getNumArgs() != 2)
2004 return None;
2005 switch (Node.getOperator()) {
2006 default:
2007 return None;
2008 case OO_ArrowStar:
2009 return BO_PtrMemI;
2010 case OO_Star:
2011 return BO_Mul;
2012 case OO_Slash:
2013 return BO_Div;
2014 case OO_Percent:
2015 return BO_Rem;
2016 case OO_Plus:
2017 return BO_Add;
2018 case OO_Minus:
2019 return BO_Sub;
2020 case OO_LessLess:
2021 return BO_Shl;
2022 case OO_GreaterGreater:
2023 return BO_Shr;
2024 case OO_Spaceship:
2025 return BO_Cmp;
2026 case OO_Less:
2027 return BO_LT;
2028 case OO_Greater:
2029 return BO_GT;
2030 case OO_LessEqual:
2031 return BO_LE;
2032 case OO_GreaterEqual:
2033 return BO_GE;
2034 case OO_EqualEqual:
2035 return BO_EQ;
2036 case OO_ExclaimEqual:
2037 return BO_NE;
2038 case OO_Amp:
2039 return BO_And;
2040 case OO_Caret:
2041 return BO_Xor;
2042 case OO_Pipe:
2043 return BO_Or;
2044 case OO_AmpAmp:
2045 return BO_LAnd;
2046 case OO_PipePipe:
2047 return BO_LOr;
2048 case OO_Equal:
2049 return BO_Assign;
2050 case OO_StarEqual:
2051 return BO_MulAssign;
2052 case OO_SlashEqual:
2053 return BO_DivAssign;
2054 case OO_PercentEqual:
2055 return BO_RemAssign;
2056 case OO_PlusEqual:
2057 return BO_AddAssign;
2058 case OO_MinusEqual:
2059 return BO_SubAssign;
2060 case OO_LessLessEqual:
2061 return BO_ShlAssign;
2062 case OO_GreaterGreaterEqual:
2063 return BO_ShrAssign;
2064 case OO_AmpEqual:
2065 return BO_AndAssign;
2066 case OO_CaretEqual:
2067 return BO_XorAssign;
2068 case OO_PipeEqual:
2069 return BO_OrAssign;
2070 case OO_Comma:
2071 return BO_Comma;
2072 }
2073}
2074
2075template <typename NodeType>
2076inline Optional<UnaryOperatorKind>
2077equivalentUnaryOperator(const NodeType &Node) {
2078 return Node.getOpcode();
2079}
2080
2081template <>
2082inline Optional<UnaryOperatorKind>
2083equivalentUnaryOperator<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
2084 if (Node.getNumArgs() != 1 && Node.getOperator() != OO_PlusPlus &&
2085 Node.getOperator() != OO_MinusMinus)
2086 return None;
2087 switch (Node.getOperator()) {
2088 default:
2089 return None;
2090 case OO_Plus:
2091 return UO_Plus;
2092 case OO_Minus:
2093 return UO_Minus;
2094 case OO_Amp:
2095 return UO_AddrOf;
2096 case OO_Star:
2097 return UO_Deref;
2098 case OO_Tilde:
2099 return UO_Not;
2100 case OO_Exclaim:
2101 return UO_LNot;
2102 case OO_PlusPlus: {
2103 const auto *FD = Node.getDirectCallee();
2104 if (!FD)
2105 return None;
2106 return FD->getNumParams() > 0 ? UO_PostInc : UO_PreInc;
2107 }
2108 case OO_MinusMinus: {
2109 const auto *FD = Node.getDirectCallee();
2110 if (!FD)
2111 return None;
2112 return FD->getNumParams() > 0 ? UO_PostDec : UO_PreDec;
2113 }
2114 case OO_Coawait:
2115 return UO_Coawait;
2116 }
2117}
2118
2119template <typename NodeType> inline const Expr *getLHS(const NodeType &Node) {
2120 return Node.getLHS();
2121}
2122template <>
2123inline const Expr *
2124getLHS<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
2125 if (!internal::equivalentBinaryOperator(Node))
2126 return nullptr;
2127 return Node.getArg(0);
2128}
2129template <typename NodeType> inline const Expr *getRHS(const NodeType &Node) {
2130 return Node.getRHS();
2131}
2132template <>
2133inline const Expr *
2134getRHS<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
2135 if (!internal::equivalentBinaryOperator(Node))
2136 return nullptr;
2137 return Node.getArg(1);
2138}
2139template <typename NodeType>
2140inline const Expr *getSubExpr(const NodeType &Node) {
2141 return Node.getSubExpr();
2142}
2143template <>
2144inline const Expr *
2145getSubExpr<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
2146 if (!internal::equivalentUnaryOperator(Node))
2147 return nullptr;
2148 return Node.getArg(0);
2149}
2150
2151template <typename Ty>
2152struct HasSizeMatcher {
2153 static bool hasSize(const Ty &Node, unsigned int N) {
2154 return Node.getSize() == N;
2155 }
2156};
2157
2158template <>
2159inline bool HasSizeMatcher<StringLiteral>::hasSize(
2160 const StringLiteral &Node, unsigned int N) {
2161 return Node.getLength() == N;
2162}
2163
2164template <typename Ty>
2165struct GetSourceExpressionMatcher {
2166 static const Expr *get(const Ty &Node) {
2167 return Node.getSubExpr();
2168 }
2169};
2170
2171template <>
2172inline const Expr *GetSourceExpressionMatcher<OpaqueValueExpr>::get(
2173 const OpaqueValueExpr &Node) {
2174 return Node.getSourceExpr();
2175}
2176
2177template <typename Ty>
2178struct CompoundStmtMatcher {
2179 static const CompoundStmt *get(const Ty &Node) {
2180 return &Node;
2181 }
2182};
2183
2184template <>
2185inline const CompoundStmt *
2186CompoundStmtMatcher<StmtExpr>::get(const StmtExpr &Node) {
2187 return Node.getSubStmt();
2188}
2189
2190/// If \p Loc is (transitively) expanded from macro \p MacroName, returns the
2191/// location (in the chain of expansions) at which \p MacroName was
2192/// expanded. Since the macro may have been expanded inside a series of
2193/// expansions, that location may itself be a MacroID.
2194llvm::Optional<SourceLocation>
2195getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc,
2196 const ASTContext &Context);
2197
2198inline Optional<StringRef> getOpName(const UnaryOperator &Node) {
2199 return Node.getOpcodeStr(Node.getOpcode());
2200}
2201inline Optional<StringRef> getOpName(const BinaryOperator &Node) {
2202 return Node.getOpcodeStr();
2203}
2204inline StringRef getOpName(const CXXRewrittenBinaryOperator &Node) {
2205 return Node.getOpcodeStr();
2206}
2207inline Optional<StringRef> getOpName(const CXXOperatorCallExpr &Node) {
2208 auto optBinaryOpcode = equivalentBinaryOperator(Node);
2209 if (!optBinaryOpcode) {
2210 auto optUnaryOpcode = equivalentUnaryOperator(Node);
2211 if (!optUnaryOpcode)
2212 return None;
2213 return UnaryOperator::getOpcodeStr(*optUnaryOpcode);
2214 }
2215 return BinaryOperator::getOpcodeStr(*optBinaryOpcode);
2216}
2217
2218/// Matches overloaded operators with a specific name.
2219///
2220/// The type argument ArgT is not used by this matcher but is used by
2221/// PolymorphicMatcher and should be std::vector<std::string>>.
2222template <typename T, typename ArgT = std::vector<std::string>>
2223class HasAnyOperatorNameMatcher : public SingleNodeMatcherInterface<T> {
2224 static_assert(std::is_same<T, BinaryOperator>::value ||
2225 std::is_same<T, CXXOperatorCallExpr>::value ||
2226 std::is_same<T, CXXRewrittenBinaryOperator>::value ||
2227 std::is_same<T, UnaryOperator>::value,
2228 "Matcher only supports `BinaryOperator`, `UnaryOperator`, "
2229 "`CXXOperatorCallExpr` and `CXXRewrittenBinaryOperator`");
2230 static_assert(std::is_same<ArgT, std::vector<std::string>>::value,
2231 "Matcher ArgT must be std::vector<std::string>");
2232
2233public:
2234 explicit HasAnyOperatorNameMatcher(std::vector<std::string> Names)
2235 : SingleNodeMatcherInterface<T>(), Names(std::move(Names)) {}
2236
2237 bool matchesNode(const T &Node) const override {
2238 Optional<StringRef> OptOpName = getOpName(Node);
2239 return OptOpName && llvm::is_contained(Names, *OptOpName);
2240 }
2241
2242private:
2243 static Optional<StringRef> getOpName(const UnaryOperator &Node) {
2244 return Node.getOpcodeStr(Node.getOpcode());
2245 }
2246 static Optional<StringRef> getOpName(const BinaryOperator &Node) {
2247 return Node.getOpcodeStr();
2248 }
2249 static StringRef getOpName(const CXXRewrittenBinaryOperator &Node) {
2250 return Node.getOpcodeStr();
2251 }
2252 static Optional<StringRef> getOpName(const CXXOperatorCallExpr &Node) {
2253 auto optBinaryOpcode = equivalentBinaryOperator(Node);
2254 if (!optBinaryOpcode) {
2255 auto optUnaryOpcode = equivalentUnaryOperator(Node);
2256 if (!optUnaryOpcode)
2257 return None;
2258 return UnaryOperator::getOpcodeStr(*optUnaryOpcode);
2259 }
2260 return BinaryOperator::getOpcodeStr(*optBinaryOpcode);
2261 }
2262
2263 std::vector<std::string> Names;
2264};
2265
2266using HasOpNameMatcher =
2267 PolymorphicMatcher<HasAnyOperatorNameMatcher,
2268 void(
2269 TypeList<BinaryOperator, CXXOperatorCallExpr,
2270 CXXRewrittenBinaryOperator, UnaryOperator>),
2271 std::vector<std::string>>;
2272
2273HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef<const StringRef *> NameRefs);
2274
2275using HasOverloadOpNameMatcher =
2276 PolymorphicMatcher<HasOverloadedOperatorNameMatcher,
2277 void(TypeList<CXXOperatorCallExpr, FunctionDecl>),
2278 std::vector<std::string>>;
2279
2280HasOverloadOpNameMatcher
2281hasAnyOverloadedOperatorNameFunc(ArrayRef<const StringRef *> NameRefs);
2282
2283/// Returns true if \p Node has a base specifier matching \p BaseSpec.
2284///
2285/// A class is not considered to be derived from itself.
2286bool matchesAnyBase(const CXXRecordDecl &Node,
2287 const Matcher<CXXBaseSpecifier> &BaseSpecMatcher,
2288 ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder);
2289
2290std::shared_ptr<llvm::Regex> createAndVerifyRegex(StringRef Regex,
2291 llvm::Regex::RegexFlags Flags,
2292 StringRef MatcherID);
2293
2294inline bool
2295MatchTemplateArgLocAt(const DeclRefExpr &Node, unsigned int Index,
2296 internal::Matcher<TemplateArgumentLoc> InnerMatcher,
2297 internal::ASTMatchFinder *Finder,
2298 internal::BoundNodesTreeBuilder *Builder) {
2299 llvm::ArrayRef<TemplateArgumentLoc> ArgLocs = Node.template_arguments();
2300 return Index < ArgLocs.size() &&
2301 InnerMatcher.matches(ArgLocs[Index], Finder, Builder);
2302}
2303
2304inline bool
2305MatchTemplateArgLocAt(const TemplateSpecializationTypeLoc &Node,
2306 unsigned int Index,
2307 internal::Matcher<TemplateArgumentLoc> InnerMatcher,
2308 internal::ASTMatchFinder *Finder,
2309 internal::BoundNodesTreeBuilder *Builder) {
2310 return !Node.isNull() && Index < Node.getNumArgs() &&
2311 InnerMatcher.matches(Node.getArgLoc(Index), Finder, Builder);
2312}
2313
2314} // namespace internal
2315
2316} // namespace ast_matchers
2317
2318} // namespace clang
2319
2320#endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H

/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/stl_tree.h

1// RB tree implementation -*- C++ -*-
2
3// Copyright (C) 2001-2020 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/*
26 *
27 * Copyright (c) 1996,1997
28 * Silicon Graphics Computer Systems, Inc.
29 *
30 * Permission to use, copy, modify, distribute and sell this software
31 * and its documentation for any purpose is hereby granted without fee,
32 * provided that the above copyright notice appear in all copies and
33 * that both that copyright notice and this permission notice appear
34 * in supporting documentation. Silicon Graphics makes no
35 * representations about the suitability of this software for any
36 * purpose. It is provided "as is" without express or implied warranty.
37 *
38 *
39 * Copyright (c) 1994
40 * Hewlett-Packard Company
41 *
42 * Permission to use, copy, modify, distribute and sell this software
43 * and its documentation for any purpose is hereby granted without fee,
44 * provided that the above copyright notice appear in all copies and
45 * that both that copyright notice and this permission notice appear
46 * in supporting documentation. Hewlett-Packard Company makes no
47 * representations about the suitability of this software for any
48 * purpose. It is provided "as is" without express or implied warranty.
49 *
50 *
51 */
52
53/** @file bits/stl_tree.h
54 * This is an internal header file, included by other library headers.
55 * Do not attempt to use it directly. @headername{map,set}
56 */
57
58#ifndef _STL_TREE_H1
59#define _STL_TREE_H1 1
60
61#pragma GCC system_header
62
63#include <bits/stl_algobase.h>
64#include <bits/allocator.h>
65#include <bits/stl_function.h>
66#include <bits/cpp_type_traits.h>
67#include <ext/alloc_traits.h>
68#if __cplusplus201402L >= 201103L
69# include <ext/aligned_buffer.h>
70#endif
71#if __cplusplus201402L > 201402L
72# include <bits/node_handle.h>
73#endif
74
75namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
76{
77_GLIBCXX_BEGIN_NAMESPACE_VERSION
78
79#if __cplusplus201402L > 201103L
80# define __cpp_lib_generic_associative_lookup201304 201304
81#endif
82
83 // Red-black tree class, designed for use in implementing STL
84 // associative containers (set, multiset, map, and multimap). The
85 // insertion and deletion algorithms are based on those in Cormen,
86 // Leiserson, and Rivest, Introduction to Algorithms (MIT Press,
87 // 1990), except that
88 //
89 // (1) the header cell is maintained with links not only to the root
90 // but also to the leftmost node of the tree, to enable constant
91 // time begin(), and to the rightmost node of the tree, to enable
92 // linear time performance when used with the generic set algorithms
93 // (set_union, etc.)
94 //
95 // (2) when a node being deleted has two children its successor node
96 // is relinked into its place, rather than copied, so that the only
97 // iterators invalidated are those referring to the deleted node.
98
99 enum _Rb_tree_color { _S_red = false, _S_black = true };
100
101 struct _Rb_tree_node_base
102 {
103 typedef _Rb_tree_node_base* _Base_ptr;
104 typedef const _Rb_tree_node_base* _Const_Base_ptr;
105
106 _Rb_tree_color _M_color;
107 _Base_ptr _M_parent;
108 _Base_ptr _M_left;
109 _Base_ptr _M_right;
110
111 static _Base_ptr
112 _S_minimum(_Base_ptr __x) _GLIBCXX_NOEXCEPTnoexcept
113 {
114 while (__x->_M_left != 0) __x = __x->_M_left;
115 return __x;
116 }
117
118 static _Const_Base_ptr
119 _S_minimum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPTnoexcept
120 {
121 while (__x->_M_left != 0) __x = __x->_M_left;
122 return __x;
123 }
124
125 static _Base_ptr
126 _S_maximum(_Base_ptr __x) _GLIBCXX_NOEXCEPTnoexcept
127 {
128 while (__x->_M_right != 0) __x = __x->_M_right;
129 return __x;
130 }
131
132 static _Const_Base_ptr
133 _S_maximum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPTnoexcept
134 {
135 while (__x->_M_right != 0) __x = __x->_M_right;
136 return __x;
137 }
138 };
139
140 // Helper type offering value initialization guarantee on the compare functor.
141 template<typename _Key_compare>
142 struct _Rb_tree_key_compare
143 {
144 _Key_compare _M_key_compare;
145
146 _Rb_tree_key_compare()
147 _GLIBCXX_NOEXCEPT_IF(noexcept(is_nothrow_default_constructible<_Key_compare>
::value)
148 is_nothrow_default_constructible<_Key_compare>::value)noexcept(is_nothrow_default_constructible<_Key_compare>
::value)
149 : _M_key_compare()
150 { }
151
152 _Rb_tree_key_compare(const _Key_compare& __comp)
153 : _M_key_compare(__comp)
154 { }
155
156#if __cplusplus201402L >= 201103L
157 // Copy constructor added for consistency with C++98 mode.
158 _Rb_tree_key_compare(const _Rb_tree_key_compare&) = default;
159
160 _Rb_tree_key_compare(_Rb_tree_key_compare&& __x)
161 noexcept(is_nothrow_copy_constructible<_Key_compare>::value)
162 : _M_key_compare(__x._M_key_compare)
163 { }
164#endif
165 };
166
167 // Helper type to manage default initialization of node count and header.
168 struct _Rb_tree_header
169 {
170 _Rb_tree_node_base _M_header;
171 size_t _M_node_count; // Keeps track of size of tree.
172
173 _Rb_tree_header() _GLIBCXX_NOEXCEPTnoexcept
174 {
175 _M_header._M_color = _S_red;
176 _M_reset();
177 }
178
179#if __cplusplus201402L >= 201103L
180 _Rb_tree_header(_Rb_tree_header&& __x) noexcept
181 {
182 if (__x._M_header._M_parent != nullptr)
183 _M_move_data(__x);
184 else
185 {
186 _M_header._M_color = _S_red;
187 _M_reset();
188 }
189 }
190#endif
191
192 void
193 _M_move_data(_Rb_tree_header& __from)
194 {
195 _M_header._M_color = __from._M_header._M_color;
196 _M_header._M_parent = __from._M_header._M_parent;
197 _M_header._M_left = __from._M_header._M_left;
198 _M_header._M_right = __from._M_header._M_right;
199 _M_header._M_parent->_M_parent = &_M_header;
200 _M_node_count = __from._M_node_count;
201
202 __from._M_reset();
203 }
204
205 void
206 _M_reset()
207 {
208 _M_header._M_parent = 0;
209 _M_header._M_left = &_M_header;
210 _M_header._M_right = &_M_header;
211 _M_node_count = 0;
212 }
213 };
214
215 template<typename _Val>
216 struct _Rb_tree_node : public _Rb_tree_node_base
217 {
218 typedef _Rb_tree_node<_Val>* _Link_type;
219
220#if __cplusplus201402L < 201103L
221 _Val _M_value_field;
222
223 _Val*
224 _M_valptr()
225 { return std::__addressof(_M_value_field); }
226
227 const _Val*
228 _M_valptr() const
229 { return std::__addressof(_M_value_field); }
230#else
231 __gnu_cxx::__aligned_membuf<_Val> _M_storage;
232
233 _Val*
234 _M_valptr()
235 { return _M_storage._M_ptr(); }
236
237 const _Val*
238 _M_valptr() const
239 { return _M_storage._M_ptr(); }
240#endif
241 };
242
243 _GLIBCXX_PURE__attribute__ ((__pure__)) _Rb_tree_node_base*
244 _Rb_tree_increment(_Rb_tree_node_base* __x) throw ();
245
246 _GLIBCXX_PURE__attribute__ ((__pure__)) const _Rb_tree_node_base*
247 _Rb_tree_increment(const _Rb_tree_node_base* __x) throw ();
248
249 _GLIBCXX_PURE__attribute__ ((__pure__)) _Rb_tree_node_base*
250 _Rb_tree_decrement(_Rb_tree_node_base* __x) throw ();
251
252 _GLIBCXX_PURE__attribute__ ((__pure__)) const _Rb_tree_node_base*
253 _Rb_tree_decrement(const _Rb_tree_node_base* __x) throw ();
254
255 template<typename _Tp>
256 struct _Rb_tree_iterator
257 {
258 typedef _Tp value_type;
259 typedef _Tp& reference;
260 typedef _Tp* pointer;
261
262 typedef bidirectional_iterator_tag iterator_category;
263 typedef ptrdiff_t difference_type;
264
265 typedef _Rb_tree_iterator<_Tp> _Self;
266 typedef _Rb_tree_node_base::_Base_ptr _Base_ptr;
267 typedef _Rb_tree_node<_Tp>* _Link_type;
268
269 _Rb_tree_iterator() _GLIBCXX_NOEXCEPTnoexcept
270 : _M_node() { }
271
272 explicit
273 _Rb_tree_iterator(_Base_ptr __x) _GLIBCXX_NOEXCEPTnoexcept
274 : _M_node(__x) { }
275
276 reference
277 operator*() const _GLIBCXX_NOEXCEPTnoexcept
278 { return *static_cast<_Link_type>(_M_node)->_M_valptr(); }
279
280 pointer
281 operator->() const _GLIBCXX_NOEXCEPTnoexcept
282 { return static_cast<_Link_type> (_M_node)->_M_valptr(); }
283
284 _Self&
285 operator++() _GLIBCXX_NOEXCEPTnoexcept
286 {
287 _M_node = _Rb_tree_increment(_M_node);
288 return *this;
289 }
290
291 _Self
292 operator++(int) _GLIBCXX_NOEXCEPTnoexcept
293 {
294 _Self __tmp = *this;
295 _M_node = _Rb_tree_increment(_M_node);
296 return __tmp;
297 }
298
299 _Self&
300 operator--() _GLIBCXX_NOEXCEPTnoexcept
301 {
302 _M_node = _Rb_tree_decrement(_M_node);
303 return *this;
304 }
305
306 _Self
307 operator--(int) _GLIBCXX_NOEXCEPTnoexcept
308 {
309 _Self __tmp = *this;
310 _M_node = _Rb_tree_decrement(_M_node);
311 return __tmp;
312 }
313
314 friend bool
315 operator==(const _Self& __x, const _Self& __y) _GLIBCXX_NOEXCEPTnoexcept
316 { return __x._M_node == __y._M_node; }
317
318#if ! __cpp_lib_three_way_comparison
319 friend bool
320 operator!=(const _Self& __x, const _Self& __y) _GLIBCXX_NOEXCEPTnoexcept
321 { return __x._M_node != __y._M_node; }
322#endif
323
324 _Base_ptr _M_node;
325 };
326
327 template<typename _Tp>
328 struct _Rb_tree_const_iterator
329 {
330 typedef _Tp value_type;
331 typedef const _Tp& reference;
332 typedef const _Tp* pointer;
333
334 typedef _Rb_tree_iterator<_Tp> iterator;
335
336 typedef bidirectional_iterator_tag iterator_category;
337 typedef ptrdiff_t difference_type;
338
339 typedef _Rb_tree_const_iterator<_Tp> _Self;
340 typedef _Rb_tree_node_base::_Const_Base_ptr _Base_ptr;
341 typedef const _Rb_tree_node<_Tp>* _Link_type;
342
343 _Rb_tree_const_iterator() _GLIBCXX_NOEXCEPTnoexcept
344 : _M_node() { }
345
346 explicit
347 _Rb_tree_const_iterator(_Base_ptr __x) _GLIBCXX_NOEXCEPTnoexcept
348 : _M_node(__x) { }
349
350 _Rb_tree_const_iterator(const iterator& __it) _GLIBCXX_NOEXCEPTnoexcept
351 : _M_node(__it._M_node) { }
352
353 iterator
354 _M_const_cast() const _GLIBCXX_NOEXCEPTnoexcept
355 { return iterator(const_cast<typename iterator::_Base_ptr>(_M_node)); }
356
357 reference
358 operator*() const _GLIBCXX_NOEXCEPTnoexcept
359 { return *static_cast<_Link_type>(_M_node)->_M_valptr(); }
360
361 pointer
362 operator->() const _GLIBCXX_NOEXCEPTnoexcept
363 { return static_cast<_Link_type>(_M_node)->_M_valptr(); }
364
365 _Self&
366 operator++() _GLIBCXX_NOEXCEPTnoexcept
367 {
368 _M_node = _Rb_tree_increment(_M_node);
369 return *this;
370 }
371
372 _Self
373 operator++(int) _GLIBCXX_NOEXCEPTnoexcept
374 {
375 _Self __tmp = *this;
376 _M_node = _Rb_tree_increment(_M_node);
377 return __tmp;
378 }
379
380 _Self&
381 operator--() _GLIBCXX_NOEXCEPTnoexcept
382 {
383 _M_node = _Rb_tree_decrement(_M_node);
384 return *this;
385 }
386
387 _Self
388 operator--(int) _GLIBCXX_NOEXCEPTnoexcept
389 {
390 _Self __tmp = *this;
391 _M_node = _Rb_tree_decrement(_M_node);
392 return __tmp;
393 }
394
395 friend bool
396 operator==(const _Self& __x, const _Self& __y) _GLIBCXX_NOEXCEPTnoexcept
397 { return __x._M_node == __y._M_node; }
4
Assuming '__x._M_node' is not equal to '__y._M_node'
5
Returning zero, which participates in a condition later
23
Assuming '__x._M_node' is not equal to '__y._M_node'
24
Returning zero, which participates in a condition later
42
Assuming '__x._M_node' is not equal to '__y._M_node'
43
Returning zero, which participates in a condition later
61
Assuming '__x._M_node' is not equal to '__y._M_node'
62
Returning zero, which participates in a condition later
398
399#if ! __cpp_lib_three_way_comparison
400 friend bool
401 operator!=(const _Self& __x, const _Self& __y) _GLIBCXX_NOEXCEPTnoexcept
402 { return __x._M_node != __y._M_node; }
403#endif
404
405 _Base_ptr _M_node;
406 };
407
408 void
409 _Rb_tree_insert_and_rebalance(const bool __insert_left,
410 _Rb_tree_node_base* __x,
411 _Rb_tree_node_base* __p,
412 _Rb_tree_node_base& __header) throw ();
413
414 _Rb_tree_node_base*
415 _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z,
416 _Rb_tree_node_base& __header) throw ();
417
418#if __cplusplus201402L >= 201402L
419 template<typename _Cmp, typename _SfinaeType, typename = __void_t<>>
420 struct __has_is_transparent
421 { };
422
423 template<typename _Cmp, typename _SfinaeType>
424 struct __has_is_transparent<_Cmp, _SfinaeType,
425 __void_t<typename _Cmp::is_transparent>>
426 { typedef void type; };
427
428 template<typename _Cmp, typename _SfinaeType>
429 using __has_is_transparent_t
430 = typename __has_is_transparent<_Cmp, _SfinaeType>::type;
431#endif
432
433#if __cplusplus201402L > 201402L
434 template<typename _Tree1, typename _Cmp2>
435 struct _Rb_tree_merge_helper { };
436#endif
437
438 template<typename _Key, typename _Val, typename _KeyOfValue,
439 typename _Compare, typename _Alloc = allocator<_Val> >
440 class _Rb_tree
441 {
442 typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
443 rebind<_Rb_tree_node<_Val> >::other _Node_allocator;
444
445 typedef __gnu_cxx::__alloc_traits<_Node_allocator> _Alloc_traits;
446
447 protected:
448 typedef _Rb_tree_node_base* _Base_ptr;
449 typedef const _Rb_tree_node_base* _Const_Base_ptr;
450 typedef _Rb_tree_node<_Val>* _Link_type;
451 typedef const _Rb_tree_node<_Val>* _Const_Link_type;
452
453 private:
454 // Functor recycling a pool of nodes and using allocation once the pool
455 // is empty.
456 struct _Reuse_or_alloc_node
457 {
458 _Reuse_or_alloc_node(_Rb_tree& __t)
459 : _M_root(__t._M_root()), _M_nodes(__t._M_rightmost()), _M_t(__t)
460 {
461 if (_M_root)
462 {
463 _M_root->_M_parent = 0;
464
465 if (_M_nodes->_M_left)
466 _M_nodes = _M_nodes->_M_left;
467 }
468 else
469 _M_nodes = 0;
470 }
471
472#if __cplusplus201402L >= 201103L
473 _Reuse_or_alloc_node(const _Reuse_or_alloc_node&) = delete;
474#endif
475
476 ~_Reuse_or_alloc_node()
477 { _M_t._M_erase(static_cast<_Link_type>(_M_root)); }
478
479 template<typename _Arg>
480 _Link_type
481#if __cplusplus201402L < 201103L
482 operator()(const _Arg& __arg)
483#else
484 operator()(_Arg&& __arg)
485#endif
486 {
487 _Link_type __node = static_cast<_Link_type>(_M_extract());
488 if (__node)
489 {
490 _M_t._M_destroy_node(__node);
491 _M_t._M_construct_node(__node, _GLIBCXX_FORWARD(_Arg, __arg)std::forward<_Arg>(__arg));
492 return __node;
493 }
494
495 return _M_t._M_create_node(_GLIBCXX_FORWARD(_Arg, __arg)std::forward<_Arg>(__arg));
496 }
497
498 private:
499 _Base_ptr
500 _M_extract()
501 {
502 if (!_M_nodes)
503 return _M_nodes;
504
505 _Base_ptr __node = _M_nodes;
506 _M_nodes = _M_nodes->_M_parent;
507 if (_M_nodes)
508 {
509 if (_M_nodes->_M_right == __node)
510 {
511 _M_nodes->_M_right = 0;
512
513 if (_M_nodes->_M_left)
514 {
515 _M_nodes = _M_nodes->_M_left;
516
517 while (_M_nodes->_M_right)
518 _M_nodes = _M_nodes->_M_right;
519
520 if (_M_nodes->_M_left)
521 _M_nodes = _M_nodes->_M_left;
522 }
523 }
524 else // __node is on the left.
525 _M_nodes->_M_left = 0;
526 }
527 else
528 _M_root = 0;
529
530 return __node;
531 }
532
533 _Base_ptr _M_root;
534 _Base_ptr _M_nodes;
535 _Rb_tree& _M_t;
536 };
537
538 // Functor similar to the previous one but without any pool of nodes to
539 // recycle.
540 struct _Alloc_node
541 {
542 _Alloc_node(_Rb_tree& __t)
543 : _M_t(__t) { }
544
545 template<typename _Arg>
546 _Link_type
547#if __cplusplus201402L < 201103L
548 operator()(const _Arg& __arg) const
549#else
550 operator()(_Arg&& __arg) const
551#endif
552 { return _M_t._M_create_node(_GLIBCXX_FORWARD(_Arg, __arg)std::forward<_Arg>(__arg)); }
553
554 private:
555 _Rb_tree& _M_t;
556 };
557
558 public:
559 typedef _Key key_type;
560 typedef _Val value_type;
561 typedef value_type* pointer;
562 typedef const value_type* const_pointer;
563 typedef value_type& reference;
564 typedef const value_type& const_reference;
565 typedef size_t size_type;
566 typedef ptrdiff_t difference_type;
567 typedef _Alloc allocator_type;
568
569 _Node_allocator&
570 _M_get_Node_allocator() _GLIBCXX_NOEXCEPTnoexcept
571 { return this->_M_impl; }
572
573 const _Node_allocator&
574 _M_get_Node_allocator() const _GLIBCXX_NOEXCEPTnoexcept
575 { return this->_M_impl; }
576
577 allocator_type
578 get_allocator() const _GLIBCXX_NOEXCEPTnoexcept
579 { return allocator_type(_M_get_Node_allocator()); }
580
581 protected:
582 _Link_type
583 _M_get_node()
584 { return _Alloc_traits::allocate(_M_get_Node_allocator(), 1); }
585
586 void
587 _M_put_node(_Link_type __p) _GLIBCXX_NOEXCEPTnoexcept
588 { _Alloc_traits::deallocate(_M_get_Node_allocator(), __p, 1); }
589
590#if __cplusplus201402L < 201103L
591 void
592 _M_construct_node(_Link_type __node, const value_type& __x)
593 {
594 __tryif (true)
595 { get_allocator().construct(__node->_M_valptr(), __x); }
596 __catch(...)if (false)
597 {
598 _M_put_node(__node);
599 __throw_exception_again;
600 }
601 }
602
603 _Link_type
604 _M_create_node(const value_type& __x)
605 {
606 _Link_type __tmp = _M_get_node();
607 _M_construct_node(__tmp, __x);
608 return __tmp;
609 }
610#else
611 template<typename... _Args>
612 void
613 _M_construct_node(_Link_type __node, _Args&&... __args)
614 {
615 __tryif (true)
616 {
617 ::new(__node) _Rb_tree_node<_Val>;
618 _Alloc_traits::construct(_M_get_Node_allocator(),
619 __node->_M_valptr(),
620 std::forward<_Args>(__args)...);
621 }
622 __catch(...)if (false)
623 {
624 __node->~_Rb_tree_node<_Val>();
625 _M_put_node(__node);
626 __throw_exception_again;
627 }
628 }
629
630 template<typename... _Args>
631 _Link_type
632 _M_create_node(_Args&&... __args)
633 {
634 _Link_type __tmp = _M_get_node();
635 _M_construct_node(__tmp, std::forward<_Args>(__args)...);
636 return __tmp;
637 }
638#endif
639
640 void
641 _M_destroy_node(_Link_type __p) _GLIBCXX_NOEXCEPTnoexcept
642 {
643#if __cplusplus201402L < 201103L
644 get_allocator().destroy(__p->_M_valptr());
645#else
646 _Alloc_traits::destroy(_M_get_Node_allocator(), __p->_M_valptr());
647 __p->~_Rb_tree_node<_Val>();
648#endif
649 }
650
651 void
652 _M_drop_node(_Link_type __p) _GLIBCXX_NOEXCEPTnoexcept
653 {
654 _M_destroy_node(__p);
655 _M_put_node(__p);
656 }
657
658 template<typename _NodeGen>
659 _Link_type
660 _M_clone_node(_Const_Link_type __x, _NodeGen& __node_gen)
661 {
662 _Link_type __tmp = __node_gen(*__x->_M_valptr());
663 __tmp->_M_color = __x->_M_color;
664 __tmp->_M_left = 0;
665 __tmp->_M_right = 0;
666 return __tmp;
667 }
668
669 protected:
670#if _GLIBCXX_INLINE_VERSION0
671 template<typename _Key_compare>
672#else
673 // Unused _Is_pod_comparator is kept as it is part of mangled name.
674 template<typename _Key_compare,
675 bool /* _Is_pod_comparator */ = __is_pod(_Key_compare)>
676#endif
677 struct _Rb_tree_impl
678 : public _Node_allocator
679 , public _Rb_tree_key_compare<_Key_compare>
680 , public _Rb_tree_header
681 {
682 typedef _Rb_tree_key_compare<_Key_compare> _Base_key_compare;
683
684 _Rb_tree_impl()
685 _GLIBCXX_NOEXCEPT_IF(noexcept(is_nothrow_default_constructible<_Node_allocator>
::value && is_nothrow_default_constructible<_Base_key_compare
>::value)
686 is_nothrow_default_constructible<_Node_allocator>::valuenoexcept(is_nothrow_default_constructible<_Node_allocator>
::value && is_nothrow_default_constructible<_Base_key_compare
>::value)
687 && is_nothrow_default_constructible<_Base_key_compare>::value )noexcept(is_nothrow_default_constructible<_Node_allocator>
::value && is_nothrow_default_constructible<_Base_key_compare
>::value)
688 : _Node_allocator()
689 { }
690
691 _Rb_tree_impl(const _Rb_tree_impl& __x)
692 : _Node_allocator(_Alloc_traits::_S_select_on_copy(__x))
693 , _Base_key_compare(__x._M_key_compare)
694 { }
695
696#if __cplusplus201402L < 201103L
697 _Rb_tree_impl(const _Key_compare& __comp, const _Node_allocator& __a)
698 : _Node_allocator(__a), _Base_key_compare(__comp)
699 { }
700#else
701 _Rb_tree_impl(_Rb_tree_impl&&) = default;
702
703 explicit
704 _Rb_tree_impl(_Node_allocator&& __a)
705 : _Node_allocator(std::move(__a))
706 { }
707
708 _Rb_tree_impl(_Rb_tree_impl&& __x, _Node_allocator&& __a)
709 : _Node_allocator(std::move(__a)),
710 _Base_key_compare(std::move(__x)),
711 _Rb_tree_header(std::move(__x))
712 { }
713
714 _Rb_tree_impl(const _Key_compare& __comp, _Node_allocator&& __a)
715 : _Node_allocator(std::move(__a)), _Base_key_compare(__comp)
716 { }
717#endif
718 };
719
720 _Rb_tree_impl<_Compare> _M_impl;
721
722 protected:
723 _Base_ptr&
724 _M_root() _GLIBCXX_NOEXCEPTnoexcept
725 { return this->_M_impl._M_header._M_parent; }
726
727 _Const_Base_ptr
728 _M_root() const _GLIBCXX_NOEXCEPTnoexcept
729 { return this->_M_impl._M_header._M_parent; }
730
731 _Base_ptr&
732 _M_leftmost() _GLIBCXX_NOEXCEPTnoexcept
733 { return this->_M_impl._M_header._M_left; }
734
735 _Const_Base_ptr
736 _M_leftmost() const _GLIBCXX_NOEXCEPTnoexcept
737 { return this->_M_impl._M_header._M_left; }
738
739 _Base_ptr&
740 _M_rightmost() _GLIBCXX_NOEXCEPTnoexcept
741 { return this->_M_impl._M_header._M_right; }
742
743 _Const_Base_ptr
744 _M_rightmost() const _GLIBCXX_NOEXCEPTnoexcept
745 { return this->_M_impl._M_header._M_right; }
746
747 _Link_type
748 _M_begin() _GLIBCXX_NOEXCEPTnoexcept
749 { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); }
750
751 _Const_Link_type
752 _M_begin() const _GLIBCXX_NOEXCEPTnoexcept
753 {
754 return static_cast<_Const_Link_type>
755 (this->_M_impl._M_header._M_parent);
756 }
757
758 _Base_ptr
759 _M_end() _GLIBCXX_NOEXCEPTnoexcept
760 { return &this->_M_impl._M_header; }
761
762 _Const_Base_ptr
763 _M_end() const _GLIBCXX_NOEXCEPTnoexcept
764 { return &this->_M_impl._M_header; }
765
766 static const _Key&
767 _S_key(_Const_Link_type __x)
768 {
769#if __cplusplus201402L >= 201103L
770 // If we're asking for the key we're presumably using the comparison
771 // object, and so this is a good place to sanity check it.
772 static_assert(__is_invocable<_Compare&, const _Key&, const _Key&>{},
773 "comparison object must be invocable "
774 "with two arguments of key type");
775# if __cplusplus201402L >= 201703L
776 // _GLIBCXX_RESOLVE_LIB_DEFECTS
777 // 2542. Missing const requirements for associative containers
778 if constexpr (__is_invocable<_Compare&, const _Key&, const _Key&>{})
779 static_assert(
780 is_invocable_v<const _Compare&, const _Key&, const _Key&>,
781 "comparison object must be invocable as const");
782# endif // C++17
783#endif // C++11
784
785 return _KeyOfValue()(*__x->_M_valptr());
786 }
787
788 static _Link_type
789 _S_left(_Base_ptr __x) _GLIBCXX_NOEXCEPTnoexcept
790 { return static_cast<_Link_type>(__x->_M_left); }
791
792 static _Const_Link_type
793 _S_left(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPTnoexcept
794 { return static_cast<_Const_Link_type>(__x->_M_left); }
795
796 static _Link_type
797 _S_right(_Base_ptr __x) _GLIBCXX_NOEXCEPTnoexcept
798 { return static_cast<_Link_type>(__x->_M_right); }
799
800 static _Const_Link_type
801 _S_right(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPTnoexcept
802 { return static_cast<_Const_Link_type>(__x->_M_right); }
803
804 static const _Key&
805 _S_key(_Const_Base_ptr __x)
806 { return _S_key(static_cast<_Const_Link_type>(__x)); }
807
808 static _Base_ptr
809 _S_minimum(_Base_ptr __x) _GLIBCXX_NOEXCEPTnoexcept
810 { return _Rb_tree_node_base::_S_minimum(__x); }
811
812 static _Const_Base_ptr
813 _S_minimum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPTnoexcept
814 { return _Rb_tree_node_base::_S_minimum(__x); }
815
816 static _Base_ptr
817 _S_maximum(_Base_ptr __x) _GLIBCXX_NOEXCEPTnoexcept
818 { return _Rb_tree_node_base::_S_maximum(__x); }
819
820 static _Const_Base_ptr
821 _S_maximum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPTnoexcept
822 { return _Rb_tree_node_base::_S_maximum(__x); }
823
824 public:
825 typedef _Rb_tree_iterator<value_type> iterator;
826 typedef _Rb_tree_const_iterator<value_type> const_iterator;
827
828 typedef std::reverse_iterator<iterator> reverse_iterator;
829 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
830
831#if __cplusplus201402L > 201402L
832 using node_type = _Node_handle<_Key, _Val, _Node_allocator>;
833 using insert_return_type = _Node_insert_return<
834 conditional_t<is_same_v<_Key, _Val>, const_iterator, iterator>,
835 node_type>;
836#endif
837
838 pair<_Base_ptr, _Base_ptr>
839 _M_get_insert_unique_pos(const key_type& __k);
840
841 pair<_Base_ptr, _Base_ptr>
842 _M_get_insert_equal_pos(const key_type& __k);
843
844 pair<_Base_ptr, _Base_ptr>
845 _M_get_insert_hint_unique_pos(const_iterator __pos,
846 const key_type& __k);
847
848 pair<_Base_ptr, _Base_ptr>
849 _M_get_insert_hint_equal_pos(const_iterator __pos,
850 const key_type& __k);
851
852 private:
853#if __cplusplus201402L >= 201103L
854 template<typename _Arg, typename _NodeGen>
855 iterator
856 _M_insert_(_Base_ptr __x, _Base_ptr __y, _Arg&& __v, _NodeGen&);
857
858 iterator
859 _M_insert_node(_Base_ptr __x, _Base_ptr __y, _Link_type __z);
860
861 template<typename _Arg>
862 iterator
863 _M_insert_lower(_Base_ptr __y, _Arg&& __v);
864
865 template<typename _Arg>
866 iterator
867 _M_insert_equal_lower(_Arg&& __x);
868
869 iterator
870 _M_insert_lower_node(_Base_ptr __p, _Link_type __z);
871
872 iterator
873 _M_insert_equal_lower_node(_Link_type __z);
874#else
875 template<typename _NodeGen>
876 iterator
877 _M_insert_(_Base_ptr __x, _Base_ptr __y,
878 const value_type& __v, _NodeGen&);
879
880 // _GLIBCXX_RESOLVE_LIB_DEFECTS
881 // 233. Insertion hints in associative containers.
882 iterator
883 _M_insert_lower(_Base_ptr __y, const value_type& __v);
884
885 iterator
886 _M_insert_equal_lower(const value_type& __x);
887#endif
888
889 template<typename _NodeGen>
890 _Link_type
891 _M_copy(_Const_Link_type __x, _Base_ptr __p, _NodeGen&);
892
893 template<typename _NodeGen>
894 _Link_type
895 _M_copy(const _Rb_tree& __x, _NodeGen& __gen)
896 {
897 _Link_type __root = _M_copy(__x._M_begin(), _M_end(), __gen);
898 _M_leftmost() = _S_minimum(__root);
899 _M_rightmost() = _S_maximum(__root);
900 _M_impl._M_node_count = __x._M_impl._M_node_count;
901 return __root;
902 }
903
904 _Link_type
905 _M_copy(const _Rb_tree& __x)
906 {
907 _Alloc_node __an(*this);
908 return _M_copy(__x, __an);
909 }
910
911 void
912 _M_erase(_Link_type __x);
913
914 iterator
915 _M_lower_bound(_Link_type __x, _Base_ptr __y,
916 const _Key& __k);
917
918 const_iterator
919 _M_lower_bound(_Const_Link_type __x, _Const_Base_ptr __y,
920 const _Key& __k) const;
921
922 iterator
923 _M_upper_bound(_Link_type __x, _Base_ptr __y,
924 const _Key& __k);
925
926 const_iterator
927 _M_upper_bound(_Const_Link_type __x, _Const_Base_ptr __y,
928 const _Key& __k) const;
929
930 public:
931 // allocation/deallocation
932#if __cplusplus201402L < 201103L
933 _Rb_tree() { }
934#else
935 _Rb_tree() = default;
936#endif
937
938 _Rb_tree(const _Compare& __comp,
939 const allocator_type& __a = allocator_type())
940 : _M_impl(__comp, _Node_allocator(__a)) { }
941
942 _Rb_tree(const _Rb_tree& __x)
943 : _M_impl(__x._M_impl)
944 {
945 if (__x._M_root() != 0)
946 _M_root() = _M_copy(__x);
947 }
948
949#if __cplusplus201402L >= 201103L
950 _Rb_tree(const allocator_type& __a)
951 : _M_impl(_Node_allocator(__a))
952 { }
953
954 _Rb_tree(const _Rb_tree& __x, const allocator_type& __a)
955 : _M_impl(__x._M_impl._M_key_compare, _Node_allocator(__a))
956 {
957 if (__x._M_root() != nullptr)
958 _M_root() = _M_copy(__x);
959 }
960
961 _Rb_tree(_Rb_tree&&) = default;
962
963 _Rb_tree(_Rb_tree&& __x, const allocator_type& __a)
964 : _Rb_tree(std::move(__x), _Node_allocator(__a))
965 { }
966
967 private:
968 _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a, true_type)
969 noexcept(is_nothrow_default_constructible<_Compare>::value)
970 : _M_impl(std::move(__x._M_impl), std::move(__a))
971 { }
972
973 _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a, false_type)
974 : _M_impl(__x._M_impl._M_key_compare, std::move(__a))
975 {
976 if (__x._M_root() != nullptr)
977 _M_move_data(__x, false_type{});
978 }
979
980 public:
981 _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a)
982 noexcept( noexcept(
983 _Rb_tree(std::declval<_Rb_tree&&>(), std::declval<_Node_allocator&&>(),
984 std::declval<typename _Alloc_traits::is_always_equal>())) )
985 : _Rb_tree(std::move(__x), std::move(__a),
986 typename _Alloc_traits::is_always_equal{})
987 { }
988#endif
989
990 ~_Rb_tree() _GLIBCXX_NOEXCEPTnoexcept
991 { _M_erase(_M_begin()); }
992
993 _Rb_tree&
994 operator=(const _Rb_tree& __x);
995
996 // Accessors.
997 _Compare
998 key_comp() const
999 { return _M_impl._M_key_compare; }
1000
1001 iterator
1002 begin() _GLIBCXX_NOEXCEPTnoexcept
1003 { return iterator(this->_M_impl._M_header._M_left); }
1004
1005 const_iterator
1006 begin() const _GLIBCXX_NOEXCEPTnoexcept
1007 { return const_iterator(this->_M_impl._M_header._M_left); }
1008
1009 iterator
1010 end() _GLIBCXX_NOEXCEPTnoexcept
1011 { return iterator(&this->_M_impl._M_header); }
1012
1013 const_iterator
1014 end() const _GLIBCXX_NOEXCEPTnoexcept
1015 { return const_iterator(&this->_M_impl._M_header); }
1016
1017 reverse_iterator
1018 rbegin() _GLIBCXX_NOEXCEPTnoexcept
1019 { return reverse_iterator(end()); }
1020
1021 const_reverse_iterator
1022 rbegin() const _GLIBCXX_NOEXCEPTnoexcept
1023 { return const_reverse_iterator(end()); }
1024
1025 reverse_iterator
1026 rend() _GLIBCXX_NOEXCEPTnoexcept
1027 { return reverse_iterator(begin()); }
1028
1029 const_reverse_iterator
1030 rend() const _GLIBCXX_NOEXCEPTnoexcept
1031 { return const_reverse_iterator(begin()); }
1032
1033 _GLIBCXX_NODISCARD bool
1034 empty() const _GLIBCXX_NOEXCEPTnoexcept
1035 { return _M_impl._M_node_count == 0; }
1036
1037 size_type
1038 size() const _GLIBCXX_NOEXCEPTnoexcept
1039 { return _M_impl._M_node_count; }
1040
1041 size_type
1042 max_size() const _GLIBCXX_NOEXCEPTnoexcept
1043 { return _Alloc_traits::max_size(_M_get_Node_allocator()); }
1044
1045 void
1046 swap(_Rb_tree& __t)
1047 _GLIBCXX_NOEXCEPT_IF(__is_nothrow_swappable<_Compare>::value)noexcept(__is_nothrow_swappable<_Compare>::value);
1048
1049 // Insert/erase.
1050#if __cplusplus201402L >= 201103L
1051 template<typename _Arg>
1052 pair<iterator, bool>
1053 _M_insert_unique(_Arg&& __x);
1054
1055 template<typename _Arg>
1056 iterator
1057 _M_insert_equal(_Arg&& __x);
1058
1059 template<typename _Arg, typename _NodeGen>
1060 iterator
1061 _M_insert_unique_(const_iterator __pos, _Arg&& __x, _NodeGen&);
1062
1063 template<typename _Arg>
1064 iterator
1065 _M_insert_unique_(const_iterator __pos, _Arg&& __x)
1066 {
1067 _Alloc_node __an(*this);
1068 return _M_insert_unique_(__pos, std::forward<_Arg>(__x), __an);
1069 }
1070
1071 template<typename _Arg, typename _NodeGen>
1072 iterator
1073 _M_insert_equal_(const_iterator __pos, _Arg&& __x, _NodeGen&);
1074
1075 template<typename _Arg>
1076 iterator
1077 _M_insert_equal_(const_iterator __pos, _Arg&& __x)
1078 {
1079 _Alloc_node __an(*this);
1080 return _M_insert_equal_(__pos, std::forward<_Arg>(__x), __an);
1081 }
1082
1083 template<typename... _Args>
1084 pair<iterator, bool>
1085 _M_emplace_unique(_Args&&... __args);
1086
1087 template<typename... _Args>
1088 iterator
1089 _M_emplace_equal(_Args&&... __args);
1090
1091 template<typename... _Args>
1092 iterator
1093 _M_emplace_hint_unique(const_iterator __pos, _Args&&... __args);
1094
1095 template<typename... _Args>
1096 iterator
1097 _M_emplace_hint_equal(const_iterator __pos, _Args&&... __args);
1098
1099 template<typename _Iter>
1100 using __same_value_type
1101 = is_same<value_type, typename iterator_traits<_Iter>::value_type>;
1102
1103 template<typename _InputIterator>
1104 __enable_if_t<__same_value_type<_InputIterator>::value>
1105 _M_insert_range_unique(_InputIterator __first, _InputIterator __last)
1106 {
1107 _Alloc_node __an(*this);
1108 for (; __first != __last; ++__first)
1109 _M_insert_unique_(end(), *__first, __an);
1110 }
1111
1112 template<typename _InputIterator>
1113 __enable_if_t<!__same_value_type<_InputIterator>::value>
1114 _M_insert_range_unique(_InputIterator __first, _InputIterator __last)
1115 {
1116 for (; __first != __last; ++__first)
1117 _M_emplace_unique(*__first);
1118 }
1119
1120 template<typename _InputIterator>
1121 __enable_if_t<__same_value_type<_InputIterator>::value>
1122 _M_insert_range_equal(_InputIterator __first, _InputIterator __last)
1123 {
1124 _Alloc_node __an(*this);
1125 for (; __first != __last; ++__first)
1126 _M_insert_equal_(end(), *__first, __an);
1127 }
1128
1129 template<typename _InputIterator>
1130 __enable_if_t<!__same_value_type<_InputIterator>::value>
1131 _M_insert_range_equal(_InputIterator __first, _InputIterator __last)
1132 {
1133 _Alloc_node __an(*this);
1134 for (; __first != __last; ++__first)
1135 _M_emplace_equal(*__first);
1136 }
1137#else
1138 pair<iterator, bool>
1139 _M_insert_unique(const value_type& __x);
1140
1141 iterator
1142 _M_insert_equal(const value_type& __x);
1143
1144 template<typename _NodeGen>
1145 iterator
1146 _M_insert_unique_(const_iterator __pos, const value_type& __x,
1147 _NodeGen&);
1148
1149 iterator
1150 _M_insert_unique_(const_iterator __pos, const value_type& __x)
1151 {
1152 _Alloc_node __an(*this);
1153 return _M_insert_unique_(__pos, __x, __an);
1154 }
1155
1156 template<typename _NodeGen>
1157 iterator
1158 _M_insert_equal_(const_iterator __pos, const value_type& __x,
1159 _NodeGen&);
1160 iterator
1161 _M_insert_equal_(const_iterator __pos, const value_type& __x)
1162 {
1163 _Alloc_node __an(*this);
1164 return _M_insert_equal_(__pos, __x, __an);
1165 }
1166
1167 template<typename _InputIterator>
1168 void
1169 _M_insert_range_unique(_InputIterator __first, _InputIterator __last)
1170 {
1171 _Alloc_node __an(*this);
1172 for (; __first != __last; ++__first)
1173 _M_insert_unique_(end(), *__first, __an);
1174 }
1175
1176 template<typename _InputIterator>
1177 void
1178 _M_insert_range_equal(_InputIterator __first, _InputIterator __last)
1179 {
1180 _Alloc_node __an(*this);
1181 for (; __first != __last; ++__first)
1182 _M_insert_equal_(end(), *__first, __an);
1183 }
1184#endif
1185
1186 private:
1187 void
1188 _M_erase_aux(const_iterator __position);
1189
1190 void
1191 _M_erase_aux(const_iterator __first, const_iterator __last);
1192
1193 public:
1194#if __cplusplus201402L >= 201103L
1195 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1196 // DR 130. Associative erase should return an iterator.
1197 _GLIBCXX_ABI_TAG_CXX11__attribute ((__abi_tag__ ("cxx11")))
1198 iterator
1199 erase(const_iterator __position)
1200 {
1201 __glibcxx_assert(__position != end());
1202 const_iterator __result = __position;
1203 ++__result;
1204 _M_erase_aux(__position);
1205 return __result._M_const_cast();
1206 }
1207
1208 // LWG 2059.
1209 _GLIBCXX_ABI_TAG_CXX11__attribute ((__abi_tag__ ("cxx11")))
1210 iterator
1211 erase(iterator __position)
1212 {
1213 __glibcxx_assert(__position != end());
1214 iterator __result = __position;
1215 ++__result;
1216 _M_erase_aux(__position);
1217 return __result;
1218 }
1219#else
1220 void
1221 erase(iterator __position)
1222 {
1223 __glibcxx_assert(__position != end());
1224 _M_erase_aux(__position);
1225 }
1226
1227 void
1228 erase(const_iterator __position)
1229 {
1230 __glibcxx_assert(__position != end());
1231 _M_erase_aux(__position);
1232 }
1233#endif
1234
1235 size_type
1236 erase(const key_type& __x);
1237
1238#if __cplusplus201402L >= 201103L
1239 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1240 // DR 130. Associative erase should return an iterator.
1241 _GLIBCXX_ABI_TAG_CXX11__attribute ((__abi_tag__ ("cxx11")))
1242 iterator
1243 erase(const_iterator __first, const_iterator __last)
1244 {
1245 _M_erase_aux(__first, __last);
1246 return __last._M_const_cast();
1247 }
1248#else
1249 void
1250 erase(iterator __first, iterator __last)
1251 { _M_erase_aux(__first, __last); }
1252
1253 void
1254 erase(const_iterator __first, const_iterator __last)
1255 { _M_erase_aux(__first, __last); }
1256#endif
1257
1258 void
1259 clear() _GLIBCXX_NOEXCEPTnoexcept
1260 {
1261 _M_erase(_M_begin());
1262 _M_impl._M_reset();
1263 }
1264
1265 // Set operations.
1266 iterator
1267 find(const key_type& __k);
1268
1269 const_iterator
1270 find(const key_type& __k) const;
1271
1272 size_type
1273 count(const key_type& __k) const;
1274
1275 iterator
1276 lower_bound(const key_type& __k)
1277 { return _M_lower_bound(_M_begin(), _M_end(), __k); }
1278
1279 const_iterator
1280 lower_bound(const key_type& __k) const
1281 { return _M_lower_bound(_M_begin(), _M_end(), __k); }
1282
1283 iterator
1284 upper_bound(const key_type& __k)
1285 { return _M_upper_bound(_M_begin(), _M_end(), __k); }
1286
1287 const_iterator
1288 upper_bound(const key_type& __k) const
1289 { return _M_upper_bound(_M_begin(), _M_end(), __k); }
1290
1291 pair<iterator, iterator>
1292 equal_range(const key_type& __k);
1293
1294 pair<const_iterator, const_iterator>
1295 equal_range(const key_type& __k) const;
1296
1297#if __cplusplus201402L >= 201402L
1298 template<typename _Kt,
1299 typename _Req = __has_is_transparent_t<_Compare, _Kt>>
1300 iterator
1301 _M_find_tr(const _Kt& __k)
1302 {
1303 const _Rb_tree* __const_this = this;
1304 return __const_this->_M_find_tr(__k)._M_const_cast();
1305 }
1306
1307 template<typename _Kt,
1308 typename _Req = __has_is_transparent_t<_Compare, _Kt>>
1309 const_iterator
1310 _M_find_tr(const _Kt& __k) const
1311 {
1312 auto __j = _M_lower_bound_tr(__k);
1313 if (__j != end() && _M_impl._M_key_compare(__k, _S_key(__j._M_node)))
1314 __j = end();
1315 return __j;
1316 }
1317
1318 template<typename _Kt,
1319 typename _Req = __has_is_transparent_t<_Compare, _Kt>>
1320 size_type
1321 _M_count_tr(const _Kt& __k) const
1322 {
1323 auto __p = _M_equal_range_tr(__k);
1324 return std::distance(__p.first, __p.second);
1325 }
1326
1327 template<typename _Kt,
1328 typename _Req = __has_is_transparent_t<_Compare, _Kt>>
1329 iterator
1330 _M_lower_bound_tr(const _Kt& __k)
1331 {
1332 const _Rb_tree* __const_this = this;
1333 return __const_this->_M_lower_bound_tr(__k)._M_const_cast();
1334 }
1335
1336 template<typename _Kt,
1337 typename _Req = __has_is_transparent_t<_Compare, _Kt>>
1338 const_iterator
1339 _M_lower_bound_tr(const _Kt& __k) const
1340 {
1341 auto __x = _M_begin();
1342 auto __y = _M_end();
1343 while (__x != 0)
1344 if (!_M_impl._M_key_compare(_S_key(__x), __k))
1345 {
1346 __y = __x;
1347 __x = _S_left(__x);
1348 }
1349 else
1350 __x = _S_right(__x);
1351 return const_iterator(__y);
1352 }
1353
1354 template<typename _Kt,
1355 typename _Req = __has_is_transparent_t<_Compare, _Kt>>
1356 iterator
1357 _M_upper_bound_tr(const _Kt& __k)
1358 {
1359 const _Rb_tree* __const_this = this;
1360 return __const_this->_M_upper_bound_tr(__k)._M_const_cast();
1361 }
1362
1363 template<typename _Kt,
1364 typename _Req = __has_is_transparent_t<_Compare, _Kt>>
1365 const_iterator
1366 _M_upper_bound_tr(const _Kt& __k) const
1367 {
1368 auto __x = _M_begin();
1369 auto __y = _M_end();
1370 while (__x != 0)
1371 if (_M_impl._M_key_compare(__k, _S_key(__x)))
1372 {
1373 __y = __x;
1374 __x = _S_left(__x);
1375 }
1376 else
1377 __x = _S_right(__x);
1378 return const_iterator(__y);
1379 }
1380
1381 template<typename _Kt,
1382 typename _Req = __has_is_transparent_t<_Compare, _Kt>>
1383 pair<iterator, iterator>
1384 _M_equal_range_tr(const _Kt& __k)
1385 {
1386 const _Rb_tree* __const_this = this;
1387 auto __ret = __const_this->_M_equal_range_tr(__k);
1388 return { __ret.first._M_const_cast(), __ret.second._M_const_cast() };
1389 }
1390
1391 template<typename _Kt,
1392 typename _Req = __has_is_transparent_t<_Compare, _Kt>>
1393 pair<const_iterator, const_iterator>
1394 _M_equal_range_tr(const _Kt& __k) const
1395 {
1396 auto __low = _M_lower_bound_tr(__k);
1397 auto __high = __low;
1398 auto& __cmp = _M_impl._M_key_compare;
1399 while (__high != end() && !__cmp(__k, _S_key(__high._M_node)))
1400 ++__high;
1401 return { __low, __high };
1402 }
1403#endif
1404
1405 // Debugging.
1406 bool
1407 __rb_verify() const;
1408
1409#if __cplusplus201402L >= 201103L
1410 _Rb_tree&
1411 operator=(_Rb_tree&&)
1412 noexcept(_Alloc_traits::_S_nothrow_move()
1413 && is_nothrow_move_assignable<_Compare>::value);
1414
1415 template<typename _Iterator>
1416 void
1417 _M_assign_unique(_Iterator, _Iterator);
1418
1419 template<typename _Iterator>
1420 void
1421 _M_assign_equal(_Iterator, _Iterator);
1422
1423 private:
1424 // Move elements from container with equal allocator.
1425 void
1426 _M_move_data(_Rb_tree& __x, true_type)
1427 { _M_impl._M_move_data(__x._M_impl); }
1428
1429 // Move elements from container with possibly non-equal allocator,
1430 // which might result in a copy not a move.
1431 void
1432 _M_move_data(_Rb_tree&, false_type);
1433
1434 // Move assignment from container with equal allocator.
1435 void
1436 _M_move_assign(_Rb_tree&, true_type);
1437
1438 // Move assignment from container with possibly non-equal allocator,
1439 // which might result in a copy not a move.
1440 void
1441 _M_move_assign(_Rb_tree&, false_type);
1442#endif
1443
1444#if __cplusplus201402L > 201402L
1445 public:
1446 /// Re-insert an extracted node.
1447 insert_return_type
1448 _M_reinsert_node_unique(node_type&& __nh)
1449 {
1450 insert_return_type __ret;
1451 if (__nh.empty())
1452 __ret.position = end();
1453 else
1454 {
1455 __glibcxx_assert(_M_get_Node_allocator() == *__nh._M_alloc);
1456
1457 auto __res = _M_get_insert_unique_pos(__nh._M_key());
1458 if (__res.second)
1459 {
1460 __ret.position
1461 = _M_insert_node(__res.first, __res.second, __nh._M_ptr);
1462 __nh._M_ptr = nullptr;
1463 __ret.inserted = true;
1464 }
1465 else
1466 {
1467 __ret.node = std::move(__nh);
1468 __ret.position = iterator(__res.first);
1469 __ret.inserted = false;
1470 }
1471 }
1472 return __ret;
1473 }
1474
1475 /// Re-insert an extracted node.
1476 iterator
1477 _M_reinsert_node_equal(node_type&& __nh)
1478 {
1479 iterator __ret;
1480 if (__nh.empty())
1481 __ret = end();
1482 else
1483 {
1484 __glibcxx_assert(_M_get_Node_allocator() == *__nh._M_alloc);
1485 auto __res = _M_get_insert_equal_pos(__nh._M_key());
1486 if (__res.second)
1487 __ret = _M_insert_node(__res.first, __res.second, __nh._M_ptr);
1488 else
1489 __ret = _M_insert_equal_lower_node(__nh._M_ptr);
1490 __nh._M_ptr = nullptr;
1491 }
1492 return __ret;
1493 }
1494
1495 /// Re-insert an extracted node.
1496 iterator
1497 _M_reinsert_node_hint_unique(const_iterator __hint, node_type&& __nh)
1498 {
1499 iterator __ret;
1500 if (__nh.empty())
1501 __ret = end();
1502 else
1503 {
1504 __glibcxx_assert(_M_get_Node_allocator() == *__nh._M_alloc);
1505 auto __res = _M_get_insert_hint_unique_pos(__hint, __nh._M_key());
1506 if (__res.second)
1507 {
1508 __ret = _M_insert_node(__res.first, __res.second, __nh._M_ptr);
1509 __nh._M_ptr = nullptr;
1510 }
1511 else
1512 __ret = iterator(__res.first);
1513 }
1514 return __ret;
1515 }
1516
1517 /// Re-insert an extracted node.
1518 iterator
1519 _M_reinsert_node_hint_equal(const_iterator __hint, node_type&& __nh)
1520 {
1521 iterator __ret;
1522 if (__nh.empty())
1523 __ret = end();
1524 else
1525 {
1526 __glibcxx_assert(_M_get_Node_allocator() == *__nh._M_alloc);
1527 auto __res = _M_get_insert_hint_equal_pos(__hint, __nh._M_key());
1528 if (__res.second)
1529 __ret = _M_insert_node(__res.first, __res.second, __nh._M_ptr);
1530 else
1531 __ret = _M_insert_equal_lower_node(__nh._M_ptr);
1532 __nh._M_ptr = nullptr;
1533 }
1534 return __ret;
1535 }
1536
1537 /// Extract a node.
1538 node_type
1539 extract(const_iterator __pos)
1540 {
1541 auto __ptr = _Rb_tree_rebalance_for_erase(
1542 __pos._M_const_cast()._M_node, _M_impl._M_header);
1543 --_M_impl._M_node_count;
1544 return { static_cast<_Link_type>(__ptr), _M_get_Node_allocator() };
1545 }
1546
1547 /// Extract a node.
1548 node_type
1549 extract(const key_type& __k)
1550 {
1551 node_type __nh;
1552 auto __pos = find(__k);
1553 if (__pos != end())
1554 __nh = extract(const_iterator(__pos));
1555 return __nh;
1556 }
1557
1558 template<typename _Compare2>
1559 using _Compatible_tree
1560 = _Rb_tree<_Key, _Val, _KeyOfValue, _Compare2, _Alloc>;
1561
1562 template<typename, typename>
1563 friend class _Rb_tree_merge_helper;
1564
1565 /// Merge from a compatible container into one with unique keys.
1566 template<typename _Compare2>
1567 void
1568 _M_merge_unique(_Compatible_tree<_Compare2>& __src) noexcept
1569 {
1570 using _Merge_helper = _Rb_tree_merge_helper<_Rb_tree, _Compare2>;
1571 for (auto __i = __src.begin(), __end = __src.end(); __i != __end;)
1572 {
1573 auto __pos = __i++;
1574 auto __res = _M_get_insert_unique_pos(_KeyOfValue()(*__pos));
1575 if (__res.second)
1576 {
1577 auto& __src_impl = _Merge_helper::_S_get_impl(__src);
1578 auto __ptr = _Rb_tree_rebalance_for_erase(
1579 __pos._M_node, __src_impl._M_header);
1580 --__src_impl._M_node_count;
1581 _M_insert_node(__res.first, __res.second,
1582 static_cast<_Link_type>(__ptr));
1583 }
1584 }
1585 }
1586
1587 /// Merge from a compatible container into one with equivalent keys.
1588 template<typename _Compare2>
1589 void
1590 _M_merge_equal(_Compatible_tree<_Compare2>& __src) noexcept
1591 {
1592 using _Merge_helper = _Rb_tree_merge_helper<_Rb_tree, _Compare2>;
1593 for (auto __i = __src.begin(), __end = __src.end(); __i != __end;)
1594 {
1595 auto __pos = __i++;
1596 auto __res = _M_get_insert_equal_pos(_KeyOfValue()(*__pos));
1597 if (__res.second)
1598 {
1599 auto& __src_impl = _Merge_helper::_S_get_impl(__src);
1600 auto __ptr = _Rb_tree_rebalance_for_erase(
1601 __pos._M_node, __src_impl._M_header);
1602 --__src_impl._M_node_count;
1603 _M_insert_node(__res.first, __res.second,
1604 static_cast<_Link_type>(__ptr));
1605 }
1606 }
1607 }
1608#endif // C++17
1609
1610 friend bool
1611 operator==(const _Rb_tree& __x, const _Rb_tree& __y)
1612 {
1613 return __x.size() == __y.size()
1614 && std::equal(__x.begin(), __x.end(), __y.begin());
1615 }
1616
1617#if __cpp_lib_three_way_comparison
1618 friend auto
1619 operator<=>(const _Rb_tree& __x, const _Rb_tree& __y)
1620 {
1621 if constexpr (requires { typename __detail::__synth3way_t<_Val>; })
1622 return std::lexicographical_compare_three_way(__x.begin(), __x.end(),
1623 __y.begin(), __y.end(),
1624 __detail::__synth3way);
1625 }
1626#else
1627 friend bool
1628 operator<(const _Rb_tree& __x, const _Rb_tree& __y)
1629 {
1630 return std::lexicographical_compare(__x.begin(), __x.end(),
1631 __y.begin(), __y.end());
1632 }
1633
1634 friend bool _GLIBCXX_DEPRECATED__attribute__ ((__deprecated__))
1635 operator!=(const _Rb_tree& __x, const _Rb_tree& __y)
1636 { return !(__x == __y); }
1637
1638 friend bool _GLIBCXX_DEPRECATED__attribute__ ((__deprecated__))
1639 operator>(const _Rb_tree& __x, const _Rb_tree& __y)
1640 { return __y < __x; }
1641
1642 friend bool _GLIBCXX_DEPRECATED__attribute__ ((__deprecated__))
1643 operator<=(const _Rb_tree& __x, const _Rb_tree& __y)
1644 { return !(__y < __x); }
1645
1646 friend bool _GLIBCXX_DEPRECATED__attribute__ ((__deprecated__))
1647 operator>=(const _Rb_tree& __x, const _Rb_tree& __y)
1648 { return !(__x < __y); }
1649#endif
1650 };
1651
1652 template<typename _Key, typename _Val, typename _KeyOfValue,
1653 typename _Compare, typename _Alloc>
1654 inline void
1655 swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
1656 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
1657 { __x.swap(__y); }
1658
1659#if __cplusplus201402L >= 201103L
1660 template<typename _Key, typename _Val, typename _KeyOfValue,
1661 typename _Compare, typename _Alloc>
1662 void
1663 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1664 _M_move_data(_Rb_tree& __x, false_type)
1665 {
1666 if (_M_get_Node_allocator() == __x._M_get_Node_allocator())
1667 _M_move_data(__x, true_type());
1668 else
1669 {
1670 _Alloc_node __an(*this);
1671 auto __lbd =
1672 [&__an](const value_type& __cval)
1673 {
1674 auto& __val = const_cast<value_type&>(__cval);
1675 return __an(std::move_if_noexcept(__val));
1676 };
1677 _M_root() = _M_copy(__x, __lbd);
1678 }
1679 }
1680
1681 template<typename _Key, typename _Val, typename _KeyOfValue,
1682 typename _Compare, typename _Alloc>
1683 inline void
1684 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1685 _M_move_assign(_Rb_tree& __x, true_type)
1686 {
1687 clear();
1688 if (__x._M_root() != nullptr)
1689 _M_move_data(__x, true_type());
1690 std::__alloc_on_move(_M_get_Node_allocator(),
1691 __x._M_get_Node_allocator());
1692 }
1693
1694 template<typename _Key, typename _Val, typename _KeyOfValue,
1695 typename _Compare, typename _Alloc>
1696 void
1697 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1698 _M_move_assign(_Rb_tree& __x, false_type)
1699 {
1700 if (_M_get_Node_allocator() == __x._M_get_Node_allocator())
1701 return _M_move_assign(__x, true_type{});
1702
1703 // Try to move each node reusing existing nodes and copying __x nodes
1704 // structure.
1705 _Reuse_or_alloc_node __roan(*this);
1706 _M_impl._M_reset();
1707 if (__x._M_root() != nullptr)
1708 {
1709 auto __lbd =
1710 [&__roan](const value_type& __cval)
1711 {
1712 auto& __val = const_cast<value_type&>(__cval);
1713 return __roan(std::move(__val));
1714 };
1715 _M_root() = _M_copy(__x, __lbd);
1716 __x.clear();
1717 }
1718 }
1719
1720 template<typename _Key, typename _Val, typename _KeyOfValue,
1721 typename _Compare, typename _Alloc>
1722 inline _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&
1723 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1724 operator=(_Rb_tree&& __x)
1725 noexcept(_Alloc_traits::_S_nothrow_move()
1726 && is_nothrow_move_assignable<_Compare>::value)
1727 {
1728 _M_impl._M_key_compare = std::move(__x._M_impl._M_key_compare);
1729 _M_move_assign(__x, __bool_constant<_Alloc_traits::_S_nothrow_move()>());
1730 return *this;
1731 }
1732
1733 template<typename _Key, typename _Val, typename _KeyOfValue,
1734 typename _Compare, typename _Alloc>
1735 template<typename _Iterator>
1736 void
1737 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1738 _M_assign_unique(_Iterator __first, _Iterator __last)
1739 {
1740 _Reuse_or_alloc_node __roan(*this);
1741 _M_impl._M_reset();
1742 for (; __first != __last; ++__first)
1743 _M_insert_unique_(end(), *__first, __roan);
1744 }
1745
1746 template<typename _Key, typename _Val, typename _KeyOfValue,
1747 typename _Compare, typename _Alloc>
1748 template<typename _Iterator>
1749 void
1750 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1751 _M_assign_equal(_Iterator __first, _Iterator __last)
1752 {
1753 _Reuse_or_alloc_node __roan(*this);
1754 _M_impl._M_reset();
1755 for (; __first != __last; ++__first)
1756 _M_insert_equal_(end(), *__first, __roan);
1757 }
1758#endif
1759
1760 template<typename _Key, typename _Val, typename _KeyOfValue,
1761 typename _Compare, typename _Alloc>
1762 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&
1763 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1764 operator=(const _Rb_tree& __x)
1765 {
1766 if (this != &__x)
1767 {
1768 // Note that _Key may be a constant type.
1769#if __cplusplus201402L >= 201103L
1770 if (_Alloc_traits::_S_propagate_on_copy_assign())
1771 {
1772 auto& __this_alloc = this->_M_get_Node_allocator();
1773 auto& __that_alloc = __x._M_get_Node_allocator();
1774 if (!_Alloc_traits::_S_always_equal()
1775 && __this_alloc != __that_alloc)
1776 {
1777 // Replacement allocator cannot free existing storage, we need
1778 // to erase nodes first.
1779 clear();
1780 std::__alloc_on_copy(__this_alloc, __that_alloc);
1781 }
1782 }
1783#endif
1784
1785 _Reuse_or_alloc_node __roan(*this);
1786 _M_impl._M_reset();
1787 _M_impl._M_key_compare = __x._M_impl._M_key_compare;
1788 if (__x._M_root() != 0)
1789 _M_root() = _M_copy(__x, __roan);
1790 }
1791
1792 return *this;
1793 }
1794
1795 template<typename _Key, typename _Val, typename _KeyOfValue,
1796 typename _Compare, typename _Alloc>
1797#if __cplusplus201402L >= 201103L
1798 template<typename _Arg, typename _NodeGen>
1799#else
1800 template<typename _NodeGen>
1801#endif
1802 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1803 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1804 _M_insert_(_Base_ptr __x, _Base_ptr __p,
1805#if __cplusplus201402L >= 201103L
1806 _Arg&& __v,
1807#else
1808 const _Val& __v,
1809#endif
1810 _NodeGen& __node_gen)
1811 {
1812 bool __insert_left = (__x != 0 || __p == _M_end()
1813 || _M_impl._M_key_compare(_KeyOfValue()(__v),
1814 _S_key(__p)));
1815
1816 _Link_type __z = __node_gen(_GLIBCXX_FORWARD(_Arg, __v)std::forward<_Arg>(__v));
1817
1818 _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
1819 this->_M_impl._M_header);
1820 ++_M_impl._M_node_count;
1821 return iterator(__z);
1822 }
1823
1824 template<typename _Key, typename _Val, typename _KeyOfValue,
1825 typename _Compare, typename _Alloc>
1826#if __cplusplus201402L >= 201103L
1827 template<typename _Arg>
1828#endif
1829 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1830 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1831#if __cplusplus201402L >= 201103L
1832 _M_insert_lower(_Base_ptr __p, _Arg&& __v)
1833#else
1834 _M_insert_lower(_Base_ptr __p, const _Val& __v)
1835#endif
1836 {
1837 bool __insert_left = (__p == _M_end()
1838 || !_M_impl._M_key_compare(_S_key(__p),
1839 _KeyOfValue()(__v)));
1840
1841 _Link_type __z = _M_create_node(_GLIBCXX_FORWARD(_Arg, __v)std::forward<_Arg>(__v));
1842
1843 _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
1844 this->_M_impl._M_header);
1845 ++_M_impl._M_node_count;
1846 return iterator(__z);
1847 }
1848
1849 template<typename _Key, typename _Val, typename _KeyOfValue,
1850 typename _Compare, typename _Alloc>
1851#if __cplusplus201402L >= 201103L
1852 template<typename _Arg>
1853#endif
1854 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
1855 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1856#if __cplusplus201402L >= 201103L
1857 _M_insert_equal_lower(_Arg&& __v)
1858#else
1859 _M_insert_equal_lower(const _Val& __v)
1860#endif
1861 {
1862 _Link_type __x = _M_begin();
1863 _Base_ptr __y = _M_end();
1864 while (__x != 0)
1865 {
1866 __y = __x;
1867 __x = !_M_impl._M_key_compare(_S_key(__x), _KeyOfValue()(__v)) ?
1868 _S_left(__x) : _S_right(__x);
1869 }
1870 return _M_insert_lower(__y, _GLIBCXX_FORWARD(_Arg, __v)std::forward<_Arg>(__v));
1871 }
1872
1873 template<typename _Key, typename _Val, typename _KoV,
1874 typename _Compare, typename _Alloc>
1875 template<typename _NodeGen>
1876 typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type
1877 _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::
1878 _M_copy(_Const_Link_type __x, _Base_ptr __p, _NodeGen& __node_gen)
1879 {
1880 // Structural copy. __x and __p must be non-null.
1881 _Link_type __top = _M_clone_node(__x, __node_gen);
1882 __top->_M_parent = __p;
1883
1884 __tryif (true)
1885 {
1886 if (__x->_M_right)
1887 __top->_M_right = _M_copy(_S_right(__x), __top, __node_gen);
1888 __p = __top;
1889 __x = _S_left(__x);
1890
1891 while (__x != 0)
1892 {
1893 _Link_type __y = _M_clone_node(__x, __node_gen);
1894 __p->_M_left = __y;
1895 __y->_M_parent = __p;
1896 if (__x->_M_right)
1897 __y->_M_right = _M_copy(_S_right(__x), __y, __node_gen);
1898 __p = __y;
1899 __x = _S_left(__x);
1900 }
1901 }
1902 __catch(...)if (false)
1903 {
1904 _M_erase(__top);
1905 __throw_exception_again;
1906 }
1907 return __top;
1908 }
1909
1910 template<typename _Key, typename _Val, typename _KeyOfValue,
1911 typename _Compare, typename _Alloc>
1912 void
1913 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1914 _M_erase(_Link_type __x)
1915 {
1916 // Erase without rebalancing.
1917 while (__x != 0)
1918 {
1919 _M_erase(_S_right(__x));
1920 _Link_type __y = _S_left(__x);
1921 _M_drop_node(__x);
1922 __x = __y;
1923 }
1924 }
1925
1926 template<typename _Key, typename _Val, typename _KeyOfValue,
1927 typename _Compare, typename _Alloc>
1928 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1929 _Compare, _Alloc>::iterator
1930 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1931 _M_lower_bound(_Link_type __x, _Base_ptr __y,
1932 const _Key& __k)
1933 {
1934 while (__x != 0)
1935 if (!_M_impl._M_key_compare(_S_key(__x), __k))
1936 __y = __x, __x = _S_left(__x);
1937 else
1938 __x = _S_right(__x);
1939 return iterator(__y);
1940 }
1941
1942 template<typename _Key, typename _Val, typename _KeyOfValue,
1943 typename _Compare, typename _Alloc>
1944 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1945 _Compare, _Alloc>::const_iterator
1946 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1947 _M_lower_bound(_Const_Link_type __x, _Const_Base_ptr __y,
1948 const _Key& __k) const
1949 {
1950 while (__x != 0)
1951 if (!_M_impl._M_key_compare(_S_key(__x), __k))
1952 __y = __x, __x = _S_left(__x);
1953 else
1954 __x = _S_right(__x);
1955 return const_iterator(__y);
1956 }
1957
1958 template<typename _Key, typename _Val, typename _KeyOfValue,
1959 typename _Compare, typename _Alloc>
1960 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1961 _Compare, _Alloc>::iterator
1962 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1963 _M_upper_bound(_Link_type __x, _Base_ptr __y,
1964 const _Key& __k)
1965 {
1966 while (__x != 0)
1967 if (_M_impl._M_key_compare(__k, _S_key(__x)))
1968 __y = __x, __x = _S_left(__x);
1969 else
1970 __x = _S_right(__x);
1971 return iterator(__y);
1972 }
1973
1974 template<typename _Key, typename _Val, typename _KeyOfValue,
1975 typename _Compare, typename _Alloc>
1976 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1977 _Compare, _Alloc>::const_iterator
1978 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1979 _M_upper_bound(_Const_Link_type __x, _Const_Base_ptr __y,
1980 const _Key& __k) const
1981 {
1982 while (__x != 0)
1983 if (_M_impl._M_key_compare(__k, _S_key(__x)))
1984 __y = __x, __x = _S_left(__x);
1985 else
1986 __x = _S_right(__x);
1987 return const_iterator(__y);
1988 }
1989
1990 template<typename _Key, typename _Val, typename _KeyOfValue,
1991 typename _Compare, typename _Alloc>
1992 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
1993 _Compare, _Alloc>::iterator,
1994 typename _Rb_tree<_Key, _Val, _KeyOfValue,
1995 _Compare, _Alloc>::iterator>
1996 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
1997 equal_range(const _Key& __k)
1998 {
1999 _Link_type __x = _M_begin();
2000 _Base_ptr __y = _M_end();
2001 while (__x != 0)
2002 {
2003 if (_M_impl._M_key_compare(_S_key(__x), __k))
2004 __x = _S_right(__x);
2005 else if (_M_impl._M_key_compare(__k, _S_key(__x)))
2006 __y = __x, __x = _S_left(__x);
2007 else
2008 {
2009 _Link_type __xu(__x);
2010 _Base_ptr __yu(__y);
2011 __y = __x, __x = _S_left(__x);
2012 __xu = _S_right(__xu);
2013 return pair<iterator,
2014 iterator>(_M_lower_bound(__x, __y, __k),
2015 _M_upper_bound(__xu, __yu, __k));
2016 }
2017 }
2018 return pair<iterator, iterator>(iterator(__y),
2019 iterator(__y));
2020 }
2021
2022 template<typename _Key, typename _Val, typename _KeyOfValue,
2023 typename _Compare, typename _Alloc>
2024 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
2025 _Compare, _Alloc>::const_iterator,
2026 typename _Rb_tree<_Key, _Val, _KeyOfValue,
2027 _Compare, _Alloc>::const_iterator>
2028 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2029 equal_range(const _Key& __k) const
2030 {
2031 _Const_Link_type __x = _M_begin();
2032 _Const_Base_ptr __y = _M_end();
2033 while (__x != 0)
2034 {
2035 if (_M_impl._M_key_compare(_S_key(__x), __k))
2036 __x = _S_right(__x);
2037 else if (_M_impl._M_key_compare(__k, _S_key(__x)))
2038 __y = __x, __x = _S_left(__x);
2039 else
2040 {
2041 _Const_Link_type __xu(__x);
2042 _Const_Base_ptr __yu(__y);
2043 __y = __x, __x = _S_left(__x);
2044 __xu = _S_right(__xu);
2045 return pair<const_iterator,
2046 const_iterator>(_M_lower_bound(__x, __y, __k),
2047 _M_upper_bound(__xu, __yu, __k));
2048 }
2049 }
2050 return pair<const_iterator, const_iterator>(const_iterator(__y),
2051 const_iterator(__y));
2052 }
2053
2054 template<typename _Key, typename _Val, typename _KeyOfValue,
2055 typename _Compare, typename _Alloc>
2056 void
2057 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2058 swap(_Rb_tree& __t)
2059 _GLIBCXX_NOEXCEPT_IF(__is_nothrow_swappable<_Compare>::value)noexcept(__is_nothrow_swappable<_Compare>::value)
2060 {
2061 if (_M_root() == 0)
2062 {
2063 if (__t._M_root() != 0)
2064 _M_impl._M_move_data(__t._M_impl);
2065 }
2066 else if (__t._M_root() == 0)
2067 __t._M_impl._M_move_data(_M_impl);
2068 else
2069 {
2070 std::swap(_M_root(),__t._M_root());
2071 std::swap(_M_leftmost(),__t._M_leftmost());
2072 std::swap(_M_rightmost(),__t._M_rightmost());
2073
2074 _M_root()->_M_parent = _M_end();
2075 __t._M_root()->_M_parent = __t._M_end();
2076 std::swap(this->_M_impl._M_node_count, __t._M_impl._M_node_count);
2077 }
2078 // No need to swap header's color as it does not change.
2079 std::swap(this->_M_impl._M_key_compare, __t._M_impl._M_key_compare);
2080
2081 _Alloc_traits::_S_on_swap(_M_get_Node_allocator(),
2082 __t._M_get_Node_allocator());
2083 }
2084
2085 template<typename _Key, typename _Val, typename _KeyOfValue,
2086 typename _Compare, typename _Alloc>
2087 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
2088 _Compare, _Alloc>::_Base_ptr,
2089 typename _Rb_tree<_Key, _Val, _KeyOfValue,
2090 _Compare, _Alloc>::_Base_ptr>
2091 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2092 _M_get_insert_unique_pos(const key_type& __k)
2093 {
2094 typedef pair<_Base_ptr, _Base_ptr> _Res;
2095 _Link_type __x = _M_begin();
2096 _Base_ptr __y = _M_end();
2097 bool __comp = true;
2098 while (__x != 0)
2099 {
2100 __y = __x;
2101 __comp = _M_impl._M_key_compare(__k, _S_key(__x));
2102 __x = __comp ? _S_left(__x) : _S_right(__x);
2103 }
2104 iterator __j = iterator(__y);
2105 if (__comp)
2106 {
2107 if (__j == begin())
2108 return _Res(__x, __y);
2109 else
2110 --__j;
2111 }
2112 if (_M_impl._M_key_compare(_S_key(__j._M_node), __k))
2113 return _Res(__x, __y);
2114 return _Res(__j._M_node, 0);
2115 }
2116
2117 template<typename _Key, typename _Val, typename _KeyOfValue,
2118 typename _Compare, typename _Alloc>
2119 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
2120 _Compare, _Alloc>::_Base_ptr,
2121 typename _Rb_tree<_Key, _Val, _KeyOfValue,
2122 _Compare, _Alloc>::_Base_ptr>
2123 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2124 _M_get_insert_equal_pos(const key_type& __k)
2125 {
2126 typedef pair<_Base_ptr, _Base_ptr> _Res;
2127 _Link_type __x = _M_begin();
2128 _Base_ptr __y = _M_end();
2129 while (__x != 0)
2130 {
2131 __y = __x;
2132 __x = _M_impl._M_key_compare(__k, _S_key(__x)) ?
2133 _S_left(__x) : _S_right(__x);
2134 }
2135 return _Res(__x, __y);
2136 }
2137
2138 template<typename _Key, typename _Val, typename _KeyOfValue,
2139 typename _Compare, typename _Alloc>
2140#if __cplusplus201402L >= 201103L
2141 template<typename _Arg>
2142#endif
2143 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
2144 _Compare, _Alloc>::iterator, bool>
2145 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2146#if __cplusplus201402L >= 201103L
2147 _M_insert_unique(_Arg&& __v)
2148#else
2149 _M_insert_unique(const _Val& __v)
2150#endif
2151 {
2152 typedef pair<iterator, bool> _Res;
2153 pair<_Base_ptr, _Base_ptr> __res
2154 = _M_get_insert_unique_pos(_KeyOfValue()(__v));
2155
2156 if (__res.second)
2157 {
2158 _Alloc_node __an(*this);
2159 return _Res(_M_insert_(__res.first, __res.second,
2160 _GLIBCXX_FORWARD(_Arg, __v)std::forward<_Arg>(__v), __an),
2161 true);
2162 }
2163
2164 return _Res(iterator(__res.first), false);
2165 }
2166
2167 template<typename _Key, typename _Val, typename _KeyOfValue,
2168 typename _Compare, typename _Alloc>
2169#if __cplusplus201402L >= 201103L
2170 template<typename _Arg>
2171#endif
2172 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
2173 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2174#if __cplusplus201402L >= 201103L
2175 _M_insert_equal(_Arg&& __v)
2176#else
2177 _M_insert_equal(const _Val& __v)
2178#endif
2179 {
2180 pair<_Base_ptr, _Base_ptr> __res
2181 = _M_get_insert_equal_pos(_KeyOfValue()(__v));
2182 _Alloc_node __an(*this);
2183 return _M_insert_(__res.first, __res.second,
2184 _GLIBCXX_FORWARD(_Arg, __v)std::forward<_Arg>(__v), __an);
2185 }
2186
2187 template<typename _Key, typename _Val, typename _KeyOfValue,
2188 typename _Compare, typename _Alloc>
2189 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
2190 _Compare, _Alloc>::_Base_ptr,
2191 typename _Rb_tree<_Key, _Val, _KeyOfValue,
2192 _Compare, _Alloc>::_Base_ptr>
2193 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2194 _M_get_insert_hint_unique_pos(const_iterator __position,
2195 const key_type& __k)
2196 {
2197 iterator __pos = __position._M_const_cast();
2198 typedef pair<_Base_ptr, _Base_ptr> _Res;
2199
2200 // end()
2201 if (__pos._M_node == _M_end())
2202 {
2203 if (size() > 0
2204 && _M_impl._M_key_compare(_S_key(_M_rightmost()), __k))
2205 return _Res(0, _M_rightmost());
2206 else
2207 return _M_get_insert_unique_pos(__k);
2208 }
2209 else if (_M_impl._M_key_compare(__k, _S_key(__pos._M_node)))
2210 {
2211 // First, try before...
2212 iterator __before = __pos;
2213 if (__pos._M_node == _M_leftmost()) // begin()
2214 return _Res(_M_leftmost(), _M_leftmost());
2215 else if (_M_impl._M_key_compare(_S_key((--__before)._M_node), __k))
2216 {
2217 if (_S_right(__before._M_node) == 0)
2218 return _Res(0, __before._M_node);
2219 else
2220 return _Res(__pos._M_node, __pos._M_node);
2221 }
2222 else
2223 return _M_get_insert_unique_pos(__k);
2224 }
2225 else if (_M_impl._M_key_compare(_S_key(__pos._M_node), __k))
2226 {
2227 // ... then try after.
2228 iterator __after = __pos;
2229 if (__pos._M_node == _M_rightmost())
2230 return _Res(0, _M_rightmost());
2231 else if (_M_impl._M_key_compare(__k, _S_key((++__after)._M_node)))
2232 {
2233 if (_S_right(__pos._M_node) == 0)
2234 return _Res(0, __pos._M_node);
2235 else
2236 return _Res(__after._M_node, __after._M_node);
2237 }
2238 else
2239 return _M_get_insert_unique_pos(__k);
2240 }
2241 else
2242 // Equivalent keys.
2243 return _Res(__pos._M_node, 0);
2244 }
2245
2246 template<typename _Key, typename _Val, typename _KeyOfValue,
2247 typename _Compare, typename _Alloc>
2248#if __cplusplus201402L >= 201103L
2249 template<typename _Arg, typename _NodeGen>
2250#else
2251 template<typename _NodeGen>
2252#endif
2253 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
2254 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2255 _M_insert_unique_(const_iterator __position,
2256#if __cplusplus201402L >= 201103L
2257 _Arg&& __v,
2258#else
2259 const _Val& __v,
2260#endif
2261 _NodeGen& __node_gen)
2262 {
2263 pair<_Base_ptr, _Base_ptr> __res
2264 = _M_get_insert_hint_unique_pos(__position, _KeyOfValue()(__v));
2265
2266 if (__res.second)
2267 return _M_insert_(__res.first, __res.second,
2268 _GLIBCXX_FORWARD(_Arg, __v)std::forward<_Arg>(__v),
2269 __node_gen);
2270 return iterator(__res.first);
2271 }
2272
2273 template<typename _Key, typename _Val, typename _KeyOfValue,
2274 typename _Compare, typename _Alloc>
2275 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
2276 _Compare, _Alloc>::_Base_ptr,
2277 typename _Rb_tree<_Key, _Val, _KeyOfValue,
2278 _Compare, _Alloc>::_Base_ptr>
2279 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2280 _M_get_insert_hint_equal_pos(const_iterator __position, const key_type& __k)
2281 {
2282 iterator __pos = __position._M_const_cast();
2283 typedef pair<_Base_ptr, _Base_ptr> _Res;
2284
2285 // end()
2286 if (__pos._M_node == _M_end())
2287 {
2288 if (size() > 0
2289 && !_M_impl._M_key_compare(__k, _S_key(_M_rightmost())))
2290 return _Res(0, _M_rightmost());
2291 else
2292 return _M_get_insert_equal_pos(__k);
2293 }
2294 else if (!_M_impl._M_key_compare(_S_key(__pos._M_node), __k))
2295 {
2296 // First, try before...
2297 iterator __before = __pos;
2298 if (__pos._M_node == _M_leftmost()) // begin()
2299 return _Res(_M_leftmost(), _M_leftmost());
2300 else if (!_M_impl._M_key_compare(__k, _S_key((--__before)._M_node)))
2301 {
2302 if (_S_right(__before._M_node) == 0)
2303 return _Res(0, __before._M_node);
2304 else
2305 return _Res(__pos._M_node, __pos._M_node);
2306 }
2307 else
2308 return _M_get_insert_equal_pos(__k);
2309 }
2310 else
2311 {
2312 // ... then try after.
2313 iterator __after = __pos;
2314 if (__pos._M_node == _M_rightmost())
2315 return _Res(0, _M_rightmost());
2316 else if (!_M_impl._M_key_compare(_S_key((++__after)._M_node), __k))
2317 {
2318 if (_S_right(__pos._M_node) == 0)
2319 return _Res(0, __pos._M_node);
2320 else
2321 return _Res(__after._M_node, __after._M_node);
2322 }
2323 else
2324 return _Res(0, 0);
2325 }
2326 }
2327
2328 template<typename _Key, typename _Val, typename _KeyOfValue,
2329 typename _Compare, typename _Alloc>
2330#if __cplusplus201402L >= 201103L
2331 template<typename _Arg, typename _NodeGen>
2332#else
2333 template<typename _NodeGen>
2334#endif
2335 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
2336 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2337 _M_insert_equal_(const_iterator __position,
2338#if __cplusplus201402L >= 201103L
2339 _Arg&& __v,
2340#else
2341 const _Val& __v,
2342#endif
2343 _NodeGen& __node_gen)
2344 {
2345 pair<_Base_ptr, _Base_ptr> __res
2346 = _M_get_insert_hint_equal_pos(__position, _KeyOfValue()(__v));
2347
2348 if (__res.second)
2349 return _M_insert_(__res.first, __res.second,
2350 _GLIBCXX_FORWARD(_Arg, __v)std::forward<_Arg>(__v),
2351 __node_gen);
2352
2353 return _M_insert_equal_lower(_GLIBCXX_FORWARD(_Arg, __v)std::forward<_Arg>(__v));
2354 }
2355
2356#if __cplusplus201402L >= 201103L
2357 template<typename _Key, typename _Val, typename _KeyOfValue,
2358 typename _Compare, typename _Alloc>
2359 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
2360 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2361 _M_insert_node(_Base_ptr __x, _Base_ptr __p, _Link_type __z)
2362 {
2363 bool __insert_left = (__x != 0 || __p == _M_end()
2364 || _M_impl._M_key_compare(_S_key(__z),
2365 _S_key(__p)));
2366
2367 _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
2368 this->_M_impl._M_header);
2369 ++_M_impl._M_node_count;
2370 return iterator(__z);
2371 }
2372
2373 template<typename _Key, typename _Val, typename _KeyOfValue,
2374 typename _Compare, typename _Alloc>
2375 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
2376 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2377 _M_insert_lower_node(_Base_ptr __p, _Link_type __z)
2378 {
2379 bool __insert_left = (__p == _M_end()
2380 || !_M_impl._M_key_compare(_S_key(__p),
2381 _S_key(__z)));
2382
2383 _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
2384 this->_M_impl._M_header);
2385 ++_M_impl._M_node_count;
2386 return iterator(__z);
2387 }
2388
2389 template<typename _Key, typename _Val, typename _KeyOfValue,
2390 typename _Compare, typename _Alloc>
2391 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
2392 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2393 _M_insert_equal_lower_node(_Link_type __z)
2394 {
2395 _Link_type __x = _M_begin();
2396 _Base_ptr __y = _M_end();
2397 while (__x != 0)
2398 {
2399 __y = __x;
2400 __x = !_M_impl._M_key_compare(_S_key(__x), _S_key(__z)) ?
2401 _S_left(__x) : _S_right(__x);
2402 }
2403 return _M_insert_lower_node(__y, __z);
2404 }
2405
2406 template<typename _Key, typename _Val, typename _KeyOfValue,
2407 typename _Compare, typename _Alloc>
2408 template<typename... _Args>
2409 pair<typename _Rb_tree<_Key, _Val, _KeyOfValue,
2410 _Compare, _Alloc>::iterator, bool>
2411 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2412 _M_emplace_unique(_Args&&... __args)
2413 {
2414 _Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
2415
2416 __tryif (true)
2417 {
2418 typedef pair<iterator, bool> _Res;
2419 auto __res = _M_get_insert_unique_pos(_S_key(__z));
2420 if (__res.second)
2421 return _Res(_M_insert_node(__res.first, __res.second, __z), true);
2422
2423 _M_drop_node(__z);
2424 return _Res(iterator(__res.first), false);
2425 }
2426 __catch(...)if (false)
2427 {
2428 _M_drop_node(__z);
2429 __throw_exception_again;
2430 }
2431 }
2432
2433 template<typename _Key, typename _Val, typename _KeyOfValue,
2434 typename _Compare, typename _Alloc>
2435 template<typename... _Args>
2436 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
2437 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2438 _M_emplace_equal(_Args&&... __args)
2439 {
2440 _Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
2441
2442 __tryif (true)
2443 {
2444 auto __res = _M_get_insert_equal_pos(_S_key(__z));
2445 return _M_insert_node(__res.first, __res.second, __z);
2446 }
2447 __catch(...)if (false)
2448 {
2449 _M_drop_node(__z);
2450 __throw_exception_again;
2451 }
2452 }
2453
2454 template<typename _Key, typename _Val, typename _KeyOfValue,
2455 typename _Compare, typename _Alloc>
2456 template<typename... _Args>
2457 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
2458 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2459 _M_emplace_hint_unique(const_iterator __pos, _Args&&... __args)
2460 {
2461 _Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
2462
2463 __tryif (true)
2464 {
2465 auto __res = _M_get_insert_hint_unique_pos(__pos, _S_key(__z));
2466
2467 if (__res.second)
2468 return _M_insert_node(__res.first, __res.second, __z);
2469
2470 _M_drop_node(__z);
2471 return iterator(__res.first);
2472 }
2473 __catch(...)if (false)
2474 {
2475 _M_drop_node(__z);
2476 __throw_exception_again;
2477 }
2478 }
2479
2480 template<typename _Key, typename _Val, typename _KeyOfValue,
2481 typename _Compare, typename _Alloc>
2482 template<typename... _Args>
2483 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
2484 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2485 _M_emplace_hint_equal(const_iterator __pos, _Args&&... __args)
2486 {
2487 _Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
2488
2489 __tryif (true)
2490 {
2491 auto __res = _M_get_insert_hint_equal_pos(__pos, _S_key(__z));
2492
2493 if (__res.second)
2494 return _M_insert_node(__res.first, __res.second, __z);
2495
2496 return _M_insert_equal_lower_node(__z);
2497 }
2498 __catch(...)if (false)
2499 {
2500 _M_drop_node(__z);
2501 __throw_exception_again;
2502 }
2503 }
2504#endif
2505
2506
2507 template<typename _Key, typename _Val, typename _KeyOfValue,
2508 typename _Compare, typename _Alloc>
2509 void
2510 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2511 _M_erase_aux(const_iterator __position)
2512 {
2513 _Link_type __y =
2514 static_cast<_Link_type>(_Rb_tree_rebalance_for_erase
2515 (const_cast<_Base_ptr>(__position._M_node),
2516 this->_M_impl._M_header));
2517 _M_drop_node(__y);
2518 --_M_impl._M_node_count;
2519 }
2520
2521 template<typename _Key, typename _Val, typename _KeyOfValue,
2522 typename _Compare, typename _Alloc>
2523 void
2524 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2525 _M_erase_aux(const_iterator __first, const_iterator __last)
2526 {
2527 if (__first == begin() && __last == end())
2528 clear();
2529 else
2530 while (__first != __last)
2531 _M_erase_aux(__first++);
2532 }
2533
2534 template<typename _Key, typename _Val, typename _KeyOfValue,
2535 typename _Compare, typename _Alloc>
2536 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type
2537 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2538 erase(const _Key& __x)
2539 {
2540 pair<iterator, iterator> __p = equal_range(__x);
2541 const size_type __old_size = size();
2542 _M_erase_aux(__p.first, __p.second);
2543 return __old_size - size();
2544 }
2545
2546 template<typename _Key, typename _Val, typename _KeyOfValue,
2547 typename _Compare, typename _Alloc>
2548 typename _Rb_tree<_Key, _Val, _KeyOfValue,
2549 _Compare, _Alloc>::iterator
2550 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2551 find(const _Key& __k)
2552 {
2553 iterator __j = _M_lower_bound(_M_begin(), _M_end(), __k);
2554 return (__j == end()
2555 || _M_impl._M_key_compare(__k,
2556 _S_key(__j._M_node))) ? end() : __j;
2557 }
2558
2559 template<typename _Key, typename _Val, typename _KeyOfValue,
2560 typename _Compare, typename _Alloc>
2561 typename _Rb_tree<_Key, _Val, _KeyOfValue,
2562 _Compare, _Alloc>::const_iterator
2563 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2564 find(const _Key& __k) const
2565 {
2566 const_iterator __j = _M_lower_bound(_M_begin(), _M_end(), __k);
2567 return (__j == end()
2568 || _M_impl._M_key_compare(__k,
2569 _S_key(__j._M_node))) ? end() : __j;
2570 }
2571
2572 template<typename _Key, typename _Val, typename _KeyOfValue,
2573 typename _Compare, typename _Alloc>
2574 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type
2575 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
2576 count(const _Key& __k) const
2577 {
2578 pair<const_iterator, const_iterator> __p = equal_range(__k);
2579 const size_type __n = std::distance(__p.first, __p.second);
2580 return __n;
2581 }
2582
2583 _GLIBCXX_PURE__attribute__ ((__pure__)) unsigned int
2584 _Rb_tree_black_count(const _Rb_tree_node_base* __node,
2585 const _Rb_tree_node_base* __root) throw ();
2586
2587 template<typename _Key, typename _Val, typename _KeyOfValue,
2588 typename _Compare, typename _Alloc>
2589 bool
2590 _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const
2591 {
2592 if (_M_impl._M_node_count == 0 || begin() == end())
2593 return _M_impl._M_node_count == 0 && begin() == end()
2594 && this->_M_impl._M_header._M_left == _M_end()
2595 && this->_M_impl._M_header._M_right == _M_end();
2596
2597 unsigned int __len = _Rb_tree_black_count(_M_leftmost(), _M_root());
2598 for (const_iterator __it = begin(); __it != end(); ++__it)
2599 {
2600 _Const_Link_type __x = static_cast<_Const_Link_type>(__it._M_node);
2601 _Const_Link_type __L = _S_left(__x);
2602 _Const_Link_type __R = _S_right(__x);
2603
2604 if (__x->_M_color == _S_red)
2605 if ((__L && __L->_M_color == _S_red)
2606 || (__R && __R->_M_color == _S_red))
2607 return false;
2608
2609 if (__L && _M_impl._M_key_compare(_S_key(__x), _S_key(__L)))
2610 return false;
2611 if (__R && _M_impl._M_key_compare(_S_key(__R), _S_key(__x)))
2612 return false;
2613
2614 if (!__L && !__R && _Rb_tree_black_count(__x, _M_root()) != __len)
2615 return false;
2616 }
2617
2618 if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root()))
2619 return false;
2620 if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root()))
2621 return false;
2622 return true;
2623 }
2624
2625#if __cplusplus201402L > 201402L
2626 // Allow access to internals of compatible _Rb_tree specializations.
2627 template<typename _Key, typename _Val, typename _Sel, typename _Cmp1,
2628 typename _Alloc, typename _Cmp2>
2629 struct _Rb_tree_merge_helper<_Rb_tree<_Key, _Val, _Sel, _Cmp1, _Alloc>,
2630 _Cmp2>
2631 {
2632 private:
2633 friend class _Rb_tree<_Key, _Val, _Sel, _Cmp1, _Alloc>;
2634
2635 static auto&
2636 _S_get_impl(_Rb_tree<_Key, _Val, _Sel, _Cmp2, _Alloc>& __tree)
2637 { return __tree._M_impl; }
2638 };
2639#endif // C++17
2640
2641_GLIBCXX_END_NAMESPACE_VERSION
2642} // namespace
2643
2644#endif

/build/llvm-toolchain-snapshot-15~++20220212111237+869c066ca8a4/clang/include/clang/AST/ASTTypeTraits.h

1//===--- ASTTypeTraits.h ----------------------------------------*- C++ -*-===//
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// Provides a dynamic type identifier and a dynamically typed node container
10// that can be used to store an AST base node at runtime in the same storage in
11// a type safe way.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_AST_ASTTYPETRAITS_H
16#define LLVM_CLANG_AST_ASTTYPETRAITS_H
17
18#include "clang/AST/ASTFwd.h"
19#include "clang/AST/DeclCXX.h"
20#include "clang/AST/LambdaCapture.h"
21#include "clang/AST/NestedNameSpecifier.h"
22#include "clang/AST/TemplateBase.h"
23#include "clang/AST/TypeLoc.h"
24#include "clang/Basic/LLVM.h"
25#include "llvm/ADT/DenseMapInfo.h"
26#include "llvm/Support/AlignOf.h"
27
28namespace llvm {
29class raw_ostream;
30} // namespace llvm
31
32namespace clang {
33
34struct PrintingPolicy;
35
36/// Defines how we descend a level in the AST when we pass
37/// through expressions.
38enum TraversalKind {
39 /// Will traverse all child nodes.
40 TK_AsIs,
41
42 /// Ignore AST nodes not written in the source
43 TK_IgnoreUnlessSpelledInSource
44};
45
46/// Kind identifier.
47///
48/// It can be constructed from any node kind and allows for runtime type
49/// hierarchy checks.
50/// Use getFromNodeKind<T>() to construct them.
51class ASTNodeKind {
52public:
53 /// Empty identifier. It matches nothing.
54 ASTNodeKind() : KindId(NKI_None) {}
55
56 /// Construct an identifier for T.
57 template <class T>
58 static ASTNodeKind getFromNodeKind() {
59 return ASTNodeKind(KindToKindId<T>::Id);
60 }
61
62 /// \{
63 /// Construct an identifier for the dynamic type of the node
64 static ASTNodeKind getFromNode(const Decl &D);
65 static ASTNodeKind getFromNode(const Stmt &S);
66 static ASTNodeKind getFromNode(const Type &T);
67 static ASTNodeKind getFromNode(const TypeLoc &T);
68 static ASTNodeKind getFromNode(const LambdaCapture &L);
69 static ASTNodeKind getFromNode(const OMPClause &C);
70 static ASTNodeKind getFromNode(const Attr &A);
71 /// \}
72
73 /// Returns \c true if \c this and \c Other represent the same kind.
74 bool isSame(ASTNodeKind Other) const {
75 return KindId != NKI_None && KindId == Other.KindId;
76 }
77
78 /// Returns \c true only for the default \c ASTNodeKind()
79 bool isNone() const { return KindId == NKI_None; }
80
81 /// Returns \c true if \c this is a base kind of (or same as) \c Other.
82 /// \param Distance If non-null, used to return the distance between \c this
83 /// and \c Other in the class hierarchy.
84 bool isBaseOf(ASTNodeKind Other, unsigned *Distance = nullptr) const;
85
86 /// String representation of the kind.
87 StringRef asStringRef() const;
88
89 /// Strict weak ordering for ASTNodeKind.
90 bool operator<(const ASTNodeKind &Other) const {
91 return KindId < Other.KindId;
92 }
93
94 /// Return the most derived type between \p Kind1 and \p Kind2.
95 ///
96 /// Return ASTNodeKind() if they are not related.
97 static ASTNodeKind getMostDerivedType(ASTNodeKind Kind1, ASTNodeKind Kind2);
98
99 /// Return the most derived common ancestor between Kind1 and Kind2.
100 ///
101 /// Return ASTNodeKind() if they are not related.
102 static ASTNodeKind getMostDerivedCommonAncestor(ASTNodeKind Kind1,
103 ASTNodeKind Kind2);
104
105 ASTNodeKind getCladeKind() const;
106
107 /// Hooks for using ASTNodeKind as a key in a DenseMap.
108 struct DenseMapInfo {
109 // ASTNodeKind() is a good empty key because it is represented as a 0.
110 static inline ASTNodeKind getEmptyKey() { return ASTNodeKind(); }
111 // NKI_NumberOfKinds is not a valid value, so it is good for a
112 // tombstone key.
113 static inline ASTNodeKind getTombstoneKey() {
114 return ASTNodeKind(NKI_NumberOfKinds);
115 }
116 static unsigned getHashValue(const ASTNodeKind &Val) { return Val.KindId; }
117 static bool isEqual(const ASTNodeKind &LHS, const ASTNodeKind &RHS) {
118 return LHS.KindId == RHS.KindId;
119 }
120 };
121
122 /// Check if the given ASTNodeKind identifies a type that offers pointer
123 /// identity. This is useful for the fast path in DynTypedNode.
124 bool hasPointerIdentity() const {
125 return KindId > NKI_LastKindWithoutPointerIdentity;
126 }
127
128private:
129 /// Kind ids.
130 ///
131 /// Includes all possible base and derived kinds.
132 enum NodeKindId {
133 NKI_None,
134 NKI_TemplateArgument,
135 NKI_TemplateArgumentLoc,
136 NKI_LambdaCapture,
137 NKI_TemplateName,
138 NKI_NestedNameSpecifierLoc,
139 NKI_QualType,
140#define TYPELOC(CLASS, PARENT) NKI_##CLASS##TypeLoc,
141#include "clang/AST/TypeLocNodes.def"
142 NKI_TypeLoc,
143 NKI_LastKindWithoutPointerIdentity = NKI_TypeLoc,
144 NKI_CXXBaseSpecifier,
145 NKI_CXXCtorInitializer,
146 NKI_NestedNameSpecifier,
147 NKI_Decl,
148#define DECL(DERIVED, BASE) NKI_##DERIVED##Decl,
149#include "clang/AST/DeclNodes.inc"
150 NKI_Stmt,
151#define STMT(DERIVED, BASE) NKI_##DERIVED,
152#include "clang/AST/StmtNodes.inc"
153 NKI_Type,
154#define TYPE(DERIVED, BASE) NKI_##DERIVED##Type,
155#include "clang/AST/TypeNodes.inc"
156 NKI_OMPClause,
157#define GEN_CLANG_CLAUSE_CLASS
158#define CLAUSE_CLASS(Enum, Str, Class) NKI_##Class,
159#include "llvm/Frontend/OpenMP/OMP.inc"
160 NKI_Attr,
161#define ATTR(A) NKI_##A##Attr,
162#include "clang/Basic/AttrList.inc"
163 NKI_NumberOfKinds
164 };
165
166 /// Use getFromNodeKind<T>() to construct the kind.
167 ASTNodeKind(NodeKindId KindId) : KindId(KindId) {}
168
169 /// Returns \c true if \c Base is a base kind of (or same as) \c
170 /// Derived.
171 /// \param Distance If non-null, used to return the distance between \c Base
172 /// and \c Derived in the class hierarchy.
173 static bool isBaseOf(NodeKindId Base, NodeKindId Derived, unsigned *Distance);
174
175 /// Helper meta-function to convert a kind T to its enum value.
176 ///
177 /// This struct is specialized below for all known kinds.
178 template <class T> struct KindToKindId {
179 static const NodeKindId Id = NKI_None;
180 };
181 template <class T>
182 struct KindToKindId<const T> : KindToKindId<T> {};
183
184 /// Per kind info.
185 struct KindInfo {
186 /// The id of the parent kind, or None if it has no parent.
187 NodeKindId ParentId;
188 /// Name of the kind.
189 const char *Name;
190 };
191 static const KindInfo AllKindInfo[NKI_NumberOfKinds];
192
193 NodeKindId KindId;
194};
195
196#define KIND_TO_KIND_ID(Class) \
197 template <> struct ASTNodeKind::KindToKindId<Class> { \
198 static const NodeKindId Id = NKI_##Class; \
199 };
200KIND_TO_KIND_ID(CXXCtorInitializer)
201KIND_TO_KIND_ID(TemplateArgument)
202KIND_TO_KIND_ID(TemplateArgumentLoc)
203KIND_TO_KIND_ID(LambdaCapture)
204KIND_TO_KIND_ID(TemplateName)
205KIND_TO_KIND_ID(NestedNameSpecifier)
206KIND_TO_KIND_ID(NestedNameSpecifierLoc)
207KIND_TO_KIND_ID(QualType)
208#define TYPELOC(CLASS, PARENT) KIND_TO_KIND_ID(CLASS##TypeLoc)
209#include "clang/AST/TypeLocNodes.def"
210KIND_TO_KIND_ID(TypeLoc)
211KIND_TO_KIND_ID(Decl)
212KIND_TO_KIND_ID(Stmt)
213KIND_TO_KIND_ID(Type)
214KIND_TO_KIND_ID(OMPClause)
215KIND_TO_KIND_ID(Attr)
216KIND_TO_KIND_ID(CXXBaseSpecifier)
217#define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl)
218#include "clang/AST/DeclNodes.inc"
219#define STMT(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED)
220#include "clang/AST/StmtNodes.inc"
221#define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type)
222#include "clang/AST/TypeNodes.inc"
223#define GEN_CLANG_CLAUSE_CLASS
224#define CLAUSE_CLASS(Enum, Str, Class) KIND_TO_KIND_ID(Class)
225#include "llvm/Frontend/OpenMP/OMP.inc"
226#define ATTR(A) KIND_TO_KIND_ID(A##Attr)
227#include "clang/Basic/AttrList.inc"
228#undef KIND_TO_KIND_ID
229
230inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
231 OS << K.asStringRef();
232 return OS;
233}
234
235/// A dynamically typed AST node container.
236///
237/// Stores an AST node in a type safe way. This allows writing code that
238/// works with different kinds of AST nodes, despite the fact that they don't
239/// have a common base class.
240///
241/// Use \c create(Node) to create a \c DynTypedNode from an AST node,
242/// and \c get<T>() to retrieve the node as type T if the types match.
243///
244/// See \c ASTNodeKind for which node base types are currently supported;
245/// You can create DynTypedNodes for all nodes in the inheritance hierarchy of
246/// the supported base types.
247class DynTypedNode {
248public:
249 /// Creates a \c DynTypedNode from \c Node.
250 template <typename T>
251 static DynTypedNode create(const T &Node) {
252 return BaseConverter<T>::create(Node);
253 }
254
255 /// Retrieve the stored node as type \c T.
256 ///
257 /// Returns NULL if the stored node does not have a type that is
258 /// convertible to \c T.
259 ///
260 /// For types that have identity via their pointer in the AST
261 /// (like \c Stmt, \c Decl, \c Type and \c NestedNameSpecifier) the returned
262 /// pointer points to the referenced AST node.
263 /// For other types (like \c QualType) the value is stored directly
264 /// in the \c DynTypedNode, and the returned pointer points at
265 /// the storage inside DynTypedNode. For those nodes, do not
266 /// use the pointer outside the scope of the DynTypedNode.
267 template <typename T> const T *get() const {
268 return BaseConverter<T>::get(NodeKind, &Storage);
9
Calling 'DynCastPtrConverter::get'
13
Returning from 'DynCastPtrConverter::get'
14
Returning null pointer, which participates in a condition later
28
Calling 'DynCastPtrConverter::get'
32
Returning from 'DynCastPtrConverter::get'
33
Returning null pointer, which participates in a condition later
47
Calling 'DynCastPtrConverter::get'
51
Returning from 'DynCastPtrConverter::get'
52
Returning null pointer, which participates in a condition later
66
Calling 'DynCastPtrConverter::get'
70
Returning from 'DynCastPtrConverter::get'
71
Returning pointer, which participates in a condition later
269 }
270
271 /// Retrieve the stored node as type \c T.
272 ///
273 /// Similar to \c get(), but asserts that the type is what we are expecting.
274 template <typename T>
275 const T &getUnchecked() const {
276 return BaseConverter<T>::getUnchecked(NodeKind, &Storage);
277 }
278
279 ASTNodeKind getNodeKind() const { return NodeKind; }
280
281 /// Returns a pointer that identifies the stored AST node.
282 ///
283 /// Note that this is not supported by all AST nodes. For AST nodes
284 /// that don't have a pointer-defined identity inside the AST, this
285 /// method returns NULL.
286 const void *getMemoizationData() const {
287 return NodeKind.hasPointerIdentity()
288 ? *reinterpret_cast<void *const *>(&Storage)
289 : nullptr;
290 }
291
292 /// Prints the node to the given output stream.
293 void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const;
294
295 /// Dumps the node to the given output stream.
296 void dump(llvm::raw_ostream &OS, const ASTContext &Context) const;
297
298 /// For nodes which represent textual entities in the source code,
299 /// return their SourceRange. For all other nodes, return SourceRange().
300 SourceRange getSourceRange() const;
301
302 /// @{
303 /// Imposes an order on \c DynTypedNode.
304 ///
305 /// Supports comparison of nodes that support memoization.
306 /// FIXME: Implement comparison for other node types (currently
307 /// only Stmt, Decl, Type and NestedNameSpecifier return memoization data).
308 bool operator<(const DynTypedNode &Other) const {
309 if (!NodeKind.isSame(Other.NodeKind))
310 return NodeKind < Other.NodeKind;
311
312 if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
313 return getUnchecked<QualType>().getAsOpaquePtr() <
314 Other.getUnchecked<QualType>().getAsOpaquePtr();
315
316 if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(NodeKind)) {
317 auto TLA = getUnchecked<TypeLoc>();
318 auto TLB = Other.getUnchecked<TypeLoc>();
319 return std::make_pair(TLA.getType().getAsOpaquePtr(),
320 TLA.getOpaqueData()) <
321 std::make_pair(TLB.getType().getAsOpaquePtr(),
322 TLB.getOpaqueData());
323 }
324
325 if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(
326 NodeKind)) {
327 auto NNSLA = getUnchecked<NestedNameSpecifierLoc>();
328 auto NNSLB = Other.getUnchecked<NestedNameSpecifierLoc>();
329 return std::make_pair(NNSLA.getNestedNameSpecifier(),
330 NNSLA.getOpaqueData()) <
331 std::make_pair(NNSLB.getNestedNameSpecifier(),
332 NNSLB.getOpaqueData());
333 }
334
335 assert(getMemoizationData() && Other.getMemoizationData())(static_cast <bool> (getMemoizationData() && Other
.getMemoizationData()) ? void (0) : __assert_fail ("getMemoizationData() && Other.getMemoizationData()"
, "clang/include/clang/AST/ASTTypeTraits.h", 335, __extension__
__PRETTY_FUNCTION__))
;
336 return getMemoizationData() < Other.getMemoizationData();
337 }
338 bool operator==(const DynTypedNode &Other) const {
339 // DynTypedNode::create() stores the exact kind of the node in NodeKind.
340 // If they contain the same node, their NodeKind must be the same.
341 if (!NodeKind.isSame(Other.NodeKind))
342 return false;
343
344 // FIXME: Implement for other types.
345 if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
346 return getUnchecked<QualType>() == Other.getUnchecked<QualType>();
347
348 if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(NodeKind))
349 return getUnchecked<TypeLoc>() == Other.getUnchecked<TypeLoc>();
350
351 if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(NodeKind))
352 return getUnchecked<NestedNameSpecifierLoc>() ==
353 Other.getUnchecked<NestedNameSpecifierLoc>();
354
355 assert(getMemoizationData() && Other.getMemoizationData())(static_cast <bool> (getMemoizationData() && Other
.getMemoizationData()) ? void (0) : __assert_fail ("getMemoizationData() && Other.getMemoizationData()"
, "clang/include/clang/AST/ASTTypeTraits.h", 355, __extension__
__PRETTY_FUNCTION__))
;
356 return getMemoizationData() == Other.getMemoizationData();
357 }
358 bool operator!=(const DynTypedNode &Other) const {
359 return !operator==(Other);
360 }
361 /// @}
362
363 /// Hooks for using DynTypedNode as a key in a DenseMap.
364 struct DenseMapInfo {
365 static inline DynTypedNode getEmptyKey() {
366 DynTypedNode Node;
367 Node.NodeKind = ASTNodeKind::DenseMapInfo::getEmptyKey();
368 return Node;
369 }
370 static inline DynTypedNode getTombstoneKey() {
371 DynTypedNode Node;
372 Node.NodeKind = ASTNodeKind::DenseMapInfo::getTombstoneKey();
373 return Node;
374 }
375 static unsigned getHashValue(const DynTypedNode &Val) {
376 // FIXME: Add hashing support for the remaining types.
377 if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(Val.NodeKind)) {
378 auto TL = Val.getUnchecked<TypeLoc>();
379 return llvm::hash_combine(TL.getType().getAsOpaquePtr(),
380 TL.getOpaqueData());
381 }
382
383 if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(
384 Val.NodeKind)) {
385 auto NNSL = Val.getUnchecked<NestedNameSpecifierLoc>();
386 return llvm::hash_combine(NNSL.getNestedNameSpecifier(),
387 NNSL.getOpaqueData());
388 }
389
390 assert(Val.getMemoizationData())(static_cast <bool> (Val.getMemoizationData()) ? void (
0) : __assert_fail ("Val.getMemoizationData()", "clang/include/clang/AST/ASTTypeTraits.h"
, 390, __extension__ __PRETTY_FUNCTION__))
;
391 return llvm::hash_value(Val.getMemoizationData());
392 }
393 static bool isEqual(const DynTypedNode &LHS, const DynTypedNode &RHS) {
394 auto Empty = ASTNodeKind::DenseMapInfo::getEmptyKey();
395 auto TombStone = ASTNodeKind::DenseMapInfo::getTombstoneKey();
396 return (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKind, Empty) &&
397 ASTNodeKind::DenseMapInfo::isEqual(RHS.NodeKind, Empty)) ||
398 (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKind, TombStone) &&
399 ASTNodeKind::DenseMapInfo::isEqual(RHS.NodeKind, TombStone)) ||
400 LHS == RHS;
401 }
402 };
403
404private:
405 /// Takes care of converting from and to \c T.
406 template <typename T, typename EnablerT = void> struct BaseConverter;
407
408 /// Converter that uses dyn_cast<T> from a stored BaseT*.
409 template <typename T, typename BaseT> struct DynCastPtrConverter {
410 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
411 if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
10
Assuming the condition is false
11
Taking false branch
29
Assuming the condition is false
30
Taking false branch
48
Assuming the condition is false
49
Taking false branch
67
Assuming the condition is true
68
Taking true branch
412 return &getUnchecked(NodeKind, Storage);
69
Returning pointer, which participates in a condition later
413 return nullptr;
12
Returning null pointer, which participates in a condition later
31
Returning null pointer, which participates in a condition later
50
Returning null pointer, which participates in a condition later
414 }
415 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
416 assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))(static_cast <bool> (ASTNodeKind::getFromNodeKind<T>
().isBaseOf(NodeKind)) ? void (0) : __assert_fail ("ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind)"
, "clang/include/clang/AST/ASTTypeTraits.h", 416, __extension__
__PRETTY_FUNCTION__))
;
417 return *cast<T>(static_cast<const BaseT *>(
418 *reinterpret_cast<const void *const *>(Storage)));
419 }
420 static DynTypedNode create(const BaseT &Node) {
421 DynTypedNode Result;
422 Result.NodeKind = ASTNodeKind::getFromNode(Node);
423 new (&Result.Storage) const void *(&Node);
424 return Result;
425 }
426 };
427
428 /// Converter that stores T* (by pointer).
429 template <typename T> struct PtrConverter {
430 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
431 if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
432 return &getUnchecked(NodeKind, Storage);
433 return nullptr;
434 }
435 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
436 assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))(static_cast <bool> (ASTNodeKind::getFromNodeKind<T>
().isSame(NodeKind)) ? void (0) : __assert_fail ("ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind)"
, "clang/include/clang/AST/ASTTypeTraits.h", 436, __extension__
__PRETTY_FUNCTION__))
;
437 return *static_cast<const T *>(
438 *reinterpret_cast<const void *const *>(Storage));
439 }
440 static DynTypedNode create(const T &Node) {
441 DynTypedNode Result;
442 Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
443 new (&Result.Storage) const void *(&Node);
444 return Result;
445 }
446 };
447
448 /// Converter that stores T (by value).
449 template <typename T> struct ValueConverter {
450 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
451 if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
452 return reinterpret_cast<const T *>(Storage);
453 return nullptr;
454 }
455 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
456 assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))(static_cast <bool> (ASTNodeKind::getFromNodeKind<T>
().isSame(NodeKind)) ? void (0) : __assert_fail ("ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind)"
, "clang/include/clang/AST/ASTTypeTraits.h", 456, __extension__
__PRETTY_FUNCTION__))
;
457 return *reinterpret_cast<const T *>(Storage);
458 }
459 static DynTypedNode create(const T &Node) {
460 DynTypedNode Result;
461 Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
462 new (&Result.Storage) T(Node);
463 return Result;
464 }
465 };
466
467 /// Converter that stores nodes by value. It must be possible to dynamically
468 /// cast the stored node within a type hierarchy without breaking (especially
469 /// through slicing).
470 template <typename T, typename BaseT,
471 typename = std::enable_if_t<(sizeof(T) == sizeof(BaseT))>>
472 struct DynCastValueConverter {
473 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
474 if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
475 return &getUnchecked(NodeKind, Storage);
476 return nullptr;
477 }
478 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
479 assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))(static_cast <bool> (ASTNodeKind::getFromNodeKind<T>
().isBaseOf(NodeKind)) ? void (0) : __assert_fail ("ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind)"
, "clang/include/clang/AST/ASTTypeTraits.h", 479, __extension__
__PRETTY_FUNCTION__))
;
480 return *static_cast<const T *>(reinterpret_cast<const BaseT *>(Storage));
481 }
482 static DynTypedNode create(const T &Node) {
483 DynTypedNode Result;
484 Result.NodeKind = ASTNodeKind::getFromNode(Node);
485 new (&Result.Storage) T(Node);
486 return Result;
487 }
488 };
489
490 ASTNodeKind NodeKind;
491
492 /// Stores the data of the node.
493 ///
494 /// Note that we can store \c Decls, \c Stmts, \c Types,
495 /// \c NestedNameSpecifiers and \c CXXCtorInitializer by pointer as they are
496 /// guaranteed to be unique pointers pointing to dedicated storage in the AST.
497 /// \c QualTypes, \c NestedNameSpecifierLocs, \c TypeLocs,
498 /// \c TemplateArguments and \c TemplateArgumentLocs on the other hand do not
499 /// have storage or unique pointers and thus need to be stored by value.
500 llvm::AlignedCharArrayUnion<const void *, TemplateArgument,
501 TemplateArgumentLoc, NestedNameSpecifierLoc,
502 QualType, TypeLoc>
503 Storage;
504};
505
506template <typename T>
507struct DynTypedNode::BaseConverter<
508 T, std::enable_if_t<std::is_base_of<Decl, T>::value>>
509 : public DynCastPtrConverter<T, Decl> {};
510
511template <typename T>
512struct DynTypedNode::BaseConverter<
513 T, std::enable_if_t<std::is_base_of<Stmt, T>::value>>
514 : public DynCastPtrConverter<T, Stmt> {};
515
516template <typename T>
517struct DynTypedNode::BaseConverter<
518 T, std::enable_if_t<std::is_base_of<Type, T>::value>>
519 : public DynCastPtrConverter<T, Type> {};
520
521template <typename T>
522struct DynTypedNode::BaseConverter<
523 T, std::enable_if_t<std::is_base_of<OMPClause, T>::value>>
524 : public DynCastPtrConverter<T, OMPClause> {};
525
526template <typename T>
527struct DynTypedNode::BaseConverter<
528 T, std::enable_if_t<std::is_base_of<Attr, T>::value>>
529 : public DynCastPtrConverter<T, Attr> {};
530
531template <>
532struct DynTypedNode::BaseConverter<
533 NestedNameSpecifier, void> : public PtrConverter<NestedNameSpecifier> {};
534
535template <>
536struct DynTypedNode::BaseConverter<
537 CXXCtorInitializer, void> : public PtrConverter<CXXCtorInitializer> {};
538
539template <>
540struct DynTypedNode::BaseConverter<
541 TemplateArgument, void> : public ValueConverter<TemplateArgument> {};
542
543template <>
544struct DynTypedNode::BaseConverter<TemplateArgumentLoc, void>
545 : public ValueConverter<TemplateArgumentLoc> {};
546
547template <>
548struct DynTypedNode::BaseConverter<LambdaCapture, void>
549 : public ValueConverter<LambdaCapture> {};
550
551template <>
552struct DynTypedNode::BaseConverter<
553 TemplateName, void> : public ValueConverter<TemplateName> {};
554
555template <>
556struct DynTypedNode::BaseConverter<
557 NestedNameSpecifierLoc,
558 void> : public ValueConverter<NestedNameSpecifierLoc> {};
559
560template <>
561struct DynTypedNode::BaseConverter<QualType,
562 void> : public ValueConverter<QualType> {};
563
564template <typename T>
565struct DynTypedNode::BaseConverter<
566 T, std::enable_if_t<std::is_base_of<TypeLoc, T>::value>>
567 : public DynCastValueConverter<T, TypeLoc> {};
568
569template <>
570struct DynTypedNode::BaseConverter<CXXBaseSpecifier, void>
571 : public PtrConverter<CXXBaseSpecifier> {};
572
573// The only operation we allow on unsupported types is \c get.
574// This allows to conveniently use \c DynTypedNode when having an arbitrary
575// AST node that is not supported, but prevents misuse - a user cannot create
576// a DynTypedNode from arbitrary types.
577template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter {
578 static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
579 return NULL__null;
580 }
581};
582
583} // end namespace clang
584
585namespace llvm {
586
587template <>
588struct DenseMapInfo<clang::ASTNodeKind> : clang::ASTNodeKind::DenseMapInfo {};
589
590template <>
591struct DenseMapInfo<clang::DynTypedNode> : clang::DynTypedNode::DenseMapInfo {};
592
593} // end namespace llvm
594
595#endif