Bug Summary

File:tools/clang/tools/extra/clang-move/ClangMove.cpp
Warning:line 185, column 7
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ClangMove.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -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 -mrelocation-model pic -pic-level 2 -mthread-model posix -relaxed-aliasing -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-7/lib/clang/7.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn326551/build-llvm/tools/clang/tools/extra/clang-move -I /build/llvm-toolchain-snapshot-7~svn326551/tools/clang/tools/extra/clang-move -I /build/llvm-toolchain-snapshot-7~svn326551/tools/clang/include -I /build/llvm-toolchain-snapshot-7~svn326551/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-7~svn326551/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn326551/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/backward -internal-isystem /usr/include/clang/7.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-7~svn326551/build-llvm/tools/clang/tools/extra/clang-move -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fno-common -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-03-02-155150-1477-1 -x c++ /build/llvm-toolchain-snapshot-7~svn326551/tools/clang/tools/extra/clang-move/ClangMove.cpp

/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/tools/extra/clang-move/ClangMove.cpp

1//===-- ClangMove.cpp - Implement ClangMove functationalities ---*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "ClangMove.h"
11#include "HelperDeclRefGraph.h"
12#include "clang/ASTMatchers/ASTMatchers.h"
13#include "clang/Basic/SourceManager.h"
14#include "clang/Format/Format.h"
15#include "clang/Frontend/CompilerInstance.h"
16#include "clang/Lex/Lexer.h"
17#include "clang/Lex/Preprocessor.h"
18#include "clang/Rewrite/Core/Rewriter.h"
19#include "clang/Tooling/Core/Replacement.h"
20#include "llvm/Support/Debug.h"
21#include "llvm/Support/Path.h"
22
23#define DEBUG_TYPE"clang-move" "clang-move"
24
25using namespace clang::ast_matchers;
26
27namespace clang {
28namespace move {
29namespace {
30
31// FIXME: Move to ASTMatchers.
32AST_MATCHER(VarDecl, isStaticDataMember)namespace internal { class matcher_isStaticDataMemberMatcher :
public ::clang::ast_matchers::internal::MatcherInterface<
VarDecl> { public: explicit matcher_isStaticDataMemberMatcher
() = 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
> isStaticDataMember() { return ::clang::ast_matchers::internal
::makeMatcher( new internal::matcher_isStaticDataMemberMatcher
()); } inline bool internal::matcher_isStaticDataMemberMatcher
::matches( const VarDecl &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{ return Node.isStaticDataMember(); }
33
34AST_MATCHER(NamedDecl, notInMacro)namespace internal { class matcher_notInMacroMatcher : public
::clang::ast_matchers::internal::MatcherInterface<NamedDecl
> { public: explicit matcher_notInMacroMatcher() = 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> notInMacro
() { return ::clang::ast_matchers::internal::makeMatcher( new
internal::matcher_notInMacroMatcher()); } inline bool internal
::matcher_notInMacroMatcher::matches( const NamedDecl &Node
, ::clang::ast_matchers::internal::ASTMatchFinder *Finder, ::
clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder
) const
{ return !Node.getLocation().isMacroID(); }
35
36AST_MATCHER_P(Decl, hasOutermostEnclosingClass,namespace internal { class matcher_hasOutermostEnclosingClass0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
Decl> { public: explicit matcher_hasOutermostEnclosingClass0Matcher
( ast_matchers::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: ast_matchers::internal::Matcher<
Decl> const InnerMatcher; }; } inline ::clang::ast_matchers
::internal::Matcher<Decl> hasOutermostEnclosingClass( ast_matchers
::internal::Matcher<Decl> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasOutermostEnclosingClass0Matcher(InnerMatcher)); } typedef
::clang::ast_matchers::internal::Matcher<Decl>( &hasOutermostEnclosingClass_Type0
)(ast_matchers::internal::Matcher<Decl> const &InnerMatcher
); inline bool internal::matcher_hasOutermostEnclosingClass0Matcher
::matches( const Decl &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
37 ast_matchers::internal::Matcher<Decl>, InnerMatcher)namespace internal { class matcher_hasOutermostEnclosingClass0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
Decl> { public: explicit matcher_hasOutermostEnclosingClass0Matcher
( ast_matchers::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: ast_matchers::internal::Matcher<
Decl> const InnerMatcher; }; } inline ::clang::ast_matchers
::internal::Matcher<Decl> hasOutermostEnclosingClass( ast_matchers
::internal::Matcher<Decl> const &InnerMatcher) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_hasOutermostEnclosingClass0Matcher(InnerMatcher)); } typedef
::clang::ast_matchers::internal::Matcher<Decl>( &hasOutermostEnclosingClass_Type0
)(ast_matchers::internal::Matcher<Decl> const &InnerMatcher
); inline bool internal::matcher_hasOutermostEnclosingClass0Matcher
::matches( const Decl &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
38 const auto *Context = Node.getDeclContext();
39 if (!Context)
40 return false;
41 while (const auto *NextContext = Context->getParent()) {
42 if (isa<NamespaceDecl>(NextContext) ||
43 isa<TranslationUnitDecl>(NextContext))
44 break;
45 Context = NextContext;
46 }
47 return InnerMatcher.matches(*Decl::castFromDeclContext(Context), Finder,
48 Builder);
49}
50
51AST_MATCHER_P(CXXMethodDecl, ofOutermostEnclosingClass,namespace internal { class matcher_ofOutermostEnclosingClass0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
CXXMethodDecl> { public: explicit matcher_ofOutermostEnclosingClass0Matcher
( ast_matchers::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: ast_matchers::internal::Matcher
<CXXRecordDecl> const InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<CXXMethodDecl> ofOutermostEnclosingClass
( ast_matchers::internal::Matcher<CXXRecordDecl> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_ofOutermostEnclosingClass0Matcher(InnerMatcher
)); } typedef ::clang::ast_matchers::internal::Matcher<CXXMethodDecl
>( &ofOutermostEnclosingClass_Type0)(ast_matchers::internal
::Matcher<CXXRecordDecl> const &InnerMatcher); inline
bool internal::matcher_ofOutermostEnclosingClass0Matcher::matches
( const CXXMethodDecl &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
52 ast_matchers::internal::Matcher<CXXRecordDecl>, InnerMatcher)namespace internal { class matcher_ofOutermostEnclosingClass0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
CXXMethodDecl> { public: explicit matcher_ofOutermostEnclosingClass0Matcher
( ast_matchers::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: ast_matchers::internal::Matcher
<CXXRecordDecl> const InnerMatcher; }; } inline ::clang
::ast_matchers::internal::Matcher<CXXMethodDecl> ofOutermostEnclosingClass
( ast_matchers::internal::Matcher<CXXRecordDecl> const &
InnerMatcher) { return ::clang::ast_matchers::internal::makeMatcher
( new internal::matcher_ofOutermostEnclosingClass0Matcher(InnerMatcher
)); } typedef ::clang::ast_matchers::internal::Matcher<CXXMethodDecl
>( &ofOutermostEnclosingClass_Type0)(ast_matchers::internal
::Matcher<CXXRecordDecl> const &InnerMatcher); inline
bool internal::matcher_ofOutermostEnclosingClass0Matcher::matches
( const CXXMethodDecl &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
53 const CXXRecordDecl *Parent = Node.getParent();
54 if (!Parent)
55 return false;
56 while (const auto *NextParent =
57 dyn_cast<CXXRecordDecl>(Parent->getParent())) {
58 Parent = NextParent;
59 }
60
61 return InnerMatcher.matches(*Parent, Finder, Builder);
62}
63
64// Make the Path absolute using the CurrentDir if the Path is not an absolute
65// path. An empty Path will result in an empty string.
66std::string MakeAbsolutePath(StringRef CurrentDir, StringRef Path) {
67 if (Path.empty())
68 return "";
69 llvm::SmallString<128> InitialDirectory(CurrentDir);
70 llvm::SmallString<128> AbsolutePath(Path);
71 if (std::error_code EC =
72 llvm::sys::fs::make_absolute(InitialDirectory, AbsolutePath))
73 llvm::errs() << "Warning: could not make absolute file: '" << EC.message()
74 << '\n';
75 llvm::sys::path::remove_dots(AbsolutePath, /*remove_dot_dot=*/true);
76 llvm::sys::path::native(AbsolutePath);
77 return AbsolutePath.str();
78}
79
80// Make the Path absolute using the current working directory of the given
81// SourceManager if the Path is not an absolute path.
82//
83// The Path can be a path relative to the build directory, or retrieved from
84// the SourceManager.
85std::string MakeAbsolutePath(const SourceManager &SM, StringRef Path) {
86 llvm::SmallString<128> AbsolutePath(Path);
87 if (std::error_code EC =
88 SM.getFileManager().getVirtualFileSystem()->makeAbsolute(
89 AbsolutePath))
90 llvm::errs() << "Warning: could not make absolute file: '" << EC.message()
91 << '\n';
92 // Handle symbolic link path cases.
93 // We are trying to get the real file path of the symlink.
94 const DirectoryEntry *Dir = SM.getFileManager().getDirectory(
95 llvm::sys::path::parent_path(AbsolutePath.str()));
96 if (Dir) {
97 StringRef DirName = SM.getFileManager().getCanonicalName(Dir);
98 SmallVector<char, 128> AbsoluteFilename;
99 llvm::sys::path::append(AbsoluteFilename, DirName,
100 llvm::sys::path::filename(AbsolutePath.str()));
101 return llvm::StringRef(AbsoluteFilename.data(), AbsoluteFilename.size())
102 .str();
103 }
104 return AbsolutePath.str();
105}
106
107// Matches AST nodes that are expanded within the given AbsoluteFilePath.
108AST_POLYMORPHIC_MATCHER_P(isExpansionInFile,namespace internal { template <typename NodeType, typename
ParamT> class matcher_isExpansionInFile0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_isExpansionInFile0Matcher( std::string
const &AAbsoluteFilePath) : AbsoluteFilePath(AAbsoluteFilePath
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: std
::string const AbsoluteFilePath; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcherWithParam1< internal::matcher_isExpansionInFile0Matcher
, std::string, void(::clang::ast_matchers::internal::TypeList
<Decl, Stmt, TypeLoc>)> isExpansionInFile(std::string
const &AbsoluteFilePath) { return ::clang::ast_matchers::
internal::PolymorphicMatcherWithParam1< internal::matcher_isExpansionInFile0Matcher
, std::string, void(::clang::ast_matchers::internal::TypeList
<Decl, Stmt, TypeLoc>)>(AbsoluteFilePath); } typedef
::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_isExpansionInFile0Matcher, std::string
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>)>(&isExpansionInFile_Type0)( std::string
const &AbsoluteFilePath); template <typename NodeType
, typename ParamT> bool internal:: matcher_isExpansionInFile0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
109 AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc),namespace internal { template <typename NodeType, typename
ParamT> class matcher_isExpansionInFile0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_isExpansionInFile0Matcher( std::string
const &AAbsoluteFilePath) : AbsoluteFilePath(AAbsoluteFilePath
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: std
::string const AbsoluteFilePath; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcherWithParam1< internal::matcher_isExpansionInFile0Matcher
, std::string, void(::clang::ast_matchers::internal::TypeList
<Decl, Stmt, TypeLoc>)> isExpansionInFile(std::string
const &AbsoluteFilePath) { return ::clang::ast_matchers::
internal::PolymorphicMatcherWithParam1< internal::matcher_isExpansionInFile0Matcher
, std::string, void(::clang::ast_matchers::internal::TypeList
<Decl, Stmt, TypeLoc>)>(AbsoluteFilePath); } typedef
::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_isExpansionInFile0Matcher, std::string
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>)>(&isExpansionInFile_Type0)( std::string
const &AbsoluteFilePath); template <typename NodeType
, typename ParamT> bool internal:: matcher_isExpansionInFile0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
110 std::string, AbsoluteFilePath)namespace internal { template <typename NodeType, typename
ParamT> class matcher_isExpansionInFile0Matcher : public ::
clang::ast_matchers::internal::MatcherInterface<NodeType>
{ public: explicit matcher_isExpansionInFile0Matcher( std::string
const &AAbsoluteFilePath) : AbsoluteFilePath(AAbsoluteFilePath
) {} bool matches(const NodeType &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: std
::string const AbsoluteFilePath; }; } inline ::clang::ast_matchers
::internal::PolymorphicMatcherWithParam1< internal::matcher_isExpansionInFile0Matcher
, std::string, void(::clang::ast_matchers::internal::TypeList
<Decl, Stmt, TypeLoc>)> isExpansionInFile(std::string
const &AbsoluteFilePath) { return ::clang::ast_matchers::
internal::PolymorphicMatcherWithParam1< internal::matcher_isExpansionInFile0Matcher
, std::string, void(::clang::ast_matchers::internal::TypeList
<Decl, Stmt, TypeLoc>)>(AbsoluteFilePath); } typedef
::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_isExpansionInFile0Matcher, std::string
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>)>(&isExpansionInFile_Type0)( std::string
const &AbsoluteFilePath); template <typename NodeType
, typename ParamT> bool internal:: matcher_isExpansionInFile0Matcher
<NodeType, ParamT>::matches( const NodeType &Node, ::
clang::ast_matchers::internal::ASTMatchFinder *Finder, ::clang
::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
{
111 auto &SourceManager = Finder->getASTContext().getSourceManager();
112 auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getLocStart());
113 if (ExpansionLoc.isInvalid())
114 return false;
115 auto FileEntry =
116 SourceManager.getFileEntryForID(SourceManager.getFileID(ExpansionLoc));
117 if (!FileEntry)
118 return false;
119 return MakeAbsolutePath(SourceManager, FileEntry->getName()) ==
120 AbsoluteFilePath;
121}
122
123class FindAllIncludes : public clang::PPCallbacks {
124public:
125 explicit FindAllIncludes(SourceManager *SM, ClangMoveTool *const MoveTool)
126 : SM(*SM), MoveTool(MoveTool) {}
127
128 void InclusionDirective(clang::SourceLocation HashLoc,
129 const clang::Token & /*IncludeTok*/,
130 StringRef FileName, bool IsAngled,
131 clang::CharSourceRange FilenameRange,
132 const clang::FileEntry * /*File*/,
133 StringRef SearchPath, StringRef /*RelativePath*/,
134 const clang::Module * /*Imported*/) override {
135 if (const auto *FileEntry = SM.getFileEntryForID(SM.getFileID(HashLoc)))
136 MoveTool->addIncludes(FileName, IsAngled, SearchPath,
137 FileEntry->getName(), FilenameRange, SM);
138 }
139
140private:
141 const SourceManager &SM;
142 ClangMoveTool *const MoveTool;
143};
144
145/// Add a declatration being moved to new.h/cc. Note that the declaration will
146/// also be deleted in old.h/cc.
147void MoveDeclFromOldFileToNewFile(ClangMoveTool *MoveTool, const NamedDecl *D) {
148 MoveTool->getMovedDecls().push_back(D);
149 MoveTool->addRemovedDecl(D);
150 MoveTool->getUnremovedDeclsInOldHeader().erase(D);
151}
152
153class FunctionDeclarationMatch : public MatchFinder::MatchCallback {
154public:
155 explicit FunctionDeclarationMatch(ClangMoveTool *MoveTool)
156 : MoveTool(MoveTool) {}
157
158 void run(const MatchFinder::MatchResult &Result) override {
159 const auto *FD = Result.Nodes.getNodeAs<clang::FunctionDecl>("function");
160 assert(FD)(static_cast <bool> (FD) ? void (0) : __assert_fail ("FD"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/tools/extra/clang-move/ClangMove.cpp"
, 160, __extension__ __PRETTY_FUNCTION__))
;
161 const clang::NamedDecl *D = FD;
162 if (const auto *FTD = FD->getDescribedFunctionTemplate())
163 D = FTD;
164 MoveDeclFromOldFileToNewFile(MoveTool, D);
165 }
166
167private:
168 ClangMoveTool *MoveTool;
169};
170
171class VarDeclarationMatch : public MatchFinder::MatchCallback {
172public:
173 explicit VarDeclarationMatch(ClangMoveTool *MoveTool)
174 : MoveTool(MoveTool) {}
175
176 void run(const MatchFinder::MatchResult &Result) override {
177 const auto *VD = Result.Nodes.getNodeAs<clang::VarDecl>("var");
178 assert(VD)(static_cast <bool> (VD) ? void (0) : __assert_fail ("VD"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/tools/extra/clang-move/ClangMove.cpp"
, 178, __extension__ __PRETTY_FUNCTION__))
;
179 MoveDeclFromOldFileToNewFile(MoveTool, VD);
180 }
181
182private:
183 ClangMoveTool *MoveTool;
184};
185
186class TypeAliasMatch : public MatchFinder::MatchCallback {
187public:
188 explicit TypeAliasMatch(ClangMoveTool *MoveTool)
189 : MoveTool(MoveTool) {}
190
191 void run(const MatchFinder::MatchResult &Result) override {
192 if (const auto *TD = Result.Nodes.getNodeAs<clang::TypedefDecl>("typedef"))
193 MoveDeclFromOldFileToNewFile(MoveTool, TD);
194 else if (const auto *TAD =
195 Result.Nodes.getNodeAs<clang::TypeAliasDecl>("type_alias")) {
196 const NamedDecl * D = TAD;
197 if (const auto * TD = TAD->getDescribedAliasTemplate())
198 D = TD;
199 MoveDeclFromOldFileToNewFile(MoveTool, D);
200 }
201 }
202
203private:
204 ClangMoveTool *MoveTool;
205};
206
207class EnumDeclarationMatch : public MatchFinder::MatchCallback {
208public:
209 explicit EnumDeclarationMatch(ClangMoveTool *MoveTool)
210 : MoveTool(MoveTool) {}
211
212 void run(const MatchFinder::MatchResult &Result) override {
213 const auto *ED = Result.Nodes.getNodeAs<clang::EnumDecl>("enum");
214 assert(ED)(static_cast <bool> (ED) ? void (0) : __assert_fail ("ED"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/tools/extra/clang-move/ClangMove.cpp"
, 214, __extension__ __PRETTY_FUNCTION__))
;
215 MoveDeclFromOldFileToNewFile(MoveTool, ED);
216 }
217
218private:
219 ClangMoveTool *MoveTool;
220};
221
222class ClassDeclarationMatch : public MatchFinder::MatchCallback {
223public:
224 explicit ClassDeclarationMatch(ClangMoveTool *MoveTool)
225 : MoveTool(MoveTool) {}
226 void run(const MatchFinder::MatchResult &Result) override {
227 clang::SourceManager* SM = &Result.Context->getSourceManager();
228 if (const auto *CMD =
229 Result.Nodes.getNodeAs<clang::CXXMethodDecl>("class_method"))
230 MatchClassMethod(CMD, SM);
231 else if (const auto *VD = Result.Nodes.getNodeAs<clang::VarDecl>(
232 "class_static_var_decl"))
233 MatchClassStaticVariable(VD, SM);
234 else if (const auto *CD = Result.Nodes.getNodeAs<clang::CXXRecordDecl>(
235 "moved_class"))
236 MatchClassDeclaration(CD, SM);
237 }
238
239private:
240 void MatchClassMethod(const clang::CXXMethodDecl* CMD,
241 clang::SourceManager* SM) {
242 // Skip inline class methods. isInline() ast matcher doesn't ignore this
243 // case.
244 if (!CMD->isInlined()) {
245 MoveTool->getMovedDecls().push_back(CMD);
246 MoveTool->addRemovedDecl(CMD);
247 // Get template class method from its method declaration as
248 // UnremovedDecls stores template class method.
249 if (const auto *FTD = CMD->getDescribedFunctionTemplate())
250 MoveTool->getUnremovedDeclsInOldHeader().erase(FTD);
251 else
252 MoveTool->getUnremovedDeclsInOldHeader().erase(CMD);
253 }
254 }
255
256 void MatchClassStaticVariable(const clang::NamedDecl *VD,
257 clang::SourceManager* SM) {
258 MoveDeclFromOldFileToNewFile(MoveTool, VD);
259 }
260
261 void MatchClassDeclaration(const clang::CXXRecordDecl *CD,
262 clang::SourceManager* SM) {
263 // Get class template from its class declaration as UnremovedDecls stores
264 // class template.
265 if (const auto *TC = CD->getDescribedClassTemplate())
266 MoveTool->getMovedDecls().push_back(TC);
267 else
268 MoveTool->getMovedDecls().push_back(CD);
269 MoveTool->addRemovedDecl(MoveTool->getMovedDecls().back());
270 MoveTool->getUnremovedDeclsInOldHeader().erase(
271 MoveTool->getMovedDecls().back());
272 }
273
274 ClangMoveTool *MoveTool;
275};
276
277// Expand to get the end location of the line where the EndLoc of the given
278// Decl.
279SourceLocation
280getLocForEndOfDecl(const clang::Decl *D,
281 const LangOptions &LangOpts = clang::LangOptions()) {
282 const auto &SM = D->getASTContext().getSourceManager();
283 auto EndExpansionLoc = SM.getExpansionRange(D->getLocEnd()).second;
284 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(EndExpansionLoc);
285 // Try to load the file buffer.
286 bool InvalidTemp = false;
287 llvm::StringRef File = SM.getBufferData(LocInfo.first, &InvalidTemp);
288 if (InvalidTemp)
289 return SourceLocation();
290
291 const char *TokBegin = File.data() + LocInfo.second;
292 // Lex from the start of the given location.
293 Lexer Lex(SM.getLocForStartOfFile(LocInfo.first), LangOpts, File.begin(),
294 TokBegin, File.end());
295
296 llvm::SmallVector<char, 16> Line;
297 // FIXME: this is a bit hacky to get ReadToEndOfLine work.
298 Lex.setParsingPreprocessorDirective(true);
299 Lex.ReadToEndOfLine(&Line);
300 SourceLocation EndLoc = EndExpansionLoc.getLocWithOffset(Line.size());
301 // If we already reach EOF, just return the EOF SourceLocation;
302 // otherwise, move 1 offset ahead to include the trailing newline character
303 // '\n'.
304 return SM.getLocForEndOfFile(LocInfo.first) == EndLoc
305 ? EndLoc
306 : EndLoc.getLocWithOffset(1);
307}
308
309// Get full range of a Decl including the comments associated with it.
310clang::CharSourceRange
311getFullRange(const clang::Decl *D,
312 const clang::LangOptions &options = clang::LangOptions()) {
313 const auto &SM = D->getASTContext().getSourceManager();
314 clang::SourceRange Full(SM.getExpansionLoc(D->getLocStart()),
315 getLocForEndOfDecl(D));
316 // Expand to comments that are associated with the Decl.
317 if (const auto *Comment = D->getASTContext().getRawCommentForDeclNoCache(D)) {
318 if (SM.isBeforeInTranslationUnit(Full.getEnd(), Comment->getLocEnd()))
319 Full.setEnd(Comment->getLocEnd());
320 // FIXME: Don't delete a preceding comment, if there are no other entities
321 // it could refer to.
322 if (SM.isBeforeInTranslationUnit(Comment->getLocStart(), Full.getBegin()))
323 Full.setBegin(Comment->getLocStart());
324 }
325
326 return clang::CharSourceRange::getCharRange(Full);
327}
328
329std::string getDeclarationSourceText(const clang::Decl *D) {
330 const auto &SM = D->getASTContext().getSourceManager();
331 llvm::StringRef SourceText =
332 clang::Lexer::getSourceText(getFullRange(D), SM, clang::LangOptions());
333 return SourceText.str();
334}
335
336bool isInHeaderFile(const clang::Decl *D,
337 llvm::StringRef OriginalRunningDirectory,
338 llvm::StringRef OldHeader) {
339 const auto &SM = D->getASTContext().getSourceManager();
340 if (OldHeader.empty())
341 return false;
342 auto ExpansionLoc = SM.getExpansionLoc(D->getLocStart());
343 if (ExpansionLoc.isInvalid())
344 return false;
345
346 if (const auto *FE = SM.getFileEntryForID(SM.getFileID(ExpansionLoc))) {
347 return MakeAbsolutePath(SM, FE->getName()) ==
348 MakeAbsolutePath(OriginalRunningDirectory, OldHeader);
349 }
350
351 return false;
352}
353
354std::vector<std::string> getNamespaces(const clang::Decl *D) {
355 std::vector<std::string> Namespaces;
356 for (const auto *Context = D->getDeclContext(); Context;
357 Context = Context->getParent()) {
358 if (llvm::isa<clang::TranslationUnitDecl>(Context) ||
359 llvm::isa<clang::LinkageSpecDecl>(Context))
360 break;
361
362 if (const auto *ND = llvm::dyn_cast<clang::NamespaceDecl>(Context))
363 Namespaces.push_back(ND->getName().str());
364 }
365 std::reverse(Namespaces.begin(), Namespaces.end());
366 return Namespaces;
367}
368
369clang::tooling::Replacements
370createInsertedReplacements(const std::vector<std::string> &Includes,
371 const std::vector<const NamedDecl *> &Decls,
372 llvm::StringRef FileName, bool IsHeader = false,
373 StringRef OldHeaderInclude = "") {
374 std::string NewCode;
375 std::string GuardName(FileName);
376 if (IsHeader) {
377 for (size_t i = 0; i < GuardName.size(); ++i) {
378 if (!isAlphanumeric(GuardName[i]))
379 GuardName[i] = '_';
380 }
381 GuardName = StringRef(GuardName).upper();
382 NewCode += "#ifndef " + GuardName + "\n";
383 NewCode += "#define " + GuardName + "\n\n";
384 }
385
386 NewCode += OldHeaderInclude;
387 // Add #Includes.
388 for (const auto &Include : Includes)
389 NewCode += Include;
390
391 if (!Includes.empty())
392 NewCode += "\n";
393
394 // Add moved class definition and its related declarations. All declarations
395 // in same namespace are grouped together.
396 //
397 // Record namespaces where the current position is in.
398 std::vector<std::string> CurrentNamespaces;
399 for (const auto *MovedDecl : Decls) {
400 // The namespaces of the declaration being moved.
401 std::vector<std::string> DeclNamespaces = getNamespaces(MovedDecl);
402 auto CurrentIt = CurrentNamespaces.begin();
403 auto DeclIt = DeclNamespaces.begin();
404 // Skip the common prefix.
405 while (CurrentIt != CurrentNamespaces.end() &&
406 DeclIt != DeclNamespaces.end()) {
407 if (*CurrentIt != *DeclIt)
408 break;
409 ++CurrentIt;
410 ++DeclIt;
411 }
412 // Calculate the new namespaces after adding MovedDecl in CurrentNamespace,
413 // which is used for next iteration of this loop.
414 std::vector<std::string> NextNamespaces(CurrentNamespaces.begin(),
415 CurrentIt);
416 NextNamespaces.insert(NextNamespaces.end(), DeclIt, DeclNamespaces.end());
417
418
419 // End with CurrentNamespace.
420 bool HasEndCurrentNamespace = false;
421 auto RemainingSize = CurrentNamespaces.end() - CurrentIt;
422 for (auto It = CurrentNamespaces.rbegin(); RemainingSize > 0;
423 --RemainingSize, ++It) {
424 assert(It < CurrentNamespaces.rend())(static_cast <bool> (It < CurrentNamespaces.rend()) ?
void (0) : __assert_fail ("It < CurrentNamespaces.rend()"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/tools/extra/clang-move/ClangMove.cpp"
, 424, __extension__ __PRETTY_FUNCTION__))
;
425 NewCode += "} // namespace " + *It + "\n";
426 HasEndCurrentNamespace = true;
427 }
428 // Add trailing '\n' after the nested namespace definition.
429 if (HasEndCurrentNamespace)
430 NewCode += "\n";
431
432 // If the moved declaration is not in CurrentNamespace, add extra namespace
433 // definitions.
434 bool IsInNewNamespace = false;
435 while (DeclIt != DeclNamespaces.end()) {
436 NewCode += "namespace " + *DeclIt + " {\n";
437 IsInNewNamespace = true;
438 ++DeclIt;
439 }
440 // If the moved declaration is in same namespace CurrentNamespace, add
441 // a preceeding `\n' before the moved declaration.
442 // FIXME: Don't add empty lines between using declarations.
443 if (!IsInNewNamespace)
444 NewCode += "\n";
445 NewCode += getDeclarationSourceText(MovedDecl);
446 CurrentNamespaces = std::move(NextNamespaces);
447 }
448 std::reverse(CurrentNamespaces.begin(), CurrentNamespaces.end());
449 for (const auto &NS : CurrentNamespaces)
450 NewCode += "} // namespace " + NS + "\n";
451
452 if (IsHeader)
453 NewCode += "\n#endif // " + GuardName + "\n";
454 return clang::tooling::Replacements(
455 clang::tooling::Replacement(FileName, 0, 0, NewCode));
456}
457
458// Return a set of all decls which are used/referenced by the given Decls.
459// Specically, given a class member declaration, this method will return all
460// decls which are used by the whole class.
461llvm::DenseSet<const Decl *>
462getUsedDecls(const HelperDeclRefGraph *RG,
463 const std::vector<const NamedDecl *> &Decls) {
464 assert(RG)(static_cast <bool> (RG) ? void (0) : __assert_fail ("RG"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/tools/extra/clang-move/ClangMove.cpp"
, 464, __extension__ __PRETTY_FUNCTION__))
;
465 llvm::DenseSet<const CallGraphNode *> Nodes;
466 for (const auto *D : Decls) {
467 auto Result = RG->getReachableNodes(
468 HelperDeclRGBuilder::getOutmostClassOrFunDecl(D));
469 Nodes.insert(Result.begin(), Result.end());
470 }
471 llvm::DenseSet<const Decl *> Results;
472 for (const auto *Node : Nodes)
473 Results.insert(Node->getDecl());
474 return Results;
475}
476
477} // namespace
478
479std::unique_ptr<clang::ASTConsumer>
480ClangMoveAction::CreateASTConsumer(clang::CompilerInstance &Compiler,
481 StringRef /*InFile*/) {
482 Compiler.getPreprocessor().addPPCallbacks(llvm::make_unique<FindAllIncludes>(
483 &Compiler.getSourceManager(), &MoveTool));
484 return MatchFinder.newASTConsumer();
485}
486
487ClangMoveTool::ClangMoveTool(ClangMoveContext *const Context,
488 DeclarationReporter *const Reporter)
489 : Context(Context), Reporter(Reporter) {
490 if (!Context->Spec.NewHeader.empty())
491 CCIncludes.push_back("#include \"" + Context->Spec.NewHeader + "\"\n");
492}
493
494void ClangMoveTool::addRemovedDecl(const NamedDecl *Decl) {
495 const auto &SM = Decl->getASTContext().getSourceManager();
496 auto Loc = Decl->getLocation();
497 StringRef FilePath = SM.getFilename(Loc);
498 FilePathToFileID[FilePath] = SM.getFileID(Loc);
499 RemovedDecls.push_back(Decl);
500}
501
502void ClangMoveTool::registerMatchers(ast_matchers::MatchFinder *Finder) {
503 auto InOldHeader =
504 isExpansionInFile(makeAbsolutePath(Context->Spec.OldHeader));
505 auto InOldCC = isExpansionInFile(makeAbsolutePath(Context->Spec.OldCC));
506 auto InOldFiles = anyOf(InOldHeader, InOldCC);
507 auto classTemplateForwardDecls =
508 classTemplateDecl(unless(has(cxxRecordDecl(isDefinition()))));
509 auto ForwardClassDecls = namedDecl(
510 anyOf(cxxRecordDecl(unless(anyOf(isImplicit(), isDefinition()))),
511 classTemplateForwardDecls));
512 auto TopLevelDecl =
513 hasDeclContext(anyOf(namespaceDecl(), translationUnitDecl()));
514
515 //============================================================================
516 // Matchers for old header
517 //============================================================================
518 // Match all top-level named declarations (e.g. function, variable, enum) in
519 // old header, exclude forward class declarations and namespace declarations.
520 //
521 // We consider declarations inside a class belongs to the class. So these
522 // declarations will be ignored.
523 auto AllDeclsInHeader = namedDecl(
524 unless(ForwardClassDecls), unless(namespaceDecl()),
525 unless(usingDirectiveDecl()), // using namespace decl.
526 notInMacro(),
527 InOldHeader,
528 hasParent(decl(anyOf(namespaceDecl(), translationUnitDecl()))),
529 hasDeclContext(decl(anyOf(namespaceDecl(), translationUnitDecl()))));
530 Finder->addMatcher(AllDeclsInHeader.bind("decls_in_header"), this);
531
532 // Don't register other matchers when dumping all declarations in header.
533 if (Context->DumpDeclarations)
1
Assuming the condition is false
2
Taking false branch
534 return;
535
536 // Match forward declarations in old header.
537 Finder->addMatcher(namedDecl(ForwardClassDecls, InOldHeader).bind("fwd_decl"),
538 this);
539
540 //============================================================================
541 // Matchers for old cc
542 //============================================================================
543 auto IsOldCCTopLevelDecl = allOf(
544 hasParent(decl(anyOf(namespaceDecl(), translationUnitDecl()))), InOldCC);
545 // Matching using decls/type alias decls which are in named/anonymous/global
546 // namespace, these decls are always copied to new.h/cc. Those in classes,
547 // functions are covered in other matchers.
548 Finder->addMatcher(namedDecl(anyOf(usingDecl(IsOldCCTopLevelDecl),
549 usingDirectiveDecl(IsOldCCTopLevelDecl),
550 typeAliasDecl(IsOldCCTopLevelDecl)),
551 notInMacro())
552 .bind("using_decl"),
553 this);
554
555 // Match static functions/variable definitions which are defined in named
556 // namespaces.
557 Optional<ast_matchers::internal::Matcher<NamedDecl>> HasAnySymbolNames;
558 for (StringRef SymbolName : Context->Spec.Names) {
3
Assuming '__begin2' is not equal to '__end2'
559 llvm::StringRef GlobalSymbolName = SymbolName.trim().ltrim(':');
560 const auto HasName = hasName(("::" + GlobalSymbolName).str());
4
Calling 'hasName'
6
Returned allocated memory
561 HasAnySymbolNames =
562 HasAnySymbolNames ? anyOf(*HasAnySymbolNames, HasName) : HasName;
7
'?' condition is false
24
'?' condition is true
25
Calling 'VariadicOperatorMatcher::operator Matcher'
563 }
8
Calling implicit destructor for 'Matcher'
9
Calling implicit destructor for 'DynTypedMatcher'
10
Calling '~IntrusiveRefCntPtr'
21
Returning from '~IntrusiveRefCntPtr'
22
Returning from destructor for 'DynTypedMatcher'
23
Returning from destructor for 'Matcher'
564
565 if (!HasAnySymbolNames) {
566 llvm::errs() << "No symbols being moved.\n";
567 return;
568 }
569 auto InMovedClass =
570 hasOutermostEnclosingClass(cxxRecordDecl(*HasAnySymbolNames));
571
572 // Matchers for helper declarations in old.cc.
573 auto InAnonymousNS = hasParent(namespaceDecl(isAnonymous()));
574 auto NotInMovedClass= allOf(unless(InMovedClass), InOldCC);
575 auto IsOldCCHelper =
576 allOf(NotInMovedClass, anyOf(isStaticStorageClass(), InAnonymousNS));
577 // Match helper classes separately with helper functions/variables since we
578 // want to reuse these matchers in finding helpers usage below.
579 //
580 // There could be forward declarations usage for helpers, especially for
581 // classes and functions. We need include these forward declarations.
582 //
583 // Forward declarations for variable helpers will be excluded as these
584 // declarations (with "extern") are not supposed in cpp file.
585 auto HelperFuncOrVar =
586 namedDecl(notInMacro(), anyOf(functionDecl(IsOldCCHelper),
587 varDecl(isDefinition(), IsOldCCHelper)));
588 auto HelperClasses =
589 cxxRecordDecl(notInMacro(), NotInMovedClass, InAnonymousNS);
590 // Save all helper declarations in old.cc.
591 Finder->addMatcher(
592 namedDecl(anyOf(HelperFuncOrVar, HelperClasses)).bind("helper_decls"),
593 this);
594
595 // Construct an AST-based call graph of helper declarations in old.cc.
596 // In the following matcheres, "dc" is a caller while "helper_decls" and
597 // "used_class" is a callee, so a new edge starting from caller to callee will
598 // be add in the graph.
599 //
600 // Find helper function/variable usages.
601 Finder->addMatcher(
602 declRefExpr(to(HelperFuncOrVar), hasAncestor(decl().bind("dc")))
603 .bind("func_ref"),
604 &RGBuilder);
605 // Find helper class usages.
606 Finder->addMatcher(
607 typeLoc(loc(recordType(hasDeclaration(HelperClasses.bind("used_class")))),
608 hasAncestor(decl().bind("dc"))),
609 &RGBuilder);
610
611 //============================================================================
612 // Matchers for old files, including old.h/old.cc
613 //============================================================================
614 // Create a MatchCallback for class declarations.
615 MatchCallbacks.push_back(llvm::make_unique<ClassDeclarationMatch>(this));
616 // Match moved class declarations.
617 auto MovedClass = cxxRecordDecl(InOldFiles, *HasAnySymbolNames,
618 isDefinition(), TopLevelDecl)
619 .bind("moved_class");
620 Finder->addMatcher(MovedClass, MatchCallbacks.back().get());
621 // Match moved class methods (static methods included) which are defined
622 // outside moved class declaration.
623 Finder->addMatcher(
624 cxxMethodDecl(InOldFiles, ofOutermostEnclosingClass(*HasAnySymbolNames),
625 isDefinition())
626 .bind("class_method"),
627 MatchCallbacks.back().get());
628 // Match static member variable definition of the moved class.
629 Finder->addMatcher(
630 varDecl(InMovedClass, InOldFiles, isDefinition(), isStaticDataMember())
631 .bind("class_static_var_decl"),
632 MatchCallbacks.back().get());
633
634 MatchCallbacks.push_back(llvm::make_unique<FunctionDeclarationMatch>(this));
635 Finder->addMatcher(functionDecl(InOldFiles, *HasAnySymbolNames, TopLevelDecl)
636 .bind("function"),
637 MatchCallbacks.back().get());
638
639 MatchCallbacks.push_back(llvm::make_unique<VarDeclarationMatch>(this));
640 Finder->addMatcher(
641 varDecl(InOldFiles, *HasAnySymbolNames, TopLevelDecl).bind("var"),
642 MatchCallbacks.back().get());
643
644 // Match enum definition in old.h. Enum helpers (which are defined in old.cc)
645 // will not be moved for now no matter whether they are used or not.
646 MatchCallbacks.push_back(llvm::make_unique<EnumDeclarationMatch>(this));
647 Finder->addMatcher(
648 enumDecl(InOldHeader, *HasAnySymbolNames, isDefinition(), TopLevelDecl)
649 .bind("enum"),
650 MatchCallbacks.back().get());
651
652 // Match type alias in old.h, this includes "typedef" and "using" type alias
653 // declarations. Type alias helpers (which are defined in old.cc) will not be
654 // moved for now no matter whether they are used or not.
655 MatchCallbacks.push_back(llvm::make_unique<TypeAliasMatch>(this));
656 Finder->addMatcher(namedDecl(anyOf(typedefDecl().bind("typedef"),
657 typeAliasDecl().bind("type_alias")),
658 InOldHeader, *HasAnySymbolNames, TopLevelDecl),
659 MatchCallbacks.back().get());
660}
661
662void ClangMoveTool::run(const ast_matchers::MatchFinder::MatchResult &Result) {
663 if (const auto *D =
664 Result.Nodes.getNodeAs<clang::NamedDecl>("decls_in_header")) {
665 UnremovedDeclsInOldHeader.insert(D);
666 } else if (const auto *FWD =
667 Result.Nodes.getNodeAs<clang::CXXRecordDecl>("fwd_decl")) {
668 // Skip all forward declarations which appear after moved class declaration.
669 if (RemovedDecls.empty()) {
670 if (const auto *DCT = FWD->getDescribedClassTemplate())
671 MovedDecls.push_back(DCT);
672 else
673 MovedDecls.push_back(FWD);
674 }
675 } else if (const auto *ND =
676 Result.Nodes.getNodeAs<clang::NamedDecl>("helper_decls")) {
677 MovedDecls.push_back(ND);
678 HelperDeclarations.push_back(ND);
679 DEBUG(llvm::dbgs() << "Add helper : "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("clang-move")) { llvm::dbgs() << "Add helper : " <<
ND->getNameAsString() << " (" << ND << ")\n"
; } } while (false)
680 << ND->getNameAsString() << " (" << ND << ")\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("clang-move")) { llvm::dbgs() << "Add helper : " <<
ND->getNameAsString() << " (" << ND << ")\n"
; } } while (false)
;
681 } else if (const auto *UD =
682 Result.Nodes.getNodeAs<clang::NamedDecl>("using_decl")) {
683 MovedDecls.push_back(UD);
684 }
685}
686
687std::string ClangMoveTool::makeAbsolutePath(StringRef Path) {
688 return MakeAbsolutePath(Context->OriginalRunningDirectory, Path);
689}
690
691void ClangMoveTool::addIncludes(llvm::StringRef IncludeHeader, bool IsAngled,
692 llvm::StringRef SearchPath,
693 llvm::StringRef FileName,
694 clang::CharSourceRange IncludeFilenameRange,
695 const SourceManager &SM) {
696 SmallVector<char, 128> HeaderWithSearchPath;
697 llvm::sys::path::append(HeaderWithSearchPath, SearchPath, IncludeHeader);
698 std::string AbsoluteIncludeHeader =
699 MakeAbsolutePath(SM, llvm::StringRef(HeaderWithSearchPath.data(),
700 HeaderWithSearchPath.size()));
701 std::string IncludeLine =
702 IsAngled ? ("#include <" + IncludeHeader + ">\n").str()
703 : ("#include \"" + IncludeHeader + "\"\n").str();
704
705 std::string AbsoluteOldHeader = makeAbsolutePath(Context->Spec.OldHeader);
706 std::string AbsoluteCurrentFile = MakeAbsolutePath(SM, FileName);
707 if (AbsoluteOldHeader == AbsoluteCurrentFile) {
708 // Find old.h includes "old.h".
709 if (AbsoluteOldHeader == AbsoluteIncludeHeader) {
710 OldHeaderIncludeRangeInHeader = IncludeFilenameRange;
711 return;
712 }
713 HeaderIncludes.push_back(IncludeLine);
714 } else if (makeAbsolutePath(Context->Spec.OldCC) == AbsoluteCurrentFile) {
715 // Find old.cc includes "old.h".
716 if (AbsoluteOldHeader == AbsoluteIncludeHeader) {
717 OldHeaderIncludeRangeInCC = IncludeFilenameRange;
718 return;
719 }
720 CCIncludes.push_back(IncludeLine);
721 }
722}
723
724void ClangMoveTool::removeDeclsInOldFiles() {
725 if (RemovedDecls.empty()) return;
726
727 // If old_header is not specified (only move declarations from old.cc), remain
728 // all the helper function declarations in old.cc as UnremovedDeclsInOldHeader
729 // is empty in this case, there is no way to verify unused/used helpers.
730 if (!Context->Spec.OldHeader.empty()) {
731 std::vector<const NamedDecl *> UnremovedDecls;
732 for (const auto *D : UnremovedDeclsInOldHeader)
733 UnremovedDecls.push_back(D);
734
735 auto UsedDecls = getUsedDecls(RGBuilder.getGraph(), UnremovedDecls);
736
737 // We remove the helper declarations which are not used in the old.cc after
738 // moving the given declarations.
739 for (const auto *D : HelperDeclarations) {
740 DEBUG(llvm::dbgs() << "Check helper is used: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("clang-move")) { llvm::dbgs() << "Check helper is used: "
<< D->getNameAsString() << " (" << D <<
")\n"; } } while (false)
741 << D->getNameAsString() << " (" << D << ")\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("clang-move")) { llvm::dbgs() << "Check helper is used: "
<< D->getNameAsString() << " (" << D <<
")\n"; } } while (false)
;
742 if (!UsedDecls.count(HelperDeclRGBuilder::getOutmostClassOrFunDecl(
743 D->getCanonicalDecl()))) {
744 DEBUG(llvm::dbgs() << "Helper removed in old.cc: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("clang-move")) { llvm::dbgs() << "Helper removed in old.cc: "
<< D->getNameAsString() << " (" << D <<
")\n"; } } while (false)
745 << D->getNameAsString() << " (" << D << ")\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("clang-move")) { llvm::dbgs() << "Helper removed in old.cc: "
<< D->getNameAsString() << " (" << D <<
")\n"; } } while (false)
;
746 RemovedDecls.push_back(D);
747 }
748 }
749 }
750
751 for (const auto *RemovedDecl : RemovedDecls) {
752 const auto &SM = RemovedDecl->getASTContext().getSourceManager();
753 auto Range = getFullRange(RemovedDecl);
754 clang::tooling::Replacement RemoveReplacement(
755 SM,
756 clang::CharSourceRange::getCharRange(Range.getBegin(), Range.getEnd()),
757 "");
758 std::string FilePath = RemoveReplacement.getFilePath().str();
759 auto Err = Context->FileToReplacements[FilePath].add(RemoveReplacement);
760 if (Err)
761 llvm::errs() << llvm::toString(std::move(Err)) << "\n";
762 }
763 const auto &SM = RemovedDecls[0]->getASTContext().getSourceManager();
764
765 // Post process of cleanup around all the replacements.
766 for (auto &FileAndReplacements : Context->FileToReplacements) {
767 StringRef FilePath = FileAndReplacements.first;
768 // Add #include of new header to old header.
769 if (Context->Spec.OldDependOnNew &&
770 MakeAbsolutePath(SM, FilePath) ==
771 makeAbsolutePath(Context->Spec.OldHeader)) {
772 // FIXME: Minimize the include path like include-fixer.
773 std::string IncludeNewH =
774 "#include \"" + Context->Spec.NewHeader + "\"\n";
775 // This replacment for inserting header will be cleaned up at the end.
776 auto Err = FileAndReplacements.second.add(
777 tooling::Replacement(FilePath, UINT_MAX(2147483647 *2U +1U), 0, IncludeNewH));
778 if (Err)
779 llvm::errs() << llvm::toString(std::move(Err)) << "\n";
780 }
781
782 auto SI = FilePathToFileID.find(FilePath);
783 // Ignore replacements for new.h/cc.
784 if (SI == FilePathToFileID.end()) continue;
785 llvm::StringRef Code = SM.getBufferData(SI->second);
786 auto Style = format::getStyle("file", FilePath, Context->FallbackStyle);
787 if (!Style) {
788 llvm::errs() << llvm::toString(Style.takeError()) << "\n";
789 continue;
790 }
791 auto CleanReplacements = format::cleanupAroundReplacements(
792 Code, Context->FileToReplacements[FilePath], *Style);
793
794 if (!CleanReplacements) {
795 llvm::errs() << llvm::toString(CleanReplacements.takeError()) << "\n";
796 continue;
797 }
798 Context->FileToReplacements[FilePath] = *CleanReplacements;
799 }
800}
801
802void ClangMoveTool::moveDeclsToNewFiles() {
803 std::vector<const NamedDecl *> NewHeaderDecls;
804 std::vector<const NamedDecl *> NewCCDecls;
805 for (const auto *MovedDecl : MovedDecls) {
806 if (isInHeaderFile(MovedDecl, Context->OriginalRunningDirectory,
807 Context->Spec.OldHeader))
808 NewHeaderDecls.push_back(MovedDecl);
809 else
810 NewCCDecls.push_back(MovedDecl);
811 }
812
813 auto UsedDecls = getUsedDecls(RGBuilder.getGraph(), RemovedDecls);
814 std::vector<const NamedDecl *> ActualNewCCDecls;
815
816 // Filter out all unused helpers in NewCCDecls.
817 // We only move the used helpers (including transively used helpers) and the
818 // given symbols being moved.
819 for (const auto *D : NewCCDecls) {
820 if (llvm::is_contained(HelperDeclarations, D) &&
821 !UsedDecls.count(HelperDeclRGBuilder::getOutmostClassOrFunDecl(
822 D->getCanonicalDecl())))
823 continue;
824
825 DEBUG(llvm::dbgs() << "Helper used in new.cc: " << D->getNameAsString()do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("clang-move")) { llvm::dbgs() << "Helper used in new.cc: "
<< D->getNameAsString() << " " << D <<
"\n"; } } while (false)
826 << " " << D << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("clang-move")) { llvm::dbgs() << "Helper used in new.cc: "
<< D->getNameAsString() << " " << D <<
"\n"; } } while (false)
;
827 ActualNewCCDecls.push_back(D);
828 }
829
830 if (!Context->Spec.NewHeader.empty()) {
831 std::string OldHeaderInclude =
832 Context->Spec.NewDependOnOld
833 ? "#include \"" + Context->Spec.OldHeader + "\"\n"
834 : "";
835 Context->FileToReplacements[Context->Spec.NewHeader] =
836 createInsertedReplacements(HeaderIncludes, NewHeaderDecls,
837 Context->Spec.NewHeader, /*IsHeader=*/true,
838 OldHeaderInclude);
839 }
840 if (!Context->Spec.NewCC.empty())
841 Context->FileToReplacements[Context->Spec.NewCC] =
842 createInsertedReplacements(CCIncludes, ActualNewCCDecls,
843 Context->Spec.NewCC);
844}
845
846// Move all contents from OldFile to NewFile.
847void ClangMoveTool::moveAll(SourceManager &SM, StringRef OldFile,
848 StringRef NewFile) {
849 const FileEntry *FE = SM.getFileManager().getFile(makeAbsolutePath(OldFile));
850 if (!FE) {
851 llvm::errs() << "Failed to get file: " << OldFile << "\n";
852 return;
853 }
854 FileID ID = SM.getOrCreateFileID(FE, SrcMgr::C_User);
855 auto Begin = SM.getLocForStartOfFile(ID);
856 auto End = SM.getLocForEndOfFile(ID);
857 clang::tooling::Replacement RemoveAll (
858 SM, clang::CharSourceRange::getCharRange(Begin, End), "");
859 std::string FilePath = RemoveAll.getFilePath().str();
860 Context->FileToReplacements[FilePath] =
861 clang::tooling::Replacements(RemoveAll);
862
863 StringRef Code = SM.getBufferData(ID);
864 if (!NewFile.empty()) {
865 auto AllCode = clang::tooling::Replacements(
866 clang::tooling::Replacement(NewFile, 0, 0, Code));
867 auto ReplaceOldInclude = [&](clang::CharSourceRange OldHeaderIncludeRange) {
868 AllCode = AllCode.merge(clang::tooling::Replacements(
869 clang::tooling::Replacement(SM, OldHeaderIncludeRange,
870 '"' + Context->Spec.NewHeader + '"')));
871 };
872 // Fix the case where old.h/old.cc includes "old.h", we replace the
873 // `#include "old.h"` with `#include "new.h"`.
874 if (Context->Spec.NewCC == NewFile && OldHeaderIncludeRangeInCC.isValid())
875 ReplaceOldInclude(OldHeaderIncludeRangeInCC);
876 else if (Context->Spec.NewHeader == NewFile &&
877 OldHeaderIncludeRangeInHeader.isValid())
878 ReplaceOldInclude(OldHeaderIncludeRangeInHeader);
879 Context->FileToReplacements[NewFile] = std::move(AllCode);
880 }
881}
882
883void ClangMoveTool::onEndOfTranslationUnit() {
884 if (Context->DumpDeclarations) {
885 assert(Reporter)(static_cast <bool> (Reporter) ? void (0) : __assert_fail
("Reporter", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/tools/extra/clang-move/ClangMove.cpp"
, 885, __extension__ __PRETTY_FUNCTION__))
;
886 for (const auto *Decl : UnremovedDeclsInOldHeader) {
887 auto Kind = Decl->getKind();
888 const std::string QualifiedName = Decl->getQualifiedNameAsString();
889 if (Kind == Decl::Kind::Var)
890 Reporter->reportDeclaration(QualifiedName, "Variable");
891 else if (Kind == Decl::Kind::Function ||
892 Kind == Decl::Kind::FunctionTemplate)
893 Reporter->reportDeclaration(QualifiedName, "Function");
894 else if (Kind == Decl::Kind::ClassTemplate ||
895 Kind == Decl::Kind::CXXRecord)
896 Reporter->reportDeclaration(QualifiedName, "Class");
897 else if (Kind == Decl::Kind::Enum)
898 Reporter->reportDeclaration(QualifiedName, "Enum");
899 else if (Kind == Decl::Kind::Typedef ||
900 Kind == Decl::Kind::TypeAlias ||
901 Kind == Decl::Kind::TypeAliasTemplate)
902 Reporter->reportDeclaration(QualifiedName, "TypeAlias");
903 }
904 return;
905 }
906
907 if (RemovedDecls.empty())
908 return;
909 // Ignore symbols that are not supported when checking if there is unremoved
910 // symbol in old header. This makes sure that we always move old files to new
911 // files when all symbols produced from dump_decls are moved.
912 auto IsSupportedKind = [](const clang::NamedDecl *Decl) {
913 switch (Decl->getKind()) {
914 case Decl::Kind::Function:
915 case Decl::Kind::FunctionTemplate:
916 case Decl::Kind::ClassTemplate:
917 case Decl::Kind::CXXRecord:
918 case Decl::Kind::Enum:
919 case Decl::Kind::Typedef:
920 case Decl::Kind::TypeAlias:
921 case Decl::Kind::TypeAliasTemplate:
922 case Decl::Kind::Var:
923 return true;
924 default:
925 return false;
926 }
927 };
928 if (std::none_of(UnremovedDeclsInOldHeader.begin(),
929 UnremovedDeclsInOldHeader.end(), IsSupportedKind) &&
930 !Context->Spec.OldHeader.empty()) {
931 auto &SM = RemovedDecls[0]->getASTContext().getSourceManager();
932 moveAll(SM, Context->Spec.OldHeader, Context->Spec.NewHeader);
933 moveAll(SM, Context->Spec.OldCC, Context->Spec.NewCC);
934 return;
935 }
936 DEBUG(RGBuilder.getGraph()->dump())do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("clang-move")) { RGBuilder.getGraph()->dump(); } } while (
false)
;
937 moveDeclsToNewFiles();
938 removeDeclsInOldFiles();
939}
940
941} // namespace move
942} // namespace clang

