diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 11:06:01 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 11:06:01 +0000 |
commit | 486754660bb926339aefcf012a3f848592babb8b (patch) | |
tree | ecdbc446c9876f4f120f701c243373cd3cb43db3 /include/clang/ASTMatchers/ASTMatchers.h | |
parent | 55e6d896ad333f07bb3b1ba487df214fc268a4ab (diff) |
Notes
Diffstat (limited to 'include/clang/ASTMatchers/ASTMatchers.h')
-rw-r--r-- | include/clang/ASTMatchers/ASTMatchers.h | 1138 |
1 files changed, 693 insertions, 445 deletions
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index 64e7e908d51ed..58f65a39fb48b 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -92,7 +92,7 @@ namespace clang { namespace ast_matchers { -/// \brief Maps string IDs to AST nodes matched by parts of a matcher. +/// Maps string IDs to AST nodes matched by parts of a matcher. /// /// The bound nodes are generated by calling \c bind("id") on the node matchers /// of the nodes we want to access later. @@ -101,7 +101,7 @@ namespace ast_matchers { /// callbacks are executed every time a match is found. class BoundNodes { public: - /// \brief Returns the AST node bound to \c ID. + /// Returns the AST node bound to \c ID. /// /// Returns NULL if there was no node bound to \c ID or if there is a node but /// it cannot be converted to the specified type. @@ -110,12 +110,12 @@ public: return MyBoundNodes.getNodeAs<T>(ID); } - /// \brief Type of mapping from binding identifiers to bound nodes. This type + /// Type of mapping from binding identifiers to bound nodes. This type /// is an associative container with a key type of \c std::string and a value /// type of \c clang::ast_type_traits::DynTypedNode using IDToNodeMap = internal::BoundNodesMap::IDToNodeMap; - /// \brief Retrieve mapping from binding identifiers to bound nodes. + /// Retrieve mapping from binding identifiers to bound nodes. const IDToNodeMap &getMap() const { return MyBoundNodes.getMap(); } @@ -123,14 +123,14 @@ public: private: friend class internal::BoundNodesTreeBuilder; - /// \brief Create BoundNodes from a pre-filled map of bindings. + /// Create BoundNodes from a pre-filled map of bindings. BoundNodes(internal::BoundNodesMap &MyBoundNodes) : MyBoundNodes(MyBoundNodes) {} internal::BoundNodesMap MyBoundNodes; }; -/// \brief If the provided matcher matches a node, binds the node to \c ID. +/// If the provided matcher matches a node, binds the node to \c ID. /// /// FIXME: Do we want to support this now that we have bind()? template <typename T> @@ -139,7 +139,7 @@ internal::Matcher<T> id(StringRef ID, return InnerMatcher.bind(ID); } -/// \brief Types of matchers for the top-level classes in the AST class +/// Types of matchers for the top-level classes in the AST class /// hierarchy. /// @{ using DeclarationMatcher = internal::Matcher<Decl>; @@ -151,7 +151,7 @@ using NestedNameSpecifierLocMatcher = internal::Matcher<NestedNameSpecifierLoc>; using CXXCtorInitializerMatcher = internal::Matcher<CXXCtorInitializer>; /// @} -/// \brief Matches any node. +/// Matches any node. /// /// Useful when another matcher requires a child matcher, but there's no /// additional constraint. This will often be used with an explicit conversion @@ -167,7 +167,7 @@ using CXXCtorInitializerMatcher = internal::Matcher<CXXCtorInitializer>; /// Usable as: Any Matcher inline internal::TrueMatcher anything() { return internal::TrueMatcher(); } -/// \brief Matches the top declaration context. +/// Matches the top declaration context. /// /// Given /// \code @@ -181,7 +181,7 @@ inline internal::TrueMatcher anything() { return internal::TrueMatcher(); } extern const internal::VariadicDynCastAllOfMatcher<Decl, TranslationUnitDecl> translationUnitDecl; -/// \brief Matches typedef declarations. +/// Matches typedef declarations. /// /// Given /// \code @@ -193,7 +193,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, TranslationUnitDecl> extern const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl> typedefDecl; -/// \brief Matches typedef name declarations. +/// Matches typedef name declarations. /// /// Given /// \code @@ -205,7 +205,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl> extern const internal::VariadicDynCastAllOfMatcher<Decl, TypedefNameDecl> typedefNameDecl; -/// \brief Matches type alias declarations. +/// Matches type alias declarations. /// /// Given /// \code @@ -217,7 +217,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, TypedefNameDecl> extern const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasDecl> typeAliasDecl; -/// \brief Matches type alias template declarations. +/// Matches type alias template declarations. /// /// typeAliasTemplateDecl() matches /// \code @@ -227,7 +227,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasDecl> extern const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasTemplateDecl> typeAliasTemplateDecl; -/// \brief Matches AST nodes that were expanded within the main-file. +/// Matches AST nodes that were expanded within the main-file. /// /// Example matches X but not Y /// (matcher = cxxRecordDecl(isExpansionInMainFile()) @@ -248,7 +248,7 @@ AST_POLYMORPHIC_MATCHER(isExpansionInMainFile, SourceManager.getExpansionLoc(Node.getLocStart())); } -/// \brief Matches AST nodes that were expanded within system-header-files. +/// Matches AST nodes that were expanded within system-header-files. /// /// Example matches Y but not X /// (matcher = cxxRecordDecl(isExpansionInSystemHeader()) @@ -272,7 +272,7 @@ AST_POLYMORPHIC_MATCHER(isExpansionInSystemHeader, return SourceManager.isInSystemHeader(ExpansionLoc); } -/// \brief Matches AST nodes that were expanded within files whose name is +/// Matches AST nodes that were expanded within files whose name is /// partially matching a given regex. /// /// Example matches Y but not X @@ -306,7 +306,7 @@ AST_POLYMORPHIC_MATCHER_P(isExpansionInFileMatching, return RE.match(Filename); } -/// \brief Matches declarations. +/// Matches declarations. /// /// Examples matches \c X, \c C, and the friend declaration inside \c C; /// \code @@ -317,7 +317,7 @@ AST_POLYMORPHIC_MATCHER_P(isExpansionInFileMatching, /// \endcode extern const internal::VariadicAllOfMatcher<Decl> decl; -/// \brief Matches a declaration of a linkage specification. +/// Matches a declaration of a linkage specification. /// /// Given /// \code @@ -328,7 +328,7 @@ extern const internal::VariadicAllOfMatcher<Decl> decl; extern const internal::VariadicDynCastAllOfMatcher<Decl, LinkageSpecDecl> linkageSpecDecl; -/// \brief Matches a declaration of anything that could have a name. +/// Matches a declaration of anything that could have a name. /// /// Example matches \c X, \c S, the anonymous union type, \c i, and \c U; /// \code @@ -341,7 +341,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, LinkageSpecDecl> /// \endcode extern const internal::VariadicDynCastAllOfMatcher<Decl, NamedDecl> namedDecl; -/// \brief Matches a declaration of label. +/// Matches a declaration of label. /// /// Given /// \code @@ -352,7 +352,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, NamedDecl> namedDecl; /// matches 'FOO:' extern const internal::VariadicDynCastAllOfMatcher<Decl, LabelDecl> labelDecl; -/// \brief Matches a declaration of a namespace. +/// Matches a declaration of a namespace. /// /// Given /// \code @@ -364,7 +364,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, LabelDecl> labelDecl; extern const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceDecl> namespaceDecl; -/// \brief Matches a declaration of a namespace alias. +/// Matches a declaration of a namespace alias. /// /// Given /// \code @@ -376,7 +376,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceDecl> extern const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceAliasDecl> namespaceAliasDecl; -/// \brief Matches class, struct, and union declarations. +/// Matches class, struct, and union declarations. /// /// Example matches \c X, \c Z, \c U, and \c S /// \code @@ -387,7 +387,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceAliasDecl> /// \endcode extern const internal::VariadicDynCastAllOfMatcher<Decl, RecordDecl> recordDecl; -/// \brief Matches C++ class declarations. +/// Matches C++ class declarations. /// /// Example matches \c X, \c Z /// \code @@ -397,7 +397,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, RecordDecl> recordDecl; extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXRecordDecl> cxxRecordDecl; -/// \brief Matches C++ class template declarations. +/// Matches C++ class template declarations. /// /// Example matches \c Z /// \code @@ -406,7 +406,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXRecordDecl> extern const internal::VariadicDynCastAllOfMatcher<Decl, ClassTemplateDecl> classTemplateDecl; -/// \brief Matches C++ class template specializations. +/// Matches C++ class template specializations. /// /// Given /// \code @@ -420,7 +420,7 @@ extern const internal::VariadicDynCastAllOfMatcher< Decl, ClassTemplateSpecializationDecl> classTemplateSpecializationDecl; -/// \brief Matches declarator declarations (field, variable, function +/// Matches declarator declarations (field, variable, function /// and non-type template parameter declarations). /// /// Given @@ -432,7 +432,7 @@ extern const internal::VariadicDynCastAllOfMatcher< extern const internal::VariadicDynCastAllOfMatcher<Decl, DeclaratorDecl> declaratorDecl; -/// \brief Matches parameter variable declarations. +/// Matches parameter variable declarations. /// /// Given /// \code @@ -443,7 +443,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, DeclaratorDecl> extern const internal::VariadicDynCastAllOfMatcher<Decl, ParmVarDecl> parmVarDecl; -/// \brief Matches C++ access specifier declarations. +/// Matches C++ access specifier declarations. /// /// Given /// \code @@ -457,7 +457,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, ParmVarDecl> extern const internal::VariadicDynCastAllOfMatcher<Decl, AccessSpecDecl> accessSpecDecl; -/// \brief Matches constructor initializers. +/// Matches constructor initializers. /// /// Examples matches \c i(42). /// \code @@ -469,7 +469,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, AccessSpecDecl> extern const internal::VariadicAllOfMatcher<CXXCtorInitializer> cxxCtorInitializer; -/// \brief Matches template arguments. +/// Matches template arguments. /// /// Given /// \code @@ -480,7 +480,7 @@ extern const internal::VariadicAllOfMatcher<CXXCtorInitializer> /// matches 'int' in C<int>. extern const internal::VariadicAllOfMatcher<TemplateArgument> templateArgument; -/// \brief Matches template name. +/// Matches template name. /// /// Given /// \code @@ -491,7 +491,7 @@ extern const internal::VariadicAllOfMatcher<TemplateArgument> templateArgument; /// matches 'X' in X<int>. extern const internal::VariadicAllOfMatcher<TemplateName> templateName; -/// \brief Matches non-type template parameter declarations. +/// Matches non-type template parameter declarations. /// /// Given /// \code @@ -503,7 +503,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, NonTypeTemplateParmDecl> nonTypeTemplateParmDecl; -/// \brief Matches template type parameter declarations. +/// Matches template type parameter declarations. /// /// Given /// \code @@ -514,7 +514,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, extern const internal::VariadicDynCastAllOfMatcher<Decl, TemplateTypeParmDecl> templateTypeParmDecl; -/// \brief Matches public C++ declarations. +/// Matches public C++ declarations. /// /// Given /// \code @@ -530,7 +530,7 @@ AST_MATCHER(Decl, isPublic) { return Node.getAccess() == AS_public; } -/// \brief Matches protected C++ declarations. +/// Matches protected C++ declarations. /// /// Given /// \code @@ -546,7 +546,7 @@ AST_MATCHER(Decl, isProtected) { return Node.getAccess() == AS_protected; } -/// \brief Matches private C++ declarations. +/// Matches private C++ declarations. /// /// Given /// \code @@ -562,7 +562,7 @@ AST_MATCHER(Decl, isPrivate) { return Node.getAccess() == AS_private; } -/// \brief Matches non-static data members that are bit-fields. +/// Matches non-static data members that are bit-fields. /// /// Given /// \code @@ -577,7 +577,7 @@ AST_MATCHER(FieldDecl, isBitField) { return Node.isBitField(); } -/// \brief Matches non-static data members that are bit-fields of the specified +/// Matches non-static data members that are bit-fields of the specified /// bit width. /// /// Given @@ -595,7 +595,7 @@ AST_MATCHER_P(FieldDecl, hasBitWidth, unsigned, Width) { Node.getBitWidthValue(Finder->getASTContext()) == Width; } -/// \brief Matches non-static data members that have an in-class initializer. +/// Matches non-static data members that have an in-class initializer. /// /// Given /// \code @@ -616,7 +616,13 @@ AST_MATCHER_P(FieldDecl, hasInClassInitializer, internal::Matcher<Expr>, InnerMatcher.matches(*Initializer, Finder, Builder)); } -/// \brief Matches the specialized template of a specialization declaration. +/// Determines whether the function is "main", which is the entry point +/// into an executable program. +AST_MATCHER(FunctionDecl, isMain) { + return Node.isMain(); +} + +/// Matches the specialized template of a specialization declaration. /// /// Given /// \code @@ -633,13 +639,13 @@ AST_MATCHER_P(ClassTemplateSpecializationDecl, hasSpecializedTemplate, InnerMatcher.matches(*Decl, Finder, Builder)); } -/// \brief Matches a declaration that has been implicitly added +/// Matches a declaration that has been implicitly added /// by the compiler (eg. implicit default/copy constructors). AST_MATCHER(Decl, isImplicit) { return Node.isImplicit(); } -/// \brief Matches classTemplateSpecializations, templateSpecializationType and +/// Matches classTemplateSpecializations, templateSpecializationType and /// functionDecl that have at least one TemplateArgument matching the given /// InnerMatcher. /// @@ -672,7 +678,7 @@ AST_POLYMORPHIC_MATCHER_P( Builder); } -/// \brief Matches expressions that match InnerMatcher after any implicit AST +/// Matches expressions that match InnerMatcher after any implicit AST /// nodes are stripped off. /// /// Parentheses and explicit casts are not discarded. @@ -693,12 +699,12 @@ AST_POLYMORPHIC_MATCHER_P( /// varDecl(hasInitializer(cxxConstructExpr())) /// \endcode /// only match the declarations for b and c. -AST_MATCHER_P(Expr, ignoringImplicit, ast_matchers::internal::Matcher<Expr>, +AST_MATCHER_P(Expr, ignoringImplicit, internal::Matcher<Expr>, InnerMatcher) { return InnerMatcher.matches(*Node.IgnoreImplicit(), Finder, Builder); } -/// \brief Matches expressions that match InnerMatcher after any implicit casts +/// Matches expressions that match InnerMatcher after any implicit casts /// are stripped off. /// /// Parentheses and explicit casts are not discarded. @@ -728,7 +734,7 @@ AST_MATCHER_P(Expr, ignoringImpCasts, return InnerMatcher.matches(*Node.IgnoreImpCasts(), Finder, Builder); } -/// \brief Matches expressions that match InnerMatcher after parentheses and +/// Matches expressions that match InnerMatcher after parentheses and /// casts are stripped off. /// /// Implicit and non-C Style casts are also discarded. @@ -749,7 +755,7 @@ AST_MATCHER_P(Expr, ignoringParenCasts, internal::Matcher<Expr>, InnerMatcher) { return InnerMatcher.matches(*Node.IgnoreParenCasts(), Finder, Builder); } -/// \brief Matches expressions that match InnerMatcher after implicit casts and +/// Matches expressions that match InnerMatcher after implicit casts and /// parentheses are stripped off. /// /// Explicit casts are not discarded. @@ -775,7 +781,7 @@ AST_MATCHER_P(Expr, ignoringParenImpCasts, return InnerMatcher.matches(*Node.IgnoreParenImpCasts(), Finder, Builder); } -/// \brief Matches types that match InnerMatcher after any parens are stripped. +/// Matches types that match InnerMatcher after any parens are stripped. /// /// Given /// \code @@ -791,7 +797,7 @@ AST_MATCHER_P(QualType, ignoringParens, return InnerMatcher.matches(Node.IgnoreParens(), Finder, Builder); } -/// \brief Matches classTemplateSpecializations, templateSpecializationType and +/// Matches classTemplateSpecializations, templateSpecializationType and /// functionDecl where the n'th TemplateArgument matches the given InnerMatcher. /// /// Given @@ -800,7 +806,7 @@ AST_MATCHER_P(QualType, ignoringParens, /// A<bool, int> b; /// A<int, bool> c; /// -/// template<typename T> f() {}; +/// template<typename T> void f() {} /// void func() { f<int>(); }; /// \endcode /// classTemplateSpecializationDecl(hasTemplateArgument( @@ -822,7 +828,7 @@ AST_POLYMORPHIC_MATCHER_P2( return InnerMatcher.matches(List[N], Finder, Builder); } -/// \brief Matches if the number of template arguments equals \p N. +/// Matches if the number of template arguments equals \p N. /// /// Given /// \code @@ -839,7 +845,7 @@ AST_POLYMORPHIC_MATCHER_P( return internal::getTemplateSpecializationArgs(Node).size() == N; } -/// \brief Matches a TemplateArgument that refers to a certain type. +/// Matches a TemplateArgument that refers to a certain type. /// /// Given /// \code @@ -857,7 +863,7 @@ AST_MATCHER_P(TemplateArgument, refersToType, return InnerMatcher.matches(Node.getAsType(), Finder, Builder); } -/// \brief Matches a TemplateArgument that refers to a certain template. +/// Matches a TemplateArgument that refers to a certain template. /// /// Given /// \code @@ -875,17 +881,17 @@ AST_MATCHER_P(TemplateArgument, refersToTemplate, return InnerMatcher.matches(Node.getAsTemplate(), Finder, Builder); } -/// \brief Matches a canonical TemplateArgument that refers to a certain +/// Matches a canonical TemplateArgument that refers to a certain /// declaration. /// /// Given /// \code -/// template<typename T> struct A {}; -/// struct B { B* next; }; +/// struct B { int next; }; +/// template<int(B::*next_ptr)> struct A {}; /// A<&B::next> a; /// \endcode /// classTemplateSpecializationDecl(hasAnyTemplateArgument( -/// refersToDeclaration(fieldDecl(hasName("next")))) +/// refersToDeclaration(fieldDecl(hasName("next"))))) /// matches the specialization \c A<&B::next> with \c fieldDecl(...) matching /// \c B::next AST_MATCHER_P(TemplateArgument, refersToDeclaration, @@ -895,12 +901,12 @@ AST_MATCHER_P(TemplateArgument, refersToDeclaration, return false; } -/// \brief Matches a sugar TemplateArgument that refers to a certain expression. +/// Matches a sugar TemplateArgument that refers to a certain expression. /// /// Given /// \code -/// template<typename T> struct A {}; -/// struct B { B* next; }; +/// struct B { int next; }; +/// template<int(B::*next_ptr)> struct A {}; /// A<&B::next> a; /// \endcode /// templateSpecializationType(hasAnyTemplateArgument( @@ -913,11 +919,11 @@ AST_MATCHER_P(TemplateArgument, isExpr, internal::Matcher<Expr>, InnerMatcher) { return false; } -/// \brief Matches a TemplateArgument that is an integral value. +/// Matches a TemplateArgument that is an integral value. /// /// Given /// \code -/// template<int T> struct A {}; +/// template<int T> struct C {}; /// C<42> c; /// \endcode /// classTemplateSpecializationDecl( @@ -928,11 +934,11 @@ AST_MATCHER(TemplateArgument, isIntegral) { return Node.getKind() == TemplateArgument::Integral; } -/// \brief Matches a TemplateArgument that referes to an integral type. +/// Matches a TemplateArgument that referes to an integral type. /// /// Given /// \code -/// template<int T> struct A {}; +/// template<int T> struct C {}; /// C<42> c; /// \endcode /// classTemplateSpecializationDecl( @@ -945,7 +951,7 @@ AST_MATCHER_P(TemplateArgument, refersToIntegralType, return InnerMatcher.matches(Node.getIntegralType(), Finder, Builder); } -/// \brief Matches a TemplateArgument of integral type with a given value. +/// Matches a TemplateArgument of integral type with a given value. /// /// Note that 'Value' is a string as the template argument's value is /// an arbitrary precision integer. 'Value' must be euqal to the canonical @@ -953,7 +959,7 @@ AST_MATCHER_P(TemplateArgument, refersToIntegralType, /// /// Given /// \code -/// template<int T> struct A {}; +/// template<int T> struct C {}; /// C<42> c; /// \endcode /// classTemplateSpecializationDecl( @@ -966,7 +972,20 @@ AST_MATCHER_P(TemplateArgument, equalsIntegralValue, return Node.getAsIntegral().toString(10) == Value; } -/// \brief Matches any value declaration. +/// Matches an Objective-C autorelease pool statement. +/// +/// Given +/// \code +/// @autoreleasepool { +/// int x = 0; +/// } +/// \endcode +/// autoreleasePoolStmt(stmt()) matches the declaration of "x" +/// inside the autorelease pool. +extern const internal::VariadicDynCastAllOfMatcher<Stmt, + ObjCAutoreleasePoolStmt> autoreleasePoolStmt; + +/// Matches any value declaration. /// /// Example matches A, B, C and F /// \code @@ -975,7 +994,7 @@ AST_MATCHER_P(TemplateArgument, equalsIntegralValue, /// \endcode extern const internal::VariadicDynCastAllOfMatcher<Decl, ValueDecl> valueDecl; -/// \brief Matches C++ constructor declarations. +/// Matches C++ constructor declarations. /// /// Example matches Foo::Foo() and Foo::Foo(int) /// \code @@ -989,7 +1008,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, ValueDecl> valueDecl; extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXConstructorDecl> cxxConstructorDecl; -/// \brief Matches explicit C++ destructor declarations. +/// Matches explicit C++ destructor declarations. /// /// Example matches Foo::~Foo() /// \code @@ -1001,7 +1020,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXConstructorDecl> extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXDestructorDecl> cxxDestructorDecl; -/// \brief Matches enum declarations. +/// Matches enum declarations. /// /// Example matches X /// \code @@ -1011,7 +1030,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXDestructorDecl> /// \endcode extern const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl; -/// \brief Matches enum constants. +/// Matches enum constants. /// /// Example matches A, B, C /// \code @@ -1022,7 +1041,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl; extern const internal::VariadicDynCastAllOfMatcher<Decl, EnumConstantDecl> enumConstantDecl; -/// \brief Matches method declarations. +/// Matches method declarations. /// /// Example matches y /// \code @@ -1031,7 +1050,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, EnumConstantDecl> extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> cxxMethodDecl; -/// \brief Matches conversion operator declarations. +/// Matches conversion operator declarations. /// /// Example matches the operator. /// \code @@ -1040,7 +1059,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl> cxxConversionDecl; -/// \brief Matches variable declarations. +/// Matches variable declarations. /// /// Note: this does not match declarations of member variables, which are /// "field" declarations in Clang parlance. @@ -1051,7 +1070,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl> /// \endcode extern const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> varDecl; -/// \brief Matches field declarations. +/// Matches field declarations. /// /// Given /// \code @@ -1061,7 +1080,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> varDecl; /// matches 'm'. extern const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> fieldDecl; -/// \brief Matches function declarations. +/// Matches function declarations. /// /// Example matches f /// \code @@ -1070,7 +1089,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> fieldDecl; extern const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl> functionDecl; -/// \brief Matches C++ function template declarations. +/// Matches C++ function template declarations. /// /// Example matches f /// \code @@ -1079,7 +1098,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl> extern const internal::VariadicDynCastAllOfMatcher<Decl, FunctionTemplateDecl> functionTemplateDecl; -/// \brief Matches friend declarations. +/// Matches friend declarations. /// /// Given /// \code @@ -1089,7 +1108,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, FunctionTemplateDecl> /// matches 'friend void foo()'. extern const internal::VariadicDynCastAllOfMatcher<Decl, FriendDecl> friendDecl; -/// \brief Matches statements. +/// Matches statements. /// /// Given /// \code @@ -1099,7 +1118,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, FriendDecl> friendDecl; /// matches both the compound statement '{ ++a; }' and '++a'. extern const internal::VariadicAllOfMatcher<Stmt> stmt; -/// \brief Matches declaration statements. +/// Matches declaration statements. /// /// Given /// \code @@ -1109,7 +1128,7 @@ extern const internal::VariadicAllOfMatcher<Stmt> stmt; /// matches 'int a'. extern const internal::VariadicDynCastAllOfMatcher<Stmt, DeclStmt> declStmt; -/// \brief Matches member expressions. +/// Matches member expressions. /// /// Given /// \code @@ -1122,7 +1141,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, DeclStmt> declStmt; /// matches this->x, x, y.x, a, this->b extern const internal::VariadicDynCastAllOfMatcher<Stmt, MemberExpr> memberExpr; -/// \brief Matches call expressions. +/// Matches call expressions. /// /// Example matches x.y() and y() /// \code @@ -1132,7 +1151,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, MemberExpr> memberExpr; /// \endcode extern const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> callExpr; -/// \brief Matches lambda expressions. +/// Matches lambda expressions. /// /// Example matches [&](){return 5;} /// \code @@ -1140,7 +1159,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> callExpr; /// \endcode extern const internal::VariadicDynCastAllOfMatcher<Stmt, LambdaExpr> lambdaExpr; -/// \brief Matches member call expressions. +/// Matches member call expressions. /// /// Example matches x.y() /// \code @@ -1150,7 +1169,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, LambdaExpr> lambdaExpr; extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXMemberCallExpr> cxxMemberCallExpr; -/// \brief Matches ObjectiveC Message invocation expressions. +/// Matches ObjectiveC Message invocation expressions. /// /// The innermost message send invokes the "alloc" class method on the /// NSString class, while the outermost message send invokes the @@ -1162,7 +1181,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXMemberCallExpr> extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCMessageExpr> objcMessageExpr; -/// \brief Matches Objective-C interface declarations. +/// Matches Objective-C interface declarations. /// /// Example matches Foo /// \code @@ -1172,7 +1191,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCMessageExpr> extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCInterfaceDecl> objcInterfaceDecl; -/// \brief Matches Objective-C implementation declarations. +/// Matches Objective-C implementation declarations. /// /// Example matches Foo /// \code @@ -1182,7 +1201,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCInterfaceDecl> extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCImplementationDecl> objcImplementationDecl; -/// \brief Matches Objective-C protocol declarations. +/// Matches Objective-C protocol declarations. /// /// Example matches FooDelegate /// \code @@ -1192,7 +1211,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCImplementationDecl> extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCProtocolDecl> objcProtocolDecl; -/// \brief Matches Objective-C category declarations. +/// Matches Objective-C category declarations. /// /// Example matches Foo (Additions) /// \code @@ -1202,7 +1221,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCProtocolDecl> extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryDecl> objcCategoryDecl; -/// \brief Matches Objective-C category definitions. +/// Matches Objective-C category definitions. /// /// Example matches Foo (Additions) /// \code @@ -1212,7 +1231,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryDecl> extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryImplDecl> objcCategoryImplDecl; -/// \brief Matches Objective-C method declarations. +/// Matches Objective-C method declarations. /// /// Example matches both declaration and definition of -[Foo method] /// \code @@ -1227,7 +1246,20 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryImplDecl> extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCMethodDecl> objcMethodDecl; -/// \brief Matches Objective-C instance variable declarations. +/// Matches block declarations. +/// +/// Example matches the declaration of the nameless block printing an input +/// integer. +/// +/// \code +/// myFunc(^(int p) { +/// printf("%d", p); +/// }) +/// \endcode +extern const internal::VariadicDynCastAllOfMatcher<Decl, BlockDecl> + blockDecl; + +/// Matches Objective-C instance variable declarations. /// /// Example matches _enabled /// \code @@ -1239,7 +1271,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCMethodDecl> extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCIvarDecl> objcIvarDecl; -/// \brief Matches Objective-C property declarations. +/// Matches Objective-C property declarations. /// /// Example matches enabled /// \code @@ -1250,7 +1282,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCIvarDecl> extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCPropertyDecl> objcPropertyDecl; -/// \brief Matches Objective-C \@throw statements. +/// Matches Objective-C \@throw statements. /// /// Example matches \@throw /// \code @@ -1259,7 +1291,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCPropertyDecl> extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtThrowStmt> objcThrowStmt; -/// \brief Matches Objective-C @try statements. +/// Matches Objective-C @try statements. /// /// Example matches @try /// \code @@ -1269,7 +1301,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtThrowStmt> extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtTryStmt> objcTryStmt; -/// \brief Matches Objective-C @catch statements. +/// Matches Objective-C @catch statements. /// /// Example matches @catch /// \code @@ -1279,7 +1311,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtTryStmt> extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtCatchStmt> objcCatchStmt; -/// \brief Matches Objective-C @finally statements. +/// Matches Objective-C @finally statements. /// /// Example matches @finally /// \code @@ -1289,7 +1321,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtCatchStmt> extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtFinallyStmt> objcFinallyStmt; -/// \brief Matches expressions that introduce cleanups to be run at the end +/// Matches expressions that introduce cleanups to be run at the end /// of the sub-expression's evaluation. /// /// Example matches std::string() @@ -1299,7 +1331,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtFinallyStmt> extern const internal::VariadicDynCastAllOfMatcher<Stmt, ExprWithCleanups> exprWithCleanups; -/// \brief Matches init list expressions. +/// Matches init list expressions. /// /// Given /// \code @@ -1312,7 +1344,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, ExprWithCleanups> extern const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr> initListExpr; -/// \brief Matches the syntactic form of init list expressions +/// Matches the syntactic form of init list expressions /// (if expression have it). AST_MATCHER_P(InitListExpr, hasSyntacticForm, internal::Matcher<Expr>, InnerMatcher) { @@ -1321,7 +1353,7 @@ AST_MATCHER_P(InitListExpr, hasSyntacticForm, InnerMatcher.matches(*SyntForm, Finder, Builder)); } -/// \brief Matches C++ initializer list expressions. +/// Matches C++ initializer list expressions. /// /// Given /// \code @@ -1336,7 +1368,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXStdInitializerListExpr> cxxStdInitializerListExpr; -/// \brief Matches implicit initializers of init list expressions. +/// Matches implicit initializers of init list expressions. /// /// Given /// \code @@ -1347,7 +1379,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, extern const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitValueInitExpr> implicitValueInitExpr; -/// \brief Matches paren list expressions. +/// Matches paren list expressions. /// ParenListExprs don't have a predefined type and are used for late parsing. /// In the final AST, they can be met in template declarations. /// @@ -1365,7 +1397,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitValueInitExpr> extern const internal::VariadicDynCastAllOfMatcher<Stmt, ParenListExpr> parenListExpr; -/// \brief Matches substitutions of non-type template parameters. +/// Matches substitutions of non-type template parameters. /// /// Given /// \code @@ -1379,7 +1411,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, SubstNonTypeTemplateParmExpr> substNonTypeTemplateParmExpr; -/// \brief Matches using declarations. +/// Matches using declarations. /// /// Given /// \code @@ -1390,7 +1422,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, /// matches \code using X::x \endcode extern const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl; -/// \brief Matches using namespace declarations. +/// Matches using namespace declarations. /// /// Given /// \code @@ -1402,7 +1434,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl; extern const internal::VariadicDynCastAllOfMatcher<Decl, UsingDirectiveDecl> usingDirectiveDecl; -/// \brief Matches reference to a name that can be looked up during parsing +/// Matches reference to a name that can be looked up during parsing /// but could not be resolved to a specific declaration. /// /// Given @@ -1419,7 +1451,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, UsingDirectiveDecl> extern const internal::VariadicDynCastAllOfMatcher<Stmt, UnresolvedLookupExpr> unresolvedLookupExpr; -/// \brief Matches unresolved using value declarations. +/// Matches unresolved using value declarations. /// /// Given /// \code @@ -1434,7 +1466,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, UnresolvedUsingValueDecl> unresolvedUsingValueDecl; -/// \brief Matches unresolved using value declarations that involve the +/// Matches unresolved using value declarations that involve the /// typename. /// /// Given @@ -1453,7 +1485,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, UnresolvedUsingTypenameDecl> unresolvedUsingTypenameDecl; -/// \brief Matches parentheses used in expressions. +/// Matches parentheses used in expressions. /// /// Example matches (foo() + 1) /// \code @@ -1462,7 +1494,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, /// \endcode extern const internal::VariadicDynCastAllOfMatcher<Stmt, ParenExpr> parenExpr; -/// \brief Matches constructor call expressions (including implicit ones). +/// Matches constructor call expressions (including implicit ones). /// /// Example matches string(ptr, n) and ptr within arguments of f /// (matcher = cxxConstructExpr()) @@ -1475,7 +1507,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, ParenExpr> parenExpr; extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstructExpr> cxxConstructExpr; -/// \brief Matches unresolved constructor call expressions. +/// Matches unresolved constructor call expressions. /// /// Example matches T(t) in return statement of f /// (matcher = cxxUnresolvedConstructExpr()) @@ -1487,7 +1519,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXUnresolvedConstructExpr> cxxUnresolvedConstructExpr; -/// \brief Matches implicit and explicit this expressions. +/// Matches implicit and explicit this expressions. /// /// Example matches the implicit this expression in "return i". /// (matcher = cxxThisExpr()) @@ -1500,7 +1532,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThisExpr> cxxThisExpr; -/// \brief Matches nodes where temporaries are created. +/// Matches nodes where temporaries are created. /// /// Example matches FunctionTakesString(GetStringByValue()) /// (matcher = cxxBindTemporaryExpr()) @@ -1511,7 +1543,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThisExpr> extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBindTemporaryExpr> cxxBindTemporaryExpr; -/// \brief Matches nodes where temporaries are materialized. +/// Matches nodes where temporaries are materialized. /// /// Example: Given /// \code @@ -1523,17 +1555,17 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBindTemporaryExpr> /// \code /// T u(f()); /// g(f()); +/// f().func(); /// \endcode /// but does not match /// \code /// f(); -/// f().func(); /// \endcode extern const internal::VariadicDynCastAllOfMatcher<Stmt, MaterializeTemporaryExpr> materializeTemporaryExpr; -/// \brief Matches new expressions. +/// Matches new expressions. /// /// Given /// \code @@ -1543,7 +1575,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, /// matches 'new X'. extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> cxxNewExpr; -/// \brief Matches delete expressions. +/// Matches delete expressions. /// /// Given /// \code @@ -1554,7 +1586,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> cxxNewExpr; extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDeleteExpr> cxxDeleteExpr; -/// \brief Matches array subscript expressions. +/// Matches array subscript expressions. /// /// Given /// \code @@ -1565,7 +1597,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDeleteExpr> extern const internal::VariadicDynCastAllOfMatcher<Stmt, ArraySubscriptExpr> arraySubscriptExpr; -/// \brief Matches the value of a default argument at the call site. +/// Matches the value of a default argument at the call site. /// /// Example matches the CXXDefaultArgExpr placeholder inserted for the /// default value of the second parameter in the call expression f(42) @@ -1577,7 +1609,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, ArraySubscriptExpr> extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDefaultArgExpr> cxxDefaultArgExpr; -/// \brief Matches overloaded operator calls. +/// Matches overloaded operator calls. /// /// Note that if an operator isn't overloaded, it won't match. Instead, use /// binaryOperator matcher. @@ -1594,7 +1626,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDefaultArgExpr> extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXOperatorCallExpr> cxxOperatorCallExpr; -/// \brief Matches expressions. +/// Matches expressions. /// /// Example matches x() /// \code @@ -1602,7 +1634,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXOperatorCallExpr> /// \endcode extern const internal::VariadicDynCastAllOfMatcher<Stmt, Expr> expr; -/// \brief Matches expressions that refer to declarations. +/// Matches expressions that refer to declarations. /// /// Example matches x in if (x) /// \code @@ -1612,7 +1644,22 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, Expr> expr; extern const internal::VariadicDynCastAllOfMatcher<Stmt, DeclRefExpr> declRefExpr; -/// \brief Matches if statements. +/// Matches a reference to an ObjCIvar. +/// +/// Example: matches "a" in "init" method: +/// \code +/// @implementation A { +/// NSString *a; +/// } +/// - (void) init { +/// a = @"hello"; +/// } +//} +/// \endcode +extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCIvarRefExpr> + objcIvarRefExpr; + +/// Matches if statements. /// /// Example matches 'if (x) {}' /// \code @@ -1620,7 +1667,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, DeclRefExpr> /// \endcode extern const internal::VariadicDynCastAllOfMatcher<Stmt, IfStmt> ifStmt; -/// \brief Matches for statements. +/// Matches for statements. /// /// Example matches 'for (;;) {}' /// \code @@ -1629,7 +1676,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, IfStmt> ifStmt; /// \endcode extern const internal::VariadicDynCastAllOfMatcher<Stmt, ForStmt> forStmt; -/// \brief Matches the increment statement of a for loop. +/// Matches the increment statement of a for loop. /// /// Example: /// forStmt(hasIncrement(unaryOperator(hasOperatorName("++")))) @@ -1644,7 +1691,7 @@ AST_MATCHER_P(ForStmt, hasIncrement, internal::Matcher<Stmt>, InnerMatcher.matches(*Increment, Finder, Builder)); } -/// \brief Matches the initialization statement of a for loop. +/// Matches the initialization statement of a for loop. /// /// Example: /// forStmt(hasLoopInit(declStmt())) @@ -1658,7 +1705,7 @@ AST_MATCHER_P(ForStmt, hasLoopInit, internal::Matcher<Stmt>, return (Init != nullptr && InnerMatcher.matches(*Init, Finder, Builder)); } -/// \brief Matches range-based for statements. +/// Matches range-based for statements. /// /// cxxForRangeStmt() matches 'for (auto a : i)' /// \code @@ -1668,7 +1715,7 @@ AST_MATCHER_P(ForStmt, hasLoopInit, internal::Matcher<Stmt>, extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXForRangeStmt> cxxForRangeStmt; -/// \brief Matches the initialization statement of a for loop. +/// Matches the initialization statement of a for loop. /// /// Example: /// forStmt(hasLoopVariable(anything())) @@ -1682,7 +1729,7 @@ AST_MATCHER_P(CXXForRangeStmt, hasLoopVariable, internal::Matcher<VarDecl>, return (Var != nullptr && InnerMatcher.matches(*Var, Finder, Builder)); } -/// \brief Matches the range initialization statement of a for loop. +/// Matches the range initialization statement of a for loop. /// /// Example: /// forStmt(hasRangeInit(anything())) @@ -1696,7 +1743,7 @@ AST_MATCHER_P(CXXForRangeStmt, hasRangeInit, internal::Matcher<Expr>, return (Init != nullptr && InnerMatcher.matches(*Init, Finder, Builder)); } -/// \brief Matches while statements. +/// Matches while statements. /// /// Given /// \code @@ -1706,7 +1753,7 @@ AST_MATCHER_P(CXXForRangeStmt, hasRangeInit, internal::Matcher<Expr>, /// matches 'while (true) {}'. extern const internal::VariadicDynCastAllOfMatcher<Stmt, WhileStmt> whileStmt; -/// \brief Matches do statements. +/// Matches do statements. /// /// Given /// \code @@ -1716,7 +1763,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, WhileStmt> whileStmt; /// matches 'do {} while(true)' extern const internal::VariadicDynCastAllOfMatcher<Stmt, DoStmt> doStmt; -/// \brief Matches break statements. +/// Matches break statements. /// /// Given /// \code @@ -1726,7 +1773,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, DoStmt> doStmt; /// matches 'break' extern const internal::VariadicDynCastAllOfMatcher<Stmt, BreakStmt> breakStmt; -/// \brief Matches continue statements. +/// Matches continue statements. /// /// Given /// \code @@ -1737,7 +1784,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, BreakStmt> breakStmt; extern const internal::VariadicDynCastAllOfMatcher<Stmt, ContinueStmt> continueStmt; -/// \brief Matches return statements. +/// Matches return statements. /// /// Given /// \code @@ -1747,7 +1794,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, ContinueStmt> /// matches 'return 1' extern const internal::VariadicDynCastAllOfMatcher<Stmt, ReturnStmt> returnStmt; -/// \brief Matches goto statements. +/// Matches goto statements. /// /// Given /// \code @@ -1758,7 +1805,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, ReturnStmt> returnStmt; /// matches 'goto FOO' extern const internal::VariadicDynCastAllOfMatcher<Stmt, GotoStmt> gotoStmt; -/// \brief Matches label statements. +/// Matches label statements. /// /// Given /// \code @@ -1769,7 +1816,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, GotoStmt> gotoStmt; /// matches 'FOO:' extern const internal::VariadicDynCastAllOfMatcher<Stmt, LabelStmt> labelStmt; -/// \brief Matches address of label statements (GNU extension). +/// Matches address of label statements (GNU extension). /// /// Given /// \code @@ -1782,7 +1829,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, LabelStmt> labelStmt; extern const internal::VariadicDynCastAllOfMatcher<Stmt, AddrLabelExpr> addrLabelExpr; -/// \brief Matches switch statements. +/// Matches switch statements. /// /// Given /// \code @@ -1792,47 +1839,47 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, AddrLabelExpr> /// matches 'switch(a)'. extern const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchStmt> switchStmt; -/// \brief Matches case and default statements inside switch statements. +/// Matches case and default statements inside switch statements. /// /// Given /// \code /// switch(a) { case 42: break; default: break; } /// \endcode /// switchCase() -/// matches 'case 42: break;' and 'default: break;'. +/// matches 'case 42:' and 'default:'. extern const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchCase> switchCase; -/// \brief Matches case statements inside switch statements. +/// Matches case statements inside switch statements. /// /// Given /// \code /// switch(a) { case 42: break; default: break; } /// \endcode /// caseStmt() -/// matches 'case 42: break;'. +/// matches 'case 42:'. extern const internal::VariadicDynCastAllOfMatcher<Stmt, CaseStmt> caseStmt; -/// \brief Matches default statements inside switch statements. +/// Matches default statements inside switch statements. /// /// Given /// \code /// switch(a) { case 42: break; default: break; } /// \endcode /// defaultStmt() -/// matches 'default: break;'. +/// matches 'default:'. extern const internal::VariadicDynCastAllOfMatcher<Stmt, DefaultStmt> defaultStmt; -/// \brief Matches compound statements. +/// Matches compound statements. /// -/// Example matches '{}' and '{{}}'in 'for (;;) {{}}' +/// Example matches '{}' and '{{}}' in 'for (;;) {{}}' /// \code /// for (;;) {{}} /// \endcode extern const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundStmt> compoundStmt; -/// \brief Matches catch statements. +/// Matches catch statements. /// /// \code /// try {} catch(int i) {} @@ -1842,7 +1889,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundStmt> extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXCatchStmt> cxxCatchStmt; -/// \brief Matches try statements. +/// Matches try statements. /// /// \code /// try {} catch(int i) {} @@ -1851,7 +1898,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXCatchStmt> /// matches 'try {}' extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTryStmt> cxxTryStmt; -/// \brief Matches throw expressions. +/// Matches throw expressions. /// /// \code /// try { throw 5; } catch(int i) {} @@ -1861,7 +1908,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTryStmt> cxxTryStmt; extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThrowExpr> cxxThrowExpr; -/// \brief Matches null statements. +/// Matches null statements. /// /// \code /// foo();; @@ -1870,7 +1917,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThrowExpr> /// matches the second ';' extern const internal::VariadicDynCastAllOfMatcher<Stmt, NullStmt> nullStmt; -/// \brief Matches asm statements. +/// Matches asm statements. /// /// \code /// int i = 100; @@ -1880,7 +1927,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, NullStmt> nullStmt; /// matches '__asm("mov al, 2")' extern const internal::VariadicDynCastAllOfMatcher<Stmt, AsmStmt> asmStmt; -/// \brief Matches bool literals. +/// Matches bool literals. /// /// Example matches true /// \code @@ -1889,7 +1936,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, AsmStmt> asmStmt; extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBoolLiteralExpr> cxxBoolLiteral; -/// \brief Matches string literals (also matches wide string literals). +/// Matches string literals (also matches wide string literals). /// /// Example matches "abcd", L"abcd" /// \code @@ -1899,7 +1946,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBoolLiteralExpr> extern const internal::VariadicDynCastAllOfMatcher<Stmt, StringLiteral> stringLiteral; -/// \brief Matches character literals (also matches wchar_t). +/// Matches character literals (also matches wchar_t). /// /// Not matching Hex-encoded chars (e.g. 0x1234, which is a IntegerLiteral), /// though. @@ -1912,14 +1959,14 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, StringLiteral> extern const internal::VariadicDynCastAllOfMatcher<Stmt, CharacterLiteral> characterLiteral; -/// \brief Matches integer literals of all sizes / encodings, e.g. +/// Matches integer literals of all sizes / encodings, e.g. /// 1, 1L, 0x1 and 1U. /// /// Does not match character-encoded integers such as L'a'. extern const internal::VariadicDynCastAllOfMatcher<Stmt, IntegerLiteral> integerLiteral; -/// \brief Matches float literals of all sizes / encodings, e.g. +/// Matches float literals of all sizes / encodings, e.g. /// 1.0, 1.0f, 1.0L and 1e10. /// /// Does not match implicit conversions such as @@ -1929,13 +1976,13 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, IntegerLiteral> extern const internal::VariadicDynCastAllOfMatcher<Stmt, FloatingLiteral> floatLiteral; -/// \brief Matches user defined literal operator call. +/// Matches user defined literal operator call. /// /// Example match: "foo"_suffix extern const internal::VariadicDynCastAllOfMatcher<Stmt, UserDefinedLiteral> userDefinedLiteral; -/// \brief Matches compound (i.e. non-scalar) literals +/// Matches compound (i.e. non-scalar) literals /// /// Example match: {1}, (1, 2) /// \code @@ -1945,22 +1992,22 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, UserDefinedLiteral> extern const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundLiteralExpr> compoundLiteralExpr; -/// \brief Matches nullptr literal. +/// Matches nullptr literal. extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNullPtrLiteralExpr> cxxNullPtrLiteralExpr; -/// \brief Matches GNU __null expression. +/// Matches GNU __null expression. extern const internal::VariadicDynCastAllOfMatcher<Stmt, GNUNullExpr> gnuNullExpr; -/// \brief Matches atomic builtins. +/// Matches atomic builtins. /// Example matches __atomic_load_n(ptr, 1) /// \code /// void foo() { int *ptr; __atomic_load_n(ptr, 1); } /// \endcode extern const internal::VariadicDynCastAllOfMatcher<Stmt, AtomicExpr> atomicExpr; -/// \brief Matches statement expression (GNU extension). +/// Matches statement expression (GNU extension). /// /// Example match: ({ int X = 4; X; }) /// \code @@ -1968,7 +2015,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, AtomicExpr> atomicExpr; /// \endcode extern const internal::VariadicDynCastAllOfMatcher<Stmt, StmtExpr> stmtExpr; -/// \brief Matches binary operator expressions. +/// Matches binary operator expressions. /// /// Example matches a || b /// \code @@ -1977,7 +2024,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, StmtExpr> stmtExpr; extern const internal::VariadicDynCastAllOfMatcher<Stmt, BinaryOperator> binaryOperator; -/// \brief Matches unary operator expressions. +/// Matches unary operator expressions. /// /// Example matches !a /// \code @@ -1986,7 +2033,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, BinaryOperator> extern const internal::VariadicDynCastAllOfMatcher<Stmt, UnaryOperator> unaryOperator; -/// \brief Matches conditional operator expressions. +/// Matches conditional operator expressions. /// /// Example matches a ? b : c /// \code @@ -1995,7 +2042,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, UnaryOperator> extern const internal::VariadicDynCastAllOfMatcher<Stmt, ConditionalOperator> conditionalOperator; -/// \brief Matches binary conditional operator expressions (GNU extension). +/// Matches binary conditional operator expressions (GNU extension). /// /// Example matches a ?: b /// \code @@ -2005,7 +2052,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, BinaryConditionalOperator> binaryConditionalOperator; -/// \brief Matches opaque value expressions. They are used as helpers +/// Matches opaque value expressions. They are used as helpers /// to reference another expressions and can be met /// in BinaryConditionalOperators, for example. /// @@ -2016,7 +2063,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, extern const internal::VariadicDynCastAllOfMatcher<Stmt, OpaqueValueExpr> opaqueValueExpr; -/// \brief Matches a C++ static_assert declaration. +/// Matches a C++ static_assert declaration. /// /// Example: /// staticAssertExpr() @@ -2032,7 +2079,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, OpaqueValueExpr> extern const internal::VariadicDynCastAllOfMatcher<Decl, StaticAssertDecl> staticAssertDecl; -/// \brief Matches a reinterpret_cast expression. +/// Matches a reinterpret_cast expression. /// /// Either the source expression or the destination type can be matched /// using has(), but hasDestinationType() is more specific and can be @@ -2045,7 +2092,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, StaticAssertDecl> extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXReinterpretCastExpr> cxxReinterpretCastExpr; -/// \brief Matches a C++ static_cast expression. +/// Matches a C++ static_cast expression. /// /// \see hasDestinationType /// \see reinterpretCast @@ -2061,7 +2108,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXReinterpretCastExpr> extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXStaticCastExpr> cxxStaticCastExpr; -/// \brief Matches a dynamic_cast expression. +/// Matches a dynamic_cast expression. /// /// Example: /// cxxDynamicCastExpr() @@ -2076,7 +2123,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXStaticCastExpr> extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDynamicCastExpr> cxxDynamicCastExpr; -/// \brief Matches a const_cast expression. +/// Matches a const_cast expression. /// /// Example: Matches const_cast<int*>(&r) in /// \code @@ -2087,7 +2134,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDynamicCastExpr> extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstCastExpr> cxxConstCastExpr; -/// \brief Matches a C-style cast expression. +/// Matches a C-style cast expression. /// /// Example: Matches (int) 2.2f in /// \code @@ -2096,7 +2143,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstCastExpr> extern const internal::VariadicDynCastAllOfMatcher<Stmt, CStyleCastExpr> cStyleCastExpr; -/// \brief Matches explicit cast expressions. +/// Matches explicit cast expressions. /// /// Matches any cast expression written in user code, whether it be a /// C-style cast, a functional-style cast, or a keyword cast. @@ -2120,14 +2167,14 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CStyleCastExpr> extern const internal::VariadicDynCastAllOfMatcher<Stmt, ExplicitCastExpr> explicitCastExpr; -/// \brief Matches the implicit cast nodes of Clang's AST. +/// Matches the implicit cast nodes of Clang's AST. /// /// This matches many different places, including function call return value /// eliding, as well as any type conversions. extern const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitCastExpr> implicitCastExpr; -/// \brief Matches any cast nodes of Clang's AST. +/// Matches any cast nodes of Clang's AST. /// /// Example: castExpr() matches each of the following: /// \code @@ -2142,7 +2189,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitCastExpr> /// \endcode extern const internal::VariadicDynCastAllOfMatcher<Stmt, CastExpr> castExpr; -/// \brief Matches functional cast expressions +/// Matches functional cast expressions /// /// Example: Matches Foo(bar); /// \code @@ -2153,7 +2200,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CastExpr> castExpr; extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXFunctionalCastExpr> cxxFunctionalCastExpr; -/// \brief Matches functional cast expressions having N != 1 arguments +/// Matches functional cast expressions having N != 1 arguments /// /// Example: Matches Foo(bar, bar) /// \code @@ -2162,7 +2209,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXFunctionalCastExpr> extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTemporaryObjectExpr> cxxTemporaryObjectExpr; -/// \brief Matches predefined identifier expressions [C99 6.4.2.2]. +/// Matches predefined identifier expressions [C99 6.4.2.2]. /// /// Example: Matches __func__ /// \code @@ -2171,7 +2218,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTemporaryObjectExpr> extern const internal::VariadicDynCastAllOfMatcher<Stmt, PredefinedExpr> predefinedExpr; -/// \brief Matches C99 designated initializer expressions [C99 6.7.8]. +/// Matches C99 designated initializer expressions [C99 6.7.8]. /// /// Example: Matches { [2].y = 1.0, [0].x = 1.0 } /// \code @@ -2180,7 +2227,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, PredefinedExpr> extern const internal::VariadicDynCastAllOfMatcher<Stmt, DesignatedInitExpr> designatedInitExpr; -/// \brief Matches designated initializer expressions that contain +/// Matches designated initializer expressions that contain /// a specific number of designators. /// /// Example: Given @@ -2195,16 +2242,16 @@ AST_MATCHER_P(DesignatedInitExpr, designatorCountIs, unsigned, N) { return Node.size() == N; } -/// \brief Matches \c QualTypes in the clang AST. +/// Matches \c QualTypes in the clang AST. extern const internal::VariadicAllOfMatcher<QualType> qualType; -/// \brief Matches \c Types in the clang AST. +/// Matches \c Types in the clang AST. extern const internal::VariadicAllOfMatcher<Type> type; -/// \brief Matches \c TypeLocs in the clang AST. +/// Matches \c TypeLocs in the clang AST. extern const internal::VariadicAllOfMatcher<TypeLoc> typeLoc; -/// \brief Matches if any of the given matchers matches. +/// Matches if any of the given matchers matches. /// /// Unlike \c anyOf, \c eachOf will generate a match result for each /// matching submatcher. @@ -2227,21 +2274,21 @@ extern const internal::VariadicOperatorMatcherFunc< 2, std::numeric_limits<unsigned>::max()> eachOf; -/// \brief Matches if any of the given matchers matches. +/// Matches if any of the given matchers matches. /// /// Usable as: Any Matcher extern const internal::VariadicOperatorMatcherFunc< 2, std::numeric_limits<unsigned>::max()> anyOf; -/// \brief Matches if all given matchers match. +/// Matches if all given matchers match. /// /// Usable as: Any Matcher extern const internal::VariadicOperatorMatcherFunc< 2, std::numeric_limits<unsigned>::max()> allOf; -/// \brief Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL) +/// Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL) /// /// Given /// \code @@ -2254,7 +2301,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, UnaryExprOrTypeTraitExpr> unaryExprOrTypeTraitExpr; -/// \brief Matches unary expressions that have a specific type of argument. +/// Matches unary expressions that have a specific type of argument. /// /// Given /// \code @@ -2268,7 +2315,7 @@ AST_MATCHER_P(UnaryExprOrTypeTraitExpr, hasArgumentOfType, return InnerMatcher.matches(ArgumentType, Finder, Builder); } -/// \brief Matches unary expressions of a certain kind. +/// Matches unary expressions of a certain kind. /// /// Given /// \code @@ -2281,7 +2328,7 @@ AST_MATCHER_P(UnaryExprOrTypeTraitExpr, ofKind, UnaryExprOrTypeTrait, Kind) { return Node.getKind() == Kind; } -/// \brief Same as unaryExprOrTypeTraitExpr, but only matching +/// Same as unaryExprOrTypeTraitExpr, but only matching /// alignof. inline internal::Matcher<Stmt> alignOfExpr( const internal::Matcher<UnaryExprOrTypeTraitExpr> &InnerMatcher) { @@ -2289,7 +2336,7 @@ inline internal::Matcher<Stmt> alignOfExpr( ofKind(UETT_AlignOf), InnerMatcher))); } -/// \brief Same as unaryExprOrTypeTraitExpr, but only matching +/// Same as unaryExprOrTypeTraitExpr, but only matching /// sizeof. inline internal::Matcher<Stmt> sizeOfExpr( const internal::Matcher<UnaryExprOrTypeTraitExpr> &InnerMatcher) { @@ -2297,7 +2344,7 @@ inline internal::Matcher<Stmt> sizeOfExpr( allOf(ofKind(UETT_SizeOf), InnerMatcher))); } -/// \brief Matches NamedDecl nodes that have the specified name. +/// Matches NamedDecl nodes that have the specified name. /// /// Supports specifying enclosing namespaces or classes by prefixing the name /// with '<enclosing>::'. @@ -2313,12 +2360,10 @@ inline internal::Matcher<Stmt> sizeOfExpr( /// namespace a { namespace b { class X; } } /// \endcode inline internal::Matcher<NamedDecl> hasName(const std::string &Name) { - std::vector<std::string> Names; - Names.push_back(Name); - return internal::Matcher<NamedDecl>(new internal::HasNameMatcher(Names)); + return internal::Matcher<NamedDecl>(new internal::HasNameMatcher({Name})); } -/// \brief Matches NamedDecl nodes that have any of the specified names. +/// Matches NamedDecl nodes that have any of the specified names. /// /// This matcher is only provided as a performance optimization of hasName. /// \code @@ -2332,7 +2377,7 @@ extern const internal::VariadicFunction<internal::Matcher<NamedDecl>, StringRef, internal::hasAnyNameFunc> hasAnyName; -/// \brief Matches NamedDecl nodes whose fully qualified names contain +/// Matches NamedDecl nodes whose fully qualified names contain /// a substring matched by the given RegExp. /// /// Supports specifying enclosing namespaces or classes by @@ -2355,7 +2400,7 @@ AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp) { return RE.match(FullNameString); } -/// \brief Matches overloaded operator names. +/// Matches overloaded operator names. /// /// Matches overloaded operator names specified in strings without the /// "operator" prefix: e.g. "<<". @@ -2383,7 +2428,7 @@ hasOverloadedOperatorName(StringRef Name) { AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)>(Name); } -/// \brief Matches C++ classes that are directly or indirectly derived from +/// Matches C++ classes that are directly or indirectly derived from /// a class matching \c Base. /// /// Note that a class is not considered to be derived from itself. @@ -2409,13 +2454,13 @@ AST_MATCHER_P(CXXRecordDecl, isDerivedFrom, return Finder->classIsDerivedFrom(&Node, Base, Builder); } -/// \brief Overloaded method as shortcut for \c isDerivedFrom(hasName(...)). +/// Overloaded method as shortcut for \c isDerivedFrom(hasName(...)). AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isDerivedFrom, std::string, BaseName, 1) { assert(!BaseName.empty()); return isDerivedFrom(hasName(BaseName)).matches(Node, Finder, Builder); } -/// \brief Similar to \c isDerivedFrom(), but also matches classes that directly +/// Similar to \c isDerivedFrom(), but also matches classes that directly /// match \c Base. AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isSameOrDerivedFrom, internal::Matcher<NamedDecl>, Base, 0) { @@ -2423,7 +2468,7 @@ AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isSameOrDerivedFrom, .matches(Node, Finder, Builder); } -/// \brief Overloaded method as shortcut for +/// Overloaded method as shortcut for /// \c isSameOrDerivedFrom(hasName(...)). AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isSameOrDerivedFrom, std::string, BaseName, 1) { @@ -2431,7 +2476,7 @@ AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isSameOrDerivedFrom, std::string, return isSameOrDerivedFrom(hasName(BaseName)).matches(Node, Finder, Builder); } -/// \brief Matches the first method of a class or struct that satisfies \c +/// Matches the first method of a class or struct that satisfies \c /// InnerMatcher. /// /// Given: @@ -2448,7 +2493,7 @@ AST_MATCHER_P(CXXRecordDecl, hasMethod, internal::Matcher<CXXMethodDecl>, Node.method_end(), Finder, Builder); } -/// \brief Matches the generated class of lambda expressions. +/// Matches the generated class of lambda expressions. /// /// Given: /// \code @@ -2461,7 +2506,7 @@ AST_MATCHER(CXXRecordDecl, isLambda) { return Node.isLambda(); } -/// \brief Matches AST nodes that have child AST nodes that match the +/// Matches AST nodes that have child AST nodes that match the /// provided matcher. /// /// Example matches X, Y @@ -2481,7 +2526,7 @@ AST_MATCHER(CXXRecordDecl, isLambda) { /// has(ignoringParenImpCasts(expr())). extern const internal::ArgumentAdaptingMatcherFunc<internal::HasMatcher> has; -/// \brief Matches AST nodes that have descendant AST nodes that match the +/// Matches AST nodes that have descendant AST nodes that match the /// provided matcher. /// /// Example matches X, Y, Z @@ -2499,14 +2544,15 @@ extern const internal::ArgumentAdaptingMatcherFunc< internal::HasDescendantMatcher> hasDescendant; -/// \brief Matches AST nodes that have child AST nodes that match the +/// Matches AST nodes that have child AST nodes that match the /// provided matcher. /// -/// Example matches X, Y +/// Example matches X, Y, Y::X, Z::Y, Z::Y::X /// (matcher = cxxRecordDecl(forEach(cxxRecordDecl(hasName("X"))) /// \code -/// class X {}; // Matches X, because X::X is a class of name X inside X. -/// class Y { class X {}; }; +/// class X {}; +/// class Y { class X {}; }; // Matches Y, because Y::X is a class of name X +/// // inside Y. /// class Z { class Y { class X {}; }; }; // Does not match Z. /// \endcode /// @@ -2519,14 +2565,15 @@ extern const internal::ArgumentAdaptingMatcherFunc< extern const internal::ArgumentAdaptingMatcherFunc<internal::ForEachMatcher> forEach; -/// \brief Matches AST nodes that have descendant AST nodes that match the +/// Matches AST nodes that have descendant AST nodes that match the /// provided matcher. /// -/// Example matches X, A, B, C +/// Example matches X, A, A::X, B, B::C, B::C::X /// (matcher = cxxRecordDecl(forEachDescendant(cxxRecordDecl(hasName("X"))))) /// \code -/// class X {}; // Matches X, because X::X is a class of name X inside X. -/// class A { class X {}; }; +/// class X {}; +/// class A { class X {}; }; // Matches A, because A::X is a class of name +/// // X inside A. /// class B { class C { class X {}; }; }; /// \endcode /// @@ -2549,7 +2596,7 @@ extern const internal::ArgumentAdaptingMatcherFunc< internal::ForEachDescendantMatcher> forEachDescendant; -/// \brief Matches if the node or any descendant matches. +/// Matches if the node or any descendant matches. /// /// Generates results for each match. /// @@ -2570,7 +2617,7 @@ internal::Matcher<T> findAll(const internal::Matcher<T> &Matcher) { return eachOf(Matcher, forEachDescendant(Matcher)); } -/// \brief Matches AST nodes that have a parent that matches the provided +/// Matches AST nodes that have a parent that matches the provided /// matcher. /// /// Given @@ -2586,7 +2633,7 @@ extern const internal::ArgumentAdaptingMatcherFunc< internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>> hasParent; -/// \brief Matches AST nodes that have an ancestor that matches the provided +/// Matches AST nodes that have an ancestor that matches the provided /// matcher. /// /// Given @@ -2603,7 +2650,7 @@ extern const internal::ArgumentAdaptingMatcherFunc< internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>> hasAncestor; -/// \brief Matches if the provided matcher does not match. +/// Matches if the provided matcher does not match. /// /// Example matches Y (matcher = cxxRecordDecl(unless(hasName("X")))) /// \code @@ -2614,7 +2661,7 @@ extern const internal::ArgumentAdaptingMatcherFunc< /// Usable as: Any Matcher extern const internal::VariadicOperatorMatcherFunc<1, 1> unless; -/// \brief Matches a node if the declaration associated with that node +/// Matches a node if the declaration associated with that node /// matches the given matcher. /// /// The associated declaration is: @@ -2623,6 +2670,7 @@ extern const internal::VariadicOperatorMatcherFunc<1, 1> unless; /// - for MemberExpr, the declaration of the referenced member /// - for CXXConstructExpr, the declaration of the constructor /// - for CXXNewExpr, the declaration of the operator new +/// - for ObjCIvarExpr, the declaration of the ivar /// /// For type nodes, hasDeclaration will generally match the declaration of the /// sugared type. Given @@ -2656,7 +2704,7 @@ hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) { void(internal::HasDeclarationSupportedTypes)>(InnerMatcher); } -/// \brief Matches a \c NamedDecl whose underlying declaration matches the given +/// Matches a \c NamedDecl whose underlying declaration matches the given /// matcher. /// /// Given @@ -2675,13 +2723,13 @@ AST_MATCHER_P(NamedDecl, hasUnderlyingDecl, internal::Matcher<NamedDecl>, InnerMatcher.matches(*UnderlyingDecl, Finder, Builder); } -/// \brief Matches on the implicit object argument of a member call expression. +/// Matches on the implicit object argument of a member call expression. /// /// Example matches y.x() /// (matcher = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y")))))) /// \code /// class Y { public: void x(); }; -/// void z() { Y y; y.x(); }", +/// void z() { Y y; y.x(); } /// \endcode /// /// FIXME: Overload to allow directly matching types? @@ -2694,7 +2742,7 @@ AST_MATCHER_P(CXXMemberCallExpr, on, internal::Matcher<Expr>, } -/// \brief Matches on the receiver of an ObjectiveC Message expression. +/// Matches on the receiver of an ObjectiveC Message expression. /// /// Example /// matcher = objCMessageExpr(hasReceiverType(asString("UIWebView *"))); @@ -2709,8 +2757,43 @@ AST_MATCHER_P(ObjCMessageExpr, hasReceiverType, internal::Matcher<QualType>, const QualType TypeDecl = Node.getReceiverType(); return InnerMatcher.matches(TypeDecl, Finder, Builder); } - -/// \brief Matches when BaseName == Selector.getAsString() + +/// Returns true when the Objective-C message is sent to an instance. +/// +/// Example +/// matcher = objcMessagaeExpr(isInstanceMessage()) +/// matches +/// \code +/// NSString *x = @"hello"; +/// [x containsString:@"h"]; +/// \endcode +/// but not +/// \code +/// [NSString stringWithFormat:@"format"]; +/// \endcode +AST_MATCHER(ObjCMessageExpr, isInstanceMessage) { + return Node.isInstanceMessage(); +} + +/// Matches if the Objective-C message is sent to an instance, +/// and the inner matcher matches on that instance. +/// +/// For example the method call in +/// \code +/// NSString *x = @"hello"; +/// [x containsString:@"h"]; +/// \endcode +/// is matched by +/// objcMessageExpr(hasReceiver(declRefExpr(to(varDecl(hasName("x")))))) +AST_MATCHER_P(ObjCMessageExpr, hasReceiver, internal::Matcher<Expr>, + InnerMatcher) { + const Expr *ReceiverNode = Node.getInstanceReceiver(); + return (ReceiverNode != nullptr && + InnerMatcher.matches(*ReceiverNode->IgnoreParenImpCasts(), Finder, + Builder)); +} + +/// Matches when BaseName == Selector.getAsString() /// /// matcher = objCMessageExpr(hasSelector("loadHTMLString:baseURL:")); /// matches the outer message expr in the code below, but NOT the message @@ -2723,8 +2806,22 @@ AST_MATCHER_P(ObjCMessageExpr, hasSelector, std::string, BaseName) { return BaseName.compare(Sel.getAsString()) == 0; } - -/// \brief Matches ObjC selectors whose name contains + +/// Matches when at least one of the supplied string equals to the +/// Selector.getAsString() +/// +/// matcher = objCMessageExpr(hasSelector("methodA:", "methodB:")); +/// matches both of the expressions below: +/// \code +/// [myObj methodA:argA]; +/// [myObj methodB:argB]; +/// \endcode +extern const internal::VariadicFunction<internal::Matcher<ObjCMessageExpr>, + StringRef, + internal::hasAnySelectorFunc> + hasAnySelector; + +/// Matches ObjC selectors whose name contains /// a substring matched by the given RegExp. /// matcher = objCMessageExpr(matchesSelector("loadHTMLString\:baseURL?")); /// matches the outer message expr in the code below, but NOT the message @@ -2739,7 +2836,7 @@ AST_MATCHER_P(ObjCMessageExpr, matchesSelector, std::string, RegExp) { return RE.match(SelectorString); } -/// \brief Matches when the selector is the empty selector +/// Matches when the selector is the empty selector /// /// Matches only when the selector of the objCMessageExpr is NULL. This may /// represent an error condition in the tree! @@ -2747,7 +2844,7 @@ AST_MATCHER(ObjCMessageExpr, hasNullSelector) { return Node.getSelector().isNull(); } -/// \brief Matches when the selector is a Unary Selector +/// Matches when the selector is a Unary Selector /// /// matcher = objCMessageExpr(matchesSelector(hasUnarySelector()); /// matches self.bodyView in the code below, but NOT the outer message @@ -2759,7 +2856,7 @@ AST_MATCHER(ObjCMessageExpr, hasUnarySelector) { return Node.getSelector().isUnarySelector(); } -/// \brief Matches when the selector is a keyword selector +/// Matches when the selector is a keyword selector /// /// objCMessageExpr(hasKeywordSelector()) matches the generated setFrame /// message expression in @@ -2775,7 +2872,7 @@ AST_MATCHER(ObjCMessageExpr, hasKeywordSelector) { return Node.getSelector().isKeywordSelector(); } -/// \brief Matches when the selector has the specified number of arguments +/// Matches when the selector has the specified number of arguments /// /// matcher = objCMessageExpr(numSelectorArgs(0)); /// matches self.bodyView in the code below @@ -2790,7 +2887,7 @@ AST_MATCHER_P(ObjCMessageExpr, numSelectorArgs, unsigned, N) { return Node.getSelector().getNumArgs() == N; } -/// \brief Matches if the call expression's callee expression matches. +/// Matches if the call expression's callee expression matches. /// /// Given /// \code @@ -2813,7 +2910,7 @@ AST_MATCHER_P(CallExpr, callee, internal::Matcher<Stmt>, InnerMatcher.matches(*ExprNode, Finder, Builder)); } -/// \brief Matches if the call expression's callee's declaration matches the +/// Matches if the call expression's callee's declaration matches the /// given matcher. /// /// Example matches y.x() (matcher = callExpr(callee( @@ -2827,25 +2924,31 @@ AST_MATCHER_P_OVERLOAD(CallExpr, callee, internal::Matcher<Decl>, InnerMatcher, return callExpr(hasDeclaration(InnerMatcher)).matches(Node, Finder, Builder); } -/// \brief Matches if the expression's or declaration's type matches a type +/// Matches if the expression's or declaration's type matches a type /// matcher. /// /// Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X"))))) /// and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X"))))) /// and U (matcher = typedefDecl(hasType(asString("int"))) +/// and friend class X (matcher = friendDecl(hasType("X")) /// \code /// class X {}; /// void y(X &x) { x; X z; } /// typedef int U; +/// class Y { friend class X; }; /// \endcode AST_POLYMORPHIC_MATCHER_P_OVERLOAD( - hasType, AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, TypedefNameDecl, ValueDecl), + hasType, + AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, FriendDecl, TypedefNameDecl, + ValueDecl), internal::Matcher<QualType>, InnerMatcher, 0) { - return InnerMatcher.matches(internal::getUnderlyingType(Node), - Finder, Builder); + QualType QT = internal::getUnderlyingType(Node); + if (!QT.isNull()) + return InnerMatcher.matches(QT, Finder, Builder); + return false; } -/// \brief Overloaded to match the declaration of the expression's or value +/// Overloaded to match the declaration of the expression's or value /// declaration's type. /// /// In case of a value declaration (for example a variable declaration), @@ -2856,21 +2959,24 @@ AST_POLYMORPHIC_MATCHER_P_OVERLOAD( /// /// Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X"))))) /// and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X"))))) +/// and friend class X (matcher = friendDecl(hasType("X")) /// \code /// class X {}; /// void y(X &x) { x; X z; } +/// class Y { friend class X; }; /// \endcode /// /// Usable as: Matcher<Expr>, Matcher<ValueDecl> -AST_POLYMORPHIC_MATCHER_P_OVERLOAD(hasType, - AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, - ValueDecl), - internal::Matcher<Decl>, InnerMatcher, 1) { - return qualType(hasDeclaration(InnerMatcher)) - .matches(Node.getType(), Finder, Builder); +AST_POLYMORPHIC_MATCHER_P_OVERLOAD( + hasType, AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, FriendDecl, ValueDecl), + internal::Matcher<Decl>, InnerMatcher, 1) { + QualType QT = internal::getUnderlyingType(Node); + if (!QT.isNull()) + return qualType(hasDeclaration(InnerMatcher)).matches(QT, Finder, Builder); + return false; } -/// \brief Matches if the type location of the declarator decl's type matches +/// Matches if the type location of the declarator decl's type matches /// the inner matcher. /// /// Given @@ -2886,7 +2992,7 @@ AST_MATCHER_P(DeclaratorDecl, hasTypeLoc, internal::Matcher<TypeLoc>, Inner) { return Inner.matches(Node.getTypeSourceInfo()->getTypeLoc(), Finder, Builder); } -/// \brief Matches if the matched type is represented by the given string. +/// Matches if the matched type is represented by the given string. /// /// Given /// \code @@ -2899,7 +3005,7 @@ AST_MATCHER_P(QualType, asString, std::string, Name) { return Name == Node.getAsString(); } -/// \brief Matches if the matched type is a pointer type and the pointee type +/// Matches if the matched type is a pointer type and the pointee type /// matches the specified matcher. /// /// Example matches y->x() @@ -2916,14 +3022,14 @@ AST_MATCHER_P( InnerMatcher.matches(Node->getPointeeType(), Finder, Builder)); } -/// \brief Overloaded to match the pointee type's declaration. +/// Overloaded to match the pointee type's declaration. AST_MATCHER_P_OVERLOAD(QualType, pointsTo, internal::Matcher<Decl>, InnerMatcher, 1) { return pointsTo(qualType(hasDeclaration(InnerMatcher))) .matches(Node, Finder, Builder); } -/// \brief Matches if the matched type matches the unqualified desugared +/// Matches if the matched type matches the unqualified desugared /// type of the matched node. /// /// For example, in: @@ -2931,7 +3037,7 @@ AST_MATCHER_P_OVERLOAD(QualType, pointsTo, internal::Matcher<Decl>, /// class A {}; /// using B = A; /// \endcode -/// The matcher type(hasUnqualifeidDesugaredType(recordType())) matches +/// The matcher type(hasUnqualifiedDesugaredType(recordType())) matches /// both B and A. AST_MATCHER_P(Type, hasUnqualifiedDesugaredType, internal::Matcher<Type>, InnerMatcher) { @@ -2939,7 +3045,7 @@ AST_MATCHER_P(Type, hasUnqualifiedDesugaredType, internal::Matcher<Type>, Builder); } -/// \brief Matches if the matched type is a reference type and the referenced +/// Matches if the matched type is a reference type and the referenced /// type matches the specified matcher. /// /// Example matches X &x and const X &y @@ -2958,7 +3064,7 @@ AST_MATCHER_P(QualType, references, internal::Matcher<QualType>, InnerMatcher.matches(Node->getPointeeType(), Finder, Builder)); } -/// \brief Matches QualTypes whose canonical type matches InnerMatcher. +/// Matches QualTypes whose canonical type matches InnerMatcher. /// /// Given: /// \code @@ -2977,7 +3083,7 @@ AST_MATCHER_P(QualType, hasCanonicalType, internal::Matcher<QualType>, return InnerMatcher.matches(Node.getCanonicalType(), Finder, Builder); } -/// \brief Overloaded to match the referenced type's declaration. +/// Overloaded to match the referenced type's declaration. AST_MATCHER_P_OVERLOAD(QualType, references, internal::Matcher<Decl>, InnerMatcher, 1) { return references(qualType(hasDeclaration(InnerMatcher))) @@ -2991,7 +3097,7 @@ AST_MATCHER_P(CXXMemberCallExpr, onImplicitObjectArgument, InnerMatcher.matches(*ExprNode, Finder, Builder)); } -/// \brief Matches if the expression's type either matches the specified +/// Matches if the expression's type either matches the specified /// matcher, or is a pointer to a type that matches the InnerMatcher. AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType, internal::Matcher<QualType>, InnerMatcher, 0) { @@ -3000,7 +3106,7 @@ AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType, .matches(Node, Finder, Builder); } -/// \brief Overloaded to match the type's declaration. +/// Overloaded to match the type's declaration. AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType, internal::Matcher<Decl>, InnerMatcher, 1) { return onImplicitObjectArgument( @@ -3008,7 +3114,7 @@ AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType, .matches(Node, Finder, Builder); } -/// \brief Matches a DeclRefExpr that refers to a declaration that matches the +/// Matches a DeclRefExpr that refers to a declaration that matches the /// specified matcher. /// /// Example matches x in if(x) @@ -3024,7 +3130,7 @@ AST_MATCHER_P(DeclRefExpr, to, internal::Matcher<Decl>, InnerMatcher.matches(*DeclNode, Finder, Builder)); } -/// \brief Matches a \c DeclRefExpr that refers to a declaration through a +/// Matches a \c DeclRefExpr that refers to a declaration through a /// specific using shadow declaration. /// /// Given @@ -3046,7 +3152,7 @@ AST_MATCHER_P(DeclRefExpr, throughUsingDecl, return false; } -/// \brief Matches an \c OverloadExpr if any of the declarations in the set of +/// Matches an \c OverloadExpr if any of the declarations in the set of /// overloads matches the given matcher. /// /// Given @@ -3067,7 +3173,7 @@ AST_MATCHER_P(OverloadExpr, hasAnyDeclaration, internal::Matcher<Decl>, Node.decls_end(), Finder, Builder); } -/// \brief Matches the Decl of a DeclStmt which has a single declaration. +/// Matches the Decl of a DeclStmt which has a single declaration. /// /// Given /// \code @@ -3084,7 +3190,7 @@ AST_MATCHER_P(DeclStmt, hasSingleDecl, internal::Matcher<Decl>, InnerMatcher) { return false; } -/// \brief Matches a variable declaration that has an initializer expression +/// Matches a variable declaration that has an initializer expression /// that matches the given matcher. /// /// Example matches x (matcher = varDecl(hasInitializer(callExpr()))) @@ -3100,7 +3206,7 @@ AST_MATCHER_P( InnerMatcher.matches(*Initializer, Finder, Builder)); } -/// \brief Matches a variable declaration that has function scope and is a +/// Matches a variable declaration that has function scope and is a /// non-static local variable. /// /// Example matches x (matcher = varDecl(hasLocalStorage()) @@ -3115,7 +3221,7 @@ AST_MATCHER(VarDecl, hasLocalStorage) { return Node.hasLocalStorage(); } -/// \brief Matches a variable declaration that does not have local storage. +/// Matches a variable declaration that does not have local storage. /// /// Example matches y and z (matcher = varDecl(hasGlobalStorage()) /// \code @@ -3129,7 +3235,7 @@ AST_MATCHER(VarDecl, hasGlobalStorage) { return Node.hasGlobalStorage(); } -/// \brief Matches a variable declaration that has automatic storage duration. +/// Matches a variable declaration that has automatic storage duration. /// /// Example matches x, but not y, z, or a. /// (matcher = varDecl(hasAutomaticStorageDuration()) @@ -3145,7 +3251,7 @@ AST_MATCHER(VarDecl, hasAutomaticStorageDuration) { return Node.getStorageDuration() == SD_Automatic; } -/// \brief Matches a variable declaration that has static storage duration. +/// Matches a variable declaration that has static storage duration. /// It includes the variable declared at namespace scope and those declared /// with "static" and "extern" storage class specifiers. /// @@ -3165,7 +3271,7 @@ AST_MATCHER(VarDecl, hasStaticStorageDuration) { return Node.getStorageDuration() == SD_Static; } -/// \brief Matches a variable declaration that has thread storage duration. +/// Matches a variable declaration that has thread storage duration. /// /// Example matches z, but not x, z, or a. /// (matcher = varDecl(hasThreadStorageDuration()) @@ -3181,7 +3287,7 @@ AST_MATCHER(VarDecl, hasThreadStorageDuration) { return Node.getStorageDuration() == SD_Thread; } -/// \brief Matches a variable declaration that is an exception variable from +/// Matches a variable declaration that is an exception variable from /// a C++ catch block, or an Objective-C \@catch statement. /// /// Example matches x (matcher = varDecl(isExceptionVariable()) @@ -3196,7 +3302,7 @@ AST_MATCHER(VarDecl, isExceptionVariable) { return Node.isExceptionVariable(); } -/// \brief Checks that a call expression or a constructor call expression has +/// Checks that a call expression or a constructor call expression has /// a specific number of arguments (including absent default arguments). /// /// Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2))) @@ -3212,7 +3318,7 @@ AST_POLYMORPHIC_MATCHER_P(argumentCountIs, return Node.getNumArgs() == N; } -/// \brief Matches the n'th argument of a call expression or a constructor +/// Matches the n'th argument of a call expression or a constructor /// call expression. /// /// Example matches y in x(y) @@ -3230,7 +3336,7 @@ AST_POLYMORPHIC_MATCHER_P2(hasArgument, *Node.getArg(N)->IgnoreParenImpCasts(), Finder, Builder)); } -/// \brief Matches declaration statements that contain a specific number of +/// Matches declaration statements that contain a specific number of /// declarations. /// /// Example: Given @@ -3245,7 +3351,7 @@ AST_MATCHER_P(DeclStmt, declCountIs, unsigned, N) { return std::distance(Node.decl_begin(), Node.decl_end()) == (ptrdiff_t)N; } -/// \brief Matches the n'th declaration of a declaration statement. +/// Matches the n'th declaration of a declaration statement. /// /// Note that this does not work for global declarations because the AST /// breaks up multiple-declaration DeclStmt's into multiple single-declaration @@ -3274,7 +3380,7 @@ AST_MATCHER_P2(DeclStmt, containsDeclaration, unsigned, N, return InnerMatcher.matches(**Iterator, Finder, Builder); } -/// \brief Matches a C++ catch statement that has a catch-all handler. +/// Matches a C++ catch statement that has a catch-all handler. /// /// Given /// \code @@ -3291,7 +3397,7 @@ AST_MATCHER(CXXCatchStmt, isCatchAll) { return Node.getExceptionDecl() == nullptr; } -/// \brief Matches a constructor initializer. +/// Matches a constructor initializer. /// /// Given /// \code @@ -3310,7 +3416,7 @@ AST_MATCHER_P(CXXConstructorDecl, hasAnyConstructorInitializer, Node.init_end(), Finder, Builder); } -/// \brief Matches the field declaration of a constructor initializer. +/// Matches the field declaration of a constructor initializer. /// /// Given /// \code @@ -3330,7 +3436,7 @@ AST_MATCHER_P(CXXCtorInitializer, forField, InnerMatcher.matches(*NodeAsDecl, Finder, Builder)); } -/// \brief Matches the initializer expression of a constructor initializer. +/// Matches the initializer expression of a constructor initializer. /// /// Given /// \code @@ -3350,7 +3456,7 @@ AST_MATCHER_P(CXXCtorInitializer, withInitializer, InnerMatcher.matches(*NodeAsExpr, Finder, Builder)); } -/// \brief Matches a constructor initializer if it is explicitly written in +/// Matches a constructor initializer if it is explicitly written in /// code (as opposed to implicitly added by the compiler). /// /// Given @@ -3367,7 +3473,7 @@ AST_MATCHER(CXXCtorInitializer, isWritten) { return Node.isWritten(); } -/// \brief Matches a constructor initializer if it is initializing a base, as +/// Matches a constructor initializer if it is initializing a base, as /// opposed to a member. /// /// Given @@ -3387,7 +3493,7 @@ AST_MATCHER(CXXCtorInitializer, isBaseInitializer) { return Node.isBaseInitializer(); } -/// \brief Matches a constructor initializer if it is initializing a member, as +/// Matches a constructor initializer if it is initializing a member, as /// opposed to a base. /// /// Given @@ -3407,8 +3513,8 @@ AST_MATCHER(CXXCtorInitializer, isMemberInitializer) { return Node.isMemberInitializer(); } -/// \brief Matches any argument of a call expression or a constructor call -/// expression. +/// Matches any argument of a call expression or a constructor call +/// expression, or an ObjC-message-send expression. /// /// Given /// \code @@ -3418,9 +3524,18 @@ AST_MATCHER(CXXCtorInitializer, isMemberInitializer) { /// matches x(1, y, 42) /// with hasAnyArgument(...) /// matching y +/// +/// For ObjectiveC, given +/// \code +/// @interface I - (void) f:(int) y; @end +/// void foo(I *i) { [i f:12]; } +/// \endcode +/// objcMessageExpr(hasAnyArgument(integerLiteral(equals(12)))) +/// matches [i f:12] AST_POLYMORPHIC_MATCHER_P(hasAnyArgument, AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr, - CXXConstructExpr), + CXXConstructExpr, + ObjCMessageExpr), internal::Matcher<Expr>, InnerMatcher) { for (const Expr *Arg : Node.arguments()) { BoundNodesTreeBuilder Result(*Builder); @@ -3432,12 +3547,12 @@ AST_POLYMORPHIC_MATCHER_P(hasAnyArgument, return false; } -/// \brief Matches a constructor call expression which uses list initialization. +/// Matches a constructor call expression which uses list initialization. AST_MATCHER(CXXConstructExpr, isListInitialization) { return Node.isListInitialization(); } -/// \brief Matches a constructor call expression which requires +/// Matches a constructor call expression which requires /// zero initialization. /// /// Given @@ -3453,7 +3568,8 @@ AST_MATCHER(CXXConstructExpr, requiresZeroInitialization) { return Node.requiresZeroInitialization(); } -/// \brief Matches the n'th parameter of a function declaration. +/// Matches the n'th parameter of a function or an ObjC method +/// declaration or a block. /// /// Given /// \code @@ -3463,15 +3579,26 @@ AST_MATCHER(CXXConstructExpr, requiresZeroInitialization) { /// matches f(int x) {} /// with hasParameter(...) /// matching int x -AST_MATCHER_P2(FunctionDecl, hasParameter, - unsigned, N, internal::Matcher<ParmVarDecl>, - InnerMatcher) { - return (N < Node.getNumParams() && - InnerMatcher.matches( - *Node.getParamDecl(N), Finder, Builder)); +/// +/// For ObjectiveC, given +/// \code +/// @interface I - (void) f:(int) y; @end +/// \endcode +// +/// the matcher objcMethodDecl(hasParameter(0, hasName("y"))) +/// matches the declaration of method f with hasParameter +/// matching y. +AST_POLYMORPHIC_MATCHER_P2(hasParameter, + AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, + ObjCMethodDecl, + BlockDecl), + unsigned, N, internal::Matcher<ParmVarDecl>, + InnerMatcher) { + return (N < Node.parameters().size() + && InnerMatcher.matches(*Node.parameters()[N], Finder, Builder)); } -/// \brief Matches all arguments and their respective ParmVarDecl. +/// Matches all arguments and their respective ParmVarDecl. /// /// Given /// \code @@ -3525,7 +3652,8 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParam, return Matched; } -/// \brief Matches any parameter of a function declaration. +/// Matches any parameter of a function or an ObjC method declaration or a +/// block. /// /// Does not match the 'this' parameter of a method. /// @@ -3537,13 +3665,35 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParam, /// matches f(int x, int y, int z) {} /// with hasAnyParameter(...) /// matching int y -AST_MATCHER_P(FunctionDecl, hasAnyParameter, - internal::Matcher<ParmVarDecl>, InnerMatcher) { +/// +/// For ObjectiveC, given +/// \code +/// @interface I - (void) f:(int) y; @end +/// \endcode +// +/// the matcher objcMethodDecl(hasAnyParameter(hasName("y"))) +/// matches the declaration of method f with hasParameter +/// matching y. +/// +/// For blocks, given +/// \code +/// b = ^(int y) { printf("%d", y) }; +/// \endcode +/// +/// the matcher blockDecl(hasAnyParameter(hasName("y"))) +/// matches the declaration of the block b with hasParameter +/// matching y. +AST_POLYMORPHIC_MATCHER_P(hasAnyParameter, + AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, + ObjCMethodDecl, + BlockDecl), + internal::Matcher<ParmVarDecl>, + InnerMatcher) { return matchesFirstInPointerRange(InnerMatcher, Node.param_begin(), Node.param_end(), Finder, Builder); } -/// \brief Matches \c FunctionDecls and \c FunctionProtoTypes that have a +/// Matches \c FunctionDecls and \c FunctionProtoTypes that have a /// specific parameter count. /// /// Given @@ -3555,11 +3705,11 @@ AST_MATCHER_P(FunctionDecl, hasAnyParameter, /// void k(int x, int y, int z, ...); /// \endcode /// functionDecl(parameterCountIs(2)) -/// matches void g(int i, int j) {} +/// matches \c g and \c h /// functionProtoType(parameterCountIs(2)) -/// matches void h(int i, int j) +/// matches \c g and \c h /// functionProtoType(parameterCountIs(3)) -/// matches void k(int x, int y, int z, ...); +/// matches \c k AST_POLYMORPHIC_MATCHER_P(parameterCountIs, AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, FunctionProtoType), @@ -3567,7 +3717,23 @@ AST_POLYMORPHIC_MATCHER_P(parameterCountIs, return Node.getNumParams() == N; } -/// \brief Matches the return type of a function declaration. +/// Matches \c FunctionDecls that have a noreturn attribute. +/// +/// Given +/// \code +/// void nope(); +/// [[noreturn]] void a(); +/// __attribute__((noreturn)) void b(); +/// struct c { [[noreturn]] c(); }; +/// \endcode +/// functionDecl(isNoReturn()) +/// matches all of those except +/// \code +/// void nope(); +/// \endcode +AST_MATCHER(FunctionDecl, isNoReturn) { return Node.isNoReturn(); } + +/// Matches the return type of a function declaration. /// /// Given: /// \code @@ -3580,7 +3746,7 @@ AST_MATCHER_P(FunctionDecl, returns, return InnerMatcher.matches(Node.getReturnType(), Finder, Builder); } -/// \brief Matches extern "C" function or variable declarations. +/// Matches extern "C" function or variable declarations. /// /// Given: /// \code @@ -3600,7 +3766,7 @@ AST_POLYMORPHIC_MATCHER(isExternC, AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, return Node.isExternC(); } -/// \brief Matches variable/function declarations that have "static" storage +/// Matches variable/function declarations that have "static" storage /// class specifier ("static" keyword) written in the source. /// /// Given: @@ -3620,7 +3786,7 @@ AST_POLYMORPHIC_MATCHER(isStaticStorageClass, return Node.getStorageClass() == SC_Static; } -/// \brief Matches deleted function declarations. +/// Matches deleted function declarations. /// /// Given: /// \code @@ -3633,7 +3799,7 @@ AST_MATCHER(FunctionDecl, isDeleted) { return Node.isDeleted(); } -/// \brief Matches defaulted function declarations. +/// Matches defaulted function declarations. /// /// Given: /// \code @@ -3646,7 +3812,7 @@ AST_MATCHER(FunctionDecl, isDefaulted) { return Node.isDefaulted(); } -/// \brief Matches functions that have a dynamic exception specification. +/// Matches functions that have a dynamic exception specification. /// /// Given: /// \code @@ -3669,7 +3835,7 @@ AST_POLYMORPHIC_MATCHER(hasDynamicExceptionSpec, return false; } -/// \brief Matches functions that have a non-throwing exception specification. +/// Matches functions that have a non-throwing exception specification. /// /// Given: /// \code @@ -3696,27 +3862,32 @@ AST_POLYMORPHIC_MATCHER(isNoThrow, if (isUnresolvedExceptionSpec(FnTy->getExceptionSpecType())) return true; - return FnTy->isNothrow(Finder->getASTContext()); + return FnTy->isNothrow(); } -/// \brief Matches constexpr variable and function declarations. +/// Matches constexpr variable and function declarations, +/// and if constexpr. /// /// Given: /// \code /// constexpr int foo = 42; /// constexpr int bar(); +/// void baz() { if constexpr(1 > 0) {} } /// \endcode /// varDecl(isConstexpr()) /// matches the declaration of foo. /// functionDecl(isConstexpr()) /// matches the declaration of bar. +/// ifStmt(isConstexpr()) +/// matches the if statement in baz. AST_POLYMORPHIC_MATCHER(isConstexpr, AST_POLYMORPHIC_SUPPORTED_TYPES(VarDecl, - FunctionDecl)) { + FunctionDecl, + IfStmt)) { return Node.isConstexpr(); } -/// \brief Matches the condition expression of an if statement, for loop, +/// Matches the condition expression of an if statement, for loop, /// switch statement or conditional operator. /// /// Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true)))) @@ -3733,7 +3904,7 @@ AST_POLYMORPHIC_MATCHER_P( InnerMatcher.matches(*Condition, Finder, Builder)); } -/// \brief Matches the then-statement of an if statement. +/// Matches the then-statement of an if statement. /// /// Examples matches the if statement /// (matcher = ifStmt(hasThen(cxxBoolLiteral(equals(true))))) @@ -3745,7 +3916,7 @@ AST_MATCHER_P(IfStmt, hasThen, internal::Matcher<Stmt>, InnerMatcher) { return (Then != nullptr && InnerMatcher.matches(*Then, Finder, Builder)); } -/// \brief Matches the else-statement of an if statement. +/// Matches the else-statement of an if statement. /// /// Examples matches the if statement /// (matcher = ifStmt(hasElse(cxxBoolLiteral(equals(true))))) @@ -3757,7 +3928,7 @@ AST_MATCHER_P(IfStmt, hasElse, internal::Matcher<Stmt>, InnerMatcher) { return (Else != nullptr && InnerMatcher.matches(*Else, Finder, Builder)); } -/// \brief Matches if a node equals a previously bound node. +/// Matches if a node equals a previously bound node. /// /// Matches a node if it equals the node previously bound to \p ID. /// @@ -3794,7 +3965,7 @@ AST_POLYMORPHIC_MATCHER_P(equalsBoundNode, return Builder->removeBindings(Predicate); } -/// \brief Matches the condition variable statement in an if statement. +/// Matches the condition variable statement in an if statement. /// /// Given /// \code @@ -3810,7 +3981,7 @@ AST_MATCHER_P(IfStmt, hasConditionVariableStatement, InnerMatcher.matches(*DeclarationStatement, Finder, Builder); } -/// \brief Matches the index expression of an array subscript expression. +/// Matches the index expression of an array subscript expression. /// /// Given /// \code @@ -3826,7 +3997,7 @@ AST_MATCHER_P(ArraySubscriptExpr, hasIndex, return false; } -/// \brief Matches the base expression of an array subscript expression. +/// Matches the base expression of an array subscript expression. /// /// Given /// \code @@ -3843,7 +4014,7 @@ AST_MATCHER_P(ArraySubscriptExpr, hasBase, return false; } -/// \brief Matches a 'for', 'while', 'do while' statement or a function +/// Matches a 'for', 'while', 'do while' statement or a function /// definition that has a given body. /// /// Given @@ -3865,7 +4036,7 @@ AST_POLYMORPHIC_MATCHER_P(hasBody, InnerMatcher.matches(*Statement, Finder, Builder)); } -/// \brief Matches compound statements where at least one substatement matches +/// Matches compound statements where at least one substatement matches /// a given matcher. Also matches StmtExprs that have CompoundStmt as children. /// /// Given @@ -3885,7 +4056,7 @@ AST_POLYMORPHIC_MATCHER_P(hasAnySubstatement, CS->body_end(), Finder, Builder); } -/// \brief Checks that a compound statement contains a specific number of +/// Checks that a compound statement contains a specific number of /// child statements. /// /// Example: Given @@ -3899,7 +4070,7 @@ AST_MATCHER_P(CompoundStmt, statementCountIs, unsigned, N) { return Node.size() == N; } -/// \brief Matches literals that are equal to the given value of type ValueT. +/// Matches literals that are equal to the given value of type ValueT. /// /// Given /// \code @@ -3960,7 +4131,7 @@ AST_POLYMORPHIC_MATCHER_P_OVERLOAD(equals, .matchesNode(Node); } -/// \brief Matches the operator Name of operator expressions (binary or +/// Matches the operator Name of operator expressions (binary or /// unary). /// /// Example matches a || b (matcher = binaryOperator(hasOperatorName("||"))) @@ -3974,7 +4145,27 @@ AST_POLYMORPHIC_MATCHER_P(hasOperatorName, return Name == Node.getOpcodeStr(Node.getOpcode()); } -/// \brief Matches the left hand side of binary operator expressions. +/// Matches all kinds of assignment operators. +/// +/// Example 1: matches a += b (matcher = binaryOperator(isAssignmentOperator())) +/// \code +/// if (a == b) +/// a += b; +/// \endcode +/// +/// Example 2: matches s1 = s2 +/// (matcher = cxxOperatorCallExpr(isAssignmentOperator())) +/// \code +/// struct S { S& operator=(const S&); }; +/// void x() { S s1, s2; s1 = s2; }) +/// \endcode +AST_POLYMORPHIC_MATCHER(isAssignmentOperator, + AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, + CXXOperatorCallExpr)) { + return Node.isAssignmentOp(); +} + +/// Matches the left hand side of binary operator expressions. /// /// Example matches a (matcher = binaryOperator(hasLHS())) /// \code @@ -3989,7 +4180,7 @@ AST_POLYMORPHIC_MATCHER_P(hasLHS, InnerMatcher.matches(*LeftHandSide, Finder, Builder)); } -/// \brief Matches the right hand side of binary operator expressions. +/// Matches the right hand side of binary operator expressions. /// /// Example matches b (matcher = binaryOperator(hasRHS())) /// \code @@ -4004,14 +4195,14 @@ AST_POLYMORPHIC_MATCHER_P(hasRHS, InnerMatcher.matches(*RightHandSide, Finder, Builder)); } -/// \brief Matches if either the left hand side or the right hand side of a +/// Matches if either the left hand side or the right hand side of a /// binary operator matches. inline internal::Matcher<BinaryOperator> hasEitherOperand( const internal::Matcher<Expr> &InnerMatcher) { return anyOf(hasLHS(InnerMatcher), hasRHS(InnerMatcher)); } -/// \brief Matches if the operand of a unary operator matches. +/// Matches if the operand of a unary operator matches. /// /// Example matches true (matcher = hasUnaryOperand( /// cxxBoolLiteral(equals(true)))) @@ -4025,7 +4216,7 @@ AST_MATCHER_P(UnaryOperator, hasUnaryOperand, InnerMatcher.matches(*Operand, Finder, Builder)); } -/// \brief Matches if the cast's source expression +/// Matches if the cast's source expression /// or opaque value's source expression matches the given matcher. /// /// Example 1: matches "a string" @@ -4050,7 +4241,7 @@ AST_POLYMORPHIC_MATCHER_P(hasSourceExpression, InnerMatcher.matches(*SubExpression, Finder, Builder)); } -/// \brief Matches casts that has a given cast kind. +/// Matches casts that has a given cast kind. /// /// Example: matches the implicit cast around \c 0 /// (matcher = castExpr(hasCastKind(CK_NullToPointer))) @@ -4061,7 +4252,7 @@ AST_MATCHER_P(CastExpr, hasCastKind, CastKind, Kind) { return Node.getCastKind() == Kind; } -/// \brief Matches casts whose destination type matches a given matcher. +/// Matches casts whose destination type matches a given matcher. /// /// (Note: Clang's AST refers to other conversions as "casts" too, and calls /// actual casts "explicit" casts.) @@ -4071,7 +4262,7 @@ AST_MATCHER_P(ExplicitCastExpr, hasDestinationType, return InnerMatcher.matches(NodeType, Finder, Builder); } -/// \brief Matches implicit casts whose destination type matches a given +/// Matches implicit casts whose destination type matches a given /// matcher. /// /// FIXME: Unit test this matcher @@ -4080,7 +4271,7 @@ AST_MATCHER_P(ImplicitCastExpr, hasImplicitDestinationType, return InnerMatcher.matches(Node.getType(), Finder, Builder); } -/// \brief Matches RecordDecl object that are spelled with "struct." +/// Matches RecordDecl object that are spelled with "struct." /// /// Example matches S, but not C or U. /// \code @@ -4092,7 +4283,7 @@ AST_MATCHER(RecordDecl, isStruct) { return Node.isStruct(); } -/// \brief Matches RecordDecl object that are spelled with "union." +/// Matches RecordDecl object that are spelled with "union." /// /// Example matches U, but not C or S. /// \code @@ -4104,7 +4295,7 @@ AST_MATCHER(RecordDecl, isUnion) { return Node.isUnion(); } -/// \brief Matches RecordDecl object that are spelled with "class." +/// Matches RecordDecl object that are spelled with "class." /// /// Example matches C, but not S or U. /// \code @@ -4116,7 +4307,7 @@ AST_MATCHER(RecordDecl, isClass) { return Node.isClass(); } -/// \brief Matches the true branch expression of a conditional operator. +/// Matches the true branch expression of a conditional operator. /// /// Example 1 (conditional ternary operator): matches a /// \code @@ -4134,7 +4325,7 @@ AST_MATCHER_P(AbstractConditionalOperator, hasTrueExpression, InnerMatcher.matches(*Expression, Finder, Builder)); } -/// \brief Matches the false branch expression of a conditional operator +/// Matches the false branch expression of a conditional operator /// (binary or ternary). /// /// Example matches b @@ -4149,7 +4340,7 @@ AST_MATCHER_P(AbstractConditionalOperator, hasFalseExpression, InnerMatcher.matches(*Expression, Finder, Builder)); } -/// \brief Matches if a declaration has a body attached. +/// Matches if a declaration has a body attached. /// /// Example matches A, va, fa /// \code @@ -4176,7 +4367,7 @@ AST_POLYMORPHIC_MATCHER(isDefinition, return Node.isThisDeclarationADefinition(); } -/// \brief Matches if a function declaration is variadic. +/// Matches if a function declaration is variadic. /// /// Example matches f, but not g or h. The function i will not match, even when /// compiled in C mode. @@ -4190,7 +4381,7 @@ AST_MATCHER(FunctionDecl, isVariadic) { return Node.isVariadic(); } -/// \brief Matches the class declaration that the given method declaration +/// Matches the class declaration that the given method declaration /// belongs to. /// /// FIXME: Generalize this for other kinds of declarations. @@ -4214,7 +4405,7 @@ AST_MATCHER_P(CXXMethodDecl, ofClass, InnerMatcher.matches(*Parent, Finder, Builder)); } -/// \brief Matches each method overriden by the given method. This matcher may +/// Matches each method overridden by the given method. This matcher may /// produce multiple matches. /// /// Given @@ -4255,7 +4446,7 @@ AST_MATCHER_P(CXXMethodDecl, forEachOverridden, return Matched; } -/// \brief Matches if the given method declaration is virtual. +/// Matches if the given method declaration is virtual. /// /// Given /// \code @@ -4269,7 +4460,7 @@ AST_MATCHER(CXXMethodDecl, isVirtual) { return Node.isVirtual(); } -/// \brief Matches if the given method declaration has an explicit "virtual". +/// Matches if the given method declaration has an explicit "virtual". /// /// Given /// \code @@ -4287,7 +4478,7 @@ AST_MATCHER(CXXMethodDecl, isVirtualAsWritten) { return Node.isVirtualAsWritten(); } -/// \brief Matches if the given method or class declaration is final. +/// Matches if the given method or class declaration is final. /// /// Given: /// \code @@ -4308,7 +4499,7 @@ AST_POLYMORPHIC_MATCHER(isFinal, return Node.template hasAttr<FinalAttr>(); } -/// \brief Matches if the given method declaration is pure. +/// Matches if the given method declaration is pure. /// /// Given /// \code @@ -4322,7 +4513,7 @@ AST_MATCHER(CXXMethodDecl, isPure) { return Node.isPure(); } -/// \brief Matches if the given method declaration is const. +/// Matches if the given method declaration is const. /// /// Given /// \code @@ -4337,7 +4528,7 @@ AST_MATCHER(CXXMethodDecl, isConst) { return Node.isConst(); } -/// \brief Matches if the given method declaration declares a copy assignment +/// Matches if the given method declaration declares a copy assignment /// operator. /// /// Given @@ -4354,7 +4545,7 @@ AST_MATCHER(CXXMethodDecl, isCopyAssignmentOperator) { return Node.isCopyAssignmentOperator(); } -/// \brief Matches if the given method declaration declares a move assignment +/// Matches if the given method declaration declares a move assignment /// operator. /// /// Given @@ -4371,7 +4562,7 @@ AST_MATCHER(CXXMethodDecl, isMoveAssignmentOperator) { return Node.isMoveAssignmentOperator(); } -/// \brief Matches if the given method declaration overrides another method. +/// Matches if the given method declaration overrides another method. /// /// Given /// \code @@ -4389,7 +4580,7 @@ AST_MATCHER(CXXMethodDecl, isOverride) { return Node.size_overridden_methods() > 0 || Node.hasAttr<OverrideAttr>(); } -/// \brief Matches method declarations that are user-provided. +/// Matches method declarations that are user-provided. /// /// Given /// \code @@ -4404,7 +4595,7 @@ AST_MATCHER(CXXMethodDecl, isUserProvided) { return Node.isUserProvided(); } -/// \brief Matches member expressions that are called with '->' as opposed +/// Matches member expressions that are called with '->' as opposed /// to '.'. /// /// Member calls on the implicit this pointer match as called with '->'. @@ -4423,7 +4614,7 @@ AST_MATCHER(MemberExpr, isArrow) { return Node.isArrow(); } -/// \brief Matches QualType nodes that are of integer type. +/// Matches QualType nodes that are of integer type. /// /// Given /// \code @@ -4437,7 +4628,7 @@ AST_MATCHER(QualType, isInteger) { return Node->isIntegerType(); } -/// \brief Matches QualType nodes that are of unsigned integer type. +/// Matches QualType nodes that are of unsigned integer type. /// /// Given /// \code @@ -4451,7 +4642,7 @@ AST_MATCHER(QualType, isUnsignedInteger) { return Node->isUnsignedIntegerType(); } -/// \brief Matches QualType nodes that are of signed integer type. +/// Matches QualType nodes that are of signed integer type. /// /// Given /// \code @@ -4465,7 +4656,7 @@ AST_MATCHER(QualType, isSignedInteger) { return Node->isSignedIntegerType(); } -/// \brief Matches QualType nodes that are of character type. +/// Matches QualType nodes that are of character type. /// /// Given /// \code @@ -4479,7 +4670,7 @@ AST_MATCHER(QualType, isAnyCharacter) { return Node->isAnyCharacterType(); } -/// \brief Matches QualType nodes that are of any pointer type; this includes +/// Matches QualType nodes that are of any pointer type; this includes /// the Objective-C object pointer type, which is different despite being /// syntactically similar. /// @@ -4499,7 +4690,7 @@ AST_MATCHER(QualType, isAnyPointer) { return Node->isAnyPointerType(); } -/// \brief Matches QualType nodes that are const-qualified, i.e., that +/// Matches QualType nodes that are const-qualified, i.e., that /// include "top-level" const. /// /// Given @@ -4518,7 +4709,7 @@ AST_MATCHER(QualType, isConstQualified) { return Node.isConstQualified(); } -/// \brief Matches QualType nodes that are volatile-qualified, i.e., that +/// Matches QualType nodes that are volatile-qualified, i.e., that /// include "top-level" volatile. /// /// Given @@ -4537,7 +4728,7 @@ AST_MATCHER(QualType, isVolatileQualified) { return Node.isVolatileQualified(); } -/// \brief Matches QualType nodes that have local CV-qualifiers attached to +/// Matches QualType nodes that have local CV-qualifiers attached to /// the node, not hidden within a typedef. /// /// Given @@ -4554,7 +4745,7 @@ AST_MATCHER(QualType, hasLocalQualifiers) { return Node.hasLocalQualifiers(); } -/// \brief Matches a member expression where the member is matched by a +/// Matches a member expression where the member is matched by a /// given matcher. /// /// Given @@ -4571,7 +4762,7 @@ AST_MATCHER_P(MemberExpr, member, return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder); } -/// \brief Matches a member expression where the object expression is +/// Matches a member expression where the object expression is /// matched by a given matcher. /// /// Given @@ -4588,7 +4779,7 @@ AST_MATCHER_P(MemberExpr, hasObjectExpression, return InnerMatcher.matches(*Node.getBase(), Finder, Builder); } -/// \brief Matches any using shadow declaration. +/// Matches any using shadow declaration. /// /// Given /// \code @@ -4603,7 +4794,7 @@ AST_MATCHER_P(UsingDecl, hasAnyUsingShadowDecl, Node.shadow_end(), Finder, Builder); } -/// \brief Matches a using shadow declaration where the target declaration is +/// Matches a using shadow declaration where the target declaration is /// matched by the given matcher. /// /// Given @@ -4620,7 +4811,7 @@ AST_MATCHER_P(UsingShadowDecl, hasTargetDecl, return InnerMatcher.matches(*Node.getTargetDecl(), Finder, Builder); } -/// \brief Matches template instantiations of function, class, or static +/// Matches template instantiations of function, class, or static /// member variable template instantiations. /// /// Given @@ -4631,6 +4822,10 @@ AST_MATCHER_P(UsingShadowDecl, hasTargetDecl, /// \code /// template <typename T> class X {}; class A {}; template class X<A>; /// \endcode +/// or +/// \code +/// template <typename T> class X {}; class A {}; extern template class X<A>; +/// \endcode /// cxxRecordDecl(hasName("::X"), isTemplateInstantiation()) /// matches the template instantiation of X<A>. /// @@ -4648,10 +4843,12 @@ AST_POLYMORPHIC_MATCHER(isTemplateInstantiation, CXXRecordDecl)) { return (Node.getTemplateSpecializationKind() == TSK_ImplicitInstantiation || Node.getTemplateSpecializationKind() == - TSK_ExplicitInstantiationDefinition); + TSK_ExplicitInstantiationDefinition || + Node.getTemplateSpecializationKind() == + TSK_ExplicitInstantiationDeclaration); } -/// \brief Matches declarations that are template instantiations or are inside +/// Matches declarations that are template instantiations or are inside /// template instantiations. /// /// Given @@ -4668,7 +4865,7 @@ AST_MATCHER_FUNCTION(internal::Matcher<Decl>, isInstantiated) { return decl(anyOf(IsInstantiation, hasAncestor(IsInstantiation))); } -/// \brief Matches statements inside of a template instantiation. +/// Matches statements inside of a template instantiation. /// /// Given /// \code @@ -4688,7 +4885,7 @@ AST_MATCHER_FUNCTION(internal::Matcher<Stmt>, isInTemplateInstantiation) { functionDecl(isTemplateInstantiation()))))); } -/// \brief Matches explicit template specializations of function, class, or +/// Matches explicit template specializations of function, class, or /// static member variable template instantiations. /// /// Given @@ -4706,7 +4903,7 @@ AST_POLYMORPHIC_MATCHER(isExplicitTemplateSpecialization, return (Node.getTemplateSpecializationKind() == TSK_ExplicitSpecialization); } -/// \brief Matches \c TypeLocs for which the given inner +/// Matches \c TypeLocs for which the given inner /// QualType-matcher matches. AST_MATCHER_FUNCTION_P_OVERLOAD(internal::BindableMatcher<TypeLoc>, loc, internal::Matcher<QualType>, InnerMatcher, 0) { @@ -4714,7 +4911,7 @@ AST_MATCHER_FUNCTION_P_OVERLOAD(internal::BindableMatcher<TypeLoc>, loc, new internal::TypeLocTypeMatcher(InnerMatcher)); } -/// \brief Matches type \c bool. +/// Matches type \c bool. /// /// Given /// \code @@ -4726,7 +4923,7 @@ AST_MATCHER(Type, booleanType) { return Node.isBooleanType(); } -/// \brief Matches type \c void. +/// Matches type \c void. /// /// Given /// \code @@ -4741,7 +4938,7 @@ AST_MATCHER(Type, voidType) { template <typename NodeType> using AstTypeMatcher = internal::VariadicDynCastAllOfMatcher<Type, NodeType>; -/// \brief Matches builtin Types. +/// Matches builtin Types. /// /// Given /// \code @@ -4755,7 +4952,7 @@ using AstTypeMatcher = internal::VariadicDynCastAllOfMatcher<Type, NodeType>; /// matches "int b", "float c" and "bool d" extern const AstTypeMatcher<BuiltinType> builtinType; -/// \brief Matches all kinds of arrays. +/// Matches all kinds of arrays. /// /// Given /// \code @@ -4767,7 +4964,7 @@ extern const AstTypeMatcher<BuiltinType> builtinType; /// matches "int a[]", "int b[4]" and "int c[a[0]]"; extern const AstTypeMatcher<ArrayType> arrayType; -/// \brief Matches C99 complex types. +/// Matches C99 complex types. /// /// Given /// \code @@ -4777,7 +4974,7 @@ extern const AstTypeMatcher<ArrayType> arrayType; /// matches "_Complex float f" extern const AstTypeMatcher<ComplexType> complexType; -/// \brief Matches any real floating-point type (float, double, long double). +/// Matches any real floating-point type (float, double, long double). /// /// Given /// \code @@ -4790,7 +4987,7 @@ AST_MATCHER(Type, realFloatingPointType) { return Node.isRealFloatingType(); } -/// \brief Matches arrays and C99 complex types that have a specific element +/// Matches arrays and C99 complex types that have a specific element /// type. /// /// Given @@ -4807,7 +5004,7 @@ AST_TYPELOC_TRAVERSE_MATCHER_DECL(hasElementType, getElement, AST_POLYMORPHIC_SUPPORTED_TYPES(ArrayType, ComplexType)); -/// \brief Matches C arrays with a specified constant size. +/// Matches C arrays with a specified constant size. /// /// Given /// \code @@ -4821,7 +5018,7 @@ AST_TYPELOC_TRAVERSE_MATCHER_DECL(hasElementType, getElement, /// matches "int a[2]" extern const AstTypeMatcher<ConstantArrayType> constantArrayType; -/// \brief Matches nodes that have the specified size. +/// Matches nodes that have the specified size. /// /// Given /// \code @@ -4843,7 +5040,7 @@ AST_POLYMORPHIC_MATCHER_P(hasSize, return internal::HasSizeMatcher<NodeType>::hasSize(Node, N); } -/// \brief Matches C++ arrays whose size is a value-dependent expression. +/// Matches C++ arrays whose size is a value-dependent expression. /// /// Given /// \code @@ -4856,7 +5053,7 @@ AST_POLYMORPHIC_MATCHER_P(hasSize, /// matches "T data[Size]" extern const AstTypeMatcher<DependentSizedArrayType> dependentSizedArrayType; -/// \brief Matches C arrays with unspecified size. +/// Matches C arrays with unspecified size. /// /// Given /// \code @@ -4868,7 +5065,7 @@ extern const AstTypeMatcher<DependentSizedArrayType> dependentSizedArrayType; /// matches "int a[]" and "int c[]" extern const AstTypeMatcher<IncompleteArrayType> incompleteArrayType; -/// \brief Matches C arrays with a specified size that is not an +/// Matches C arrays with a specified size that is not an /// integer-constant-expression. /// /// Given @@ -4883,7 +5080,7 @@ extern const AstTypeMatcher<IncompleteArrayType> incompleteArrayType; /// matches "int c[a[0]]" extern const AstTypeMatcher<VariableArrayType> variableArrayType; -/// \brief Matches \c VariableArrayType nodes that have a specific size +/// Matches \c VariableArrayType nodes that have a specific size /// expression. /// /// Given @@ -4900,7 +5097,7 @@ AST_MATCHER_P(VariableArrayType, hasSizeExpr, return InnerMatcher.matches(*Node.getSizeExpr(), Finder, Builder); } -/// \brief Matches atomic types. +/// Matches atomic types. /// /// Given /// \code @@ -4910,7 +5107,7 @@ AST_MATCHER_P(VariableArrayType, hasSizeExpr, /// matches "_Atomic(int) i" extern const AstTypeMatcher<AtomicType> atomicType; -/// \brief Matches atomic types with a specific value type. +/// Matches atomic types with a specific value type. /// /// Given /// \code @@ -4924,7 +5121,7 @@ extern const AstTypeMatcher<AtomicType> atomicType; AST_TYPELOC_TRAVERSE_MATCHER_DECL(hasValueType, getValue, AST_POLYMORPHIC_SUPPORTED_TYPES(AtomicType)); -/// \brief Matches types nodes representing C++11 auto types. +/// Matches types nodes representing C++11 auto types. /// /// Given: /// \code @@ -4936,7 +5133,19 @@ AST_TYPELOC_TRAVERSE_MATCHER_DECL(hasValueType, getValue, /// matches "auto n" and "auto i" extern const AstTypeMatcher<AutoType> autoType; -/// \brief Matches \c AutoType nodes where the deduced type is a specific type. +/// Matches types nodes representing C++11 decltype(<expr>) types. +/// +/// Given: +/// \code +/// short i = 1; +/// int j = 42; +/// decltype(i + j) result = i + j; +/// \endcode +/// decltypeType() +/// matches "decltype(i + j)" +extern const AstTypeMatcher<DecltypeType> decltypeType; + +/// Matches \c AutoType nodes where the deduced type is a specific type. /// /// Note: There is no \c TypeLoc for the deduced type and thus no /// \c getDeducedLoc() matcher. @@ -4953,7 +5162,21 @@ extern const AstTypeMatcher<AutoType> autoType; AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType, AST_POLYMORPHIC_SUPPORTED_TYPES(AutoType)); -/// \brief Matches \c FunctionType nodes. +/// Matches \c DecltypeType nodes to find out the underlying type. +/// +/// Given +/// \code +/// decltype(1) a = 1; +/// decltype(2.0) b = 2.0; +/// \endcode +/// decltypeType(hasUnderlyingType(isInteger())) +/// matches "auto a" +/// +/// Usable as: Matcher<DecltypeType> +AST_TYPE_TRAVERSE_MATCHER(hasUnderlyingType, getUnderlyingType, + AST_POLYMORPHIC_SUPPORTED_TYPES(DecltypeType)); + +/// Matches \c FunctionType nodes. /// /// Given /// \code @@ -4964,7 +5187,7 @@ AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType, /// matches "int (*f)(int)" and the type of "g". extern const AstTypeMatcher<FunctionType> functionType; -/// \brief Matches \c FunctionProtoType nodes. +/// Matches \c FunctionProtoType nodes. /// /// Given /// \code @@ -4976,7 +5199,7 @@ extern const AstTypeMatcher<FunctionType> functionType; /// In C mode, "g" is not matched because it does not contain a prototype. extern const AstTypeMatcher<FunctionProtoType> functionProtoType; -/// \brief Matches \c ParenType nodes. +/// Matches \c ParenType nodes. /// /// Given /// \code @@ -4988,7 +5211,7 @@ extern const AstTypeMatcher<FunctionProtoType> functionProtoType; /// \c array_of_ptrs. extern const AstTypeMatcher<ParenType> parenType; -/// \brief Matches \c ParenType nodes where the inner type is a specific type. +/// Matches \c ParenType nodes where the inner type is a specific type. /// /// Given /// \code @@ -5003,13 +5226,13 @@ extern const AstTypeMatcher<ParenType> parenType; AST_TYPE_TRAVERSE_MATCHER(innerType, getInnerType, AST_POLYMORPHIC_SUPPORTED_TYPES(ParenType)); -/// \brief Matches block pointer types, i.e. types syntactically represented as +/// Matches block pointer types, i.e. types syntactically represented as /// "void (^)(int)". /// /// The \c pointee is always required to be a \c FunctionType. extern const AstTypeMatcher<BlockPointerType> blockPointerType; -/// \brief Matches member pointer types. +/// Matches member pointer types. /// Given /// \code /// struct A { int i; } @@ -5019,7 +5242,7 @@ extern const AstTypeMatcher<BlockPointerType> blockPointerType; /// matches "A::* ptr" extern const AstTypeMatcher<MemberPointerType> memberPointerType; -/// \brief Matches pointer types, but does not match Objective-C object pointer +/// Matches pointer types, but does not match Objective-C object pointer /// types. /// /// Given @@ -5036,7 +5259,7 @@ extern const AstTypeMatcher<MemberPointerType> memberPointerType; /// matches "int *a", but does not match "Foo *f". extern const AstTypeMatcher<PointerType> pointerType; -/// \brief Matches an Objective-C object pointer type, which is different from +/// Matches an Objective-C object pointer type, which is different from /// a pointer type, despite being syntactically similar. /// /// Given @@ -5051,7 +5274,7 @@ extern const AstTypeMatcher<PointerType> pointerType; /// matches "Foo *f", but does not match "int *a". extern const AstTypeMatcher<ObjCObjectPointerType> objcObjectPointerType; -/// \brief Matches both lvalue and rvalue reference types. +/// Matches both lvalue and rvalue reference types. /// /// Given /// \code @@ -5067,7 +5290,7 @@ extern const AstTypeMatcher<ObjCObjectPointerType> objcObjectPointerType; /// \c referenceType() matches the types of \c b, \c c, \c d, \c e, and \c f. extern const AstTypeMatcher<ReferenceType> referenceType; -/// \brief Matches lvalue reference types. +/// Matches lvalue reference types. /// /// Given: /// \code @@ -5084,7 +5307,7 @@ extern const AstTypeMatcher<ReferenceType> referenceType; /// matched since the type is deduced as int& by reference collapsing rules. extern const AstTypeMatcher<LValueReferenceType> lValueReferenceType; -/// \brief Matches rvalue reference types. +/// Matches rvalue reference types. /// /// Given: /// \code @@ -5101,7 +5324,7 @@ extern const AstTypeMatcher<LValueReferenceType> lValueReferenceType; /// matched as it is deduced to int& by reference collapsing rules. extern const AstTypeMatcher<RValueReferenceType> rValueReferenceType; -/// \brief Narrows PointerType (and similar) matchers to those where the +/// Narrows PointerType (and similar) matchers to those where the /// \c pointee matches a given matcher. /// /// Given @@ -5120,7 +5343,7 @@ AST_TYPELOC_TRAVERSE_MATCHER_DECL( AST_POLYMORPHIC_SUPPORTED_TYPES(BlockPointerType, MemberPointerType, PointerType, ReferenceType)); -/// \brief Matches typedef types. +/// Matches typedef types. /// /// Given /// \code @@ -5130,7 +5353,7 @@ AST_TYPELOC_TRAVERSE_MATCHER_DECL( /// matches "typedef int X" extern const AstTypeMatcher<TypedefType> typedefType; -/// \brief Matches enum types. +/// Matches enum types. /// /// Given /// \code @@ -5145,7 +5368,7 @@ extern const AstTypeMatcher<TypedefType> typedefType; /// \c s. extern const AstTypeMatcher<EnumType> enumType; -/// \brief Matches template specialization types. +/// Matches template specialization types. /// /// Given /// \code @@ -5161,7 +5384,7 @@ extern const AstTypeMatcher<EnumType> enumType; extern const AstTypeMatcher<TemplateSpecializationType> templateSpecializationType; -/// \brief Matches types nodes representing unary type transformations. +/// Matches types nodes representing unary type transformations. /// /// Given: /// \code @@ -5171,7 +5394,7 @@ extern const AstTypeMatcher<TemplateSpecializationType> /// matches "__underlying_type(T)" extern const AstTypeMatcher<UnaryTransformType> unaryTransformType; -/// \brief Matches record types (e.g. structs, classes). +/// Matches record types (e.g. structs, classes). /// /// Given /// \code @@ -5186,7 +5409,7 @@ extern const AstTypeMatcher<UnaryTransformType> unaryTransformType; /// and \c s. extern const AstTypeMatcher<RecordType> recordType; -/// \brief Matches tag types (record and enum types). +/// Matches tag types (record and enum types). /// /// Given /// \code @@ -5201,7 +5424,7 @@ extern const AstTypeMatcher<RecordType> recordType; /// and \c c. extern const AstTypeMatcher<TagType> tagType; -/// \brief Matches types specified with an elaborated type keyword or with a +/// Matches types specified with an elaborated type keyword or with a /// qualified name. /// /// Given @@ -5221,7 +5444,7 @@ extern const AstTypeMatcher<TagType> tagType; /// \c c and \c d. extern const AstTypeMatcher<ElaboratedType> elaboratedType; -/// \brief Matches ElaboratedTypes whose qualifier, a NestedNameSpecifier, +/// Matches ElaboratedTypes whose qualifier, a NestedNameSpecifier, /// matches \c InnerMatcher if the qualifier exists. /// /// Given @@ -5244,7 +5467,7 @@ AST_MATCHER_P(ElaboratedType, hasQualifier, return false; } -/// \brief Matches ElaboratedTypes whose named type matches \c InnerMatcher. +/// Matches ElaboratedTypes whose named type matches \c InnerMatcher. /// /// Given /// \code @@ -5264,7 +5487,7 @@ AST_MATCHER_P(ElaboratedType, namesType, internal::Matcher<QualType>, return InnerMatcher.matches(Node.getNamedType(), Finder, Builder); } -/// \brief Matches types that represent the result of substituting a type for a +/// Matches types that represent the result of substituting a type for a /// template type parameter. /// /// Given @@ -5279,7 +5502,7 @@ AST_MATCHER_P(ElaboratedType, namesType, internal::Matcher<QualType>, extern const AstTypeMatcher<SubstTemplateTypeParmType> substTemplateTypeParmType; -/// \brief Matches template type parameter substitutions that have a replacement +/// Matches template type parameter substitutions that have a replacement /// type that matches the provided matcher. /// /// Given @@ -5295,7 +5518,7 @@ AST_TYPE_TRAVERSE_MATCHER( hasReplacementType, getReplacementType, AST_POLYMORPHIC_SUPPORTED_TYPES(SubstTemplateTypeParmType)); -/// \brief Matches template type parameter types. +/// Matches template type parameter types. /// /// Example matches T, but not int. /// (matcher = templateTypeParmType()) @@ -5304,7 +5527,7 @@ AST_TYPE_TRAVERSE_MATCHER( /// \endcode extern const AstTypeMatcher<TemplateTypeParmType> templateTypeParmType; -/// \brief Matches injected class name types. +/// Matches injected class name types. /// /// Example matches S s, but not S<T> s. /// (matcher = parmVarDecl(hasType(injectedClassNameType()))) @@ -5316,7 +5539,7 @@ extern const AstTypeMatcher<TemplateTypeParmType> templateTypeParmType; /// \endcode extern const AstTypeMatcher<InjectedClassNameType> injectedClassNameType; -/// \brief Matches decayed type +/// Matches decayed type /// Example matches i[] in declaration of f. /// (matcher = valueDecl(hasType(decayedType(hasDecayedType(pointerType()))))) /// Example matches i[1]. @@ -5328,13 +5551,13 @@ extern const AstTypeMatcher<InjectedClassNameType> injectedClassNameType; /// \endcode extern const AstTypeMatcher<DecayedType> decayedType; -/// \brief Matches the decayed type, whos decayed type matches \c InnerMatcher +/// Matches the decayed type, whos decayed type matches \c InnerMatcher AST_MATCHER_P(DecayedType, hasDecayedType, internal::Matcher<QualType>, InnerType) { return InnerType.matches(Node.getDecayedType(), Finder, Builder); } -/// \brief Matches declarations whose declaration context, interpreted as a +/// Matches declarations whose declaration context, interpreted as a /// Decl, matches \c InnerMatcher. /// /// Given @@ -5354,7 +5577,7 @@ AST_MATCHER_P(Decl, hasDeclContext, internal::Matcher<Decl>, InnerMatcher) { return InnerMatcher.matches(*Decl::castFromDeclContext(DC), Finder, Builder); } -/// \brief Matches nested name specifiers. +/// Matches nested name specifiers. /// /// Given /// \code @@ -5370,11 +5593,11 @@ AST_MATCHER_P(Decl, hasDeclContext, internal::Matcher<Decl>, InnerMatcher) { extern const internal::VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier; -/// \brief Same as \c nestedNameSpecifier but matches \c NestedNameSpecifierLoc. +/// Same as \c nestedNameSpecifier but matches \c NestedNameSpecifierLoc. extern const internal::VariadicAllOfMatcher<NestedNameSpecifierLoc> nestedNameSpecifierLoc; -/// \brief Matches \c NestedNameSpecifierLocs for which the given inner +/// Matches \c NestedNameSpecifierLocs for which the given inner /// NestedNameSpecifier-matcher matches. AST_MATCHER_FUNCTION_P_OVERLOAD( internal::BindableMatcher<NestedNameSpecifierLoc>, loc, @@ -5384,7 +5607,7 @@ AST_MATCHER_FUNCTION_P_OVERLOAD( InnerMatcher)); } -/// \brief Matches nested name specifiers that specify a type matching the +/// Matches nested name specifiers that specify a type matching the /// given \c QualType matcher without qualifiers. /// /// Given @@ -5403,7 +5626,7 @@ AST_MATCHER_P(NestedNameSpecifier, specifiesType, return InnerMatcher.matches(QualType(Node.getAsType(), 0), Finder, Builder); } -/// \brief Matches nested name specifier locs that specify a type matching the +/// Matches nested name specifier locs that specify a type matching the /// given \c TypeLoc. /// /// Given @@ -5416,10 +5639,11 @@ AST_MATCHER_P(NestedNameSpecifier, specifiesType, /// matches "A::" AST_MATCHER_P(NestedNameSpecifierLoc, specifiesTypeLoc, internal::Matcher<TypeLoc>, InnerMatcher) { - return Node && InnerMatcher.matches(Node.getTypeLoc(), Finder, Builder); + return Node && Node.getNestedNameSpecifier()->getAsType() && + InnerMatcher.matches(Node.getTypeLoc(), Finder, Builder); } -/// \brief Matches on the prefix of a \c NestedNameSpecifier. +/// Matches on the prefix of a \c NestedNameSpecifier. /// /// Given /// \code @@ -5437,7 +5661,7 @@ AST_MATCHER_P_OVERLOAD(NestedNameSpecifier, hasPrefix, return InnerMatcher.matches(*NextNode, Finder, Builder); } -/// \brief Matches on the prefix of a \c NestedNameSpecifierLoc. +/// Matches on the prefix of a \c NestedNameSpecifierLoc. /// /// Given /// \code @@ -5455,7 +5679,7 @@ AST_MATCHER_P_OVERLOAD(NestedNameSpecifierLoc, hasPrefix, return InnerMatcher.matches(NextNode, Finder, Builder); } -/// \brief Matches nested name specifiers that specify a namespace matching the +/// Matches nested name specifiers that specify a namespace matching the /// given namespace matcher. /// /// Given @@ -5472,23 +5696,23 @@ AST_MATCHER_P(NestedNameSpecifier, specifiesNamespace, return InnerMatcher.matches(*Node.getAsNamespace(), Finder, Builder); } -/// \brief Overloads for the \c equalsNode matcher. +/// Overloads for the \c equalsNode matcher. /// FIXME: Implement for other node types. /// @{ -/// \brief Matches if a node equals another node. +/// Matches if a node equals another node. /// /// \c Decl has pointer identity in the AST. AST_MATCHER_P_OVERLOAD(Decl, equalsNode, const Decl*, Other, 0) { return &Node == Other; } -/// \brief Matches if a node equals another node. +/// Matches if a node equals another node. /// /// \c Stmt has pointer identity in the AST. AST_MATCHER_P_OVERLOAD(Stmt, equalsNode, const Stmt*, Other, 1) { return &Node == Other; } -/// \brief Matches if a node equals another node. +/// Matches if a node equals another node. /// /// \c Type has pointer identity in the AST. AST_MATCHER_P_OVERLOAD(Type, equalsNode, const Type*, Other, 2) { @@ -5497,7 +5721,7 @@ AST_MATCHER_P_OVERLOAD(Type, equalsNode, const Type*, Other, 2) { /// @} -/// \brief Matches each case or default statement belonging to the given switch +/// Matches each case or default statement belonging to the given switch /// statement. This matcher may produce multiple matches. /// /// Given @@ -5529,7 +5753,7 @@ AST_MATCHER_P(SwitchStmt, forEachSwitchCase, internal::Matcher<SwitchCase>, return Matched; } -/// \brief Matches each constructor initializer in a constructor definition. +/// Matches each constructor initializer in a constructor definition. /// /// Given /// \code @@ -5554,7 +5778,7 @@ AST_MATCHER_P(CXXConstructorDecl, forEachConstructorInitializer, return Matched; } -/// \brief Matches constructor declarations that are copy constructors. +/// Matches constructor declarations that are copy constructors. /// /// Given /// \code @@ -5569,7 +5793,7 @@ AST_MATCHER(CXXConstructorDecl, isCopyConstructor) { return Node.isCopyConstructor(); } -/// \brief Matches constructor declarations that are move constructors. +/// Matches constructor declarations that are move constructors. /// /// Given /// \code @@ -5584,7 +5808,7 @@ AST_MATCHER(CXXConstructorDecl, isMoveConstructor) { return Node.isMoveConstructor(); } -/// \brief Matches constructor declarations that are default constructors. +/// Matches constructor declarations that are default constructors. /// /// Given /// \code @@ -5599,7 +5823,7 @@ AST_MATCHER(CXXConstructorDecl, isDefaultConstructor) { return Node.isDefaultConstructor(); } -/// \brief Matches constructors that delegate to another constructor. +/// Matches constructors that delegate to another constructor. /// /// Given /// \code @@ -5616,7 +5840,7 @@ AST_MATCHER(CXXConstructorDecl, isDelegatingConstructor) { return Node.isDelegatingConstructor(); } -/// \brief Matches constructor and conversion declarations that are marked with +/// Matches constructor and conversion declarations that are marked with /// the explicit keyword. /// /// Given @@ -5636,7 +5860,7 @@ AST_POLYMORPHIC_MATCHER(isExplicit, return Node.isExplicit(); } -/// \brief Matches function and namespace declarations that are marked with +/// Matches function and namespace declarations that are marked with /// the inline keyword. /// /// Given @@ -5661,7 +5885,7 @@ AST_POLYMORPHIC_MATCHER(isInline, llvm_unreachable("Not a valid polymorphic type"); } -/// \brief Matches anonymous namespace declarations. +/// Matches anonymous namespace declarations. /// /// Given /// \code @@ -5674,7 +5898,7 @@ AST_MATCHER(NamespaceDecl, isAnonymous) { return Node.isAnonymousNamespace(); } -/// \brief If the given case statement does not use the GNU case range +/// If the given case statement does not use the GNU case range /// extension, matches the constant given in the statement. /// /// Given @@ -5691,7 +5915,7 @@ AST_MATCHER_P(CaseStmt, hasCaseConstant, internal::Matcher<Expr>, return InnerMatcher.matches(*Node.getLHS(), Finder, Builder); } -/// \brief Matches declaration that has a given attribute. +/// Matches declaration that has a given attribute. /// /// Given /// \code @@ -5708,7 +5932,7 @@ AST_MATCHER_P(Decl, hasAttr, attr::Kind, AttrKind) { return false; } -/// \brief Matches the return value expression of a return statement +/// Matches the return value expression of a return statement /// /// Given /// \code @@ -5725,7 +5949,7 @@ AST_MATCHER_P(ReturnStmt, hasReturnValue, internal::Matcher<Expr>, return false; } -/// \brief Matches CUDA kernel call expression. +/// Matches CUDA kernel call expression. /// /// Example matches, /// \code @@ -5734,7 +5958,7 @@ AST_MATCHER_P(ReturnStmt, hasReturnValue, internal::Matcher<Expr>, extern const internal::VariadicDynCastAllOfMatcher<Stmt, CUDAKernelCallExpr> cudaKernelCallExpr; -/// \brief Matches expressions that resolve to a null pointer constant, such as +/// Matches expressions that resolve to a null pointer constant, such as /// GNU's __null, C++11's nullptr, or C's NULL macro. /// /// Given: @@ -5755,7 +5979,7 @@ AST_MATCHER_FUNCTION(internal::Matcher<Expr>, nullPointerConstant) { integerLiteral(equals(0), hasParent(expr(hasType(pointerType()))))); } -/// \brief Matches declaration of the function the statement belongs to +/// Matches declaration of the function the statement belongs to /// /// Given: /// \code @@ -5793,7 +6017,7 @@ AST_MATCHER_P(Stmt, forFunction, internal::Matcher<FunctionDecl>, return false; } -/// \brief Matches a declaration that has external formal linkage. +/// Matches a declaration that has external formal linkage. /// /// Example matches only z (matcher = varDecl(hasExternalFormalLinkage())) /// \code @@ -5817,7 +6041,7 @@ AST_MATCHER(NamedDecl, hasExternalFormalLinkage) { return Node.hasExternalFormalLinkage(); } -/// \brief Matches a declaration that has default arguments. +/// Matches a declaration that has default arguments. /// /// Example matches y (matcher = parmVarDecl(hasDefaultArgument())) /// \code @@ -5828,7 +6052,7 @@ AST_MATCHER(ParmVarDecl, hasDefaultArgument) { return Node.hasDefaultArg(); } -/// \brief Matches array new expressions. +/// Matches array new expressions. /// /// Given: /// \code @@ -5840,7 +6064,7 @@ AST_MATCHER(CXXNewExpr, isArray) { return Node.isArray(); } -/// \brief Matches array new expressions with a given array size. +/// Matches array new expressions with a given array size. /// /// Given: /// \code @@ -5853,7 +6077,7 @@ AST_MATCHER_P(CXXNewExpr, hasArraySize, internal::Matcher<Expr>, InnerMatcher) { InnerMatcher.matches(*Node.getArraySize(), Finder, Builder); } -/// \brief Matches a class declaration that is defined. +/// Matches a class declaration that is defined. /// /// Example matches x (matcher = cxxRecordDecl(hasDefinition())) /// \code @@ -5864,6 +6088,30 @@ AST_MATCHER(CXXRecordDecl, hasDefinition) { return Node.hasDefinition(); } +/// Matches C++11 scoped enum declaration. +/// +/// Example matches Y (matcher = enumDecl(isScoped())) +/// \code +/// enum X {}; +/// enum class Y {}; +/// \endcode +AST_MATCHER(EnumDecl, isScoped) { + return Node.isScoped(); +} + +/// Matches a function declared with a trailing return type. +/// +/// Example matches Y (matcher = functionDecl(hasTrailingReturn())) +/// \code +/// int X() {} +/// auto Y() -> int {} +/// \endcode +AST_MATCHER(FunctionDecl, hasTrailingReturn) { + if (const auto *F = Node.getType()->getAs<FunctionProtoType>()) + return F->hasTrailingReturn(); + return false; +} + } // namespace ast_matchers } // namespace clang |