/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/include/clang/ASTMatchers/ASTMatchers.h

1//===- ASTMatchers.h - Structural query framework ---------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements matchers to be used together with the MatchFinder to
11// match AST nodes.
12//
13// Matchers are created by generator functions, which can be combined in
14// a functional in-language DSL to express queries over the C++ AST.
15//
16// For example, to match a class with a certain name, one would call:
17// cxxRecordDecl(hasName("MyClass"))
18// which returns a matcher that can be used to find all AST nodes that declare
19// a class named 'MyClass'.
20//
21// For more complicated match expressions we're often interested in accessing
22// multiple parts of the matched AST nodes once a match is found. In that case,
23// use the id(...) matcher around the match expressions that match the nodes
24// you want to access.
25//
26// For example, when we're interested in child classes of a certain class, we
27// would write:
28// cxxRecordDecl(hasName("MyClass"), has(id("child", recordDecl())))
29// When the match is found via the MatchFinder, a user provided callback will
30// be called with a BoundNodes instance that contains a mapping from the
31// strings that we provided for the id(...) calls to the nodes that were
32// matched.
33// In the given example, each time our matcher finds a match we get a callback
34// where "child" is bound to the RecordDecl node of the matching child
35// class declaration.
36//
37// See ASTMatchersInternal.h for a more in-depth explanation of the
38// implementation details of the matcher framework.
39//
40// See ASTMatchFinder.h for how to use the generated matchers to run over
41// an AST.
42//
43//===----------------------------------------------------------------------===//
44
45#ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERS_H
46#define LLVM_CLANG_ASTMATCHERS_ASTMATCHERS_H
47
48#include "clang/AST/ASTContext.h"
49#include "clang/AST/ASTTypeTraits.h"
50#include "clang/AST/Attr.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/NestedNameSpecifier.h"
60#include "clang/AST/OperationKinds.h"
61#include "clang/AST/Stmt.h"
62#include "clang/AST/StmtCXX.h"
63#include "clang/AST/StmtObjC.h"
64#include "clang/AST/TemplateBase.h"
65#include "clang/AST/TemplateName.h"
66#include "clang/AST/Type.h"
67#include "clang/AST/TypeLoc.h"
68#include "clang/ASTMatchers/ASTMatchersInternal.h"
69#include "clang/ASTMatchers/ASTMatchersMacros.h"
70#include "clang/Basic/AttrKinds.h"
71#include "clang/Basic/ExceptionSpecificationType.h"
72#include "clang/Basic/IdentifierTable.h"
73#include "clang/Basic/LLVM.h"
74#include "clang/Basic/SourceManager.h"
75#include "clang/Basic/Specifiers.h"
76#include "clang/Basic/TypeTraits.h"
77#include "llvm/ADT/ArrayRef.h"
78#include "llvm/ADT/SmallVector.h"
79#include "llvm/ADT/StringRef.h"
80#include "llvm/Support/Casting.h"
81#include "llvm/Support/Compiler.h"
82#include "llvm/Support/ErrorHandling.h"
83#include "llvm/Support/Regex.h"
84#include <cassert>
85#include <cstddef>
86#include <iterator>
87#include <limits>
88#include <string>
89#include <utility>
90#include <vector>
91
92namespace clang {
93namespace ast_matchers {
94
95/// \brief Maps string IDs to AST nodes matched by parts of a matcher.
96///
97/// The bound nodes are generated by calling \c bind("id") on the node matchers
98/// of the nodes we want to access later.
99///
100/// The instances of BoundNodes are created by \c MatchFinder when the user's
101/// callbacks are executed every time a match is found.
102class BoundNodes {
103public:
104 /// \brief Returns the AST node bound to \c ID.
105 ///
106 /// Returns NULL if there was no node bound to \c ID or if there is a node but
107 /// it cannot be converted to the specified type.
108 template <typename T>
109 const T *getNodeAs(StringRef ID) const {
110 return MyBoundNodes.getNodeAs<T>(ID);
111 }
112
113 /// \brief Type of mapping from binding identifiers to bound nodes. This type
114 /// is an associative container with a key type of \c std::string and a value
115 /// type of \c clang::ast_type_traits::DynTypedNode
116 using IDToNodeMap = internal::BoundNodesMap::IDToNodeMap;
117
118 /// \brief Retrieve mapping from binding identifiers to bound nodes.
119 const IDToNodeMap &getMap() const {
120 return MyBoundNodes.getMap();
121 }
122
123private:
124 friend class internal::BoundNodesTreeBuilder;
125
126 /// \brief Create BoundNodes from a pre-filled map of bindings.
127 BoundNodes(internal::BoundNodesMap &MyBoundNodes)
128 : MyBoundNodes(MyBoundNodes) {}
129
130 internal::BoundNodesMap MyBoundNodes;
131};
132
133/// \brief If the provided matcher matches a node, binds the node to \c ID.
134///
135/// FIXME: Do we want to support this now that we have bind()?
136template <typename T>
137internal::Matcher<T> id(StringRef ID,
138 const internal::BindableMatcher<T> &InnerMatcher) {
139 return InnerMatcher.bind(ID);
140}
141
142/// \brief Types of matchers for the top-level classes in the AST class
143/// hierarchy.
144/// @{
145using DeclarationMatcher = internal::Matcher<Decl>;
146using StatementMatcher = internal::Matcher<Stmt>;
147using TypeMatcher = internal::Matcher<QualType>;
148using TypeLocMatcher = internal::Matcher<TypeLoc>;
149using NestedNameSpecifierMatcher = internal::Matcher<NestedNameSpecifier>;
150using NestedNameSpecifierLocMatcher = internal::Matcher<NestedNameSpecifierLoc>;
151using CXXCtorInitializerMatcher = internal::Matcher<CXXCtorInitializer>;
152/// @}
153
154/// \brief Matches any node.
155///
156/// Useful when another matcher requires a child matcher, but there's no
157/// additional constraint. This will often be used with an explicit conversion
158/// to an \c internal::Matcher<> type such as \c TypeMatcher.
159///
160/// Example: \c DeclarationMatcher(anything()) matches all declarations, e.g.,
161/// \code
162/// "int* p" and "void f()" in
163/// int* p;
164/// void f();
165/// \endcode
166///
167/// Usable as: Any Matcher
168inline internal::TrueMatcher anything() { return internal::TrueMatcher(); }
169
170/// \brief Matches the top declaration context.
171///
172/// Given
173/// \code
174/// int X;
175/// namespace NS {
176/// int Y;
177/// } // namespace NS
178/// \endcode
179/// decl(hasDeclContext(translationUnitDecl()))
180/// matches "int X", but not "int Y".
181extern const internal::VariadicDynCastAllOfMatcher<Decl, TranslationUnitDecl>
182 translationUnitDecl;
183
184/// \brief Matches typedef declarations.
185///
186/// Given
187/// \code
188/// typedef int X;
189/// using Y = int;
190/// \endcode
191/// typedefDecl()
192/// matches "typedef int X", but not "using Y = int"
193extern const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl>
194 typedefDecl;
195
196/// \brief Matches typedef name declarations.
197///
198/// Given
199/// \code
200/// typedef int X;
201/// using Y = int;
202/// \endcode
203/// typedefNameDecl()
204/// matches "typedef int X" and "using Y = int"
205extern const internal::VariadicDynCastAllOfMatcher<Decl, TypedefNameDecl>
206 typedefNameDecl;
207
208/// \brief Matches type alias declarations.
209///
210/// Given
211/// \code
212/// typedef int X;
213/// using Y = int;
214/// \endcode
215/// typeAliasDecl()
216/// matches "using Y = int", but not "typedef int X"
217extern const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasDecl>
218 typeAliasDecl;
219
220/// \brief Matches type alias template declarations.
221///
222/// typeAliasTemplateDecl() matches
223/// \code
224/// template <typename T>
225/// using Y = X<T>;
226/// \endcode
227extern const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasTemplateDecl>
228 typeAliasTemplateDecl;
229
230/// \brief Matches AST nodes that were expanded within the main-file.
231///
232/// Example matches X but not Y
233/// (matcher = cxxRecordDecl(isExpansionInMainFile())
234/// \code
235/// #include <Y.h>
236/// class X {};
237/// \endcode
238/// Y.h:
239/// \code
240/// class Y {};
241/// \endcode
242///
243/// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
244AST_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::PolymorphicMatcherWithParam0< internal::matcher_isExpansionInMainFileMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>)> isExpansionInMainFile() { return ::clang::
ast_matchers::internal::PolymorphicMatcherWithParam0< 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
245 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::PolymorphicMatcherWithParam0< internal::matcher_isExpansionInMainFileMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>)> isExpansionInMainFile() { return ::clang::
ast_matchers::internal::PolymorphicMatcherWithParam0< 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 auto &SourceManager = Finder->getASTContext().getSourceManager();
247 return SourceManager.isInMainFile(
248 SourceManager.getExpansionLoc(Node.getLocStart()));
249}
250
251/// \brief Matches AST nodes that were expanded within system-header-files.
252///
253/// Example matches Y but not X
254/// (matcher = cxxRecordDecl(isExpansionInSystemHeader())
255/// \code
256/// #include <SystemHeader.h>
257/// class X {};
258/// \endcode
259/// SystemHeader.h:
260/// \code
261/// class Y {};
262/// \endcode
263///
264/// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
265AST_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::PolymorphicMatcherWithParam0< internal::matcher_isExpansionInSystemHeaderMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>)> isExpansionInSystemHeader() { return ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam0< 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
266 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::PolymorphicMatcherWithParam0< internal::matcher_isExpansionInSystemHeaderMatcher
, void(::clang::ast_matchers::internal::TypeList<Decl, Stmt
, TypeLoc>)> isExpansionInSystemHeader() { return ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam0< 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 auto &SourceManager = Finder->getASTContext().getSourceManager();
268 auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getLocStart());
269 if (ExpansionLoc.isInvalid()) {
270 return false;
271 }
272 return SourceManager.isInSystemHeader(ExpansionLoc);
273}
274
275/// \brief Matches AST nodes that were expanded within files whose name is
276/// partially matching a given regex.
277///
278/// Example matches Y but not X
279/// (matcher = cxxRecordDecl(isExpansionInFileMatching("AST.*"))
280/// \code
281/// #include "ASTMatcher.h"
282/// class X {};
283/// \endcode
284/// ASTMatcher.h:
285/// \code
286/// class Y {};
287/// \endcode
288///
289/// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
290AST_POLYMORPHIC_MATCHER_P(isExpansionInFileMatching,namespace internal { template <typename NodeType, typename
ParamT> class matcher_isExpansionInFileMatching0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: explicit matcher_isExpansionInFileMatching0Matcher
( std::string const &ARegExp) : RegExp(ARegExp) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string const RegExp;
}; } inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_isExpansionInFileMatching0Matcher, std
::string, void(::clang::ast_matchers::internal::TypeList<Decl
, Stmt, TypeLoc>)> isExpansionInFileMatching(std::string
const &RegExp) { return ::clang::ast_matchers::internal::
PolymorphicMatcherWithParam1< internal::matcher_isExpansionInFileMatching0Matcher
, std::string, void(::clang::ast_matchers::internal::TypeList
<Decl, Stmt, TypeLoc>)>(RegExp); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_isExpansionInFileMatching0Matcher, std::string, void
(::clang::ast_matchers::internal::TypeList<Decl, Stmt, TypeLoc
>)>(&isExpansionInFileMatching_Type0)( std::string const
&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
291 AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc),namespace internal { template <typename NodeType, typename
ParamT> class matcher_isExpansionInFileMatching0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: explicit matcher_isExpansionInFileMatching0Matcher
( std::string const &ARegExp) : RegExp(ARegExp) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string const RegExp;
}; } inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_isExpansionInFileMatching0Matcher, std
::string, void(::clang::ast_matchers::internal::TypeList<Decl
, Stmt, TypeLoc>)> isExpansionInFileMatching(std::string
const &RegExp) { return ::clang::ast_matchers::internal::
PolymorphicMatcherWithParam1< internal::matcher_isExpansionInFileMatching0Matcher
, std::string, void(::clang::ast_matchers::internal::TypeList
<Decl, Stmt, TypeLoc>)>(RegExp); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_isExpansionInFileMatching0Matcher, std::string, void
(::clang::ast_matchers::internal::TypeList<Decl, Stmt, TypeLoc
>)>(&isExpansionInFileMatching_Type0)( std::string const
&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 std::string, RegExp)namespace internal { template <typename NodeType, typename
ParamT> class matcher_isExpansionInFileMatching0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
NodeType> { public: explicit matcher_isExpansionInFileMatching0Matcher
( std::string const &ARegExp) : RegExp(ARegExp) {} bool matches
(const NodeType &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string const RegExp;
}; } inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_isExpansionInFileMatching0Matcher, std
::string, void(::clang::ast_matchers::internal::TypeList<Decl
, Stmt, TypeLoc>)> isExpansionInFileMatching(std::string
const &RegExp) { return ::clang::ast_matchers::internal::
PolymorphicMatcherWithParam1< internal::matcher_isExpansionInFileMatching0Matcher
, std::string, void(::clang::ast_matchers::internal::TypeList
<Decl, Stmt, TypeLoc>)>(RegExp); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_isExpansionInFileMatching0Matcher, std::string, void
(::clang::ast_matchers::internal::TypeList<Decl, Stmt, TypeLoc
>)>(&isExpansionInFileMatching_Type0)( std::string const
&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 auto &SourceManager = Finder->getASTContext().getSourceManager();
294 auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getLocStart());
295 if (ExpansionLoc.isInvalid()) {
296 return false;
297 }
298 auto FileEntry =
299 SourceManager.getFileEntryForID(SourceManager.getFileID(ExpansionLoc));
300 if (!FileEntry) {
301 return false;
302 }
303
304 auto Filename = FileEntry->getName();
305 llvm::Regex RE(RegExp);
306 return RE.match(Filename);
307}
308
309/// \brief Matches declarations.
310///
311/// Examples matches \c X, \c C, and the friend declaration inside \c C;
312/// \code
313/// void X();
314/// class C {
315/// friend X;
316/// };
317/// \endcode
318extern const internal::VariadicAllOfMatcher<Decl> decl;
319
320/// \brief Matches a declaration of a linkage specification.
321///
322/// Given
323/// \code
324/// extern "C" {}
325/// \endcode
326/// linkageSpecDecl()
327/// matches "extern "C" {}"
328extern const internal::VariadicDynCastAllOfMatcher<Decl, LinkageSpecDecl>
329 linkageSpecDecl;
330
331/// \brief Matches a declaration of anything that could have a name.
332///
333/// Example matches \c X, \c S, the anonymous union type, \c i, and \c U;
334/// \code
335/// typedef int X;
336/// struct S {
337/// union {
338/// int i;
339/// } U;
340/// };
341/// \endcode
342extern const internal::VariadicDynCastAllOfMatcher<Decl, NamedDecl> namedDecl;
343
344/// \brief Matches a declaration of label.
345///
346/// Given
347/// \code
348/// goto FOO;
349/// FOO: bar();
350/// \endcode
351/// labelDecl()
352/// matches 'FOO:'
353extern const internal::VariadicDynCastAllOfMatcher<Decl, LabelDecl> labelDecl;
354
355/// \brief Matches a declaration of a namespace.
356///
357/// Given
358/// \code
359/// namespace {}
360/// namespace test {}
361/// \endcode
362/// namespaceDecl()
363/// matches "namespace {}" and "namespace test {}"
364extern const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceDecl>
365 namespaceDecl;
366
367/// \brief Matches a declaration of a namespace alias.
368///
369/// Given
370/// \code
371/// namespace test {}
372/// namespace alias = ::test;
373/// \endcode
374/// namespaceAliasDecl()
375/// matches "namespace alias" but not "namespace test"
376extern const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceAliasDecl>
377 namespaceAliasDecl;
378
379/// \brief Matches class, struct, and union declarations.
380///
381/// Example matches \c X, \c Z, \c U, and \c S
382/// \code
383/// class X;
384/// template<class T> class Z {};
385/// struct S {};
386/// union U {};
387/// \endcode
388extern const internal::VariadicDynCastAllOfMatcher<Decl, RecordDecl> recordDecl;
389
390/// \brief Matches C++ class declarations.
391///
392/// Example matches \c X, \c Z
393/// \code
394/// class X;
395/// template<class T> class Z {};
396/// \endcode
397extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXRecordDecl>
398 cxxRecordDecl;
399
400/// \brief Matches C++ class template declarations.
401///
402/// Example matches \c Z
403/// \code
404/// template<class T> class Z {};
405/// \endcode
406extern const internal::VariadicDynCastAllOfMatcher<Decl, ClassTemplateDecl>
407 classTemplateDecl;
408
409/// \brief Matches C++ class template specializations.
410///
411/// Given
412/// \code
413/// template<typename T> class A {};
414/// template<> class A<double> {};
415/// A<int> a;
416/// \endcode
417/// classTemplateSpecializationDecl()
418/// matches the specializations \c A<int> and \c A<double>
419extern const internal::VariadicDynCastAllOfMatcher<
420 Decl, ClassTemplateSpecializationDecl>
421 classTemplateSpecializationDecl;
422
423/// \brief Matches declarator declarations (field, variable, function
424/// and non-type template parameter declarations).
425///
426/// Given
427/// \code
428/// class X { int y; };
429/// \endcode
430/// declaratorDecl()
431/// matches \c int y.
432extern const internal::VariadicDynCastAllOfMatcher<Decl, DeclaratorDecl>
433 declaratorDecl;
434
435/// \brief Matches parameter variable declarations.
436///
437/// Given
438/// \code
439/// void f(int x);
440/// \endcode
441/// parmVarDecl()
442/// matches \c int x.
443extern const internal::VariadicDynCastAllOfMatcher<Decl, ParmVarDecl>
444 parmVarDecl;
445
446/// \brief Matches C++ access specifier declarations.
447///
448/// Given
449/// \code
450/// class C {
451/// public:
452/// int a;
453/// };
454/// \endcode
455/// accessSpecDecl()
456/// matches 'public:'
457extern const internal::VariadicDynCastAllOfMatcher<Decl, AccessSpecDecl>
458 accessSpecDecl;
459
460/// \brief Matches constructor initializers.
461///
462/// Examples matches \c i(42).
463/// \code
464/// class C {
465/// C() : i(42) {}
466/// int i;
467/// };
468/// \endcode
469extern const internal::VariadicAllOfMatcher<CXXCtorInitializer>
470 cxxCtorInitializer;
471
472/// \brief Matches template arguments.
473///
474/// Given
475/// \code
476/// template <typename T> struct C {};
477/// C<int> c;
478/// \endcode
479/// templateArgument()
480/// matches 'int' in C<int>.
481extern const internal::VariadicAllOfMatcher<TemplateArgument> templateArgument;
482
483/// \brief Matches template name.
484///
485/// Given
486/// \code
487/// template <typename T> class X { };
488/// X<int> xi;
489/// \endcode
490/// templateName()
491/// matches 'X' in X<int>.
492extern const internal::VariadicAllOfMatcher<TemplateName> templateName;
493
494/// \brief Matches non-type template parameter declarations.
495///
496/// Given
497/// \code
498/// template <typename T, int N> struct C {};
499/// \endcode
500/// nonTypeTemplateParmDecl()
501/// matches 'N', but not 'T'.
502extern const internal::VariadicDynCastAllOfMatcher<Decl,
503 NonTypeTemplateParmDecl>
504 nonTypeTemplateParmDecl;
505
506/// \brief Matches template type parameter declarations.
507///
508/// Given
509/// \code
510/// template <typename T, int N> struct C {};
511/// \endcode
512/// templateTypeParmDecl()
513/// matches 'T', but not 'N'.
514extern const internal::VariadicDynCastAllOfMatcher<Decl, TemplateTypeParmDecl>
515 templateTypeParmDecl;
516
517/// \brief Matches public C++ declarations.
518///
519/// Given
520/// \code
521/// class C {
522/// public: int a;
523/// protected: int b;
524/// private: int c;
525/// };
526/// \endcode
527/// fieldDecl(isPublic())
528/// matches 'int a;'
529AST_MATCHER(Decl, isPublic)namespace internal { class matcher_isPublicMatcher : public ::
clang::ast_matchers::internal::MatcherInterface<Decl> {
public: explicit matcher_isPublicMatcher() = 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> isPublic() { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_isPublicMatcher
()); } inline bool internal::matcher_isPublicMatcher::matches
( const Decl &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
530 return Node.getAccess() == AS_public;
531}
532
533/// \brief Matches protected C++ declarations.
534///
535/// Given
536/// \code
537/// class C {
538/// public: int a;
539/// protected: int b;
540/// private: int c;
541/// };
542/// \endcode
543/// fieldDecl(isProtected())
544/// matches 'int b;'
545AST_MATCHER(Decl, isProtected)namespace internal { class matcher_isProtectedMatcher : public
::clang::ast_matchers::internal::MatcherInterface<Decl>
{ public: explicit matcher_isProtectedMatcher() = 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> isProtected() { return ::clang::
ast_matchers::internal::makeMatcher( new internal::matcher_isProtectedMatcher
()); } inline bool internal::matcher_isProtectedMatcher::matches
( const Decl &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
546 return Node.getAccess() == AS_protected;
547}
548
549/// \brief Matches private C++ declarations.
550///
551/// Given
552/// \code
553/// class C {
554/// public: int a;
555/// protected: int b;
556/// private: int c;
557/// };
558/// \endcode
559/// fieldDecl(isPrivate())
560/// matches 'int c;'
561AST_MATCHER(Decl, isPrivate)namespace internal { class matcher_isPrivateMatcher : public ::
clang::ast_matchers::internal::MatcherInterface<Decl> {
public: explicit matcher_isPrivateMatcher() = 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> isPrivate() { return ::clang::ast_matchers
::internal::makeMatcher( new internal::matcher_isPrivateMatcher
()); } inline bool internal::matcher_isPrivateMatcher::matches
( const Decl &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
562 return Node.getAccess() == AS_private;
563}
564
565/// \brief Matches non-static data members that are bit-fields.
566///
567/// Given
568/// \code
569/// class C {
570/// int a : 2;
571/// int b;
572/// };
573/// \endcode
574/// fieldDecl(isBitField())
575/// matches 'int a;' but not 'int b;'.
576AST_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
{
577 return Node.isBitField();
578}
579
580/// \brief Matches non-static data members that are bit-fields of the specified
581/// bit width.
582///
583/// Given
584/// \code
585/// class C {
586/// int a : 2;
587/// int b : 4;
588/// int c : 2;
589/// };
590/// \endcode
591/// fieldDecl(hasBitWidth(2))
592/// matches 'int a;' and 'int c;' but not 'int b;'.
593AST_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 const 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
{
594 return Node.isBitField() &&
595 Node.getBitWidthValue(Finder->getASTContext()) == Width;
596}
597
598/// \brief Matches non-static data members that have an in-class initializer.
599///
600/// Given
601/// \code
602/// class C {
603/// int a = 2;
604/// int b = 3;
605/// int c;
606/// };
607/// \endcode
608/// fieldDecl(hasInClassInitializer(integerLiteral(equals(2))))
609/// matches 'int a;' but not 'int b;'.
610/// fieldDecl(hasInClassInitializer(anything()))
611/// matches 'int a;' and 'int b;' but not 'int c;'.
612AST_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> const 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
613 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> const 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
{
614 const Expr *Initializer = Node.getInClassInitializer();
615 return (Initializer != nullptr &&
616 InnerMatcher.matches(*Initializer, Finder, Builder));
617}
618
619/// \brief Matches the specialized template of a specialization declaration.
620///
621/// Given
622/// \code
623/// tempalate<typename T> class A {};
624/// typedef A<int> B;
625/// \endcode
626/// classTemplateSpecializationDecl(hasSpecializedTemplate(classTemplateDecl()))
627/// matches 'B' with classTemplateDecl() matching the class template
628/// declaration of 'A'.
629AST_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
> const 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
630 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
> const 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
{
631 const ClassTemplateDecl* Decl = Node.getSpecializedTemplate();
632 return (Decl != nullptr &&
633 InnerMatcher.matches(*Decl, Finder, Builder));
634}
635
636/// \brief Matches a declaration that has been implicitly added
637/// by the compiler (eg. implicit default/copy constructors).
638AST_MATCHER(Decl, isImplicit)namespace internal { class matcher_isImplicitMatcher : public
::clang::ast_matchers::internal::MatcherInterface<Decl>
{ public: explicit matcher_isImplicitMatcher() = 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> isImplicit() { return ::clang::
ast_matchers::internal::makeMatcher( new internal::matcher_isImplicitMatcher
()); } inline bool internal::matcher_isImplicitMatcher::matches
( const Decl &Node, ::clang::ast_matchers::internal::ASTMatchFinder
*Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
639 return Node.isImplicit();
640}
641
642/// \brief Matches classTemplateSpecializations, templateSpecializationType and
643/// functionDecl that have at least one TemplateArgument matching the given
644/// InnerMatcher.
645///
646/// Given
647/// \code
648/// template<typename T> class A {};
649/// template<> class A<double> {};
650/// A<int> a;
651///
652/// template<typename T> f() {};
653/// void func() { f<int>(); };
654/// \endcode
655///
656/// \endcode
657/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
658/// refersToType(asString("int"))))
659/// matches the specialization \c A<int>
660///
661/// functionDecl(hasAnyTemplateArgument(refersToType(asString("int"))))
662/// matches the specialization \c f<int>
663AST_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
> const InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcherWithParam1< internal::matcher_hasAnyTemplateArgument0Matcher
, internal::Matcher<TemplateArgument>, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)> hasAnyTemplateArgument(internal::Matcher
<TemplateArgument> const &InnerMatcher) { return ::
clang::ast_matchers::internal::PolymorphicMatcherWithParam1<
internal::matcher_hasAnyTemplateArgument0Matcher, internal::
Matcher<TemplateArgument>, void(::clang::ast_matchers::
internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)>(InnerMatcher); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcherWithParam1< internal::matcher_hasAnyTemplateArgument0Matcher
, internal::Matcher<TemplateArgument>, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)>(&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
664 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
> const InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcherWithParam1< internal::matcher_hasAnyTemplateArgument0Matcher
, internal::Matcher<TemplateArgument>, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)> hasAnyTemplateArgument(internal::Matcher
<TemplateArgument> const &InnerMatcher) { return ::
clang::ast_matchers::internal::PolymorphicMatcherWithParam1<
internal::matcher_hasAnyTemplateArgument0Matcher, internal::
Matcher<TemplateArgument>, void(::clang::ast_matchers::
internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)>(InnerMatcher); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcherWithParam1< internal::matcher_hasAnyTemplateArgument0Matcher
, internal::Matcher<TemplateArgument>, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)>(&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
665 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
> const InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcherWithParam1< internal::matcher_hasAnyTemplateArgument0Matcher
, internal::Matcher<TemplateArgument>, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)> hasAnyTemplateArgument(internal::Matcher
<TemplateArgument> const &InnerMatcher) { return ::
clang::ast_matchers::internal::PolymorphicMatcherWithParam1<
internal::matcher_hasAnyTemplateArgument0Matcher, internal::
Matcher<TemplateArgument>, void(::clang::ast_matchers::
internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)>(InnerMatcher); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcherWithParam1< internal::matcher_hasAnyTemplateArgument0Matcher
, internal::Matcher<TemplateArgument>, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)>(&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
666 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
> const InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcherWithParam1< internal::matcher_hasAnyTemplateArgument0Matcher
, internal::Matcher<TemplateArgument>, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)> hasAnyTemplateArgument(internal::Matcher
<TemplateArgument> const &InnerMatcher) { return ::
clang::ast_matchers::internal::PolymorphicMatcherWithParam1<
internal::matcher_hasAnyTemplateArgument0Matcher, internal::
Matcher<TemplateArgument>, void(::clang::ast_matchers::
internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)>(InnerMatcher); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcherWithParam1< internal::matcher_hasAnyTemplateArgument0Matcher
, internal::Matcher<TemplateArgument>, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)>(&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
667 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
> const InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcherWithParam1< internal::matcher_hasAnyTemplateArgument0Matcher
, internal::Matcher<TemplateArgument>, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)> hasAnyTemplateArgument(internal::Matcher
<TemplateArgument> const &InnerMatcher) { return ::
clang::ast_matchers::internal::PolymorphicMatcherWithParam1<
internal::matcher_hasAnyTemplateArgument0Matcher, internal::
Matcher<TemplateArgument>, void(::clang::ast_matchers::
internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)>(InnerMatcher); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcherWithParam1< internal::matcher_hasAnyTemplateArgument0Matcher
, internal::Matcher<TemplateArgument>, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)>(&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
668 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
> const InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcherWithParam1< internal::matcher_hasAnyTemplateArgument0Matcher
, internal::Matcher<TemplateArgument>, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)> hasAnyTemplateArgument(internal::Matcher
<TemplateArgument> const &InnerMatcher) { return ::
clang::ast_matchers::internal::PolymorphicMatcherWithParam1<
internal::matcher_hasAnyTemplateArgument0Matcher, internal::
Matcher<TemplateArgument>, void(::clang::ast_matchers::
internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)>(InnerMatcher); } typedef ::clang::ast_matchers
::internal::PolymorphicMatcherWithParam1< internal::matcher_hasAnyTemplateArgument0Matcher
, internal::Matcher<TemplateArgument>, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)>(&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
{
669 ArrayRef<TemplateArgument> List =
670 internal::getTemplateSpecializationArgs(Node);
671 return matchesFirstInRange(InnerMatcher, List.begin(), List.end(), Finder,
672 Builder);
673}
674
675/// \brief Matches expressions that match InnerMatcher after any implicit AST
676/// nodes are stripped off.
677///
678/// Parentheses and explicit casts are not discarded.
679/// Given
680/// \code
681/// class C {};
682/// C a = C();
683/// C b;
684/// C c = b;
685/// \endcode
686/// The matchers
687/// \code
688/// varDecl(hasInitializer(ignoringImplicit(cxxConstructExpr())))
689/// \endcode
690/// would match the declarations for a, b, and c.
691/// While
692/// \code
693/// varDecl(hasInitializer(cxxConstructExpr()))
694/// \endcode
695/// only match the declarations for b and c.
696AST_MATCHER_P(Expr, ignoringImplicit, ast_matchers::internal::Matcher<Expr>,namespace internal { class matcher_ignoringImplicit0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
Expr> { public: explicit matcher_ignoringImplicit0Matcher(
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> const InnerMatcher; }; } inline ::clang::ast_matchers
::internal::Matcher<Expr> ignoringImplicit( ast_matchers
::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
)(ast_matchers::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
697 InnerMatcher)namespace internal { class matcher_ignoringImplicit0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
Expr> { public: explicit matcher_ignoringImplicit0Matcher(
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> const InnerMatcher; }; } inline ::clang::ast_matchers
::internal::Matcher<Expr> ignoringImplicit( ast_matchers
::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
)(ast_matchers::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
{
698 return InnerMatcher.matches(*Node.IgnoreImplicit(), Finder, Builder);
699}
700
701/// \brief Matches expressions that match InnerMatcher after any implicit casts
702/// are stripped off.
703///
704/// Parentheses and explicit casts are not discarded.
705/// Given
706/// \code
707/// int arr[5];
708/// int a = 0;
709/// char b = 0;
710/// const int c = a;
711/// int *d = arr;
712/// long e = (long) 0l;
713/// \endcode
714/// The matchers
715/// \code
716/// varDecl(hasInitializer(ignoringImpCasts(integerLiteral())))
717/// varDecl(hasInitializer(ignoringImpCasts(declRefExpr())))
718/// \endcode
719/// would match the declarations for a, b, c, and d, but not e.
720/// While
721/// \code
722/// varDecl(hasInitializer(integerLiteral()))
723/// varDecl(hasInitializer(declRefExpr()))
724/// \endcode
725/// only match the declarations for b, c, and d.
726AST_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> const 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
727 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> const 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
{
728 return InnerMatcher.matches(*Node.IgnoreImpCasts(), Finder, Builder);
729}
730
731/// \brief Matches expressions that match InnerMatcher after parentheses and
732/// casts are stripped off.
733///
734/// Implicit and non-C Style casts are also discarded.
735/// Given
736/// \code
737/// int a = 0;
738/// char b = (0);
739/// void* c = reinterpret_cast<char*>(0);
740/// char d = char(0);
741/// \endcode
742/// The matcher
743/// varDecl(hasInitializer(ignoringParenCasts(integerLiteral())))
744/// would match the declarations for a, b, c, and d.
745/// while
746/// varDecl(hasInitializer(integerLiteral()))
747/// only match the declaration for a.
748AST_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> const 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
{
749 return InnerMatcher.matches(*Node.IgnoreParenCasts(), Finder, Builder);
750}
751
752/// \brief Matches expressions that match InnerMatcher after implicit casts and
753/// parentheses are stripped off.
754///
755/// Explicit casts are not discarded.
756/// Given
757/// \code
758/// int arr[5];
759/// int a = 0;
760/// char b = (0);
761/// const int c = a;
762/// int *d = (arr);
763/// long e = ((long) 0l);
764/// \endcode
765/// The matchers
766/// varDecl(hasInitializer(ignoringParenImpCasts(integerLiteral())))
767/// varDecl(hasInitializer(ignoringParenImpCasts(declRefExpr())))
768/// would match the declarations for a, b, c, and d, but not e.
769/// while
770/// varDecl(hasInitializer(integerLiteral()))
771/// varDecl(hasInitializer(declRefExpr()))
772/// would only match the declaration for a.
773AST_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> const 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
774 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> const 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
{
775 return InnerMatcher.matches(*Node.IgnoreParenImpCasts(), Finder, Builder);
776}
777
778/// \brief Matches types that match InnerMatcher after any parens are stripped.
779///
780/// Given
781/// \code
782/// void (*fp)(void);
783/// \endcode
784/// The matcher
785/// \code
786/// varDecl(hasType(pointerType(pointee(ignoringParens(functionType())))))
787/// \endcode
788/// would match the declaration for fp.
789AST_MATCHER_P(QualType, ignoringParens,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> const 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
790 internal::Matcher<QualType>, InnerMatcher)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> const 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
{
791 return InnerMatcher.matches(Node.IgnoreParens(), Finder, Builder);
792}
793
794/// \brief Matches classTemplateSpecializations, templateSpecializationType and
795/// functionDecl where the n'th TemplateArgument matches the given InnerMatcher.
796///
797/// Given
798/// \code
799/// template<typename T, typename U> class A {};
800/// A<bool, int> b;
801/// A<int, bool> c;
802///
803/// template<typename T> void f() {}
804/// void func() { f<int>(); };
805/// \endcode
806/// classTemplateSpecializationDecl(hasTemplateArgument(
807/// 1, refersToType(asString("int"))))
808/// matches the specialization \c A<bool, int>
809///
810/// functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))
811/// matches the specialization \c f<int>
812AST_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 const N; internal
::Matcher<TemplateArgument> const InnerMatcher; }; } inline
::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_hasTemplateArgument0Matcher, unsigned,
internal::Matcher<TemplateArgument>, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)> hasTemplateArgument(unsigned const &
N, internal::Matcher<TemplateArgument> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_hasTemplateArgument0Matcher, unsigned,
internal::Matcher<TemplateArgument>, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)>(N, InnerMatcher); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcherWithParam2< internal
::matcher_hasTemplateArgument0Matcher, unsigned, internal::Matcher
<TemplateArgument>, void(::clang::ast_matchers::internal
::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)>(&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
813 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 const N; internal
::Matcher<TemplateArgument> const InnerMatcher; }; } inline
::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_hasTemplateArgument0Matcher, unsigned,
internal::Matcher<TemplateArgument>, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)> hasTemplateArgument(unsigned const &
N, internal::Matcher<TemplateArgument> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_hasTemplateArgument0Matcher, unsigned,
internal::Matcher<TemplateArgument>, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)>(N, InnerMatcher); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcherWithParam2< internal
::matcher_hasTemplateArgument0Matcher, unsigned, internal::Matcher
<TemplateArgument>, void(::clang::ast_matchers::internal
::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)>(&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
814 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 const N; internal
::Matcher<TemplateArgument> const InnerMatcher; }; } inline
::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_hasTemplateArgument0Matcher, unsigned,
internal::Matcher<TemplateArgument>, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)> hasTemplateArgument(unsigned const &
N, internal::Matcher<TemplateArgument> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_hasTemplateArgument0Matcher, unsigned,
internal::Matcher<TemplateArgument>, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)>(N, InnerMatcher); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcherWithParam2< internal
::matcher_hasTemplateArgument0Matcher, unsigned, internal::Matcher
<TemplateArgument>, void(::clang::ast_matchers::internal
::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)>(&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
815 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 const N; internal
::Matcher<TemplateArgument> const InnerMatcher; }; } inline
::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_hasTemplateArgument0Matcher, unsigned,
internal::Matcher<TemplateArgument>, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)> hasTemplateArgument(unsigned const &
N, internal::Matcher<TemplateArgument> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_hasTemplateArgument0Matcher, unsigned,
internal::Matcher<TemplateArgument>, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)>(N, InnerMatcher); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcherWithParam2< internal
::matcher_hasTemplateArgument0Matcher, unsigned, internal::Matcher
<TemplateArgument>, void(::clang::ast_matchers::internal
::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)>(&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
816 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 const N; internal
::Matcher<TemplateArgument> const InnerMatcher; }; } inline
::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_hasTemplateArgument0Matcher, unsigned,
internal::Matcher<TemplateArgument>, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)> hasTemplateArgument(unsigned const &
N, internal::Matcher<TemplateArgument> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_hasTemplateArgument0Matcher, unsigned,
internal::Matcher<TemplateArgument>, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)>(N, InnerMatcher); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcherWithParam2< internal
::matcher_hasTemplateArgument0Matcher, unsigned, internal::Matcher
<TemplateArgument>, void(::clang::ast_matchers::internal
::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)>(&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
817 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 const N; internal
::Matcher<TemplateArgument> const InnerMatcher; }; } inline
::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_hasTemplateArgument0Matcher, unsigned,
internal::Matcher<TemplateArgument>, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)> hasTemplateArgument(unsigned const &
N, internal::Matcher<TemplateArgument> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_hasTemplateArgument0Matcher, unsigned,
internal::Matcher<TemplateArgument>, void(::clang::ast_matchers
::internal::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)>(N, InnerMatcher); } typedef ::clang::
ast_matchers::internal::PolymorphicMatcherWithParam2< internal
::matcher_hasTemplateArgument0Matcher, unsigned, internal::Matcher
<TemplateArgument>, void(::clang::ast_matchers::internal
::TypeList<ClassTemplateSpecializationDecl, TemplateSpecializationType
, FunctionDecl>)>(&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
{
818 ArrayRef<TemplateArgument> List =
819 internal::getTemplateSpecializationArgs(Node);
820 if (List.size() <= N)
821 return false;
822 return InnerMatcher.matches(List[N], Finder, Builder);
823}
824
825/// \brief Matches if the number of template arguments equals \p N.
826///
827/// Given
828/// \code
829/// template<typename T> struct C {};
830/// C<int> c;
831/// \endcode
832/// classTemplateSpecializationDecl(templateArgumentCountIs(1))
833/// matches C<int>.
834AST_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 const N; }; } inline
::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_templateArgumentCountIs0Matcher, unsigned
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType>)> templateArgumentCountIs
(unsigned const &N) { return ::clang::ast_matchers::internal
::PolymorphicMatcherWithParam1< internal::matcher_templateArgumentCountIs0Matcher
, unsigned, void(::clang::ast_matchers::internal::TypeList<
ClassTemplateSpecializationDecl, TemplateSpecializationType>
)>(N); } typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_templateArgumentCountIs0Matcher, unsigned
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType>)>(&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
835 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 const N; }; } inline
::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_templateArgumentCountIs0Matcher, unsigned
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType>)> templateArgumentCountIs
(unsigned const &N) { return ::clang::ast_matchers::internal
::PolymorphicMatcherWithParam1< internal::matcher_templateArgumentCountIs0Matcher
, unsigned, void(::clang::ast_matchers::internal::TypeList<
ClassTemplateSpecializationDecl, TemplateSpecializationType>
)>(N); } typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_templateArgumentCountIs0Matcher, unsigned
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType>)>(&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
836 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 const N; }; } inline
::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_templateArgumentCountIs0Matcher, unsigned
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType>)> templateArgumentCountIs
(unsigned const &N) { return ::clang::ast_matchers::internal
::PolymorphicMatcherWithParam1< internal::matcher_templateArgumentCountIs0Matcher
, unsigned, void(::clang::ast_matchers::internal::TypeList<
ClassTemplateSpecializationDecl, TemplateSpecializationType>
)>(N); } typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_templateArgumentCountIs0Matcher, unsigned
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType>)>(&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
837 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 const N; }; } inline
::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_templateArgumentCountIs0Matcher, unsigned
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType>)> templateArgumentCountIs
(unsigned const &N) { return ::clang::ast_matchers::internal
::PolymorphicMatcherWithParam1< internal::matcher_templateArgumentCountIs0Matcher
, unsigned, void(::clang::ast_matchers::internal::TypeList<
ClassTemplateSpecializationDecl, TemplateSpecializationType>
)>(N); } typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_templateArgumentCountIs0Matcher, unsigned
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType>)>(&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
838 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 const N; }; } inline
::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_templateArgumentCountIs0Matcher, unsigned
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType>)> templateArgumentCountIs
(unsigned const &N) { return ::clang::ast_matchers::internal
::PolymorphicMatcherWithParam1< internal::matcher_templateArgumentCountIs0Matcher
, unsigned, void(::clang::ast_matchers::internal::TypeList<
ClassTemplateSpecializationDecl, TemplateSpecializationType>
)>(N); } typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_templateArgumentCountIs0Matcher, unsigned
, void(::clang::ast_matchers::internal::TypeList<ClassTemplateSpecializationDecl
, TemplateSpecializationType>)>(&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
{
839 return internal::getTemplateSpecializationArgs(Node).size() == N;
840}
841
842/// \brief Matches a TemplateArgument that refers to a certain type.
843///
844/// Given
845/// \code
846/// struct X {};
847/// template<typename T> struct A {};
848/// A<X> a;
849/// \endcode
850/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
851/// refersToType(class(hasName("X")))))
852/// matches the specialization \c A<X>
853AST_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> const
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
854 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> const
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
{
855 if (Node.getKind() != TemplateArgument::Type)
856 return false;
857 return InnerMatcher.matches(Node.getAsType(), Finder, Builder);
858}
859
860/// \brief Matches a TemplateArgument that refers to a certain template.
861///
862/// Given
863/// \code
864/// template<template <typename> class S> class X {};
865/// template<typename T> class Y {};"
866/// X<Y> xi;
867/// \endcode
868/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
869/// refersToTemplate(templateName())))
870/// matches the specialization \c X<Y>
871AST_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
> const 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
872 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
> const 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
{
873 if (Node.getKind() != TemplateArgument::Template)
874 return false;
875 return InnerMatcher.matches(Node.getAsTemplate(), Finder, Builder);
876}
877
878/// \brief Matches a canonical TemplateArgument that refers to a certain
879/// declaration.
880///
881/// Given
882/// \code
883/// struct B { int next; };
884/// template<int(B::*next_ptr)> struct A {};
885/// A<&B::next> a;
886/// \endcode
887/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
888/// refersToDeclaration(fieldDecl(hasName("next")))))
889/// matches the specialization \c A<&B::next> with \c fieldDecl(...) matching
890/// \c B::next
891AST_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> const
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
892 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> const
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
{
893 if (Node.getKind() == TemplateArgument::Declaration)
894 return InnerMatcher.matches(*Node.getAsDecl(), Finder, Builder);
895 return false;
896}
897
898/// \brief Matches a sugar TemplateArgument that refers to a certain expression.
899///
900/// Given
901/// \code
902/// struct B { int next; };
903/// template<int(B::*next_ptr)> struct A {};
904/// A<&B::next> a;
905/// \endcode
906/// templateSpecializationType(hasAnyTemplateArgument(
907/// isExpr(hasDescendant(declRefExpr(to(fieldDecl(hasName("next"))))))))
908/// matches the specialization \c A<&B::next> with \c fieldDecl(...) matching
909/// \c B::next
910AST_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> const 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
{
911 if (Node.getKind() == TemplateArgument::Expression)
912 return InnerMatcher.matches(*Node.getAsExpr(), Finder, Builder);
913 return false;
914}
915
916/// \brief Matches a TemplateArgument that is an integral value.
917///
918/// Given
919/// \code
920/// template<int T> struct C {};
921/// C<42> c;
922/// \endcode
923/// classTemplateSpecializationDecl(
924/// hasAnyTemplateArgument(isIntegral()))
925/// matches the implicit instantiation of C in C<42>
926/// with isIntegral() matching 42.
927AST_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
{
928 return Node.getKind() == TemplateArgument::Integral;
929}
930
931/// \brief Matches a TemplateArgument that referes to an integral type.
932///
933/// Given
934/// \code
935/// template<int T> struct C {};
936/// C<42> c;
937/// \endcode
938/// classTemplateSpecializationDecl(
939/// hasAnyTemplateArgument(refersToIntegralType(asString("int"))))
940/// matches the implicit instantiation of C in C<42>.
941AST_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
> const 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
942 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
> const 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
{
943 if (Node.getKind() != TemplateArgument::Integral)
944 return false;
945 return InnerMatcher.matches(Node.getIntegralType(), Finder, Builder);
946}
947
948/// \brief Matches a TemplateArgument of integral type with a given value.
949///
950/// Note that 'Value' is a string as the template argument's value is
951/// an arbitrary precision integer. 'Value' must be euqal to the canonical
952/// representation of that integral value in base 10.
953///
954/// Given
955/// \code
956/// template<int T> struct C {};
957/// C<42> c;
958/// \endcode
959/// classTemplateSpecializationDecl(
960/// hasAnyTemplateArgument(equalsIntegralValue("42")))
961/// matches the implicit instantiation of C in C<42>.
962AST_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 const 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
963 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 const 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
{
964 if (Node.getKind() != TemplateArgument::Integral)
965 return false;
966 return Node.getAsIntegral().toString(10) == Value;
967}
968
969/// \brief Matches any value declaration.
970///
971/// Example matches A, B, C and F
972/// \code
973/// enum X { A, B, C };
974/// void F();
975/// \endcode
976extern const internal::VariadicDynCastAllOfMatcher<Decl, ValueDecl> valueDecl;
977
978/// \brief Matches C++ constructor declarations.
979///
980/// Example matches Foo::Foo() and Foo::Foo(int)
981/// \code
982/// class Foo {
983/// public:
984/// Foo();
985/// Foo(int);
986/// int DoSomething();
987/// };
988/// \endcode
989extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXConstructorDecl>
990 cxxConstructorDecl;
991
992/// \brief Matches explicit C++ destructor declarations.
993///
994/// Example matches Foo::~Foo()
995/// \code
996/// class Foo {
997/// public:
998/// virtual ~Foo();
999/// };
1000/// \endcode
1001extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXDestructorDecl>
1002 cxxDestructorDecl;
1003
1004/// \brief Matches enum declarations.
1005///
1006/// Example matches X
1007/// \code
1008/// enum X {
1009/// A, B, C
1010/// };
1011/// \endcode
1012extern const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl;
1013
1014/// \brief Matches enum constants.
1015///
1016/// Example matches A, B, C
1017/// \code
1018/// enum X {
1019/// A, B, C
1020/// };
1021/// \endcode
1022extern const internal::VariadicDynCastAllOfMatcher<Decl, EnumConstantDecl>
1023 enumConstantDecl;
1024
1025/// \brief Matches method declarations.
1026///
1027/// Example matches y
1028/// \code
1029/// class X { void y(); };
1030/// \endcode
1031extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl>
1032 cxxMethodDecl;
1033
1034/// \brief Matches conversion operator declarations.
1035///
1036/// Example matches the operator.
1037/// \code
1038/// class X { operator int() const; };
1039/// \endcode
1040extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl>
1041 cxxConversionDecl;
1042
1043/// \brief Matches variable declarations.
1044///
1045/// Note: this does not match declarations of member variables, which are
1046/// "field" declarations in Clang parlance.
1047///
1048/// Example matches a
1049/// \code
1050/// int a;
1051/// \endcode
1052extern const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> varDecl;
1053
1054/// \brief Matches field declarations.
1055///
1056/// Given
1057/// \code
1058/// class X { int m; };
1059/// \endcode
1060/// fieldDecl()
1061/// matches 'm'.
1062extern const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> fieldDecl;
1063
1064/// \brief Matches function declarations.
1065///
1066/// Example matches f
1067/// \code
1068/// void f();
1069/// \endcode
1070extern const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl>
1071 functionDecl;
1072
1073/// \brief Matches C++ function template declarations.
1074///
1075/// Example matches f
1076/// \code
1077/// template<class T> void f(T t) {}
1078/// \endcode
1079extern const internal::VariadicDynCastAllOfMatcher<Decl, FunctionTemplateDecl>
1080 functionTemplateDecl;
1081
1082/// \brief Matches friend declarations.
1083///
1084/// Given
1085/// \code
1086/// class X { friend void foo(); };
1087/// \endcode
1088/// friendDecl()
1089/// matches 'friend void foo()'.
1090extern const internal::VariadicDynCastAllOfMatcher<Decl, FriendDecl> friendDecl;
1091
1092/// \brief Matches statements.
1093///
1094/// Given
1095/// \code
1096/// { ++a; }
1097/// \endcode
1098/// stmt()
1099/// matches both the compound statement '{ ++a; }' and '++a'.
1100extern const internal::VariadicAllOfMatcher<Stmt> stmt;
1101
1102/// \brief Matches declaration statements.
1103///
1104/// Given
1105/// \code
1106/// int a;
1107/// \endcode
1108/// declStmt()
1109/// matches 'int a'.
1110extern const internal::VariadicDynCastAllOfMatcher<Stmt, DeclStmt> declStmt;
1111
1112/// \brief Matches member expressions.
1113///
1114/// Given
1115/// \code
1116/// class Y {
1117/// void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; }
1118/// int a; static int b;
1119/// };
1120/// \endcode
1121/// memberExpr()
1122/// matches this->x, x, y.x, a, this->b
1123extern const internal::VariadicDynCastAllOfMatcher<Stmt, MemberExpr> memberExpr;
1124
1125/// \brief Matches call expressions.
1126///
1127/// Example matches x.y() and y()
1128/// \code
1129/// X x;
1130/// x.y();
1131/// y();
1132/// \endcode
1133extern const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> callExpr;
1134
1135/// \brief Matches lambda expressions.
1136///
1137/// Example matches [&](){return 5;}
1138/// \code
1139/// [&](){return 5;}
1140/// \endcode
1141extern const internal::VariadicDynCastAllOfMatcher<Stmt, LambdaExpr> lambdaExpr;
1142
1143/// \brief Matches member call expressions.
1144///
1145/// Example matches x.y()
1146/// \code
1147/// X x;
1148/// x.y();
1149/// \endcode
1150extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXMemberCallExpr>
1151 cxxMemberCallExpr;
1152
1153/// \brief Matches ObjectiveC Message invocation expressions.
1154///
1155/// The innermost message send invokes the "alloc" class method on the
1156/// NSString class, while the outermost message send invokes the
1157/// "initWithString" instance method on the object returned from
1158/// NSString's "alloc". This matcher should match both message sends.
1159/// \code
1160/// [[NSString alloc] initWithString:@"Hello"]
1161/// \endcode
1162extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCMessageExpr>
1163 objcMessageExpr;
1164
1165/// \brief Matches Objective-C interface declarations.
1166///
1167/// Example matches Foo
1168/// \code
1169/// @interface Foo
1170/// @end
1171/// \endcode
1172extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCInterfaceDecl>
1173 objcInterfaceDecl;
1174
1175/// \brief Matches Objective-C implementation declarations.
1176///
1177/// Example matches Foo
1178/// \code
1179/// @implementation Foo
1180/// @end
1181/// \endcode
1182extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCImplementationDecl>
1183 objcImplementationDecl;
1184
1185/// \brief Matches Objective-C protocol declarations.
1186///
1187/// Example matches FooDelegate
1188/// \code
1189/// @protocol FooDelegate
1190/// @end
1191/// \endcode
1192extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCProtocolDecl>
1193 objcProtocolDecl;
1194
1195/// \brief Matches Objective-C category declarations.
1196///
1197/// Example matches Foo (Additions)
1198/// \code
1199/// @interface Foo (Additions)
1200/// @end
1201/// \endcode
1202extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryDecl>
1203 objcCategoryDecl;
1204
1205/// \brief Matches Objective-C category definitions.
1206///
1207/// Example matches Foo (Additions)
1208/// \code
1209/// @implementation Foo (Additions)
1210/// @end
1211/// \endcode
1212extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryImplDecl>
1213 objcCategoryImplDecl;
1214
1215/// \brief Matches Objective-C method declarations.
1216///
1217/// Example matches both declaration and definition of -[Foo method]
1218/// \code
1219/// @interface Foo
1220/// - (void)method;
1221/// @end
1222///
1223/// @implementation Foo
1224/// - (void)method {}
1225/// @end
1226/// \endcode
1227extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCMethodDecl>
1228 objcMethodDecl;
1229
1230/// \brief Matches Objective-C instance variable declarations.
1231///
1232/// Example matches _enabled
1233/// \code
1234/// @implementation Foo {
1235/// BOOL _enabled;
1236/// }
1237/// @end
1238/// \endcode
1239extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCIvarDecl>
1240 objcIvarDecl;
1241
1242/// \brief Matches Objective-C property declarations.
1243///
1244/// Example matches enabled
1245/// \code
1246/// @interface Foo
1247/// @property BOOL enabled;
1248/// @end
1249/// \endcode
1250extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCPropertyDecl>
1251 objcPropertyDecl;
1252
1253/// \brief Matches Objective-C \@throw statements.
1254///
1255/// Example matches \@throw
1256/// \code
1257/// @throw obj;
1258/// \endcode
1259extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtThrowStmt>
1260 objcThrowStmt;
1261
1262/// \brief Matches Objective-C @try statements.
1263///
1264/// Example matches @try
1265/// \code
1266/// @try {}
1267/// @catch (...) {}
1268/// \endcode
1269extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtTryStmt>
1270 objcTryStmt;
1271
1272/// \brief Matches Objective-C @catch statements.
1273///
1274/// Example matches @catch
1275/// \code
1276/// @try {}
1277/// @catch (...) {}
1278/// \endcode
1279extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtCatchStmt>
1280 objcCatchStmt;
1281
1282/// \brief Matches Objective-C @finally statements.
1283///
1284/// Example matches @finally
1285/// \code
1286/// @try {}
1287/// @finally {}
1288/// \endcode
1289extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtFinallyStmt>
1290 objcFinallyStmt;
1291
1292/// \brief Matches expressions that introduce cleanups to be run at the end
1293/// of the sub-expression's evaluation.
1294///
1295/// Example matches std::string()
1296/// \code
1297/// const std::string str = std::string();
1298/// \endcode
1299extern const internal::VariadicDynCastAllOfMatcher<Stmt, ExprWithCleanups>
1300 exprWithCleanups;
1301
1302/// \brief Matches init list expressions.
1303///
1304/// Given
1305/// \code
1306/// int a[] = { 1, 2 };
1307/// struct B { int x, y; };
1308/// B b = { 5, 6 };
1309/// \endcode
1310/// initListExpr()
1311/// matches "{ 1, 2 }" and "{ 5, 6 }"
1312extern const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr>
1313 initListExpr;
1314
1315/// \brief Matches the syntactic form of init list expressions
1316/// (if expression have it).
1317AST_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> const 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
1318 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> const 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
{
1319 const Expr *SyntForm = Node.getSyntacticForm();
1320 return (SyntForm != nullptr &&
1321 InnerMatcher.matches(*SyntForm, Finder, Builder));
1322}
1323
1324/// \brief Matches C++ initializer list expressions.
1325///
1326/// Given
1327/// \code
1328/// std::vector<int> a({ 1, 2, 3 });
1329/// std::vector<int> b = { 4, 5 };
1330/// int c[] = { 6, 7 };
1331/// std::pair<int, int> d = { 8, 9 };
1332/// \endcode
1333/// cxxStdInitializerListExpr()
1334/// matches "{ 1, 2, 3 }" and "{ 4, 5 }"
1335extern const internal::VariadicDynCastAllOfMatcher<Stmt,
1336 CXXStdInitializerListExpr>
1337 cxxStdInitializerListExpr;
1338
1339/// \brief Matches implicit initializers of init list expressions.
1340///
1341/// Given
1342/// \code
1343/// point ptarray[10] = { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 };
1344/// \endcode
1345/// implicitValueInitExpr()
1346/// matches "[0].y" (implicitly)
1347extern const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitValueInitExpr>
1348 implicitValueInitExpr;
1349
1350/// \brief Matches paren list expressions.
1351/// ParenListExprs don't have a predefined type and are used for late parsing.
1352/// In the final AST, they can be met in template declarations.
1353///
1354/// Given
1355/// \code
1356/// template<typename T> class X {
1357/// void f() {
1358/// X x(*this);
1359/// int a = 0, b = 1; int i = (a, b);
1360/// }
1361/// };
1362/// \endcode
1363/// parenListExpr() matches "*this" but NOT matches (a, b) because (a, b)
1364/// has a predefined type and is a ParenExpr, not a ParenListExpr.
1365extern const internal::VariadicDynCastAllOfMatcher<Stmt, ParenListExpr>
1366 parenListExpr;
1367
1368/// \brief Matches substitutions of non-type template parameters.
1369///
1370/// Given
1371/// \code
1372/// template <int N>
1373/// struct A { static const int n = N; };
1374/// struct B : public A<42> {};
1375/// \endcode
1376/// substNonTypeTemplateParmExpr()
1377/// matches "N" in the right-hand side of "static const int n = N;"
1378extern const internal::VariadicDynCastAllOfMatcher<Stmt,
1379 SubstNonTypeTemplateParmExpr>
1380 substNonTypeTemplateParmExpr;
1381
1382/// \brief Matches using declarations.
1383///
1384/// Given
1385/// \code
1386/// namespace X { int x; }
1387/// using X::x;
1388/// \endcode
1389/// usingDecl()
1390/// matches \code using X::x \endcode
1391extern const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl;
1392
1393/// \brief Matches using namespace declarations.
1394///
1395/// Given
1396/// \code
1397/// namespace X { int x; }
1398/// using namespace X;
1399/// \endcode
1400/// usingDirectiveDecl()
1401/// matches \code using namespace X \endcode
1402extern const internal::VariadicDynCastAllOfMatcher<Decl, UsingDirectiveDecl>
1403 usingDirectiveDecl;
1404
1405/// \brief Matches reference to a name that can be looked up during parsing
1406/// but could not be resolved to a specific declaration.
1407///
1408/// Given
1409/// \code
1410/// template<typename T>
1411/// T foo() { T a; return a; }
1412/// template<typename T>
1413/// void bar() {
1414/// foo<T>();
1415/// }
1416/// \endcode
1417/// unresolvedLookupExpr()
1418/// matches \code foo<T>() \endcode
1419extern const internal::VariadicDynCastAllOfMatcher<Stmt, UnresolvedLookupExpr>
1420 unresolvedLookupExpr;
1421
1422/// \brief Matches unresolved using value declarations.
1423///
1424/// Given
1425/// \code
1426/// template<typename X>
1427/// class C : private X {
1428/// using X::x;
1429/// };
1430/// \endcode
1431/// unresolvedUsingValueDecl()
1432/// matches \code using X::x \endcode
1433extern const internal::VariadicDynCastAllOfMatcher<Decl,
1434 UnresolvedUsingValueDecl>
1435 unresolvedUsingValueDecl;
1436
1437/// \brief Matches unresolved using value declarations that involve the
1438/// typename.
1439///
1440/// Given
1441/// \code
1442/// template <typename T>
1443/// struct Base { typedef T Foo; };
1444///
1445/// template<typename T>
1446/// struct S : private Base<T> {
1447/// using typename Base<T>::Foo;
1448/// };
1449/// \endcode
1450/// unresolvedUsingTypenameDecl()
1451/// matches \code using Base<T>::Foo \endcode
1452extern const internal::VariadicDynCastAllOfMatcher<Decl,
1453 UnresolvedUsingTypenameDecl>
1454 unresolvedUsingTypenameDecl;
1455
1456/// \brief Matches parentheses used in expressions.
1457///
1458/// Example matches (foo() + 1)
1459/// \code
1460/// int foo() { return 1; }
1461/// int a = (foo() + 1);
1462/// \endcode
1463extern const internal::VariadicDynCastAllOfMatcher<Stmt, ParenExpr> parenExpr;
1464
1465/// \brief Matches constructor call expressions (including implicit ones).
1466///
1467/// Example matches string(ptr, n) and ptr within arguments of f
1468/// (matcher = cxxConstructExpr())
1469/// \code
1470/// void f(const string &a, const string &b);
1471/// char *ptr;
1472/// int n;
1473/// f(string(ptr, n), ptr);
1474/// \endcode
1475extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstructExpr>
1476 cxxConstructExpr;
1477
1478/// \brief Matches unresolved constructor call expressions.
1479///
1480/// Example matches T(t) in return statement of f
1481/// (matcher = cxxUnresolvedConstructExpr())
1482/// \code
1483/// template <typename T>
1484/// void f(const T& t) { return T(t); }
1485/// \endcode
1486extern const internal::VariadicDynCastAllOfMatcher<Stmt,
1487 CXXUnresolvedConstructExpr>
1488 cxxUnresolvedConstructExpr;
1489
1490/// \brief Matches implicit and explicit this expressions.
1491///
1492/// Example matches the implicit this expression in "return i".
1493/// (matcher = cxxThisExpr())
1494/// \code
1495/// struct foo {
1496/// int i;
1497/// int f() { return i; }
1498/// };
1499/// \endcode
1500extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThisExpr>
1501 cxxThisExpr;
1502
1503/// \brief Matches nodes where temporaries are created.
1504///
1505/// Example matches FunctionTakesString(GetStringByValue())
1506/// (matcher = cxxBindTemporaryExpr())
1507/// \code
1508/// FunctionTakesString(GetStringByValue());
1509/// FunctionTakesStringByPointer(GetStringPointer());
1510/// \endcode
1511extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBindTemporaryExpr>
1512 cxxBindTemporaryExpr;
1513
1514/// \brief Matches nodes where temporaries are materialized.
1515///
1516/// Example: Given
1517/// \code
1518/// struct T {void func();};
1519/// T f();
1520/// void g(T);
1521/// \endcode
1522/// materializeTemporaryExpr() matches 'f()' in these statements
1523/// \code
1524/// T u(f());
1525/// g(f());
1526/// f().func();
1527/// \endcode
1528/// but does not match
1529/// \code
1530/// f();
1531/// \endcode
1532extern const internal::VariadicDynCastAllOfMatcher<Stmt,
1533 MaterializeTemporaryExpr>
1534 materializeTemporaryExpr;
1535
1536/// \brief Matches new expressions.
1537///
1538/// Given
1539/// \code
1540/// new X;
1541/// \endcode
1542/// cxxNewExpr()
1543/// matches 'new X'.
1544extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> cxxNewExpr;
1545
1546/// \brief Matches delete expressions.
1547///
1548/// Given
1549/// \code
1550/// delete X;
1551/// \endcode
1552/// cxxDeleteExpr()
1553/// matches 'delete X'.
1554extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDeleteExpr>
1555 cxxDeleteExpr;
1556
1557/// \brief Matches array subscript expressions.
1558///
1559/// Given
1560/// \code
1561/// int i = a[1];
1562/// \endcode
1563/// arraySubscriptExpr()
1564/// matches "a[1]"
1565extern const internal::VariadicDynCastAllOfMatcher<Stmt, ArraySubscriptExpr>
1566 arraySubscriptExpr;
1567
1568/// \brief Matches the value of a default argument at the call site.
1569///
1570/// Example matches the CXXDefaultArgExpr placeholder inserted for the
1571/// default value of the second parameter in the call expression f(42)
1572/// (matcher = cxxDefaultArgExpr())
1573/// \code
1574/// void f(int x, int y = 0);
1575/// f(42);
1576/// \endcode
1577extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDefaultArgExpr>
1578 cxxDefaultArgExpr;
1579
1580/// \brief Matches overloaded operator calls.
1581///
1582/// Note that if an operator isn't overloaded, it won't match. Instead, use
1583/// binaryOperator matcher.
1584/// Currently it does not match operators such as new delete.
1585/// FIXME: figure out why these do not match?
1586///
1587/// Example matches both operator<<((o << b), c) and operator<<(o, b)
1588/// (matcher = cxxOperatorCallExpr())
1589/// \code
1590/// ostream &operator<< (ostream &out, int i) { };
1591/// ostream &o; int b = 1, c = 1;
1592/// o << b << c;
1593/// \endcode
1594extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXOperatorCallExpr>
1595 cxxOperatorCallExpr;
1596
1597/// \brief Matches expressions.
1598///
1599/// Example matches x()
1600/// \code
1601/// void f() { x(); }
1602/// \endcode
1603extern const internal::VariadicDynCastAllOfMatcher<Stmt, Expr> expr;
1604
1605/// \brief Matches expressions that refer to declarations.
1606///
1607/// Example matches x in if (x)
1608/// \code
1609/// bool x;
1610/// if (x) {}
1611/// \endcode
1612extern const internal::VariadicDynCastAllOfMatcher<Stmt, DeclRefExpr>
1613 declRefExpr;
1614
1615/// \brief Matches if statements.
1616///
1617/// Example matches 'if (x) {}'
1618/// \code
1619/// if (x) {}
1620/// \endcode
1621extern const internal::VariadicDynCastAllOfMatcher<Stmt, IfStmt> ifStmt;
1622
1623/// \brief Matches for statements.
1624///
1625/// Example matches 'for (;;) {}'
1626/// \code
1627/// for (;;) {}
1628/// int i[] = {1, 2, 3}; for (auto a : i);
1629/// \endcode
1630extern const internal::VariadicDynCastAllOfMatcher<Stmt, ForStmt> forStmt;
1631
1632/// \brief Matches the increment statement of a for loop.
1633///
1634/// Example:
1635/// forStmt(hasIncrement(unaryOperator(hasOperatorName("++"))))
1636/// matches '++x' in
1637/// \code
1638/// for (x; x < N; ++x) { }
1639/// \endcode
1640AST_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> const 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
1641 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> const 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
{
1642 const Stmt *const Increment = Node.getInc();
1643 return (Increment != nullptr &&
1644 InnerMatcher.matches(*Increment, Finder, Builder));
1645}
1646
1647/// \brief Matches the initialization statement of a for loop.
1648///
1649/// Example:
1650/// forStmt(hasLoopInit(declStmt()))
1651/// matches 'int x = 0' in
1652/// \code
1653/// for (int x = 0; x < N; ++x) { }
1654/// \endcode
1655AST_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> const 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
1656 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> const 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
{
1657 const Stmt *const Init = Node.getInit();
1658 return (Init != nullptr && InnerMatcher.matches(*Init, Finder, Builder));
1659}
1660
1661/// \brief Matches range-based for statements.
1662///
1663/// cxxForRangeStmt() matches 'for (auto a : i)'
1664/// \code
1665/// int i[] = {1, 2, 3}; for (auto a : i);
1666/// for(int j = 0; j < 5; ++j);
1667/// \endcode
1668extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXForRangeStmt>
1669 cxxForRangeStmt;
1670
1671/// \brief Matches the initialization statement of a for loop.
1672///
1673/// Example:
1674/// forStmt(hasLoopVariable(anything()))
1675/// matches 'int x' in
1676/// \code
1677/// for (int x : a) { }
1678/// \endcode
1679AST_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> const
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
1680 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> const
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
{
1681 const VarDecl *const Var = Node.getLoopVariable();
1682 return (Var != nullptr && InnerMatcher.matches(*Var, Finder, Builder));
1683}
1684
1685/// \brief Matches the range initialization statement of a for loop.
1686///
1687/// Example:
1688/// forStmt(hasRangeInit(anything()))
1689/// matches 'a' in
1690/// \code
1691/// for (int x : a) { }
1692/// \endcode
1693AST_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> const
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
1694 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> const
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
{
1695 const Expr *const Init = Node.getRangeInit();
1696 return (Init != nullptr && InnerMatcher.matches(*Init, Finder, Builder));
1697}
1698
1699/// \brief Matches while statements.
1700///
1701/// Given
1702/// \code
1703/// while (true) {}
1704/// \endcode
1705/// whileStmt()
1706/// matches 'while (true) {}'.
1707extern const internal::VariadicDynCastAllOfMatcher<Stmt, WhileStmt> whileStmt;
1708
1709/// \brief Matches do statements.
1710///
1711/// Given
1712/// \code
1713/// do {} while (true);
1714/// \endcode
1715/// doStmt()
1716/// matches 'do {} while(true)'
1717extern const internal::VariadicDynCastAllOfMatcher<Stmt, DoStmt> doStmt;
1718
1719/// \brief Matches break statements.
1720///
1721/// Given
1722/// \code
1723/// while (true) { break; }
1724/// \endcode
1725/// breakStmt()
1726/// matches 'break'
1727extern const internal::VariadicDynCastAllOfMatcher<Stmt, BreakStmt> breakStmt;
1728
1729/// \brief Matches continue statements.
1730///
1731/// Given
1732/// \code
1733/// while (true) { continue; }
1734/// \endcode
1735/// continueStmt()
1736/// matches 'continue'
1737extern const internal::VariadicDynCastAllOfMatcher<Stmt, ContinueStmt>
1738 continueStmt;
1739
1740/// \brief Matches return statements.
1741///
1742/// Given
1743/// \code
1744/// return 1;
1745/// \endcode
1746/// returnStmt()
1747/// matches 'return 1'
1748extern const internal::VariadicDynCastAllOfMatcher<Stmt, ReturnStmt> returnStmt;
1749
1750/// \brief Matches goto statements.
1751///
1752/// Given
1753/// \code
1754/// goto FOO;
1755/// FOO: bar();
1756/// \endcode
1757/// gotoStmt()
1758/// matches 'goto FOO'
1759extern const internal::VariadicDynCastAllOfMatcher<Stmt, GotoStmt> gotoStmt;
1760
1761/// \brief Matches label statements.
1762///
1763/// Given
1764/// \code
1765/// goto FOO;
1766/// FOO: bar();
1767/// \endcode
1768/// labelStmt()
1769/// matches 'FOO:'
1770extern const internal::VariadicDynCastAllOfMatcher<Stmt, LabelStmt> labelStmt;
1771
1772/// \brief Matches address of label statements (GNU extension).
1773///
1774/// Given
1775/// \code
1776/// FOO: bar();
1777/// void *ptr = &&FOO;
1778/// goto *bar;
1779/// \endcode
1780/// addrLabelExpr()
1781/// matches '&&FOO'
1782extern const internal::VariadicDynCastAllOfMatcher<Stmt, AddrLabelExpr>
1783 addrLabelExpr;
1784
1785/// \brief Matches switch statements.
1786///
1787/// Given
1788/// \code
1789/// switch(a) { case 42: break; default: break; }
1790/// \endcode
1791/// switchStmt()
1792/// matches 'switch(a)'.
1793extern const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchStmt> switchStmt;
1794
1795/// \brief Matches case and default statements inside switch statements.
1796///
1797/// Given
1798/// \code
1799/// switch(a) { case 42: break; default: break; }
1800/// \endcode
1801/// switchCase()
1802/// matches 'case 42:' and 'default:'.
1803extern const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchCase> switchCase;
1804
1805/// \brief Matches case statements inside switch statements.
1806///
1807/// Given
1808/// \code
1809/// switch(a) { case 42: break; default: break; }
1810/// \endcode
1811/// caseStmt()
1812/// matches 'case 42:'.
1813extern const internal::VariadicDynCastAllOfMatcher<Stmt, CaseStmt> caseStmt;
1814
1815/// \brief Matches default statements inside switch statements.
1816///
1817/// Given
1818/// \code
1819/// switch(a) { case 42: break; default: break; }
1820/// \endcode
1821/// defaultStmt()
1822/// matches 'default:'.
1823extern const internal::VariadicDynCastAllOfMatcher<Stmt, DefaultStmt>
1824 defaultStmt;
1825
1826/// \brief Matches compound statements.
1827///
1828/// Example matches '{}' and '{{}}' in 'for (;;) {{}}'
1829/// \code
1830/// for (;;) {{}}
1831/// \endcode
1832extern const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundStmt>
1833 compoundStmt;
1834
1835/// \brief Matches catch statements.
1836///
1837/// \code
1838/// try {} catch(int i) {}
1839/// \endcode
1840/// cxxCatchStmt()
1841/// matches 'catch(int i)'
1842extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXCatchStmt>
1843 cxxCatchStmt;
1844
1845/// \brief Matches try statements.
1846///
1847/// \code
1848/// try {} catch(int i) {}
1849/// \endcode
1850/// cxxTryStmt()
1851/// matches 'try {}'
1852extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTryStmt> cxxTryStmt;
1853
1854/// \brief Matches throw expressions.
1855///
1856/// \code
1857/// try { throw 5; } catch(int i) {}
1858/// \endcode
1859/// cxxThrowExpr()
1860/// matches 'throw 5'
1861extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThrowExpr>
1862 cxxThrowExpr;
1863
1864/// \brief Matches null statements.
1865///
1866/// \code
1867/// foo();;
1868/// \endcode
1869/// nullStmt()
1870/// matches the second ';'
1871extern const internal::VariadicDynCastAllOfMatcher<Stmt, NullStmt> nullStmt;
1872
1873/// \brief Matches asm statements.
1874///
1875/// \code
1876/// int i = 100;
1877/// __asm("mov al, 2");
1878/// \endcode
1879/// asmStmt()
1880/// matches '__asm("mov al, 2")'
1881extern const internal::VariadicDynCastAllOfMatcher<Stmt, AsmStmt> asmStmt;
1882
1883/// \brief Matches bool literals.
1884///
1885/// Example matches true
1886/// \code
1887/// true
1888/// \endcode
1889extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBoolLiteralExpr>
1890 cxxBoolLiteral;
1891
1892/// \brief Matches string literals (also matches wide string literals).
1893///
1894/// Example matches "abcd", L"abcd"
1895/// \code
1896/// char *s = "abcd";
1897/// wchar_t *ws = L"abcd";
1898/// \endcode
1899extern const internal::VariadicDynCastAllOfMatcher<Stmt, StringLiteral>
1900 stringLiteral;
1901
1902/// \brief Matches character literals (also matches wchar_t).
1903///
1904/// Not matching Hex-encoded chars (e.g. 0x1234, which is a IntegerLiteral),
1905/// though.
1906///
1907/// Example matches 'a', L'a'
1908/// \code
1909/// char ch = 'a';
1910/// wchar_t chw = L'a';
1911/// \endcode
1912extern const internal::VariadicDynCastAllOfMatcher<Stmt, CharacterLiteral>
1913 characterLiteral;
1914
1915/// \brief Matches integer literals of all sizes / encodings, e.g.
1916/// 1, 1L, 0x1 and 1U.
1917///
1918/// Does not match character-encoded integers such as L'a'.
1919extern const internal::VariadicDynCastAllOfMatcher<Stmt, IntegerLiteral>
1920 integerLiteral;
1921
1922/// \brief Matches float literals of all sizes / encodings, e.g.
1923/// 1.0, 1.0f, 1.0L and 1e10.
1924///
1925/// Does not match implicit conversions such as
1926/// \code
1927/// float a = 10;
1928/// \endcode
1929extern const internal::VariadicDynCastAllOfMatcher<Stmt, FloatingLiteral>
1930 floatLiteral;
1931
1932/// \brief Matches user defined literal operator call.
1933///
1934/// Example match: "foo"_suffix
1935extern const internal::VariadicDynCastAllOfMatcher<Stmt, UserDefinedLiteral>
1936 userDefinedLiteral;
1937
1938/// \brief Matches compound (i.e. non-scalar) literals
1939///
1940/// Example match: {1}, (1, 2)
1941/// \code
1942/// int array[4] = {1};
1943/// vector int myvec = (vector int)(1, 2);
1944/// \endcode
1945extern const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundLiteralExpr>
1946 compoundLiteralExpr;
1947
1948/// \brief Matches nullptr literal.
1949extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNullPtrLiteralExpr>
1950 cxxNullPtrLiteralExpr;
1951
1952/// \brief Matches GNU __null expression.
1953extern const internal::VariadicDynCastAllOfMatcher<Stmt, GNUNullExpr>
1954 gnuNullExpr;
1955
1956/// \brief Matches atomic builtins.
1957/// Example matches __atomic_load_n(ptr, 1)
1958/// \code
1959/// void foo() { int *ptr; __atomic_load_n(ptr, 1); }
1960/// \endcode
1961extern const internal::VariadicDynCastAllOfMatcher<Stmt, AtomicExpr> atomicExpr;
1962
1963/// \brief Matches statement expression (GNU extension).
1964///
1965/// Example match: ({ int X = 4; X; })
1966/// \code
1967/// int C = ({ int X = 4; X; });
1968/// \endcode
1969extern const internal::VariadicDynCastAllOfMatcher<Stmt, StmtExpr> stmtExpr;
1970
1971/// \brief Matches binary operator expressions.
1972///
1973/// Example matches a || b
1974/// \code
1975/// !(a || b)
1976/// \endcode
1977extern const internal::VariadicDynCastAllOfMatcher<Stmt, BinaryOperator>
1978 binaryOperator;
1979
1980/// \brief Matches unary operator expressions.
1981///
1982/// Example matches !a
1983/// \code
1984/// !a || b
1985/// \endcode
1986extern const internal::VariadicDynCastAllOfMatcher<Stmt, UnaryOperator>
1987 unaryOperator;
1988
1989/// \brief Matches conditional operator expressions.
1990///
1991/// Example matches a ? b : c
1992/// \code
1993/// (a ? b : c) + 42
1994/// \endcode
1995extern const internal::VariadicDynCastAllOfMatcher<Stmt, ConditionalOperator>
1996 conditionalOperator;
1997
1998/// \brief Matches binary conditional operator expressions (GNU extension).
1999///
2000/// Example matches a ?: b
2001/// \code
2002/// (a ?: b) + 42;
2003/// \endcode
2004extern const internal::VariadicDynCastAllOfMatcher<Stmt,
2005 BinaryConditionalOperator>
2006 binaryConditionalOperator;
2007
2008/// \brief Matches opaque value expressions. They are used as helpers
2009/// to reference another expressions and can be met
2010/// in BinaryConditionalOperators, for example.
2011///
2012/// Example matches 'a'
2013/// \code
2014/// (a ?: c) + 42;
2015/// \endcode
2016extern const internal::VariadicDynCastAllOfMatcher<Stmt, OpaqueValueExpr>
2017 opaqueValueExpr;
2018
2019/// \brief Matches a C++ static_assert declaration.
2020///
2021/// Example:
2022/// staticAssertExpr()
2023/// matches
2024/// static_assert(sizeof(S) == sizeof(int))
2025/// in
2026/// \code
2027/// struct S {
2028/// int x;
2029/// };
2030/// static_assert(sizeof(S) == sizeof(int));
2031/// \endcode
2032extern const internal::VariadicDynCastAllOfMatcher<Decl, StaticAssertDecl>
2033 staticAssertDecl;
2034
2035/// \brief Matches a reinterpret_cast expression.
2036///
2037/// Either the source expression or the destination type can be matched
2038/// using has(), but hasDestinationType() is more specific and can be
2039/// more readable.
2040///
2041/// Example matches reinterpret_cast<char*>(&p) in
2042/// \code
2043/// void* p = reinterpret_cast<char*>(&p);
2044/// \endcode
2045extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXReinterpretCastExpr>
2046 cxxReinterpretCastExpr;
2047
2048/// \brief Matches a C++ static_cast expression.
2049///
2050/// \see hasDestinationType
2051/// \see reinterpretCast
2052///
2053/// Example:
2054/// cxxStaticCastExpr()
2055/// matches
2056/// static_cast<long>(8)
2057/// in
2058/// \code
2059/// long eight(static_cast<long>(8));
2060/// \endcode
2061extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXStaticCastExpr>
2062 cxxStaticCastExpr;
2063
2064/// \brief Matches a dynamic_cast expression.
2065///
2066/// Example:
2067/// cxxDynamicCastExpr()
2068/// matches
2069/// dynamic_cast<D*>(&b);
2070/// in
2071/// \code
2072/// struct B { virtual ~B() {} }; struct D : B {};
2073/// B b;
2074/// D* p = dynamic_cast<D*>(&b);
2075/// \endcode
2076extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDynamicCastExpr>
2077 cxxDynamicCastExpr;
2078
2079/// \brief Matches a const_cast expression.
2080///
2081/// Example: Matches const_cast<int*>(&r) in
2082/// \code
2083/// int n = 42;
2084/// const int &r(n);
2085/// int* p = const_cast<int*>(&r);
2086/// \endcode
2087extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstCastExpr>
2088 cxxConstCastExpr;
2089
2090/// \brief Matches a C-style cast expression.
2091///
2092/// Example: Matches (int) 2.2f in
2093/// \code
2094/// int i = (int) 2.2f;
2095/// \endcode
2096extern const internal::VariadicDynCastAllOfMatcher<Stmt, CStyleCastExpr>
2097 cStyleCastExpr;
2098
2099/// \brief Matches explicit cast expressions.
2100///
2101/// Matches any cast expression written in user code, whether it be a
2102/// C-style cast, a functional-style cast, or a keyword cast.
2103///
2104/// Does not match implicit conversions.
2105///
2106/// Note: the name "explicitCast" is chosen to match Clang's terminology, as
2107/// Clang uses the term "cast" to apply to implicit conversions as well as to
2108/// actual cast expressions.
2109///
2110/// \see hasDestinationType.
2111///
2112/// Example: matches all five of the casts in
2113/// \code
2114/// int((int)(reinterpret_cast<int>(static_cast<int>(const_cast<int>(42)))))
2115/// \endcode
2116/// but does not match the implicit conversion in
2117/// \code
2118/// long ell = 42;
2119/// \endcode
2120extern const internal::VariadicDynCastAllOfMatcher<Stmt, ExplicitCastExpr>
2121 explicitCastExpr;
2122
2123/// \brief Matches the implicit cast nodes of Clang's AST.
2124///
2125/// This matches many different places, including function call return value
2126/// eliding, as well as any type conversions.
2127extern const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitCastExpr>
2128 implicitCastExpr;
2129
2130/// \brief Matches any cast nodes of Clang's AST.
2131///
2132/// Example: castExpr() matches each of the following:
2133/// \code
2134/// (int) 3;
2135/// const_cast<Expr *>(SubExpr);
2136/// char c = 0;
2137/// \endcode
2138/// but does not match
2139/// \code
2140/// int i = (0);
2141/// int k = 0;
2142/// \endcode
2143extern const internal::VariadicDynCastAllOfMatcher<Stmt, CastExpr> castExpr;
2144
2145/// \brief Matches functional cast expressions
2146///
2147/// Example: Matches Foo(bar);
2148/// \code
2149/// Foo f = bar;
2150/// Foo g = (Foo) bar;
2151/// Foo h = Foo(bar);
2152/// \endcode
2153extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXFunctionalCastExpr>
2154 cxxFunctionalCastExpr;
2155
2156/// \brief Matches functional cast expressions having N != 1 arguments
2157///
2158/// Example: Matches Foo(bar, bar)
2159/// \code
2160/// Foo h = Foo(bar, bar);
2161/// \endcode
2162extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTemporaryObjectExpr>
2163 cxxTemporaryObjectExpr;
2164
2165/// \brief Matches predefined identifier expressions [C99 6.4.2.2].
2166///
2167/// Example: Matches __func__
2168/// \code
2169/// printf("%s", __func__);
2170/// \endcode
2171extern const internal::VariadicDynCastAllOfMatcher<Stmt, PredefinedExpr>
2172 predefinedExpr;
2173
2174/// \brief Matches C99 designated initializer expressions [C99 6.7.8].
2175///
2176/// Example: Matches { [2].y = 1.0, [0].x = 1.0 }
2177/// \code
2178/// point ptarray[10] = { [2].y = 1.0, [0].x = 1.0 };
2179/// \endcode
2180extern const internal::VariadicDynCastAllOfMatcher<Stmt, DesignatedInitExpr>
2181 designatedInitExpr;
2182
2183/// \brief Matches designated initializer expressions that contain
2184/// a specific number of designators.
2185///
2186/// Example: Given
2187/// \code
2188/// point ptarray[10] = { [2].y = 1.0, [0].x = 1.0 };
2189/// point ptarray2[10] = { [2].y = 1.0, [2].x = 0.0, [0].x = 1.0 };
2190/// \endcode
2191/// designatorCountIs(2)
2192/// matches '{ [2].y = 1.0, [0].x = 1.0 }',
2193/// but not '{ [2].y = 1.0, [2].x = 0.0, [0].x = 1.0 }'.
2194AST_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 const 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
{
2195 return Node.size() == N;
2196}
2197
2198/// \brief Matches \c QualTypes in the clang AST.
2199extern const internal::VariadicAllOfMatcher<QualType> qualType;
2200
2201/// \brief Matches \c Types in the clang AST.
2202extern const internal::VariadicAllOfMatcher<Type> type;
2203
2204/// \brief Matches \c TypeLocs in the clang AST.
2205extern const internal::VariadicAllOfMatcher<TypeLoc> typeLoc;
2206
2207/// \brief Matches if any of the given matchers matches.
2208///
2209/// Unlike \c anyOf, \c eachOf will generate a match result for each
2210/// matching submatcher.
2211///
2212/// For example, in:
2213/// \code
2214/// class A { int a; int b; };
2215/// \endcode
2216/// The matcher:
2217/// \code
2218/// cxxRecordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
2219/// has(fieldDecl(hasName("b")).bind("v"))))
2220/// \endcode
2221/// will generate two results binding "v", the first of which binds
2222/// the field declaration of \c a, the second the field declaration of
2223/// \c b.
2224///
2225/// Usable as: Any Matcher
2226extern const internal::VariadicOperatorMatcherFunc<
2227 2, std::numeric_limits<unsigned>::max()>
2228 eachOf;
2229
2230/// \brief Matches if any of the given matchers matches.
2231///
2232/// Usable as: Any Matcher
2233extern const internal::VariadicOperatorMatcherFunc<
2234 2, std::numeric_limits<unsigned>::max()>
2235 anyOf;
2236
2237/// \brief Matches if all given matchers match.
2238///
2239/// Usable as: Any Matcher
2240extern const internal::VariadicOperatorMatcherFunc<
2241 2, std::numeric_limits<unsigned>::max()>
2242 allOf;
2243
2244/// \brief Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL)
2245///
2246/// Given
2247/// \code
2248/// Foo x = bar;
2249/// int y = sizeof(x) + alignof(x);
2250/// \endcode
2251/// unaryExprOrTypeTraitExpr()
2252/// matches \c sizeof(x) and \c alignof(x)
2253extern const internal::VariadicDynCastAllOfMatcher<Stmt,
2254 UnaryExprOrTypeTraitExpr>
2255 unaryExprOrTypeTraitExpr;
2256
2257/// \brief Matches unary expressions that have a specific type of argument.
2258///
2259/// Given
2260/// \code
2261/// int a, c; float b; int s = sizeof(a) + sizeof(b) + alignof(c);
2262/// \endcode
2263/// unaryExprOrTypeTraitExpr(hasArgumentOfType(asString("int"))
2264/// matches \c sizeof(a) and \c alignof(c)
2265AST_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
> const 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
2266 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
> const 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
{
2267 const QualType ArgumentType = Node.getTypeOfArgument();
2268 return InnerMatcher.matches(ArgumentType, Finder, Builder);
2269}
2270
2271/// \brief Matches unary expressions of a certain kind.
2272///
2273/// Given
2274/// \code
2275/// int x;
2276/// int s = sizeof(x) + alignof(x)
2277/// \endcode
2278/// unaryExprOrTypeTraitExpr(ofKind(UETT_SizeOf))
2279/// matches \c sizeof(x)
2280AST_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 const
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
{
2281 return Node.getKind() == Kind;
2282}
2283
2284/// \brief Same as unaryExprOrTypeTraitExpr, but only matching
2285/// alignof.
2286inline internal::Matcher<Stmt> alignOfExpr(
2287 const internal::Matcher<UnaryExprOrTypeTraitExpr> &InnerMatcher) {
2288 return stmt(unaryExprOrTypeTraitExpr(allOf(
2289 ofKind(UETT_AlignOf), InnerMatcher)));
2290}
2291
2292/// \brief Same as unaryExprOrTypeTraitExpr, but only matching
2293/// sizeof.
2294inline internal::Matcher<Stmt> sizeOfExpr(
2295 const internal::Matcher<UnaryExprOrTypeTraitExpr> &InnerMatcher) {
2296 return stmt(unaryExprOrTypeTraitExpr(
2297 allOf(ofKind(UETT_SizeOf), InnerMatcher)));
2298}
2299
2300/// \brief Matches NamedDecl nodes that have the specified name.
2301///
2302/// Supports specifying enclosing namespaces or classes by prefixing the name
2303/// with '<enclosing>::'.
2304/// Does not match typedefs of an underlying type with the given name.
2305///
2306/// Example matches X (Name == "X")
2307/// \code
2308/// class X;
2309/// \endcode
2310///
2311/// Example matches X (Name is one of "::a::b::X", "a::b::X", "b::X", "X")
2312/// \code
2313/// namespace a { namespace b { class X; } }
2314/// \endcode
2315inline internal::Matcher<NamedDecl> hasName(const std::string &Name) {
2316 std::vector<std::string> Names;
2317 Names.push_back(Name);
2318 return internal::Matcher<NamedDecl>(new internal::HasNameMatcher(Names));
5
Memory is allocated
2319}
2320
2321/// \brief Matches NamedDecl nodes that have any of the specified names.
2322///
2323/// This matcher is only provided as a performance optimization of hasName.
2324/// \code
2325/// hasAnyName(a, b, c)
2326/// \endcode
2327/// is equivalent to, but faster than
2328/// \code
2329/// anyOf(hasName(a), hasName(b), hasName(c))
2330/// \endcode
2331extern const internal::VariadicFunction<internal::Matcher<NamedDecl>, StringRef,
2332 internal::hasAnyNameFunc>
2333 hasAnyName;
2334
2335/// \brief Matches NamedDecl nodes whose fully qualified names contain
2336/// a substring matched by the given RegExp.
2337///
2338/// Supports specifying enclosing namespaces or classes by
2339/// prefixing the name with '<enclosing>::'. Does not match typedefs
2340/// of an underlying type with the given name.
2341///
2342/// Example matches X (regexp == "::X")
2343/// \code
2344/// class X;
2345/// \endcode
2346///
2347/// Example matches X (regexp is one of "::X", "^foo::.*X", among others)
2348/// \code
2349/// namespace foo { namespace bar { class X; } }
2350/// \endcode
2351AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp)namespace internal { class matcher_matchesName0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<NamedDecl
> { public: explicit matcher_matchesName0Matcher( std::string
const &ARegExp) : RegExp(ARegExp) {} bool matches(const NamedDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string const RegExp;
}; } inline ::clang::ast_matchers::internal::Matcher<NamedDecl
> matchesName( std::string const &RegExp) { return ::clang
::ast_matchers::internal::makeMatcher( new internal::matcher_matchesName0Matcher
(RegExp)); } typedef ::clang::ast_matchers::internal::Matcher
<NamedDecl>( &matchesName_Type0)(std::string const &
RegExp); inline bool internal::matcher_matchesName0Matcher::matches
( const NamedDecl &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
2352 assert(!RegExp.empty())(static_cast <bool> (!RegExp.empty()) ? void (0) : __assert_fail
("!RegExp.empty()", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/include/clang/ASTMatchers/ASTMatchers.h"
, 2352, __extension__ __PRETTY_FUNCTION__))
;
2353 std::string FullNameString = "::" + Node.getQualifiedNameAsString();
2354 llvm::Regex RE(RegExp);
2355 return RE.match(FullNameString);
2356}
2357
2358/// \brief Matches overloaded operator names.
2359///
2360/// Matches overloaded operator names specified in strings without the
2361/// "operator" prefix: e.g. "<<".
2362///
2363/// Given:
2364/// \code
2365/// class A { int operator*(); };
2366/// const A &operator<<(const A &a, const A &b);
2367/// A a;
2368/// a << a; // <-- This matches
2369/// \endcode
2370///
2371/// \c cxxOperatorCallExpr(hasOverloadedOperatorName("<<"))) matches the
2372/// specified line and
2373/// \c cxxRecordDecl(hasMethod(hasOverloadedOperatorName("*")))
2374/// matches the declaration of \c A.
2375///
2376/// Usable as: Matcher<CXXOperatorCallExpr>, Matcher<FunctionDecl>
2377inline internal::PolymorphicMatcherWithParam1<
2378 internal::HasOverloadedOperatorNameMatcher, StringRef,
2379 AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)void(::clang::ast_matchers::internal::TypeList<CXXOperatorCallExpr
, FunctionDecl>)
>
2380hasOverloadedOperatorName(StringRef Name) {
2381 return internal::PolymorphicMatcherWithParam1<
2382 internal::HasOverloadedOperatorNameMatcher, StringRef,
2383 AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)void(::clang::ast_matchers::internal::TypeList<CXXOperatorCallExpr
, FunctionDecl>)
>(Name);
2384}
2385
2386/// \brief Matches C++ classes that are directly or indirectly derived from
2387/// a class matching \c Base.
2388///
2389/// Note that a class is not considered to be derived from itself.
2390///
2391/// Example matches Y, Z, C (Base == hasName("X"))
2392/// \code
2393/// class X;
2394/// class Y : public X {}; // directly derived
2395/// class Z : public Y {}; // indirectly derived
2396/// typedef X A;
2397/// typedef A B;
2398/// class C : public B {}; // derived from a typedef of X
2399/// \endcode
2400///
2401/// In the following example, Bar matches isDerivedFrom(hasName("X")):
2402/// \code
2403/// class Foo;
2404/// typedef Foo X;
2405/// class Bar : public Foo {}; // derived from a type that X is a typedef of
2406/// \endcode
2407AST_MATCHER_P(CXXRecordDecl, isDerivedFrom,namespace internal { class matcher_isDerivedFrom0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXRecordDecl
> { public: explicit matcher_isDerivedFrom0Matcher( internal
::Matcher<NamedDecl> const &ABase) : Base(ABase) {}
bool matches(const CXXRecordDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<NamedDecl> const Base; }; } inline ::clang::ast_matchers
::internal::Matcher<CXXRecordDecl> isDerivedFrom( internal
::Matcher<NamedDecl> const &Base) { return ::clang::
ast_matchers::internal::makeMatcher( new internal::matcher_isDerivedFrom0Matcher
(Base)); } typedef ::clang::ast_matchers::internal::Matcher<
CXXRecordDecl>( &isDerivedFrom_Type0)(internal::Matcher
<NamedDecl> const &Base); inline bool internal::matcher_isDerivedFrom0Matcher
::matches( const CXXRecordDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
2408 internal::Matcher<NamedDecl>, Base)namespace internal { class matcher_isDerivedFrom0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXRecordDecl
> { public: explicit matcher_isDerivedFrom0Matcher( internal
::Matcher<NamedDecl> const &ABase) : Base(ABase) {}
bool matches(const CXXRecordDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<NamedDecl> const Base; }; } inline ::clang::ast_matchers
::internal::Matcher<CXXRecordDecl> isDerivedFrom( internal
::Matcher<NamedDecl> const &Base) { return ::clang::
ast_matchers::internal::makeMatcher( new internal::matcher_isDerivedFrom0Matcher
(Base)); } typedef ::clang::ast_matchers::internal::Matcher<
CXXRecordDecl>( &isDerivedFrom_Type0)(internal::Matcher
<NamedDecl> const &Base); inline bool internal::matcher_isDerivedFrom0Matcher
::matches( const CXXRecordDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
2409 return Finder->classIsDerivedFrom(&Node, Base, Builder);
2410}
2411
2412/// \brief Overloaded method as shortcut for \c isDerivedFrom(hasName(...)).
2413AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isDerivedFrom, std::string, BaseName, 1)namespace internal { class matcher_isDerivedFrom1Matcher : public
::clang::ast_matchers::internal::MatcherInterface<CXXRecordDecl
> { public: explicit matcher_isDerivedFrom1Matcher( std::string
const &ABaseName) : BaseName(ABaseName) {} bool matches(
const CXXRecordDecl &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string const BaseName
; }; } inline ::clang::ast_matchers::internal::Matcher<CXXRecordDecl
> isDerivedFrom( std::string const &BaseName) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_isDerivedFrom1Matcher(BaseName)); } typedef ::clang::
ast_matchers::internal::Matcher<CXXRecordDecl>( &isDerivedFrom_Type1
)(std::string const &BaseName); inline bool internal::matcher_isDerivedFrom1Matcher
::matches( const CXXRecordDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
2414 assert(!BaseName.empty())(static_cast <bool> (!BaseName.empty()) ? void (0) : __assert_fail
("!BaseName.empty()", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/include/clang/ASTMatchers/ASTMatchers.h"
, 2414, __extension__ __PRETTY_FUNCTION__))
;
2415 return isDerivedFrom(hasName(BaseName)).matches(Node, Finder, Builder);
2416}
2417
2418/// \brief Similar to \c isDerivedFrom(), but also matches classes that directly
2419/// match \c Base.
2420AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isSameOrDerivedFrom,namespace internal { class matcher_isSameOrDerivedFrom0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
CXXRecordDecl> { public: explicit matcher_isSameOrDerivedFrom0Matcher
( internal::Matcher<NamedDecl> const &ABase) : Base
(ABase) {} bool matches(const CXXRecordDecl &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<NamedDecl> const Base; }; } inline ::
clang::ast_matchers::internal::Matcher<CXXRecordDecl> isSameOrDerivedFrom
( internal::Matcher<NamedDecl> const &Base) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_isSameOrDerivedFrom0Matcher(Base)); } typedef ::clang
::ast_matchers::internal::Matcher<CXXRecordDecl>( &
isSameOrDerivedFrom_Type0)(internal::Matcher<NamedDecl>
const &Base); inline bool internal::matcher_isSameOrDerivedFrom0Matcher
::matches( const CXXRecordDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
2421 internal::Matcher<NamedDecl>, Base, 0)namespace internal { class matcher_isSameOrDerivedFrom0Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
CXXRecordDecl> { public: explicit matcher_isSameOrDerivedFrom0Matcher
( internal::Matcher<NamedDecl> const &ABase) : Base
(ABase) {} bool matches(const CXXRecordDecl &Node, ::clang
::ast_matchers::internal::ASTMatchFinder *Finder, ::clang::ast_matchers
::internal::BoundNodesTreeBuilder *Builder) const override; private
: internal::Matcher<NamedDecl> const Base; }; } inline ::
clang::ast_matchers::internal::Matcher<CXXRecordDecl> isSameOrDerivedFrom
( internal::Matcher<NamedDecl> const &Base) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_isSameOrDerivedFrom0Matcher(Base)); } typedef ::clang
::ast_matchers::internal::Matcher<CXXRecordDecl>( &
isSameOrDerivedFrom_Type0)(internal::Matcher<NamedDecl>
const &Base); inline bool internal::matcher_isSameOrDerivedFrom0Matcher
::matches( const CXXRecordDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
2422 return Matcher<CXXRecordDecl>(anyOf(Base, isDerivedFrom(Base)))
2423 .matches(Node, Finder, Builder);
2424}
2425
2426/// \brief Overloaded method as shortcut for
2427/// \c isSameOrDerivedFrom(hasName(...)).
2428AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isSameOrDerivedFrom, std::string,namespace internal { class matcher_isSameOrDerivedFrom1Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
CXXRecordDecl> { public: explicit matcher_isSameOrDerivedFrom1Matcher
( std::string const &ABaseName) : BaseName(ABaseName) {} bool
matches(const CXXRecordDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: std
::string const BaseName; }; } inline ::clang::ast_matchers::internal
::Matcher<CXXRecordDecl> isSameOrDerivedFrom( std::string
const &BaseName) { return ::clang::ast_matchers::internal
::makeMatcher( new internal::matcher_isSameOrDerivedFrom1Matcher
(BaseName)); } typedef ::clang::ast_matchers::internal::Matcher
<CXXRecordDecl>( &isSameOrDerivedFrom_Type1)(std::string
const &BaseName); inline bool internal::matcher_isSameOrDerivedFrom1Matcher
::matches( const CXXRecordDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
2429 BaseName, 1)namespace internal { class matcher_isSameOrDerivedFrom1Matcher
: public ::clang::ast_matchers::internal::MatcherInterface<
CXXRecordDecl> { public: explicit matcher_isSameOrDerivedFrom1Matcher
( std::string const &ABaseName) : BaseName(ABaseName) {} bool
matches(const CXXRecordDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: std
::string const BaseName; }; } inline ::clang::ast_matchers::internal
::Matcher<CXXRecordDecl> isSameOrDerivedFrom( std::string
const &BaseName) { return ::clang::ast_matchers::internal
::makeMatcher( new internal::matcher_isSameOrDerivedFrom1Matcher
(BaseName)); } typedef ::clang::ast_matchers::internal::Matcher
<CXXRecordDecl>( &isSameOrDerivedFrom_Type1)(std::string
const &BaseName); inline bool internal::matcher_isSameOrDerivedFrom1Matcher
::matches( const CXXRecordDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
2430 assert(!BaseName.empty())(static_cast <bool> (!BaseName.empty()) ? void (0) : __assert_fail
("!BaseName.empty()", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/include/clang/ASTMatchers/ASTMatchers.h"
, 2430, __extension__ __PRETTY_FUNCTION__))
;
2431 return isSameOrDerivedFrom(hasName(BaseName)).matches(Node, Finder, Builder);
2432}
2433
2434/// \brief Matches the first method of a class or struct that satisfies \c
2435/// InnerMatcher.
2436///
2437/// Given:
2438/// \code
2439/// class A { void func(); };
2440/// class B { void member(); };
2441/// \endcode
2442///
2443/// \c cxxRecordDecl(hasMethod(hasName("func"))) matches the declaration of
2444/// \c A but not \c B.
2445AST_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
> const 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
2446 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
> const 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
{
2447 return matchesFirstInPointerRange(InnerMatcher, Node.method_begin(),
2448 Node.method_end(), Finder, Builder);
2449}
2450
2451/// \brief Matches the generated class of lambda expressions.
2452///
2453/// Given:
2454/// \code
2455/// auto x = []{};
2456/// \endcode
2457///
2458/// \c cxxRecordDecl(isLambda()) matches the implicit class declaration of
2459/// \c decltype(x)
2460AST_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
{
2461 return Node.isLambda();
2462}
2463
2464/// \brief Matches AST nodes that have child AST nodes that match the
2465/// provided matcher.
2466///
2467/// Example matches X, Y
2468/// (matcher = cxxRecordDecl(has(cxxRecordDecl(hasName("X")))
2469/// \code
2470/// class X {}; // Matches X, because X::X is a class of name X inside X.
2471/// class Y { class X {}; };
2472/// class Z { class Y { class X {}; }; }; // Does not match Z.
2473/// \endcode
2474///
2475/// ChildT must be an AST base type.
2476///
2477/// Usable as: Any Matcher
2478/// Note that has is direct matcher, so it also matches things like implicit
2479/// casts and paren casts. If you are matching with expr then you should
2480/// probably consider using ignoringParenImpCasts like:
2481/// has(ignoringParenImpCasts(expr())).
2482extern const internal::ArgumentAdaptingMatcherFunc<internal::HasMatcher> has;
2483
2484/// \brief Matches AST nodes that have descendant AST nodes that match the
2485/// provided matcher.
2486///
2487/// Example matches X, Y, Z
2488/// (matcher = cxxRecordDecl(hasDescendant(cxxRecordDecl(hasName("X")))))
2489/// \code
2490/// class X {}; // Matches X, because X::X is a class of name X inside X.
2491/// class Y { class X {}; };
2492/// class Z { class Y { class X {}; }; };
2493/// \endcode
2494///
2495/// DescendantT must be an AST base type.
2496///
2497/// Usable as: Any Matcher
2498extern const internal::ArgumentAdaptingMatcherFunc<
2499 internal::HasDescendantMatcher>
2500 hasDescendant;
2501
2502/// \brief Matches AST nodes that have child AST nodes that match the
2503/// provided matcher.
2504///
2505/// Example matches X, Y, Y::X, Z::Y, Z::Y::X
2506/// (matcher = cxxRecordDecl(forEach(cxxRecordDecl(hasName("X")))
2507/// \code
2508/// class X {};
2509/// class Y { class X {}; }; // Matches Y, because Y::X is a class of name X
2510/// // inside Y.
2511/// class Z { class Y { class X {}; }; }; // Does not match Z.
2512/// \endcode
2513///
2514/// ChildT must be an AST base type.
2515///
2516/// As opposed to 'has', 'forEach' will cause a match for each result that
2517/// matches instead of only on the first one.
2518///
2519/// Usable as: Any Matcher
2520extern const internal::ArgumentAdaptingMatcherFunc<internal::ForEachMatcher>
2521 forEach;
2522
2523/// \brief Matches AST nodes that have descendant AST nodes that match the
2524/// provided matcher.
2525///
2526/// Example matches X, A, A::X, B, B::C, B::C::X
2527/// (matcher = cxxRecordDecl(forEachDescendant(cxxRecordDecl(hasName("X")))))
2528/// \code
2529/// class X {};
2530/// class A { class X {}; }; // Matches A, because A::X is a class of name
2531/// // X inside A.
2532/// class B { class C { class X {}; }; };
2533/// \endcode
2534///
2535/// DescendantT must be an AST base type.
2536///
2537/// As opposed to 'hasDescendant', 'forEachDescendant' will cause a match for
2538/// each result that matches instead of only on the first one.
2539///
2540/// Note: Recursively combined ForEachDescendant can cause many matches:
2541/// cxxRecordDecl(forEachDescendant(cxxRecordDecl(
2542/// forEachDescendant(cxxRecordDecl())
2543/// )))
2544/// will match 10 times (plus injected class name matches) on:
2545/// \code
2546/// class A { class B { class C { class D { class E {}; }; }; }; };
2547/// \endcode
2548///
2549/// Usable as: Any Matcher
2550extern const internal::ArgumentAdaptingMatcherFunc<
2551 internal::ForEachDescendantMatcher>
2552 forEachDescendant;
2553
2554/// \brief Matches if the node or any descendant matches.
2555///
2556/// Generates results for each match.
2557///
2558/// For example, in:
2559/// \code
2560/// class A { class B {}; class C {}; };
2561/// \endcode
2562/// The matcher:
2563/// \code
2564/// cxxRecordDecl(hasName("::A"),
2565/// findAll(cxxRecordDecl(isDefinition()).bind("m")))
2566/// \endcode
2567/// will generate results for \c A, \c B and \c C.
2568///
2569/// Usable as: Any Matcher
2570template <typename T>
2571internal::Matcher<T> findAll(const internal::Matcher<T> &Matcher) {
2572 return eachOf(Matcher, forEachDescendant(Matcher));
2573}
2574
2575/// \brief Matches AST nodes that have a parent that matches the provided
2576/// matcher.
2577///
2578/// Given
2579/// \code
2580/// void f() { for (;;) { int x = 42; if (true) { int x = 43; } } }
2581/// \endcode
2582/// \c compoundStmt(hasParent(ifStmt())) matches "{ int x = 43; }".
2583///
2584/// Usable as: Any Matcher
2585extern const internal::ArgumentAdaptingMatcherFunc<
2586 internal::HasParentMatcher,
2587 internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>,
2588 internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>>
2589 hasParent;
2590
2591/// \brief Matches AST nodes that have an ancestor that matches the provided
2592/// matcher.
2593///
2594/// Given
2595/// \code
2596/// void f() { if (true) { int x = 42; } }
2597/// void g() { for (;;) { int x = 43; } }
2598/// \endcode
2599/// \c expr(integerLiteral(hasAncestor(ifStmt()))) matches \c 42, but not 43.
2600///
2601/// Usable as: Any Matcher
2602extern const internal::ArgumentAdaptingMatcherFunc<
2603 internal::HasAncestorMatcher,
2604 internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>,
2605 internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>>
2606 hasAncestor;
2607
2608/// \brief Matches if the provided matcher does not match.
2609///
2610/// Example matches Y (matcher = cxxRecordDecl(unless(hasName("X"))))
2611/// \code
2612/// class X {};
2613/// class Y {};
2614/// \endcode
2615///
2616/// Usable as: Any Matcher
2617extern const internal::VariadicOperatorMatcherFunc<1, 1> unless;
2618
2619/// \brief Matches a node if the declaration associated with that node
2620/// matches the given matcher.
2621///
2622/// The associated declaration is:
2623/// - for type nodes, the declaration of the underlying type
2624/// - for CallExpr, the declaration of the callee
2625/// - for MemberExpr, the declaration of the referenced member
2626/// - for CXXConstructExpr, the declaration of the constructor
2627/// - for CXXNewExpr, the declaration of the operator new
2628///
2629/// For type nodes, hasDeclaration will generally match the declaration of the
2630/// sugared type. Given
2631/// \code
2632/// class X {};
2633/// typedef X Y;
2634/// Y y;
2635/// \endcode
2636/// in varDecl(hasType(hasDeclaration(decl()))) the decl will match the
2637/// typedefDecl. A common use case is to match the underlying, desugared type.
2638/// This can be achieved by using the hasUnqualifiedDesugaredType matcher:
2639/// \code
2640/// varDecl(hasType(hasUnqualifiedDesugaredType(
2641/// recordType(hasDeclaration(decl())))))
2642/// \endcode
2643/// In this matcher, the decl will match the CXXRecordDecl of class X.
2644///
2645/// Usable as: Matcher<AddrLabelExpr>, Matcher<CallExpr>,
2646/// Matcher<CXXConstructExpr>, Matcher<CXXNewExpr>, Matcher<DeclRefExpr>,
2647/// Matcher<EnumType>, Matcher<InjectedClassNameType>, Matcher<LabelStmt>,
2648/// Matcher<MemberExpr>, Matcher<QualType>, Matcher<RecordType>,
2649/// Matcher<TagType>, Matcher<TemplateSpecializationType>,
2650/// Matcher<TemplateTypeParmType>, Matcher<TypedefType>,
2651/// Matcher<UnresolvedUsingType>
2652inline internal::PolymorphicMatcherWithParam1<
2653 internal::HasDeclarationMatcher, internal::Matcher<Decl>,
2654 void(internal::HasDeclarationSupportedTypes)>
2655hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) {
2656 return internal::PolymorphicMatcherWithParam1<
2657 internal::HasDeclarationMatcher, internal::Matcher<Decl>,
2658 void(internal::HasDeclarationSupportedTypes)>(InnerMatcher);
2659}
2660
2661/// \brief Matches a \c NamedDecl whose underlying declaration matches the given
2662/// matcher.
2663///
2664/// Given
2665/// \code
2666/// namespace N { template<class T> void f(T t); }
2667/// template <class T> void g() { using N::f; f(T()); }
2668/// \endcode
2669/// \c unresolvedLookupExpr(hasAnyDeclaration(
2670/// namedDecl(hasUnderlyingDecl(hasName("::N::f")))))
2671/// matches the use of \c f in \c g() .
2672AST_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
> const 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
2673 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
> const 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
{
2674 const NamedDecl *UnderlyingDecl = Node.getUnderlyingDecl();
2675
2676 return UnderlyingDecl != nullptr &&
2677 InnerMatcher.matches(*UnderlyingDecl, Finder, Builder);
2678}
2679
2680/// \brief Matches on the implicit object argument of a member call expression.
2681///
2682/// Example matches y.x()
2683/// (matcher = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y"))))))
2684/// \code
2685/// class Y { public: void x(); };
2686/// void z() { Y y; y.x(); }
2687/// \endcode
2688///
2689/// FIXME: Overload to allow directly matching types?
2690AST_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> const 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
2691 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> const 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
{
2692 const Expr *ExprNode = Node.getImplicitObjectArgument()
2693 ->IgnoreParenImpCasts();
2694 return (ExprNode != nullptr &&
2695 InnerMatcher.matches(*ExprNode, Finder, Builder));
2696}
2697
2698
2699/// \brief Matches on the receiver of an ObjectiveC Message expression.
2700///
2701/// Example
2702/// matcher = objCMessageExpr(hasReceiverType(asString("UIWebView *")));
2703/// matches the [webView ...] message invocation.
2704/// \code
2705/// NSString *webViewJavaScript = ...
2706/// UIWebView *webView = ...
2707/// [webView stringByEvaluatingJavaScriptFromString:webViewJavascript];
2708/// \endcode
2709AST_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> const
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
2710 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> const
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
{
2711 const QualType TypeDecl = Node.getReceiverType();
2712 return InnerMatcher.matches(TypeDecl, Finder, Builder);
2713}
2714
2715/// \brief Matches when BaseName == Selector.getAsString()
2716///
2717/// matcher = objCMessageExpr(hasSelector("loadHTMLString:baseURL:"));
2718/// matches the outer message expr in the code below, but NOT the message
2719/// invocation for self.bodyView.
2720/// \code
2721/// [self.bodyView loadHTMLString:html baseURL:NULL];
2722/// \endcode
2723AST_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 const 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
{
2724 Selector Sel = Node.getSelector();
2725 return BaseName.compare(Sel.getAsString()) == 0;
2726}
2727
2728
2729/// \brief Matches ObjC selectors whose name contains
2730/// a substring matched by the given RegExp.
2731/// matcher = objCMessageExpr(matchesSelector("loadHTMLString\:baseURL?"));
2732/// matches the outer message expr in the code below, but NOT the message
2733/// invocation for self.bodyView.
2734/// \code
2735/// [self.bodyView loadHTMLString:html baseURL:NULL];
2736/// \endcode
2737AST_MATCHER_P(ObjCMessageExpr, matchesSelector, std::string, RegExp)namespace internal { class matcher_matchesSelector0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<ObjCMessageExpr
> { public: explicit matcher_matchesSelector0Matcher( std::
string const &ARegExp) : RegExp(ARegExp) {} bool matches(
const ObjCMessageExpr &Node, ::clang::ast_matchers::internal
::ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: std::string const RegExp;
}; } inline ::clang::ast_matchers::internal::Matcher<ObjCMessageExpr
> matchesSelector( std::string const &RegExp) { return
::clang::ast_matchers::internal::makeMatcher( new internal::
matcher_matchesSelector0Matcher(RegExp)); } typedef ::clang::
ast_matchers::internal::Matcher<ObjCMessageExpr>( &
matchesSelector_Type0)(std::string const &RegExp); inline
bool internal::matcher_matchesSelector0Matcher::matches( const
ObjCMessageExpr &Node, ::clang::ast_matchers::internal::
ASTMatchFinder *Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
2738 assert(!RegExp.empty())(static_cast <bool> (!RegExp.empty()) ? void (0) : __assert_fail
("!RegExp.empty()", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/include/clang/ASTMatchers/ASTMatchers.h"
, 2738, __extension__ __PRETTY_FUNCTION__))
;
2739 std::string SelectorString = Node.getSelector().getAsString();
2740 llvm::Regex RE(RegExp);
2741 return RE.match(SelectorString);
2742}
2743
2744/// \brief Matches when the selector is the empty selector
2745///
2746/// Matches only when the selector of the objCMessageExpr is NULL. This may
2747/// represent an error condition in the tree!
2748AST_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
{
2749 return Node.getSelector().isNull();
2750}
2751
2752/// \brief Matches when the selector is a Unary Selector
2753///
2754/// matcher = objCMessageExpr(matchesSelector(hasUnarySelector());
2755/// matches self.bodyView in the code below, but NOT the outer message
2756/// invocation of "loadHTMLString:baseURL:".
2757/// \code
2758/// [self.bodyView loadHTMLString:html baseURL:NULL];
2759/// \endcode
2760AST_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
{
2761 return Node.getSelector().isUnarySelector();
2762}
2763
2764/// \brief Matches when the selector is a keyword selector
2765///
2766/// objCMessageExpr(hasKeywordSelector()) matches the generated setFrame
2767/// message expression in
2768///
2769/// \code
2770/// UIWebView *webView = ...;
2771/// CGRect bodyFrame = webView.frame;
2772/// bodyFrame.size.height = self.bodyContentHeight;
2773/// webView.frame = bodyFrame;
2774/// // ^---- matches here
2775/// \endcode
2776AST_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
{
2777 return Node.getSelector().isKeywordSelector();
2778}
2779
2780/// \brief Matches when the selector has the specified number of arguments
2781///
2782/// matcher = objCMessageExpr(numSelectorArgs(0));
2783/// matches self.bodyView in the code below
2784///
2785/// matcher = objCMessageExpr(numSelectorArgs(2));
2786/// matches the invocation of "loadHTMLString:baseURL:" but not that
2787/// of self.bodyView
2788/// \code
2789/// [self.bodyView loadHTMLString:html baseURL:NULL];
2790/// \endcode
2791AST_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 const 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
{
2792 return Node.getSelector().getNumArgs() == N;
2793}
2794
2795/// \brief Matches if the call expression's callee expression matches.
2796///
2797/// Given
2798/// \code
2799/// class Y { void x() { this->x(); x(); Y y; y.x(); } };
2800/// void f() { f(); }
2801/// \endcode
2802/// callExpr(callee(expr()))
2803/// matches this->x(), x(), y.x(), f()
2804/// with callee(...)
2805/// matching this->x, x, y.x, f respectively
2806///
2807/// Note: Callee cannot take the more general internal::Matcher<Expr>
2808/// because this introduces ambiguous overloads with calls to Callee taking a
2809/// internal::Matcher<Decl>, as the matcher hierarchy is purely
2810/// implemented in terms of implicit casts.
2811AST_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> const 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
2812 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> const 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
{
2813 const Expr *ExprNode = Node.getCallee();
2814 return (ExprNode != nullptr &&
2815 InnerMatcher.matches(*ExprNode, Finder, Builder));
2816}
2817
2818/// \brief Matches if the call expression's callee's declaration matches the
2819/// given matcher.
2820///
2821/// Example matches y.x() (matcher = callExpr(callee(
2822/// cxxMethodDecl(hasName("x")))))
2823/// \code
2824/// class Y { public: void x(); };
2825/// void z() { Y y; y.x(); }
2826/// \endcode
2827AST_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> const 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
2828 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> const 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
{
2829 return callExpr(hasDeclaration(InnerMatcher)).matches(Node, Finder, Builder);
2830}
2831
2832/// \brief Matches if the expression's or declaration's type matches a type
2833/// matcher.
2834///
2835/// Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
2836/// and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
2837/// and U (matcher = typedefDecl(hasType(asString("int")))
2838/// \code
2839/// class X {};
2840/// void y(X &x) { x; X z; }
2841/// typedef int U;
2842/// \endcode
2843AST_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
> const InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcherWithParam1< internal::matcher_hasType0Matcher
, internal::Matcher<QualType>, void(::clang::ast_matchers
::internal::TypeList<Expr, TypedefNameDecl, ValueDecl>)
> hasType(internal::Matcher<QualType> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_hasType0Matcher, internal::Matcher<
QualType>, void(::clang::ast_matchers::internal::TypeList<
Expr, TypedefNameDecl, ValueDecl>)>(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_hasType0Matcher, internal::Matcher<
QualType>, void(::clang::ast_matchers::internal::TypeList<
Expr, TypedefNameDecl, ValueDecl>)>(&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
2844 hasType, AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, TypedefNameDecl, ValueDecl),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
> const InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcherWithParam1< internal::matcher_hasType0Matcher
, internal::Matcher<QualType>, void(::clang::ast_matchers
::internal::TypeList<Expr, TypedefNameDecl, ValueDecl>)
> hasType(internal::Matcher<QualType> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_hasType0Matcher, internal::Matcher<
QualType>, void(::clang::ast_matchers::internal::TypeList<
Expr, TypedefNameDecl, ValueDecl>)>(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_hasType0Matcher, internal::Matcher<
QualType>, void(::clang::ast_matchers::internal::TypeList<
Expr, TypedefNameDecl, ValueDecl>)>(&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
2845 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
> const InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcherWithParam1< internal::matcher_hasType0Matcher
, internal::Matcher<QualType>, void(::clang::ast_matchers
::internal::TypeList<Expr, TypedefNameDecl, ValueDecl>)
> hasType(internal::Matcher<QualType> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_hasType0Matcher, internal::Matcher<
QualType>, void(::clang::ast_matchers::internal::TypeList<
Expr, TypedefNameDecl, ValueDecl>)>(InnerMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_hasType0Matcher, internal::Matcher<
QualType>, void(::clang::ast_matchers::internal::TypeList<
Expr, TypedefNameDecl, ValueDecl>)>(&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
{
2846 return InnerMatcher.matches(internal::getUnderlyingType(Node),
2847 Finder, Builder);
2848}
2849
2850/// \brief Overloaded to match the declaration of the expression's or value
2851/// declaration's type.
2852///
2853/// In case of a value declaration (for example a variable declaration),
2854/// this resolves one layer of indirection. For example, in the value
2855/// declaration "X x;", cxxRecordDecl(hasName("X")) matches the declaration of
2856/// X, while varDecl(hasType(cxxRecordDecl(hasName("X")))) matches the
2857/// declaration of x.
2858///
2859/// Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
2860/// and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
2861/// \code
2862/// class X {};
2863/// void y(X &x) { x; X z; }
2864/// \endcode
2865///
2866/// Usable as: Matcher<Expr>, Matcher<ValueDecl>
2867AST_POLYMORPHIC_MATCHER_P_OVERLOAD(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
> const InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcherWithParam1< internal::matcher_hasType1Matcher
, internal::Matcher<Decl>, void(::clang::ast_matchers::
internal::TypeList<Expr, ValueDecl>)> hasType(internal
::Matcher<Decl> const &InnerMatcher) { return ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_hasType1Matcher, internal::Matcher<Decl>, void
(::clang::ast_matchers::internal::TypeList<Expr, ValueDecl
>)>(InnerMatcher); } typedef ::clang::ast_matchers::internal
::PolymorphicMatcherWithParam1< internal::matcher_hasType1Matcher
, internal::Matcher<Decl>, void(::clang::ast_matchers::
internal::TypeList<Expr, ValueDecl>)>(&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
2868 AST_POLYMORPHIC_SUPPORTED_TYPES(Expr,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
> const InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcherWithParam1< internal::matcher_hasType1Matcher
, internal::Matcher<Decl>, void(::clang::ast_matchers::
internal::TypeList<Expr, ValueDecl>)> hasType(internal
::Matcher<Decl> const &InnerMatcher) { return ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_hasType1Matcher, internal::Matcher<Decl>, void
(::clang::ast_matchers::internal::TypeList<Expr, ValueDecl
>)>(InnerMatcher); } typedef ::clang::ast_matchers::internal
::PolymorphicMatcherWithParam1< internal::matcher_hasType1Matcher
, internal::Matcher<Decl>, void(::clang::ast_matchers::
internal::TypeList<Expr, ValueDecl>)>(&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
2869 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
> const InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcherWithParam1< internal::matcher_hasType1Matcher
, internal::Matcher<Decl>, void(::clang::ast_matchers::
internal::TypeList<Expr, ValueDecl>)> hasType(internal
::Matcher<Decl> const &InnerMatcher) { return ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_hasType1Matcher, internal::Matcher<Decl>, void
(::clang::ast_matchers::internal::TypeList<Expr, ValueDecl
>)>(InnerMatcher); } typedef ::clang::ast_matchers::internal
::PolymorphicMatcherWithParam1< internal::matcher_hasType1Matcher
, internal::Matcher<Decl>, void(::clang::ast_matchers::
internal::TypeList<Expr, ValueDecl>)>(&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
2870 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
> const InnerMatcher; }; } inline ::clang::ast_matchers::internal
::PolymorphicMatcherWithParam1< internal::matcher_hasType1Matcher
, internal::Matcher<Decl>, void(::clang::ast_matchers::
internal::TypeList<Expr, ValueDecl>)> hasType(internal
::Matcher<Decl> const &InnerMatcher) { return ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_hasType1Matcher, internal::Matcher<Decl>, void
(::clang::ast_matchers::internal::TypeList<Expr, ValueDecl
>)>(InnerMatcher); } typedef ::clang::ast_matchers::internal
::PolymorphicMatcherWithParam1< internal::matcher_hasType1Matcher
, internal::Matcher<Decl>, void(::clang::ast_matchers::
internal::TypeList<Expr, ValueDecl>)>(&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
{
2871 return qualType(hasDeclaration(InnerMatcher))
2872 .matches(Node.getType(), Finder, Builder);
2873}
2874
2875/// \brief Matches if the type location of the declarator decl's type matches
2876/// the inner matcher.
2877///
2878/// Given
2879/// \code
2880/// int x;
2881/// \endcode
2882/// declaratorDecl(hasTypeLoc(loc(asString("int"))))
2883/// matches int x
2884AST_MATCHER_P(DeclaratorDecl, hasTypeLoc, internal::Matcher<TypeLoc>, Inner)namespace internal { class matcher_hasTypeLoc0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<DeclaratorDecl
> { public: explicit matcher_hasTypeLoc0Matcher( internal::
Matcher<TypeLoc> const &AInner) : Inner(AInner) {} bool
matches(const DeclaratorDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const override; private: internal
::Matcher<TypeLoc> const Inner; }; } inline ::clang::ast_matchers
::internal::Matcher<DeclaratorDecl> hasTypeLoc( internal
::Matcher<TypeLoc> const &Inner) { return ::clang::
ast_matchers::internal::makeMatcher( new internal::matcher_hasTypeLoc0Matcher
(Inner)); } typedef ::clang::ast_matchers::internal::Matcher<
DeclaratorDecl>( &hasTypeLoc_Type0)(internal::Matcher<
TypeLoc> const &Inner); inline bool internal::matcher_hasTypeLoc0Matcher
::matches( const DeclaratorDecl &Node, ::clang::ast_matchers
::internal::ASTMatchFinder *Finder, ::clang::ast_matchers::internal
::BoundNodesTreeBuilder *Builder) const
{
2885 if (!Node.getTypeSourceInfo())
2886 // This happens for example for implicit destructors.
2887 return false;
2888 return Inner.matches(Node.getTypeSourceInfo()->getTypeLoc(), Finder, Builder);
2889}
2890
2891/// \brief Matches if the matched type is represented by the given string.
2892///
2893/// Given
2894/// \code
2895/// class Y { public: void x(); };
2896/// void z() { Y* y; y->x(); }
2897/// \endcode
2898/// cxxMemberCallExpr(on(hasType(asString("class Y *"))))
2899/// matches y->x()
2900AST_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 const 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
{
2901 return Name == Node.getAsString();
2902}
2903
2904/// \brief Matches if the matched type is a pointer type and the pointee type
2905/// matches the specified matcher.
2906///
2907/// Example matches y->x()
2908/// (matcher = cxxMemberCallExpr(on(hasType(pointsTo
2909/// cxxRecordDecl(hasName("Y")))))))
2910/// \code
2911/// class Y { public: void x(); };
2912/// void z() { Y *y; y->x(); }
2913/// \endcode
2914AST_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> const 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
2915 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> const 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
2916 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> const 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
{
2917 return (!Node.isNull() && Node->isAnyPointerType() &&
2918 InnerMatcher.matches(Node->getPointeeType(), Finder, Builder));
2919}
2920
2921/// \brief Overloaded to match the pointee type's declaration.
2922AST_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> const 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
2923 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> const 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
{
2924 return pointsTo(qualType(hasDeclaration(InnerMatcher)))
2925 .matches(Node, Finder, Builder);
2926}
2927
2928/// \brief Matches if the matched type matches the unqualified desugared
2929/// type of the matched node.
2930///
2931/// For example, in:
2932/// \code
2933/// class A {};
2934/// using B = A;
2935/// \endcode
2936/// The matcher type(hasUnqualifeidDesugaredType(recordType())) matches
2937/// both B and A.
2938AST_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> const 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
2939 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> const 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
{
2940 return InnerMatcher.matches(*Node.getUnqualifiedDesugaredType(), Finder,
2941 Builder);
2942}
2943
2944/// \brief Matches if the matched type is a reference type and the referenced
2945/// type matches the specified matcher.
2946///
2947/// Example matches X &x and const X &y
2948/// (matcher = varDecl(hasType(references(cxxRecordDecl(hasName("X"))))))
2949/// \code
2950/// class X {
2951/// void a(X b) {
2952/// X &x = b;
2953/// const X &y = b;
2954/// }
2955/// };
2956/// \endcode
2957AST_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> const 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
2958 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> const 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
{
2959 return (!Node.isNull() && Node->isReferenceType() &&
2960 InnerMatcher.matches(Node->getPointeeType(), Finder, Builder));
2961}
2962
2963/// \brief Matches QualTypes whose canonical type matches InnerMatcher.
2964///
2965/// Given:
2966/// \code
2967/// typedef int &int_ref;
2968/// int a;
2969/// int_ref b = a;
2970/// \endcode
2971///
2972/// \c varDecl(hasType(qualType(referenceType()))))) will not match the
2973/// declaration of b but \c
2974/// varDecl(hasType(qualType(hasCanonicalType(referenceType())))))) does.
2975AST_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
> const 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
2976 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
> const 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
{
2977 if (Node.isNull())
2978 return false;
2979 return InnerMatcher.matches(Node.getCanonicalType(), Finder, Builder);
2980}
2981
2982/// \brief Overloaded to match the referenced type's declaration.
2983AST_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> const 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
2984 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> const 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
{
2985 return references(qualType(hasDeclaration(InnerMatcher)))
2986 .matches(Node, Finder, Builder);
2987}
2988
2989AST_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> const
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
2990 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> const
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
{
2991 const Expr *ExprNode = Node.getImplicitObjectArgument();
2992 return (ExprNode != nullptr &&
2993 InnerMatcher.matches(*ExprNode, Finder, Builder));
2994}
2995
2996/// \brief Matches if the expression's type either matches the specified
2997/// matcher, or is a pointer to a type that matches the InnerMatcher.
2998AST_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> const
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
2999 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> const
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
{
3000 return onImplicitObjectArgument(
3001 anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher))))
3002 .matches(Node, Finder, Builder);
3003}
3004
3005/// \brief Overloaded to match the type's declaration.
3006AST_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> const
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
3007 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> const
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
{
3008 return onImplicitObjectArgument(
3009 anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher))))
3010 .matches(Node, Finder, Builder);
3011}
3012
3013/// \brief Matches a DeclRefExpr that refers to a declaration that matches the
3014/// specified matcher.
3015///
3016/// Example matches x in if(x)
3017/// (matcher = declRefExpr(to(varDecl(hasName("x")))))
3018/// \code
3019/// bool x;
3020/// if (x) {}
3021/// \endcode
3022AST_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> const 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
3023 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> const 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
{
3024 const Decl *DeclNode = Node.getDecl();
3025 return (DeclNode != nullptr &&
3026 InnerMatcher.matches(*DeclNode, Finder, Builder));
3027}
3028
3029/// \brief Matches a \c DeclRefExpr that refers to a declaration through a
3030/// specific using shadow declaration.
3031///
3032/// Given
3033/// \code
3034/// namespace a { void f() {} }
3035/// using a::f;
3036/// void g() {
3037/// f(); // Matches this ..
3038/// a::f(); // .. but not this.
3039/// }
3040/// \endcode
3041/// declRefExpr(throughUsingDecl(anything()))
3042/// matches \c f()
3043AST_MATCHER_P(DeclRefExpr, throughUsingDecl,namespace internal { class matcher_throughUsingDecl0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
DeclRefExpr> { public: explicit matcher_throughUsingDecl0Matcher
( internal::Matcher<UsingShadowDecl> 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<UsingShadowDecl
> const InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<DeclRefExpr> throughUsingDecl( internal::Matcher
<UsingShadowDecl> const &InnerMatcher) { return ::clang
::ast_matchers::internal::makeMatcher( new internal::matcher_throughUsingDecl0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<DeclRefExpr>( &throughUsingDecl_Type0)(internal::Matcher
<UsingShadowDecl> const &InnerMatcher); inline bool
internal::matcher_throughUsingDecl0Matcher::matches( const DeclRefExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
3044 internal::Matcher<UsingShadowDecl>, InnerMatcher)namespace internal { class matcher_throughUsingDecl0Matcher :
public ::clang::ast_matchers::internal::MatcherInterface<
DeclRefExpr> { public: explicit matcher_throughUsingDecl0Matcher
( internal::Matcher<UsingShadowDecl> 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<UsingShadowDecl
> const InnerMatcher; }; } inline ::clang::ast_matchers::internal
::Matcher<DeclRefExpr> throughUsingDecl( internal::Matcher
<UsingShadowDecl> const &InnerMatcher) { return ::clang
::ast_matchers::internal::makeMatcher( new internal::matcher_throughUsingDecl0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<DeclRefExpr>( &throughUsingDecl_Type0)(internal::Matcher
<UsingShadowDecl> const &InnerMatcher); inline bool
internal::matcher_throughUsingDecl0Matcher::matches( const DeclRefExpr
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
3045 const NamedDecl *FoundDecl = Node.getFoundDecl();
3046 if (const UsingShadowDecl *UsingDecl = dyn_cast<UsingShadowDecl>(FoundDecl))
3047 return InnerMatcher.matches(*UsingDecl, Finder, Builder);
3048 return false;
3049}
3050
3051/// \brief Matches an \c OverloadExpr if any of the declarations in the set of
3052/// overloads matches the given matcher.
3053///
3054/// Given
3055/// \code
3056/// template <typename T> void foo(T);
3057/// template <typename T> void bar(T);
3058/// template <typename T> void baz(T t) {
3059/// foo(t);
3060/// bar(t);
3061/// }
3062/// \endcode
3063/// unresolvedLookupExpr(hasAnyDeclaration(
3064/// functionTemplateDecl(hasName("foo"))))
3065/// matches \c foo in \c foo(t); but not \c bar in \c bar(t);
3066AST_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> const 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
3067 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> const 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
{
3068 return matchesFirstInPointerRange(InnerMatcher, Node.decls_begin(),
3069 Node.decls_end(), Finder, Builder);
3070}
3071
3072/// \brief Matches the Decl of a DeclStmt which has a single declaration.
3073///
3074/// Given
3075/// \code
3076/// int a, b;
3077/// int c;
3078/// \endcode
3079/// declStmt(hasSingleDecl(anything()))
3080/// matches 'int c;' but not 'int a, b;'.
3081AST_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> const 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
{
3082 if (Node.isSingleDecl()) {
3083 const Decl *FoundDecl = Node.getSingleDecl();
3084 return InnerMatcher.matches(*FoundDecl, Finder, Builder);
3085 }
3086 return false;
3087}
3088
3089/// \brief Matches a variable declaration that has an initializer expression
3090/// that matches the given matcher.
3091///
3092/// Example matches x (matcher = varDecl(hasInitializer(callExpr())))
3093/// \code
3094/// bool y() { return true; }
3095/// bool x = y();
3096/// \endcode
3097AST_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> const 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
3098 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> const 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
3099 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> const 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
{
3100 const Expr *Initializer = Node.getAnyInitializer();
3101 return (Initializer != nullptr &&
3102 InnerMatcher.matches(*Initializer, Finder, Builder));
3103}
3104
3105/// \brief Matches a variable declaration that has function scope and is a
3106/// non-static local variable.
3107///
3108/// Example matches x (matcher = varDecl(hasLocalStorage())
3109/// \code
3110/// void f() {
3111/// int x;
3112/// static int y;
3113/// }
3114/// int z;
3115/// \endcode
3116AST_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
{
3117 return Node.hasLocalStorage();
3118}
3119
3120/// \brief Matches a variable declaration that does not have local storage.
3121///
3122/// Example matches y and z (matcher = varDecl(hasGlobalStorage())
3123/// \code
3124/// void f() {
3125/// int x;
3126/// static int y;
3127/// }
3128/// int z;
3129/// \endcode
3130AST_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
{
3131 return Node.hasGlobalStorage();
3132}
3133
3134/// \brief Matches a variable declaration that has automatic storage duration.
3135///
3136/// Example matches x, but not y, z, or a.
3137/// (matcher = varDecl(hasAutomaticStorageDuration())
3138/// \code
3139/// void f() {
3140/// int x;
3141/// static int y;
3142/// thread_local int z;
3143/// }
3144/// int a;
3145/// \endcode
3146AST_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
{
3147 return Node.getStorageDuration() == SD_Automatic;
3148}
3149
3150/// \brief Matches a variable declaration that has static storage duration.
3151/// It includes the variable declared at namespace scope and those declared
3152/// with "static" and "extern" storage class specifiers.
3153///
3154/// \code
3155/// void f() {
3156/// int x;
3157/// static int y;
3158/// thread_local int z;
3159/// }
3160/// int a;
3161/// static int b;
3162/// extern int c;
3163/// varDecl(hasStaticStorageDuration())
3164/// matches the function declaration y, a, b and c.
3165/// \endcode
3166AST_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
{
3167 return Node.getStorageDuration() == SD_Static;
3168}
3169
3170/// \brief Matches a variable declaration that has thread storage duration.
3171///
3172/// Example matches z, but not x, z, or a.
3173/// (matcher = varDecl(hasThreadStorageDuration())
3174/// \code
3175/// void f() {
3176/// int x;
3177/// static int y;
3178/// thread_local int z;
3179/// }
3180/// int a;
3181/// \endcode
3182AST_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
{
3183 return Node.getStorageDuration() == SD_Thread;
3184}
3185
3186/// \brief Matches a variable declaration that is an exception variable from
3187/// a C++ catch block, or an Objective-C \@catch statement.
3188///
3189/// Example matches x (matcher = varDecl(isExceptionVariable())
3190/// \code
3191/// void f(int y) {
3192/// try {
3193/// } catch (int x) {
3194/// }
3195/// }
3196/// \endcode
3197AST_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
{
3198 return Node.isExceptionVariable();
3199}
3200
3201/// \brief Checks that a call expression or a constructor call expression has
3202/// a specific number of arguments (including absent default arguments).
3203///
3204/// Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2)))
3205/// \code
3206/// void f(int x, int y);
3207/// f(0, 0);
3208/// \endcode
3209AST_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 const N; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_argumentCountIs0Matcher, unsigned, void(::clang::ast_matchers
::internal::TypeList<CallExpr, CXXConstructExpr, ObjCMessageExpr
>)> argumentCountIs(unsigned const &N) { return ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_argumentCountIs0Matcher, unsigned, void(::clang::ast_matchers
::internal::TypeList<CallExpr, CXXConstructExpr, ObjCMessageExpr
>)>(N); } typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_argumentCountIs0Matcher, unsigned, void
(::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
, ObjCMessageExpr>)>(&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
3210 AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,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 const N; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_argumentCountIs0Matcher, unsigned, void(::clang::ast_matchers
::internal::TypeList<CallExpr, CXXConstructExpr, ObjCMessageExpr
>)> argumentCountIs(unsigned const &N) { return ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_argumentCountIs0Matcher, unsigned, void(::clang::ast_matchers
::internal::TypeList<CallExpr, CXXConstructExpr, ObjCMessageExpr
>)>(N); } typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_argumentCountIs0Matcher, unsigned, void
(::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
, ObjCMessageExpr>)>(&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
3211 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 const N; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_argumentCountIs0Matcher, unsigned, void(::clang::ast_matchers
::internal::TypeList<CallExpr, CXXConstructExpr, ObjCMessageExpr
>)> argumentCountIs(unsigned const &N) { return ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_argumentCountIs0Matcher, unsigned, void(::clang::ast_matchers
::internal::TypeList<CallExpr, CXXConstructExpr, ObjCMessageExpr
>)>(N); } typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_argumentCountIs0Matcher, unsigned, void
(::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
, ObjCMessageExpr>)>(&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
3212 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 const N; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_argumentCountIs0Matcher, unsigned, void(::clang::ast_matchers
::internal::TypeList<CallExpr, CXXConstructExpr, ObjCMessageExpr
>)> argumentCountIs(unsigned const &N) { return ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_argumentCountIs0Matcher, unsigned, void(::clang::ast_matchers
::internal::TypeList<CallExpr, CXXConstructExpr, ObjCMessageExpr
>)>(N); } typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_argumentCountIs0Matcher, unsigned, void
(::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
, ObjCMessageExpr>)>(&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
3213 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 const N; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_argumentCountIs0Matcher, unsigned, void(::clang::ast_matchers
::internal::TypeList<CallExpr, CXXConstructExpr, ObjCMessageExpr
>)> argumentCountIs(unsigned const &N) { return ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_argumentCountIs0Matcher, unsigned, void(::clang::ast_matchers
::internal::TypeList<CallExpr, CXXConstructExpr, ObjCMessageExpr
>)>(N); } typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_argumentCountIs0Matcher, unsigned, void
(::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
, ObjCMessageExpr>)>(&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
{
3214 return Node.getNumArgs() == N;
3215}
3216
3217/// \brief Matches the n'th argument of a call expression or a constructor
3218/// call expression.
3219///
3220/// Example matches y in x(y)
3221/// (matcher = callExpr(hasArgument(0, declRefExpr())))
3222/// \code
3223/// void x(int) { int y; x(y); }
3224/// \endcode
3225AST_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 const N; internal
::Matcher<Expr> const InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam2< internal
::matcher_hasArgument0Matcher, unsigned, internal::Matcher<
Expr>, void(::clang::ast_matchers::internal::TypeList<CallExpr
, CXXConstructExpr, ObjCMessageExpr>)> hasArgument(unsigned
const &N, internal::Matcher<Expr> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_hasArgument0Matcher, unsigned, internal
::Matcher<Expr>, void(::clang::ast_matchers::internal::
TypeList<CallExpr, CXXConstructExpr, ObjCMessageExpr>)>
(N, InnerMatcher); } typedef ::clang::ast_matchers::internal::
PolymorphicMatcherWithParam2< internal::matcher_hasArgument0Matcher
, unsigned, internal::Matcher<Expr>, void(::clang::ast_matchers
::internal::TypeList<CallExpr, CXXConstructExpr, ObjCMessageExpr
>)>(&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
3226 AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,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 const N; internal
::Matcher<Expr> const InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam2< internal
::matcher_hasArgument0Matcher, unsigned, internal::Matcher<
Expr>, void(::clang::ast_matchers::internal::TypeList<CallExpr
, CXXConstructExpr, ObjCMessageExpr>)> hasArgument(unsigned
const &N, internal::Matcher<Expr> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_hasArgument0Matcher, unsigned, internal
::Matcher<Expr>, void(::clang::ast_matchers::internal::
TypeList<CallExpr, CXXConstructExpr, ObjCMessageExpr>)>
(N, InnerMatcher); } typedef ::clang::ast_matchers::internal::
PolymorphicMatcherWithParam2< internal::matcher_hasArgument0Matcher
, unsigned, internal::Matcher<Expr>, void(::clang::ast_matchers
::internal::TypeList<CallExpr, CXXConstructExpr, ObjCMessageExpr
>)>(&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
3227 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 const N; internal
::Matcher<Expr> const InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam2< internal
::matcher_hasArgument0Matcher, unsigned, internal::Matcher<
Expr>, void(::clang::ast_matchers::internal::TypeList<CallExpr
, CXXConstructExpr, ObjCMessageExpr>)> hasArgument(unsigned
const &N, internal::Matcher<Expr> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_hasArgument0Matcher, unsigned, internal
::Matcher<Expr>, void(::clang::ast_matchers::internal::
TypeList<CallExpr, CXXConstructExpr, ObjCMessageExpr>)>
(N, InnerMatcher); } typedef ::clang::ast_matchers::internal::
PolymorphicMatcherWithParam2< internal::matcher_hasArgument0Matcher
, unsigned, internal::Matcher<Expr>, void(::clang::ast_matchers
::internal::TypeList<CallExpr, CXXConstructExpr, ObjCMessageExpr
>)>(&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
3228 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 const N; internal
::Matcher<Expr> const InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam2< internal
::matcher_hasArgument0Matcher, unsigned, internal::Matcher<
Expr>, void(::clang::ast_matchers::internal::TypeList<CallExpr
, CXXConstructExpr, ObjCMessageExpr>)> hasArgument(unsigned
const &N, internal::Matcher<Expr> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_hasArgument0Matcher, unsigned, internal
::Matcher<Expr>, void(::clang::ast_matchers::internal::
TypeList<CallExpr, CXXConstructExpr, ObjCMessageExpr>)>
(N, InnerMatcher); } typedef ::clang::ast_matchers::internal::
PolymorphicMatcherWithParam2< internal::matcher_hasArgument0Matcher
, unsigned, internal::Matcher<Expr>, void(::clang::ast_matchers
::internal::TypeList<CallExpr, CXXConstructExpr, ObjCMessageExpr
>)>(&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
3229 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 const N; internal
::Matcher<Expr> const InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam2< internal
::matcher_hasArgument0Matcher, unsigned, internal::Matcher<
Expr>, void(::clang::ast_matchers::internal::TypeList<CallExpr
, CXXConstructExpr, ObjCMessageExpr>)> hasArgument(unsigned
const &N, internal::Matcher<Expr> const &InnerMatcher
) { return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_hasArgument0Matcher, unsigned, internal
::Matcher<Expr>, void(::clang::ast_matchers::internal::
TypeList<CallExpr, CXXConstructExpr, ObjCMessageExpr>)>
(N, InnerMatcher); } typedef ::clang::ast_matchers::internal::
PolymorphicMatcherWithParam2< internal::matcher_hasArgument0Matcher
, unsigned, internal::Matcher<Expr>, void(::clang::ast_matchers
::internal::TypeList<CallExpr, CXXConstructExpr, ObjCMessageExpr
>)>(&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
{
3230 return (N < Node.getNumArgs() &&
3231 InnerMatcher.matches(
3232 *Node.getArg(N)->IgnoreParenImpCasts(), Finder, Builder));
3233}
3234
3235/// \brief Matches declaration statements that contain a specific number of
3236/// declarations.
3237///
3238/// Example: Given
3239/// \code
3240/// int a, b;
3241/// int c;
3242/// int d = 2, e;
3243/// \endcode
3244/// declCountIs(2)
3245/// matches 'int a, b;' and 'int d = 2, e;', but not 'int c;'.
3246AST_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 const 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
{
3247 return std::distance(Node.decl_begin(), Node.decl_end()) == (ptrdiff_t)N;
3248}
3249
3250/// \brief Matches the n'th declaration of a declaration statement.
3251///
3252/// Note that this does not work for global declarations because the AST
3253/// breaks up multiple-declaration DeclStmt's into multiple single-declaration
3254/// DeclStmt's.
3255/// Example: Given non-global declarations
3256/// \code
3257/// int a, b = 0;
3258/// int c;
3259/// int d = 2, e;
3260/// \endcode
3261/// declStmt(containsDeclaration(
3262/// 0, varDecl(hasInitializer(anything()))))
3263/// matches only 'int d = 2, e;', and
3264/// declStmt(containsDeclaration(1, varDecl()))
3265/// \code
3266/// matches 'int a, b = 0' as well as 'int d = 2, e;'
3267/// but 'int c;' is not matched.
3268/// \endcode
3269AST_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 const N; internal
::Matcher<Decl> const 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
3270 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 const N; internal
::Matcher<Decl> const 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
{
3271 const unsigned NumDecls = std::distance(Node.decl_begin(), Node.decl_end());
3272 if (N >= NumDecls)
3273 return false;
3274 DeclStmt::const_decl_iterator Iterator = Node.decl_begin();
3275 std::advance(Iterator, N);
3276 return InnerMatcher.matches(**Iterator, Finder, Builder);
3277}
3278
3279/// \brief Matches a C++ catch statement that has a catch-all handler.
3280///
3281/// Given
3282/// \code
3283/// try {
3284/// // ...
3285/// } catch (int) {
3286/// // ...
3287/// } catch (...) {
3288/// // ...
3289/// }
3290/// /endcode
3291/// cxxCatchStmt(isCatchAll()) matches catch(...) but not catch(int).
3292AST_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
{
3293 return Node.getExceptionDecl() == nullptr;
3294}
3295
3296/// \brief Matches a constructor initializer.
3297///
3298/// Given
3299/// \code
3300/// struct Foo {
3301/// Foo() : foo_(1) { }
3302/// int foo_;
3303/// };
3304/// \endcode
3305/// cxxRecordDecl(has(cxxConstructorDecl(
3306/// hasAnyConstructorInitializer(anything())
3307/// )))
3308/// record matches Foo, hasAnyConstructorInitializer matches foo_(1)
3309AST_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
> const 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
3310 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
> const 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
{
3311 return matchesFirstInPointerRange(InnerMatcher, Node.init_begin(),
3312 Node.init_end(), Finder, Builder);
3313}
3314
3315/// \brief Matches the field declaration of a constructor initializer.
3316///
3317/// Given
3318/// \code
3319/// struct Foo {
3320/// Foo() : foo_(1) { }
3321/// int foo_;
3322/// };
3323/// \endcode
3324/// cxxRecordDecl(has(cxxConstructorDecl(hasAnyConstructorInitializer(
3325/// forField(hasName("foo_"))))))
3326/// matches Foo
3327/// with forField matching foo_
3328AST_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> const 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
3329 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> const 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
{
3330 const FieldDecl *NodeAsDecl = Node.getAnyMember();
3331 return (NodeAsDecl != nullptr &&
3332 InnerMatcher.matches(*NodeAsDecl, Finder, Builder));
3333}
3334
3335/// \brief Matches the initializer expression of a constructor initializer.
3336///
3337/// Given
3338/// \code
3339/// struct Foo {
3340/// Foo() : foo_(1) { }
3341/// int foo_;
3342/// };
3343/// \endcode
3344/// cxxRecordDecl(has(cxxConstructorDecl(hasAnyConstructorInitializer(
3345/// withInitializer(integerLiteral(equals(1)))))))
3346/// matches Foo
3347/// with withInitializer matching (1)
3348AST_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> const
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
3349 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> const
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
{
3350 const Expr* NodeAsExpr = Node.getInit();
3351 return (NodeAsExpr != nullptr &&
3352 InnerMatcher.matches(*NodeAsExpr, Finder, Builder));
3353}
3354
3355/// \brief Matches a constructor initializer if it is explicitly written in
3356/// code (as opposed to implicitly added by the compiler).
3357///
3358/// Given
3359/// \code
3360/// struct Foo {
3361/// Foo() { }
3362/// Foo(int) : foo_("A") { }
3363/// string foo_;
3364/// };
3365/// \endcode
3366/// cxxConstructorDecl(hasAnyConstructorInitializer(isWritten()))
3367/// will match Foo(int), but not Foo()
3368AST_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
{
3369 return Node.isWritten();
3370}
3371
3372/// \brief Matches a constructor initializer if it is initializing a base, as
3373/// opposed to a member.
3374///
3375/// Given
3376/// \code
3377/// struct B {};
3378/// struct D : B {
3379/// int I;
3380/// D(int i) : I(i) {}
3381/// };
3382/// struct E : B {
3383/// E() : B() {}
3384/// };
3385/// \endcode
3386/// cxxConstructorDecl(hasAnyConstructorInitializer(isBaseInitializer()))
3387/// will match E(), but not match D(int).
3388AST_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
{
3389 return Node.isBaseInitializer();
3390}
3391
3392/// \brief Matches a constructor initializer if it is initializing a member, as
3393/// opposed to a base.
3394///
3395/// Given
3396/// \code
3397/// struct B {};
3398/// struct D : B {
3399/// int I;
3400/// D(int i) : I(i) {}
3401/// };
3402/// struct E : B {
3403/// E() : B() {}
3404/// };
3405/// \endcode
3406/// cxxConstructorDecl(hasAnyConstructorInitializer(isMemberInitializer()))
3407/// will match D(int), but not match E().
3408AST_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
{
3409 return Node.isMemberInitializer();
3410}
3411
3412/// \brief Matches any argument of a call expression or a constructor call
3413/// expression.
3414///
3415/// Given
3416/// \code
3417/// void x(int, int, int) { int y; x(1, y, 42); }
3418/// \endcode
3419/// callExpr(hasAnyArgument(declRefExpr()))
3420/// matches x(1, y, 42)
3421/// with hasAnyArgument(...)
3422/// matching y
3423AST_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> const InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_hasAnyArgument0Matcher, internal::Matcher<Expr>
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr>)> hasAnyArgument(internal::Matcher<
Expr> const &InnerMatcher) { return ::clang::ast_matchers
::internal::PolymorphicMatcherWithParam1< internal::matcher_hasAnyArgument0Matcher
, internal::Matcher<Expr>, void(::clang::ast_matchers::
internal::TypeList<CallExpr, CXXConstructExpr>)>(InnerMatcher
); } typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_hasAnyArgument0Matcher, internal::Matcher
<Expr>, void(::clang::ast_matchers::internal::TypeList<
CallExpr, CXXConstructExpr>)>(&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
3424 AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,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> const InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_hasAnyArgument0Matcher, internal::Matcher<Expr>
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr>)> hasAnyArgument(internal::Matcher<
Expr> const &InnerMatcher) { return ::clang::ast_matchers
::internal::PolymorphicMatcherWithParam1< internal::matcher_hasAnyArgument0Matcher
, internal::Matcher<Expr>, void(::clang::ast_matchers::
internal::TypeList<CallExpr, CXXConstructExpr>)>(InnerMatcher
); } typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_hasAnyArgument0Matcher, internal::Matcher
<Expr>, void(::clang::ast_matchers::internal::TypeList<
CallExpr, CXXConstructExpr>)>(&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
3425 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> const InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_hasAnyArgument0Matcher, internal::Matcher<Expr>
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr>)> hasAnyArgument(internal::Matcher<
Expr> const &InnerMatcher) { return ::clang::ast_matchers
::internal::PolymorphicMatcherWithParam1< internal::matcher_hasAnyArgument0Matcher
, internal::Matcher<Expr>, void(::clang::ast_matchers::
internal::TypeList<CallExpr, CXXConstructExpr>)>(InnerMatcher
); } typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_hasAnyArgument0Matcher, internal::Matcher
<Expr>, void(::clang::ast_matchers::internal::TypeList<
CallExpr, CXXConstructExpr>)>(&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
3426 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> const InnerMatcher; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_hasAnyArgument0Matcher, internal::Matcher<Expr>
, void(::clang::ast_matchers::internal::TypeList<CallExpr,
CXXConstructExpr>)> hasAnyArgument(internal::Matcher<
Expr> const &InnerMatcher) { return ::clang::ast_matchers
::internal::PolymorphicMatcherWithParam1< internal::matcher_hasAnyArgument0Matcher
, internal::Matcher<Expr>, void(::clang::ast_matchers::
internal::TypeList<CallExpr, CXXConstructExpr>)>(InnerMatcher
); } typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1
< internal::matcher_hasAnyArgument0Matcher, internal::Matcher
<Expr>, void(::clang::ast_matchers::internal::TypeList<
CallExpr, CXXConstructExpr>)>(&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
{
3427 for (const Expr *Arg : Node.arguments()) {
3428 BoundNodesTreeBuilder Result(*Builder);
3429 if (InnerMatcher.matches(*Arg, Finder, &Result)) {
3430 *Builder = std::move(Result);
3431 return true;
3432 }
3433 }
3434 return false;
3435}
3436
3437/// \brief Matches a constructor call expression which uses list initialization.
3438AST_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
{
3439 return Node.isListInitialization();
3440}
3441
3442/// \brief Matches a constructor call expression which requires
3443/// zero initialization.
3444///
3445/// Given
3446/// \code
3447/// void foo() {
3448/// struct point { double x; double y; };
3449/// point pt[2] = { { 1.0, 2.0 } };
3450/// }
3451/// \endcode
3452/// initListExpr(has(cxxConstructExpr(requiresZeroInitialization()))
3453/// will match the implicit array filler for pt[1].
3454AST_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
{
3455 return Node.requiresZeroInitialization();
3456}
3457
3458/// \brief Matches the n'th parameter of a function declaration.
3459///
3460/// Given
3461/// \code
3462/// class X { void f(int x) {} };
3463/// \endcode
3464/// cxxMethodDecl(hasParameter(0, hasType(varDecl())))
3465/// matches f(int x) {}
3466/// with hasParameter(...)
3467/// matching int x
3468AST_MATCHER_P2(FunctionDecl, hasParameter,namespace internal { class matcher_hasParameter0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<FunctionDecl
> { public: matcher_hasParameter0Matcher(unsigned const &
AN, internal::Matcher<ParmVarDecl> const &AInnerMatcher
) : N(AN), InnerMatcher(AInnerMatcher) {} bool matches(const FunctionDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned const N; internal
::Matcher<ParmVarDecl> const InnerMatcher; }; } inline ::
clang::ast_matchers::internal::Matcher<FunctionDecl> hasParameter
( unsigned const &N, internal::Matcher<ParmVarDecl>
const &InnerMatcher) { return ::clang::ast_matchers::internal
::makeMatcher( new internal::matcher_hasParameter0Matcher(N, InnerMatcher
)); } typedef ::clang::ast_matchers::internal::Matcher<FunctionDecl
>( &hasParameter_Type0)(unsigned const &N, internal
::Matcher<ParmVarDecl> const &InnerMatcher); inline
bool internal::matcher_hasParameter0Matcher::matches( const FunctionDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
3469 unsigned, N, internal::Matcher<ParmVarDecl>,namespace internal { class matcher_hasParameter0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<FunctionDecl
> { public: matcher_hasParameter0Matcher(unsigned const &
AN, internal::Matcher<ParmVarDecl> const &AInnerMatcher
) : N(AN), InnerMatcher(AInnerMatcher) {} bool matches(const FunctionDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned const N; internal
::Matcher<ParmVarDecl> const InnerMatcher; }; } inline ::
clang::ast_matchers::internal::Matcher<FunctionDecl> hasParameter
( unsigned const &N, internal::Matcher<ParmVarDecl>
const &InnerMatcher) { return ::clang::ast_matchers::internal
::makeMatcher( new internal::matcher_hasParameter0Matcher(N, InnerMatcher
)); } typedef ::clang::ast_matchers::internal::Matcher<FunctionDecl
>( &hasParameter_Type0)(unsigned const &N, internal
::Matcher<ParmVarDecl> const &InnerMatcher); inline
bool internal::matcher_hasParameter0Matcher::matches( const FunctionDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
3470 InnerMatcher)namespace internal { class matcher_hasParameter0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<FunctionDecl
> { public: matcher_hasParameter0Matcher(unsigned const &
AN, internal::Matcher<ParmVarDecl> const &AInnerMatcher
) : N(AN), InnerMatcher(AInnerMatcher) {} bool matches(const FunctionDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const override; private: unsigned const N; internal
::Matcher<ParmVarDecl> const InnerMatcher; }; } inline ::
clang::ast_matchers::internal::Matcher<FunctionDecl> hasParameter
( unsigned const &N, internal::Matcher<ParmVarDecl>
const &InnerMatcher) { return ::clang::ast_matchers::internal
::makeMatcher( new internal::matcher_hasParameter0Matcher(N, InnerMatcher
)); } typedef ::clang::ast_matchers::internal::Matcher<FunctionDecl
>( &hasParameter_Type0)(unsigned const &N, internal
::Matcher<ParmVarDecl> const &InnerMatcher); inline
bool internal::matcher_hasParameter0Matcher::matches( const FunctionDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
3471 return (N < Node.getNumParams() &&
3472 InnerMatcher.matches(
3473 *Node.getParamDecl(N), Finder, Builder));
3474}
3475
3476/// \brief Matches all arguments and their respective ParmVarDecl.
3477///
3478/// Given
3479/// \code
3480/// void f(int i);
3481/// int y;
3482/// f(y);
3483/// \endcode
3484/// callExpr(
3485/// forEachArgumentWithParam(
3486/// declRefExpr(to(varDecl(hasName("y")))),
3487/// parmVarDecl(hasType(isInteger()))
3488/// ))
3489/// matches f(y);
3490/// with declRefExpr(...)
3491/// matching int y
3492/// and parmVarDecl(...)
3493/// matching int i
3494AST_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
> const ArgMatcher; internal::Matcher<ParmVarDecl> const
ParamMatcher; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_forEachArgumentWithParam0Matcher, internal
::Matcher<Expr>, internal::Matcher<ParmVarDecl>, void
(::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>)> forEachArgumentWithParam(internal::Matcher<Expr>
const &ArgMatcher, internal::Matcher<ParmVarDecl> const
&ParamMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcherWithParam2< internal::matcher_forEachArgumentWithParam0Matcher
, internal::Matcher<Expr>, internal::Matcher<ParmVarDecl
>, void(::clang::ast_matchers::internal::TypeList<CallExpr
, CXXConstructExpr>)>(ArgMatcher, ParamMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_forEachArgumentWithParam0Matcher, internal
::Matcher<Expr>, internal::Matcher<ParmVarDecl>, void
(::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>)>(&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
3495 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
> const ArgMatcher; internal::Matcher<ParmVarDecl> const
ParamMatcher; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_forEachArgumentWithParam0Matcher, internal
::Matcher<Expr>, internal::Matcher<ParmVarDecl>, void
(::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>)> forEachArgumentWithParam(internal::Matcher<Expr>
const &ArgMatcher, internal::Matcher<ParmVarDecl> const
&ParamMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcherWithParam2< internal::matcher_forEachArgumentWithParam0Matcher
, internal::Matcher<Expr>, internal::Matcher<ParmVarDecl
>, void(::clang::ast_matchers::internal::TypeList<CallExpr
, CXXConstructExpr>)>(ArgMatcher, ParamMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_forEachArgumentWithParam0Matcher, internal
::Matcher<Expr>, internal::Matcher<ParmVarDecl>, void
(::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>)>(&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
3496 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
> const ArgMatcher; internal::Matcher<ParmVarDecl> const
ParamMatcher; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_forEachArgumentWithParam0Matcher, internal
::Matcher<Expr>, internal::Matcher<ParmVarDecl>, void
(::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>)> forEachArgumentWithParam(internal::Matcher<Expr>
const &ArgMatcher, internal::Matcher<ParmVarDecl> const
&ParamMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcherWithParam2< internal::matcher_forEachArgumentWithParam0Matcher
, internal::Matcher<Expr>, internal::Matcher<ParmVarDecl
>, void(::clang::ast_matchers::internal::TypeList<CallExpr
, CXXConstructExpr>)>(ArgMatcher, ParamMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_forEachArgumentWithParam0Matcher, internal
::Matcher<Expr>, internal::Matcher<ParmVarDecl>, void
(::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>)>(&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
3497 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
> const ArgMatcher; internal::Matcher<ParmVarDecl> const
ParamMatcher; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_forEachArgumentWithParam0Matcher, internal
::Matcher<Expr>, internal::Matcher<ParmVarDecl>, void
(::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>)> forEachArgumentWithParam(internal::Matcher<Expr>
const &ArgMatcher, internal::Matcher<ParmVarDecl> const
&ParamMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcherWithParam2< internal::matcher_forEachArgumentWithParam0Matcher
, internal::Matcher<Expr>, internal::Matcher<ParmVarDecl
>, void(::clang::ast_matchers::internal::TypeList<CallExpr
, CXXConstructExpr>)>(ArgMatcher, ParamMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_forEachArgumentWithParam0Matcher, internal
::Matcher<Expr>, internal::Matcher<ParmVarDecl>, void
(::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>)>(&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
3498 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
> const ArgMatcher; internal::Matcher<ParmVarDecl> const
ParamMatcher; }; } inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_forEachArgumentWithParam0Matcher, internal
::Matcher<Expr>, internal::Matcher<ParmVarDecl>, void
(::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>)> forEachArgumentWithParam(internal::Matcher<Expr>
const &ArgMatcher, internal::Matcher<ParmVarDecl> const
&ParamMatcher) { return ::clang::ast_matchers::internal::
PolymorphicMatcherWithParam2< internal::matcher_forEachArgumentWithParam0Matcher
, internal::Matcher<Expr>, internal::Matcher<ParmVarDecl
>, void(::clang::ast_matchers::internal::TypeList<CallExpr
, CXXConstructExpr>)>(ArgMatcher, ParamMatcher); } typedef
::clang::ast_matchers::internal::PolymorphicMatcherWithParam2
< internal::matcher_forEachArgumentWithParam0Matcher, internal
::Matcher<Expr>, internal::Matcher<ParmVarDecl>, void
(::clang::ast_matchers::internal::TypeList<CallExpr, CXXConstructExpr
>)>(&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
{
3499 BoundNodesTreeBuilder Result;
3500 // The first argument of an overloaded member operator is the implicit object
3501 // argument of the method which should not be matched against a parameter, so
3502 // we skip over it here.
3503 BoundNodesTreeBuilder Matches;
3504 unsigned ArgIndex = cxxOperatorCallExpr(callee(cxxMethodDecl()))
3505 .matches(Node, Finder, &Matches)
3506 ? 1
3507 : 0;
3508 int ParamIndex = 0;
3509 bool Matched = false;
3510 for (; ArgIndex < Node.getNumArgs(); ++ArgIndex) {
3511 BoundNodesTreeBuilder ArgMatches(*Builder);
3512 if (ArgMatcher.matches(*(Node.getArg(ArgIndex)->IgnoreParenCasts()),
3513 Finder, &ArgMatches)) {
3514 BoundNodesTreeBuilder ParamMatches(ArgMatches);
3515 if (expr(anyOf(cxxConstructExpr(hasDeclaration(cxxConstructorDecl(
3516 hasParameter(ParamIndex, ParamMatcher)))),
3517 callExpr(callee(functionDecl(
3518 hasParameter(ParamIndex, ParamMatcher))))))
3519 .matches(Node, Finder, &ParamMatches)) {
3520 Result.addMatch(ParamMatches);
3521 Matched = true;
3522 }
3523 }
3524 ++ParamIndex;
3525 }
3526 *Builder = std::move(Result);
3527 return Matched;
3528}
3529
3530/// \brief Matches any parameter of a function declaration.
3531///
3532/// Does not match the 'this' parameter of a method.
3533///
3534/// Given
3535/// \code
3536/// class X { void f(int x, int y, int z) {} };
3537/// \endcode
3538/// cxxMethodDecl(hasAnyParameter(hasName("y")))
3539/// matches f(int x, int y, int z) {}
3540/// with hasAnyParameter(...)
3541/// matching int y
3542AST_MATCHER_P(FunctionDecl, hasAnyParameter,namespace internal { class matcher_hasAnyParameter0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<FunctionDecl
> { public: explicit matcher_hasAnyParameter0Matcher( internal
::Matcher<ParmVarDecl> 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<ParmVarDecl> const
InnerMatcher; }; } inline ::clang::ast_matchers::internal::Matcher
<FunctionDecl> hasAnyParameter( internal::Matcher<ParmVarDecl
> const &InnerMatcher) { return ::clang::ast_matchers::
internal::makeMatcher( new internal::matcher_hasAnyParameter0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<FunctionDecl>( &hasAnyParameter_Type0)(internal::Matcher
<ParmVarDecl> const &InnerMatcher); inline bool internal
::matcher_hasAnyParameter0Matcher::matches( const FunctionDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
3543 internal::Matcher<ParmVarDecl>, InnerMatcher)namespace internal { class matcher_hasAnyParameter0Matcher : public
::clang::ast_matchers::internal::MatcherInterface<FunctionDecl
> { public: explicit matcher_hasAnyParameter0Matcher( internal
::Matcher<ParmVarDecl> 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<ParmVarDecl> const
InnerMatcher; }; } inline ::clang::ast_matchers::internal::Matcher
<FunctionDecl> hasAnyParameter( internal::Matcher<ParmVarDecl
> const &InnerMatcher) { return ::clang::ast_matchers::
internal::makeMatcher( new internal::matcher_hasAnyParameter0Matcher
(InnerMatcher)); } typedef ::clang::ast_matchers::internal::Matcher
<FunctionDecl>( &hasAnyParameter_Type0)(internal::Matcher
<ParmVarDecl> const &InnerMatcher); inline bool internal
::matcher_hasAnyParameter0Matcher::matches( const FunctionDecl
&Node, ::clang::ast_matchers::internal::ASTMatchFinder *
Finder, ::clang::ast_matchers::internal::BoundNodesTreeBuilder
*Builder) const
{
3544 return matchesFirstInPointerRange(InnerMatcher, Node.param_begin(),
3545 Node.param_end(), Finder, Builder);
3546}
3547
3548/// \brief Matches \c FunctionDecls and \c FunctionProtoTypes that have a
3549/// specific parameter count.
3550///
3551/// Given
3552/// \code
3553/// void f(int i) {}
3554/// void g(int i, int j) {}
3555/// void h(int i, int j);
3556/// void j(int i);
3557/// void k(int x, int y, int z, ...);
3558/// \endcode
3559/// functionDecl(parameterCountIs(2))
3560/// matches \c g and \c h
3561/// functionProtoType(parameterCountIs(2))
3562/// matches \c g and \c h
3563/// functionProtoType(parameterCountIs(3))
3564/// matches \c k
3565AST_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 const N; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_parameterCountIs0Matcher, unsigned, void(::clang::ast_matchers
::internal::TypeList<FunctionDecl, FunctionProtoType>)>
parameterCountIs(unsigned const &N) { return ::clang::ast_matchers
::internal::PolymorphicMatcherWithParam1< internal::matcher_parameterCountIs0Matcher
, unsigned, void(::clang::ast_matchers::internal::TypeList<
FunctionDecl, FunctionProtoType>)>(N); } typedef ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_parameterCountIs0Matcher, unsigned, void(::clang::ast_matchers
::internal::TypeList<FunctionDecl, FunctionProtoType>)>
(&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
3566 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 const N; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_parameterCountIs0Matcher, unsigned, void(::clang::ast_matchers
::internal::TypeList<FunctionDecl, FunctionProtoType>)>
parameterCountIs(unsigned const &N) { return ::clang::ast_matchers
::internal::PolymorphicMatcherWithParam1< internal::matcher_parameterCountIs0Matcher
, unsigned, void(::clang::ast_matchers::internal::TypeList<
FunctionDecl, FunctionProtoType>)>(N); } typedef ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_parameterCountIs0Matcher, unsigned, void(::clang::ast_matchers
::internal::TypeList<FunctionDecl, FunctionProtoType>)>
(&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
3567 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 const N; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_parameterCountIs0Matcher, unsigned, void(::clang::ast_matchers
::internal::TypeList<FunctionDecl, FunctionProtoType>)>
parameterCountIs(unsigned const &N) { return ::clang::ast_matchers
::internal::PolymorphicMatcherWithParam1< internal::matcher_parameterCountIs0Matcher
, unsigned, void(::clang::ast_matchers::internal::TypeList<
FunctionDecl, FunctionProtoType>)>(N); } typedef ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_parameterCountIs0Matcher, unsigned, void(::clang::ast_matchers
::internal::TypeList<FunctionDecl, FunctionProtoType>)>
(&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
3568 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 const N; }; } inline ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_parameterCountIs0Matcher, unsigned, void(::clang::ast_matchers
::internal::TypeList<FunctionDecl, FunctionProtoType>)>
parameterCountIs(unsigned const &N) { return ::clang::ast_matchers
::internal::PolymorphicMatcherWithParam1< internal::matcher_parameterCountIs0Matcher
, unsigned, void(::clang::ast_matchers::internal::TypeList<
FunctionDecl, FunctionProtoType>)>(N); } typedef ::clang
::ast_matchers::internal::PolymorphicMatcherWithParam1< internal
::matcher_parameterCountIs0Matcher, unsigned, void(::clang::ast_matchers
::internal::TypeList<FunctionDecl, FunctionProtoType>)>
(&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
{
3569 return Node.getNumParams() == N;
3570}
3571
3572/// \brief Matches \c FunctionDecls that have a noreturn attribute.
3573///
3574/// Given
3575/// \code
3576/// void nope();
3577/// [[noreturn]] void a();
3578/// __attribute__((noreturn)) void b();
3579/// struct c { [[noreturn]] c(); };
3580/// \endcode
3581/// functionDecl(isNoReturn())
3582/// matches all of those except
3583/// \code
3584/// void nope();
3585/// \endcode
3586AST_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(); }
3587
3588/// \brief Matches the return type of a function declaration.
3589///
3590/// Given:
3591/// \code
3592/// class X { int f() { return 1; } };
3593/// \endcode
3594/// cxxMethodDecl(returns(asString("int")))
3595/// matches int f() { return 1; }
3596AST_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> const 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
3597 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> const 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
{
3598 return InnerMatcher.matches(Node.getReturnType(), Finder, Builder);
3599}
3600
3601/// \brief Matches extern "C" function or variable declarations.
3602///
3603/// Given:
3604/// \code