diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index e8c679412e3a..e0d786a6bcc1 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -57,15 +57,15 @@ namespace ast_matchers { /// \brief Maps string IDs to AST nodes matched by parts of a matcher. /// -/// The bound nodes are generated by adding id(...) matchers into the -/// match expression around the matchers for the nodes we want to access later. +/// The bound nodes are generated by calling \c bind("id") on the node matchers +/// of the nodes we want to access later. /// -/// The instances of BoundNodes are created by MatchFinder when the user's +/// The instances of BoundNodes are created by \c MatchFinder when the user's /// callbacks are executed every time a match is found. class BoundNodes { public: - /// \brief Returns the AST node bound to 'ID'. - /// Returns NULL if there was no node bound to 'ID' or if there is a node but + /// \brief 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. /// FIXME: We'll need one of those for every base type. /// @{ @@ -100,9 +100,9 @@ private: friend class internal::BoundNodesTree; }; -/// \brief If the provided matcher matches a node, binds the node to 'ID'. +/// \brief If the provided matcher matches a node, binds the node to \c ID. /// -/// FIXME: Add example for accessing it. +/// FIXME: Do we want to support this now that we have bind()? template internal::Matcher id(const std::string &ID, const internal::BindableMatcher &InnerMatcher) { @@ -121,12 +121,16 @@ typedef internal::Matcher StatementMatcher; /// /// Useful when another matcher requires a child matcher, but there's no /// additional constraint. This will often be used with an explicit conversion -/// to a internal::Matcher<> type such as TypeMatcher. +/// to an \c internal::Matcher<> type such as \c TypeMatcher. /// -/// Example: DeclarationMatcher(anything()) matches all declarations, e.g., +/// Example: \c DeclarationMatcher(anything()) matches all declarations, e.g., +/// \code /// "int* p" and "void f()" in /// int* p; /// void f(); +/// \endcode +/// +/// Usable as: Any Matcher inline internal::PolymorphicMatcherWithParam0 anything() { return internal::PolymorphicMatcherWithParam0(); } @@ -144,30 +148,36 @@ const internal::VariadicDynCastAllOfMatcher decl; /// \brief Matches a declaration of anything that could have a name. /// -/// Example matches X, S, the anonymous union type, i, and U; +/// Example matches \c X, \c S, the anonymous union type, \c i, and \c U; +/// \code /// typedef int X; /// struct S { /// union { /// int i; /// } U; /// }; +/// \endcode const internal::VariadicDynCastAllOfMatcher< Decl, NamedDecl> nameableDeclaration; /// \brief Matches C++ class declarations. /// -/// Example matches X, Z +/// Example matches \c X, \c Z +/// \code /// class X; /// template class Z {}; +/// \endcode const internal::VariadicDynCastAllOfMatcher< Decl, CXXRecordDecl> record; /// \brief Matches C++ class template declarations. /// -/// Example matches Z +/// Example matches \c Z +/// \code /// template class Z {}; +/// \endcode const internal::VariadicDynCastAllOfMatcher< Decl, ClassTemplateDecl> classTemplate; @@ -175,9 +185,11 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches C++ class template specializations. /// /// Given +/// \code /// template class A {}; /// template<> class A {}; /// A a; +/// \endcode /// classTemplateSpecialization() /// matches the specializations \c A and \c A const internal::VariadicDynCastAllOfMatcher< @@ -185,20 +197,22 @@ const internal::VariadicDynCastAllOfMatcher< ClassTemplateSpecializationDecl> classTemplateSpecialization; /// \brief Matches classTemplateSpecializations that have at least one -/// TemplateArgument matching the given Matcher. +/// TemplateArgument matching the given InnerMatcher. /// /// Given +/// \code /// template class A {}; /// template<> class A {}; /// A a; +/// \endcode /// classTemplateSpecialization(hasAnyTemplateArgument( /// refersToType(asString("int")))) /// matches the specialization \c A AST_MATCHER_P(ClassTemplateSpecializationDecl, hasAnyTemplateArgument, - internal::Matcher, Matcher) { + internal::Matcher, InnerMatcher) { const TemplateArgumentList &List = Node.getTemplateArgs(); for (unsigned i = 0; i < List.size(); ++i) { - if (Matcher.matches(List.get(i), Finder, Builder)) + if (InnerMatcher.matches(List.get(i), Finder, Builder)) return true; } return false; @@ -209,19 +223,25 @@ AST_MATCHER_P(ClassTemplateSpecializationDecl, hasAnyTemplateArgument, /// /// Parentheses and explicit casts are not discarded. /// Given +/// \code /// int arr[5]; /// int a = 0; /// char b = 0; /// const int c = a; /// int *d = arr; /// long e = (long) 0l; +/// \endcode /// The matchers +/// \code /// variable(hasInitializer(ignoringImpCasts(integerLiteral()))) /// variable(hasInitializer(ignoringImpCasts(declarationReference()))) +/// \endcode /// would match the declarations for a, b, c, and d, but not e. -/// while +/// While +/// \code /// variable(hasInitializer(integerLiteral())) /// variable(hasInitializer(declarationReference())) +/// \endcode /// only match the declarations for b, c, and d. AST_MATCHER_P(Expr, ignoringImpCasts, internal::Matcher, InnerMatcher) { @@ -233,10 +253,12 @@ AST_MATCHER_P(Expr, ignoringImpCasts, /// /// Implicit and non-C Style casts are also discarded. /// Given +/// \code /// int a = 0; /// char b = (0); /// void* c = reinterpret_cast(0); /// char d = char(0); +/// \endcode /// The matcher /// variable(hasInitializer(ignoringParenCasts(integerLiteral()))) /// would match the declarations for a, b, c, and d. @@ -252,12 +274,14 @@ AST_MATCHER_P(Expr, ignoringParenCasts, internal::Matcher, InnerMatcher) { /// /// Explicit casts are not discarded. /// Given +/// \code /// int arr[5]; /// int a = 0; /// char b = (0); /// const int c = a; /// int *d = (arr); /// long e = ((long) 0l); +/// \endcode /// The matchers /// variable(hasInitializer(ignoringParenImpCasts( /// integerLiteral()))) @@ -274,65 +298,73 @@ AST_MATCHER_P(Expr, ignoringParenImpCasts, } /// \brief Matches classTemplateSpecializations where the n'th TemplateArgument -/// matches the given Matcher. +/// matches the given InnerMatcher. /// /// Given +/// \code /// template class A {}; /// A b; /// A c; +/// \endcode /// classTemplateSpecialization(hasTemplateArgument( /// 1, refersToType(asString("int")))) /// matches the specialization \c A AST_MATCHER_P2(ClassTemplateSpecializationDecl, hasTemplateArgument, - unsigned, N, internal::Matcher, Matcher) { + unsigned, N, internal::Matcher, InnerMatcher) { const TemplateArgumentList &List = Node.getTemplateArgs(); if (List.size() <= N) return false; - return Matcher.matches(List.get(N), Finder, Builder); + return InnerMatcher.matches(List.get(N), Finder, Builder); } /// \brief Matches a TemplateArgument that refers to a certain type. /// /// Given +/// \code /// struct X {}; /// template struct A {}; /// A a; +/// \endcode /// classTemplateSpecialization(hasAnyTemplateArgument( /// refersToType(class(hasName("X"))))) /// matches the specialization \c A AST_MATCHER_P(TemplateArgument, refersToType, - internal::Matcher, Matcher) { + internal::Matcher, InnerMatcher) { if (Node.getKind() != TemplateArgument::Type) return false; - return Matcher.matches(Node.getAsType(), Finder, Builder); + return InnerMatcher.matches(Node.getAsType(), Finder, Builder); } /// \brief Matches a TemplateArgument that refers to a certain declaration. /// /// Given +/// \code /// template struct A {}; /// struct B { B* next; }; /// A<&B::next> a; +/// \endcode /// classTemplateSpecialization(hasAnyTemplateArgument( /// refersToDeclaration(field(hasName("next")))) /// matches the specialization \c A<&B::next> with \c field(...) matching /// \c B::next AST_MATCHER_P(TemplateArgument, refersToDeclaration, - internal::Matcher, Matcher) { + internal::Matcher, InnerMatcher) { if (const Decl *Declaration = Node.getAsDecl()) - return Matcher.matches(*Declaration, Finder, Builder); + return InnerMatcher.matches(*Declaration, Finder, Builder); return false; } /// \brief Matches C++ constructor declarations. /// /// Example matches Foo::Foo() and Foo::Foo(int) +/// \code /// class Foo { /// public: /// Foo(); /// Foo(int); /// int DoSomething(); /// }; +/// \endcode const internal::VariadicDynCastAllOfMatcher< Decl, CXXConstructorDecl> constructor; @@ -340,26 +372,32 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches explicit C++ destructor declarations. /// /// Example matches Foo::~Foo() +/// \code /// class Foo { /// public: /// virtual ~Foo(); /// }; +/// \endcode const internal::VariadicDynCastAllOfMatcher destructor; /// \brief Matches enum declarations. /// /// Example matches X +/// \code /// enum X { /// A, B, C /// }; +/// \endcode const internal::VariadicDynCastAllOfMatcher enumDecl; /// \brief Matches enum constants. /// /// Example matches A, B, C +/// \code /// enum X { /// A, B, C /// }; +/// \endcode const internal::VariadicDynCastAllOfMatcher< Decl, EnumConstantDecl> enumConstant; @@ -367,7 +405,9 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches method declarations. /// /// Example matches y +/// \code /// class X { void y() }; +/// \endcode const internal::VariadicDynCastAllOfMatcher method; /// \brief Matches variable declarations. @@ -376,13 +416,17 @@ const internal::VariadicDynCastAllOfMatcher method; /// "field" declarations in Clang parlance. /// /// Example matches a +/// \code /// int a; +/// \endcode const internal::VariadicDynCastAllOfMatcher variable; /// \brief Matches field declarations. /// /// Given +/// \code /// class X { int m; }; +/// \endcode /// field() /// matches 'm'. const internal::VariadicDynCastAllOfMatcher field; @@ -390,13 +434,17 @@ const internal::VariadicDynCastAllOfMatcher field; /// \brief Matches function declarations. /// /// Example matches f +/// \code /// void f(); +/// \endcode const internal::VariadicDynCastAllOfMatcher function; /// \brief Matches C++ function template declarations. /// /// Example matches f +/// \code /// template void f(T t) {} +/// \endcode const internal::VariadicDynCastAllOfMatcher< Decl, FunctionTemplateDecl> functionTemplate; @@ -404,7 +452,9 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches statements. /// /// Given +/// \code /// { ++a; } +/// \endcode /// statement() /// matches both the compound statement '{ ++a; }' and '++a'. const internal::VariadicDynCastAllOfMatcher statement; @@ -412,7 +462,9 @@ const internal::VariadicDynCastAllOfMatcher statement; /// \brief Matches declaration statements. /// /// Given +/// \code /// int a; +/// \endcode /// declarationStatement() /// matches 'int a'. const internal::VariadicDynCastAllOfMatcher< @@ -422,10 +474,12 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches member expressions. /// /// Given +/// \code /// class Y { /// void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; } /// int a; static int b; /// }; +/// \endcode /// memberExpression() /// matches this->x, x, y.x, a, this->b const internal::VariadicDynCastAllOfMatcher< @@ -435,24 +489,30 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches call expressions. /// /// Example matches x.y() and y() +/// \code /// X x; /// x.y(); /// y(); +/// \endcode const internal::VariadicDynCastAllOfMatcher call; /// \brief Matches member call expressions. /// /// Example matches x.y() +/// \code /// X x; /// x.y(); +/// \endcode const internal::VariadicDynCastAllOfMatcher memberCall; /// \brief Matches init list expressions. /// /// Given +/// \code /// int a[] = { 1, 2 }; /// struct B { int x, y; }; /// B b = { 5, 6 }; +/// \endcode /// initList() /// matches "{ 1, 2 }" and "{ 5, 6 }" const internal::VariadicDynCastAllOfMatcher initListExpr; @@ -460,8 +520,10 @@ const internal::VariadicDynCastAllOfMatcher initListExpr; /// \brief Matches using declarations. /// /// Given +/// \code /// namespace X { int x; } /// using X::x; +/// \endcode /// usingDecl() /// matches \code using X::x \endcode const internal::VariadicDynCastAllOfMatcher usingDecl; @@ -470,10 +532,12 @@ const internal::VariadicDynCastAllOfMatcher usingDecl; /// /// Example matches string(ptr, n) and ptr within arguments of f /// (matcher = constructorCall()) +/// \code /// void f(const string &a, const string &b); /// char *ptr; /// int n; /// f(string(ptr, n), ptr); +/// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, CXXConstructExpr> constructorCall; @@ -482,8 +546,10 @@ const internal::VariadicDynCastAllOfMatcher< /// /// Example matches FunctionTakesString(GetStringByValue()) /// (matcher = bindTemporaryExpression()) +/// \code /// FunctionTakesString(GetStringByValue()); /// FunctionTakesStringByPointer(GetStringPointer()); +/// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, CXXBindTemporaryExpr> bindTemporaryExpression; @@ -491,7 +557,9 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches new expressions. /// /// Given +/// \code /// new X; +/// \endcode /// newExpression() /// matches 'new X'. const internal::VariadicDynCastAllOfMatcher< @@ -501,7 +569,9 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches delete expressions. /// /// Given +/// \code /// delete X; +/// \endcode /// deleteExpression() /// matches 'delete X'. const internal::VariadicDynCastAllOfMatcher< @@ -511,7 +581,9 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches array subscript expressions. /// /// Given +/// \code /// int i = a[1]; +/// \endcode /// arraySubscriptExpr() /// matches "a[1]" const internal::VariadicDynCastAllOfMatcher< @@ -523,8 +595,10 @@ const internal::VariadicDynCastAllOfMatcher< /// Example matches the CXXDefaultArgExpr placeholder inserted for the /// default value of the second parameter in the call expression f(42) /// (matcher = defaultArgument()) +/// \code /// void f(int x, int y = 0); /// f(42); +/// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, CXXDefaultArgExpr> defaultArgument; @@ -538,9 +612,11 @@ const internal::VariadicDynCastAllOfMatcher< /// /// Example matches both operator<<((o << b), c) and operator<<(o, b) /// (matcher = overloadedOperatorCall()) +/// \code /// ostream &operator<< (ostream &out, int i) { }; /// ostream &o; int b = 1, c = 1; /// o << b << c; +/// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, CXXOperatorCallExpr> overloadedOperatorCall; @@ -548,7 +624,9 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches expressions. /// /// Example matches x() +/// \code /// void f() { x(); } +/// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, Expr> expression; @@ -556,8 +634,10 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches expressions that refer to declarations. /// /// Example matches x in if (x) +/// \code /// bool x; /// if (x) {} +/// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, DeclRefExpr> declarationReference; @@ -565,13 +645,17 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches if statements. /// /// Example matches 'if (x) {}' +/// \code /// if (x) {} +/// \endcode const internal::VariadicDynCastAllOfMatcher ifStmt; /// \brief Matches for statements. /// /// Example matches 'for (;;) {}' +/// \code /// for (;;) {} +/// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, ForStmt> forStmt; @@ -580,7 +664,9 @@ const internal::VariadicDynCastAllOfMatcher< /// Example: /// forStmt(hasIncrement(unaryOperator(hasOperatorName("++")))) /// matches '++x' in +/// \code /// for (x; x < N; ++x) { } +/// \endcode AST_MATCHER_P(ForStmt, hasIncrement, internal::Matcher, InnerMatcher) { const Stmt *const Increment = Node.getInc(); @@ -593,7 +679,9 @@ AST_MATCHER_P(ForStmt, hasIncrement, internal::Matcher, /// Example: /// forStmt(hasLoopInit(declarationStatement())) /// matches 'int x = 0' in +/// \code /// for (int x = 0; x < N; ++x) { } +/// \endcode AST_MATCHER_P(ForStmt, hasLoopInit, internal::Matcher, InnerMatcher) { const Stmt *const Init = Node.getInit(); @@ -603,7 +691,9 @@ AST_MATCHER_P(ForStmt, hasLoopInit, internal::Matcher, /// \brief Matches while statements. /// /// Given +/// \code /// while (true) {} +/// \endcode /// whileStmt() /// matches 'while (true) {}'. const internal::VariadicDynCastAllOfMatcher< @@ -613,7 +703,9 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches do statements. /// /// Given +/// \code /// do {} while (true); +/// \endcode /// doStmt() /// matches 'do {} while(true)' const internal::VariadicDynCastAllOfMatcher doStmt; @@ -621,7 +713,9 @@ const internal::VariadicDynCastAllOfMatcher doStmt; /// \brief 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;'. const internal::VariadicDynCastAllOfMatcher< @@ -631,7 +725,9 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches compound statements. /// /// Example matches '{}' and '{{}}'in 'for (;;) {{}}' +/// \code /// for (;;) {{}} +/// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, CompoundStmt> compoundStatement; @@ -639,7 +735,9 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches bool literals. /// /// Example matches true +/// \code /// true +/// \endcode const internal::VariadicDynCastAllOfMatcher< Expr, CXXBoolLiteralExpr> boolLiteral; @@ -647,7 +745,9 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches string literals (also matches wide string literals). /// /// Example matches "abcd", L"abcd" +/// \code /// char *s = "abcd"; wchar_t *ws = L"abcd" +/// \endcode const internal::VariadicDynCastAllOfMatcher< Expr, StringLiteral> stringLiteral; @@ -658,7 +758,9 @@ const internal::VariadicDynCastAllOfMatcher< /// though. /// /// Example matches 'a', L'a' +/// \code /// char ch = 'a'; wchar_t chw = L'a'; +/// \endcode const internal::VariadicDynCastAllOfMatcher< Expr, CharacterLiteral> characterLiteral; @@ -675,7 +777,9 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches binary operator expressions. /// /// Example matches a || b +/// \code /// !(a || b) +/// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, BinaryOperator> binaryOperator; @@ -683,7 +787,9 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches unary operator expressions. /// /// Example matches !a +/// \code /// !a || b +/// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, UnaryOperator> unaryOperator; @@ -691,7 +797,9 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches conditional operator expressions. /// /// Example matches a ? b : c +/// \code /// (a ? b : c) + 42 +/// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, ConditionalOperator> conditionalOperator; @@ -703,7 +811,9 @@ const internal::VariadicDynCastAllOfMatcher< /// more readable. /// /// Example matches reinterpret_cast(&p) in +/// \code /// void* p = reinterpret_cast(&p); +/// \endcode const internal::VariadicDynCastAllOfMatcher< Expr, CXXReinterpretCastExpr> reinterpretCast; @@ -718,7 +828,9 @@ const internal::VariadicDynCastAllOfMatcher< /// matches /// static_cast(8) /// in +/// \code /// long eight(static_cast(8)); +/// \endcode const internal::VariadicDynCastAllOfMatcher< Expr, CXXStaticCastExpr> staticCast; @@ -730,9 +842,11 @@ const internal::VariadicDynCastAllOfMatcher< /// matches /// dynamic_cast(&b); /// in +/// \code /// struct B { virtual ~B() {} }; struct D : B {}; /// B b; /// D* p = dynamic_cast(&b); +/// \endcode const internal::VariadicDynCastAllOfMatcher< Expr, CXXDynamicCastExpr> dynamicCast; @@ -740,9 +854,11 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches a const_cast expression. /// /// Example: Matches const_cast(&r) in +/// \code /// int n = 42; -/// const int& r(n); +/// const int &r(n); /// int* p = const_cast(&r); +/// \endcode const internal::VariadicDynCastAllOfMatcher< Expr, CXXConstCastExpr> constCast; @@ -761,9 +877,13 @@ const internal::VariadicDynCastAllOfMatcher< /// \see hasDestinationType. /// /// Example: matches all five of the casts in +/// \code /// int((int)(reinterpret_cast(static_cast(const_cast(42))))) +/// \endcode /// but does not match the implicit conversion in +/// \code /// long ell = 42; +/// \endcode const internal::VariadicDynCastAllOfMatcher< Expr, ExplicitCastExpr> explicitCast; @@ -779,12 +899,16 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches any cast nodes of Clang's AST. /// /// Example: castExpr() matches each of the following: +/// \code /// (int) 3; /// const_cast(SubExpr); /// char c = 0; +/// \endcode /// but does not match +/// \code /// int i = (0); /// int k = 0; +/// \endcode const internal::VariadicDynCastAllOfMatcher< Expr, CastExpr> castExpr; @@ -792,67 +916,81 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches functional cast expressions /// /// Example: Matches Foo(bar); +/// \code /// Foo f = bar; /// Foo g = (Foo) bar; /// Foo h = Foo(bar); +/// \endcode const internal::VariadicDynCastAllOfMatcher< Expr, CXXFunctionalCastExpr> functionalCast; /// \brief Various overloads for the anyOf matcher. /// @{ -template -internal::PolymorphicMatcherWithParam2 -anyOf(const C1 &P1, const C2 &P2) { + +/// \brief Matches if any of the given matchers matches. +/// +/// Usable as: Any Matcher +template +internal::PolymorphicMatcherWithParam2 +anyOf(const M1 &P1, const M2 &P2) { return internal::PolymorphicMatcherWithParam2(P1, P2); + M1, M2 >(P1, P2); } -template -internal::PolymorphicMatcherWithParam2 > -anyOf(const C1 &P1, const C2 &P2, const C3 &P3) { +template +internal::PolymorphicMatcherWithParam2 > +anyOf(const M1 &P1, const M2 &P2, const M3 &P3) { return anyOf(P1, anyOf(P2, P3)); } -template -internal::PolymorphicMatcherWithParam2 +internal::PolymorphicMatcherWithParam2 > > -anyOf(const C1 &P1, const C2 &P2, const C3 &P3, const C4 &P4) { + M3, M4> > > +anyOf(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4) { return anyOf(P1, anyOf(P2, anyOf(P3, P4))); } -template -internal::PolymorphicMatcherWithParam2 +internal::PolymorphicMatcherWithParam2 > > > -anyOf(const C1& P1, const C2& P2, const C3& P3, const C4& P4, const C5& P5) { + M4, M5> > > > +anyOf(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, const M5 &P5) { return anyOf(P1, anyOf(P2, anyOf(P3, anyOf(P4, P5)))); } + /// @} /// \brief Various overloads for the allOf matcher. /// @{ -template -internal::PolymorphicMatcherWithParam2 -allOf(const C1 &P1, const C2 &P2) { + +/// \brief Matches if all given matchers match. +/// +/// Usable as: Any Matcher +template +internal::PolymorphicMatcherWithParam2 +allOf(const M1 &P1, const M2 &P2) { return internal::PolymorphicMatcherWithParam2(P1, P2); + M1, M2>(P1, P2); } -template -internal::PolymorphicMatcherWithParam2 > -allOf(const C1& P1, const C2& P2, const C3& P3) { +template +internal::PolymorphicMatcherWithParam2 > +allOf(const M1 &P1, const M2 &P2, const M3 &P3) { return allOf(P1, allOf(P2, P3)); } + /// @} /// \brief Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL) /// /// Given +/// \code /// Foo x = bar; /// int y = sizeof(x) + alignof(x); +/// \endcode /// unaryExprOrTypeTraitExpr() /// matches \c sizeof(x) and \c alignof(x) const internal::VariadicDynCastAllOfMatcher< @@ -862,20 +1000,24 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches unary expressions that have a specific type of argument. /// /// Given +/// \code /// int a, c; float b; int s = sizeof(a) + sizeof(b) + alignof(c); +/// \endcode /// unaryExprOrTypeTraitExpr(hasArgumentOfType(asString("int")) /// matches \c sizeof(a) and \c alignof(c) AST_MATCHER_P(UnaryExprOrTypeTraitExpr, hasArgumentOfType, - internal::Matcher, Matcher) { + internal::Matcher, InnerMatcher) { const QualType ArgumentType = Node.getTypeOfArgument(); - return Matcher.matches(ArgumentType, Finder, Builder); + return InnerMatcher.matches(ArgumentType, Finder, Builder); } /// \brief Matches unary expressions of a certain kind. /// /// Given +/// \code /// int x; /// int s = sizeof(x) + alignof(x) +/// \endcode /// unaryExprOrTypeTraitExpr(ofKind(UETT_SizeOf)) /// matches \c sizeof(x) AST_MATCHER_P(UnaryExprOrTypeTraitExpr, ofKind, UnaryExprOrTypeTrait, Kind) { @@ -885,17 +1027,17 @@ AST_MATCHER_P(UnaryExprOrTypeTraitExpr, ofKind, UnaryExprOrTypeTrait, Kind) { /// \brief Same as unaryExprOrTypeTraitExpr, but only matching /// alignof. inline internal::Matcher alignOfExpr( - const internal::Matcher &Matcher) { + const internal::Matcher &InnerMatcher) { return internal::Matcher(unaryExprOrTypeTraitExpr(allOf( - ofKind(UETT_AlignOf), Matcher))); + ofKind(UETT_AlignOf), InnerMatcher))); } /// \brief Same as unaryExprOrTypeTraitExpr, but only matching /// sizeof. inline internal::Matcher sizeOfExpr( - const internal::Matcher &Matcher) { + const internal::Matcher &InnerMatcher) { return internal::Matcher(unaryExprOrTypeTraitExpr(allOf( - ofKind(UETT_SizeOf), Matcher))); + ofKind(UETT_SizeOf), InnerMatcher))); } /// \brief Matches NamedDecl nodes that have the specified name. @@ -905,10 +1047,14 @@ inline internal::Matcher sizeOfExpr( /// Does not match typedefs of an underlying type with the given name. /// /// Example matches X (Name == "X") +/// \code /// class X; +/// \endcode /// /// Example matches X (Name is one of "::a::b::X", "a::b::X", "b::X", "X") -/// namespace a { namespace b { class X; } } +/// \code +/// namespace a { namespace b { class X; } } +/// \endcode AST_MATCHER_P(NamedDecl, hasName, std::string, Name) { assert(!Name.empty()); const std::string FullNameString = "::" + Node.getQualifiedNameAsString(); @@ -929,10 +1075,14 @@ AST_MATCHER_P(NamedDecl, hasName, std::string, Name) { /// of an underlying type with the given name. /// /// Example matches X (regexp == "::X") +/// \code /// class X; +/// \endcode /// /// Example matches X (regexp is one of "::X", "^foo::.*X", among others) -/// namespace foo { namespace bar { class X; } } +/// \code +/// namespace foo { namespace bar { class X; } } +/// \endcode AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp) { assert(!RegExp.empty()); std::string FullNameString = "::" + Node.getQualifiedNameAsString(); @@ -947,9 +1097,11 @@ AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp) { /// /// Example matches a << b /// (matcher == overloadedOperatorCall(hasOverloadedOperatorName("<<"))) +/// \code /// a << b; /// c && d; // assuming both operator<< /// // and operator&& are overloaded somewhere. +/// \endcode AST_MATCHER_P(CXXOperatorCallExpr, hasOverloadedOperatorName, std::string, Name) { return getOperatorSpelling(Node.getOperator()) == Name; @@ -961,17 +1113,21 @@ AST_MATCHER_P(CXXOperatorCallExpr, /// Note that a class is considered to be also derived from itself. /// /// Example matches X, Y, Z, C (Base == hasName("X")) +/// \code /// class X; // A class is considered to be derived from itself /// class Y : public X {}; // directly derived /// class Z : public Y {}; // indirectly derived /// typedef X A; /// typedef A B; /// class C : public B {}; // derived from a typedef of X +/// \endcode /// /// In the following example, Bar matches isDerivedFrom(hasName("X")): +/// \code /// class Foo; /// typedef Foo X; /// class Bar : public Foo {}; // derived from a type that X is a typedef of +/// \endcode AST_MATCHER_P(CXXRecordDecl, isDerivedFrom, internal::Matcher, Base) { return Finder->classIsDerivedFrom(&Node, Base, Builder); @@ -987,11 +1143,15 @@ inline internal::Matcher isDerivedFrom(StringRef BaseName) { /// provided matcher. /// /// Example matches X, Y (matcher = record(has(record(hasName("X"))) +/// \code /// class X {}; // Matches X, because X::X is a class of name X inside X. /// class Y { class X {}; }; /// class Z { class Y { class X {}; }; }; // Does not match Z. +/// \endcode /// /// ChildT must be an AST base type. +/// +/// Usable as: Any Matcher template internal::ArgumentAdaptingMatcher has( const internal::Matcher &ChildMatcher) { @@ -1004,11 +1164,15 @@ internal::ArgumentAdaptingMatcher has( /// /// Example matches X, Y, Z /// (matcher = record(hasDescendant(record(hasName("X"))))) +/// \code /// class X {}; // Matches X, because X::X is a class of name X inside X. /// class Y { class X {}; }; /// class Z { class Y { class X {}; }; }; +/// \endcode /// /// DescendantT must be an AST base type. +/// +/// Usable as: Any Matcher template internal::ArgumentAdaptingMatcher hasDescendant(const internal::Matcher &DescendantMatcher) { @@ -1022,17 +1186,21 @@ hasDescendant(const internal::Matcher &DescendantMatcher) { /// provided matcher. /// /// Example matches X, Y (matcher = record(forEach(record(hasName("X"))) +/// \code /// class X {}; // Matches X, because X::X is a class of name X inside X. /// class Y { class X {}; }; /// class Z { class Y { class X {}; }; }; // Does not match Z. +/// \endcode /// /// ChildT must be an AST base type. /// /// As opposed to 'has', 'forEach' will cause a match for each result that /// matches instead of only on the first one. +/// +/// Usable as: Any Matcher template internal::ArgumentAdaptingMatcher forEach( - const internal::Matcher& ChildMatcher) { + const internal::Matcher &ChildMatcher) { return internal::ArgumentAdaptingMatcher< internal::ForEachMatcher, ChildT>(ChildMatcher); @@ -1043,9 +1211,11 @@ internal::ArgumentAdaptingMatcher forEach( /// /// Example matches X, A, B, C /// (matcher = record(forEachDescendant(record(hasName("X"))))) +/// \code /// class X {}; // Matches X, because X::X is a class of name X inside X. /// class A { class X {}; }; /// class B { class C { class X {}; }; }; +/// \endcode /// /// DescendantT must be an AST base type. /// @@ -1055,11 +1225,15 @@ internal::ArgumentAdaptingMatcher forEach( /// Note: Recursively combined ForEachDescendant can cause many matches: /// record(forEachDescendant(record(forEachDescendant(record())))) /// will match 10 times (plus injected class name matches) on: +/// \code /// class A { class B { class C { class D { class E {}; }; }; }; }; +/// \endcode +/// +/// Usable as: Any Matcher template internal::ArgumentAdaptingMatcher forEachDescendant( - const internal::Matcher& DescendantMatcher) { + const internal::Matcher &DescendantMatcher) { return internal::ArgumentAdaptingMatcher< internal::ForEachDescendantMatcher, DescendantT>(DescendantMatcher); @@ -1068,10 +1242,15 @@ forEachDescendant( /// \brief Matches if the provided matcher does not match. /// /// Example matches Y (matcher = record(unless(hasName("X")))) +/// \code /// class X {}; /// class Y {}; +/// \endcode +/// +/// Usable as: Any Matcher template -internal::PolymorphicMatcherWithParam1 unless(const M &InnerMatcher) { +internal::PolymorphicMatcherWithParam1 +unless(const M &InnerMatcher) { return internal::PolymorphicMatcherWithParam1< internal::NotMatcher, M>(InnerMatcher); } @@ -1091,8 +1270,10 @@ inline internal::PolymorphicMatcherWithParam1< internal::HasDeclarationMatcher, /// \brief Matches on the implicit object argument of a member call expression. /// /// Example matches y.x() (matcher = call(on(hasType(record(hasName("Y")))))) +/// \code /// class Y { public: void x(); }; /// void z() { Y y; y.x(); }", +/// \endcode /// /// FIXME: Overload to allow directly matching types? AST_MATCHER_P(CXXMemberCallExpr, on, internal::Matcher, @@ -1107,8 +1288,10 @@ AST_MATCHER_P(CXXMemberCallExpr, on, internal::Matcher, /// \brief Matches if the call expression's callee expression matches. /// /// Given +/// \code /// class Y { void x() { this->x(); x(); Y y; y.x(); } }; /// void f() { f(); } +/// \endcode /// call(callee(expression())) /// matches this->x(), x(), y.x(), f() /// with callee(...) @@ -1129,8 +1312,10 @@ AST_MATCHER_P(CallExpr, callee, internal::Matcher, /// given matcher. /// /// Example matches y.x() (matcher = call(callee(method(hasName("x"))))) +/// \code /// class Y { public: void x(); }; /// void z() { Y y; y.x(); +/// \endcode inline internal::Matcher callee( const internal::Matcher &InnerMatcher) { return internal::Matcher(hasDeclaration(InnerMatcher)); @@ -1143,8 +1328,10 @@ inline internal::Matcher callee( /// hasDeclaration(record(hasName("X")))))) /// and z (matcher = variable(hasType( /// hasDeclaration(record(hasName("X")))))) +/// \code /// class X {}; /// void y(X &x) { x; X z; } +/// \endcode AST_POLYMORPHIC_MATCHER_P(hasType, internal::Matcher, InnerMatcher) { TOOLING_COMPILE_ASSERT((llvm::is_base_of::value || @@ -1164,8 +1351,10 @@ AST_POLYMORPHIC_MATCHER_P(hasType, internal::Matcher, /// /// Example matches x (matcher = expression(hasType(record(hasName("X"))))) /// and z (matcher = variable(hasType(record(hasName("X"))))) +/// \code /// class X {}; /// void y(X &x) { x; X z; } +/// \endcode /// /// Usable as: Matcher, Matcher inline internal::PolymorphicMatcherWithParam1< @@ -1179,8 +1368,10 @@ hasType(const internal::Matcher &InnerMatcher) { /// \brief Matches if the matched type is represented by the given string. /// /// Given +/// \code /// class Y { public: void x(); }; /// void z() { Y* y; y->x(); } +/// \endcode /// call(on(hasType(asString("class Y *")))) /// matches y->x() AST_MATCHER_P(QualType, asString, std::string, Name) { @@ -1192,8 +1383,10 @@ AST_MATCHER_P(QualType, asString, std::string, Name) { /// /// Example matches y->x() /// (matcher = call(on(hasType(pointsTo(record(hasName("Y"))))))) +/// \code /// class Y { public: void x(); }; /// void z() { Y *y; y->x(); } +/// \endcode AST_MATCHER_P( QualType, pointsTo, internal::Matcher, InnerMatcher) { @@ -1213,11 +1406,13 @@ inline internal::Matcher pointsTo( /// /// Example matches X &x and const X &y /// (matcher = variable(hasType(references(record(hasName("X")))))) +/// \code /// class X { /// void a(X b) { /// X &x = b; /// const X &y = b; /// }; +/// \endcode AST_MATCHER_P(QualType, references, internal::Matcher, InnerMatcher) { return (!Node.isNull() && Node->isReferenceType() && @@ -1259,8 +1454,10 @@ inline internal::Matcher thisPointerType( /// /// Example matches x in if(x) /// (matcher = declarationReference(to(variable(hasName("x"))))) +/// \code /// bool x; /// if (x) {} +/// \endcode AST_MATCHER_P(DeclRefExpr, to, internal::Matcher, InnerMatcher) { const Decl *DeclNode = Node.getDecl(); @@ -1274,28 +1471,32 @@ AST_MATCHER_P(DeclRefExpr, to, internal::Matcher, /// FIXME: This currently only works for functions. Fix. /// /// Given +/// \code /// namespace a { void f() {} } /// using a::f; /// void g() { /// f(); // Matches this .. /// a::f(); // .. but not this. /// } +/// \endcode /// declarationReference(throughUsingDeclaration(anything())) /// matches \c f() AST_MATCHER_P(DeclRefExpr, throughUsingDecl, - internal::Matcher, Matcher) { + internal::Matcher, InnerMatcher) { const NamedDecl *FoundDecl = Node.getFoundDecl(); if (const UsingShadowDecl *UsingDecl = llvm::dyn_cast(FoundDecl)) - return Matcher.matches(*UsingDecl, Finder, Builder); + return InnerMatcher.matches(*UsingDecl, Finder, Builder); return false; } /// \brief Matches the Decl of a DeclStmt which has a single declaration. /// /// Given +/// \code /// int a, b; /// int c; +/// \endcode /// declarationStatement(hasSingleDecl(anything())) /// matches 'int c;' but not 'int a, b;'. AST_MATCHER_P(DeclStmt, hasSingleDecl, internal::Matcher, InnerMatcher) { @@ -1310,8 +1511,10 @@ AST_MATCHER_P(DeclStmt, hasSingleDecl, internal::Matcher, InnerMatcher) { /// that matches the given matcher. /// /// Example matches x (matcher = variable(hasInitializer(call()))) +/// \code /// bool y() { return true; } /// bool x = y(); +/// \endcode AST_MATCHER_P( VarDecl, hasInitializer, internal::Matcher, InnerMatcher) { @@ -1324,8 +1527,10 @@ AST_MATCHER_P( /// a specific number of arguments (including absent default arguments). /// /// Example matches f(0, 0) (matcher = call(argumentCountIs(2))) +/// \code /// void f(int x, int y); /// f(0, 0); +/// \endcode AST_POLYMORPHIC_MATCHER_P(argumentCountIs, unsigned, N) { TOOLING_COMPILE_ASSERT((llvm::is_base_of::value || llvm::is_base_of, InnerMatcher) { TOOLING_COMPILE_ASSERT((llvm::is_base_of::value || @@ -1355,9 +1562,11 @@ AST_POLYMORPHIC_MATCHER_P2( /// declarations. /// /// Example: Given +/// \code /// int a, b; /// int c; /// int d = 2, e; +/// \endcode /// declCountIs(2) /// matches 'int a, b;' and 'int d = 2, e;', but not 'int c;'. AST_MATCHER_P(DeclStmt, declCountIs, unsigned, N) { @@ -1370,15 +1579,19 @@ AST_MATCHER_P(DeclStmt, declCountIs, unsigned, N) { /// breaks up multiple-declaration DeclStmt's into multiple single-declaration /// DeclStmt's. /// Example: Given non-global declarations +/// \code /// int a, b = 0; /// int c; /// int d = 2, e; +/// \endcode /// declarationStatement(containsDeclaration( /// 0, variable(hasInitializer(anything())))) /// matches only 'int d = 2, e;', and /// declarationStatement(containsDeclaration(1, variable())) +/// \code /// matches 'int a, b = 0' as well as 'int d = 2, e;' /// but 'int c;' is not matched. +/// \endcode AST_MATCHER_P2(DeclStmt, containsDeclaration, unsigned, N, internal::Matcher, InnerMatcher) { const unsigned NumDecls = std::distance(Node.decl_begin(), Node.decl_end()); @@ -1392,10 +1605,12 @@ AST_MATCHER_P2(DeclStmt, containsDeclaration, unsigned, N, /// \brief Matches a constructor initializer. /// /// Given +/// \code /// struct Foo { /// Foo() : foo_(1) { } /// int foo_; /// }; +/// \endcode /// record(has(constructor(hasAnyConstructorInitializer(anything())))) /// record matches Foo, hasAnyConstructorInitializer matches foo_(1) AST_MATCHER_P(CXXConstructorDecl, hasAnyConstructorInitializer, @@ -1412,10 +1627,12 @@ AST_MATCHER_P(CXXConstructorDecl, hasAnyConstructorInitializer, /// \brief Matches the field declaration of a constructor initializer. /// /// Given +/// \code /// struct Foo { /// Foo() : foo_(1) { } /// int foo_; /// }; +/// \endcode /// record(has(constructor(hasAnyConstructorInitializer( /// forField(hasName("foo_")))))) /// matches Foo @@ -1430,10 +1647,12 @@ AST_MATCHER_P(CXXCtorInitializer, forField, /// \brief Matches the initializer expression of a constructor initializer. /// /// Given +/// \code /// struct Foo { /// Foo() : foo_(1) { } /// int foo_; /// }; +/// \endcode /// record(has(constructor(hasAnyConstructorInitializer( /// withInitializer(integerLiteral(equals(1))))))) /// matches Foo @@ -1449,11 +1668,13 @@ AST_MATCHER_P(CXXCtorInitializer, withInitializer, /// code (as opposed to implicitly added by the compiler). /// /// Given +/// \code /// struct Foo { /// Foo() { } /// Foo(int) : foo_("A") { } /// string foo_; /// }; +/// \endcode /// constructor(hasAnyConstructorInitializer(isWritten())) /// will match Foo(int), but not Foo() AST_MATCHER(CXXCtorInitializer, isWritten) { @@ -1470,7 +1691,9 @@ AST_MATCHER(CXXConstructorDecl, isImplicit) { /// expression. /// /// Given +/// \code /// void x(int, int, int) { int y; x(1, y, 42); } +/// \endcode /// call(hasAnyArgument(declarationReference())) /// matches x(1, y, 42) /// with hasAnyArgument(...) @@ -1493,7 +1716,9 @@ AST_POLYMORPHIC_MATCHER_P(hasAnyArgument, internal::Matcher, /// \brief Matches the n'th parameter of a function declaration. /// /// Given +/// \code /// class X { void f(int x) {} }; +/// \endcode /// method(hasParameter(0, hasType(variable()))) /// matches f(int x) {} /// with hasParameter(...) @@ -1511,7 +1736,9 @@ AST_MATCHER_P2(FunctionDecl, hasParameter, /// Does not match the 'this' parameter of a method. /// /// Given +/// \code /// class X { void f(int x, int y, int z) {} }; +/// \endcode /// method(hasAnyParameter(hasName("y"))) /// matches f(int x, int y, int z) {} /// with hasAnyParameter(...) @@ -1529,19 +1756,24 @@ AST_MATCHER_P(FunctionDecl, hasAnyParameter, /// \brief Matches the return type of a function declaration. /// /// Given: +/// \code /// class X { int f() { return 1; } }; +/// \endcode /// method(returns(asString("int"))) /// matches int f() { return 1; } -AST_MATCHER_P(FunctionDecl, returns, internal::Matcher, Matcher) { - return Matcher.matches(Node.getResultType(), Finder, Builder); +AST_MATCHER_P(FunctionDecl, returns, + internal::Matcher, InnerMatcher) { + return InnerMatcher.matches(Node.getResultType(), Finder, Builder); } /// \brief Matches extern "C" function declarations. /// /// Given: +/// \code /// extern "C" void f() {} /// extern "C" { void g() {} } /// void h() {} +/// \endcode /// function(isExternC()) /// matches the declaration of f and g, but not the declaration h AST_MATCHER(FunctionDecl, isExternC) { @@ -1552,7 +1784,9 @@ AST_MATCHER(FunctionDecl, isExternC) { /// or conditional operator. /// /// Example matches true (matcher = hasCondition(boolLiteral(equals(true)))) +/// \code /// if (true) {} +/// \endcode AST_POLYMORPHIC_MATCHER_P(hasCondition, internal::Matcher, InnerMatcher) { TOOLING_COMPILE_ASSERT( @@ -1570,7 +1804,9 @@ AST_POLYMORPHIC_MATCHER_P(hasCondition, internal::Matcher, /// \brief Matches the condition variable statement in an if statement. /// /// Given +/// \code /// if (A* a = GetAPointer()) {} +/// \endcode /// hasConditionVariableStatment(...) /// matches 'A* a = GetAPointer()'. AST_MATCHER_P(IfStmt, hasConditionVariableStatement, @@ -1584,29 +1820,33 @@ AST_MATCHER_P(IfStmt, hasConditionVariableStatement, /// \brief Matches the index expression of an array subscript expression. /// /// Given +/// \code /// int i[5]; /// void f() { i[1] = 42; } +/// \endcode /// arraySubscriptExpression(hasIndex(integerLiteral())) /// matches \c i[1] with the \c integerLiteral() matching \c 1 AST_MATCHER_P(ArraySubscriptExpr, hasIndex, - internal::Matcher, matcher) { + internal::Matcher, InnerMatcher) { if (const Expr* Expression = Node.getIdx()) - return matcher.matches(*Expression, Finder, Builder); + return InnerMatcher.matches(*Expression, Finder, Builder); return false; } /// \brief Matches the base expression of an array subscript expression. /// /// Given +/// \code /// int i[5]; /// void f() { i[1] = 42; } +/// \endcode /// arraySubscriptExpression(hasBase(implicitCast( /// hasSourceExpression(declarationReference())))) /// matches \c i[1] with the \c declarationReference() matching \c i AST_MATCHER_P(ArraySubscriptExpr, hasBase, - internal::Matcher, matcher) { + internal::Matcher, InnerMatcher) { if (const Expr* Expression = Node.getBase()) - return matcher.matches(*Expression, Finder, Builder); + return InnerMatcher.matches(*Expression, Finder, Builder); return false; } @@ -1614,7 +1854,9 @@ AST_MATCHER_P(ArraySubscriptExpr, hasBase, /// a given body. /// /// Given +/// \code /// for (;;) {} +/// \endcode /// hasBody(compoundStatement()) /// matches 'for (;;) {}' /// with compoundStatement() @@ -1635,7 +1877,9 @@ AST_POLYMORPHIC_MATCHER_P(hasBody, internal::Matcher, /// a given matcher. /// /// Given +/// \code /// { {}; 1+2; } +/// \endcode /// hasAnySubstatement(compoundStatement()) /// matches '{ {}; 1+2; }' /// with compoundStatement() @@ -1654,7 +1898,9 @@ AST_MATCHER_P(CompoundStmt, hasAnySubstatement, /// child statements. /// /// Example: Given +/// \code /// { for (;;) {} } +/// \endcode /// compoundStatement(statementCountIs(0))) /// matches '{}' /// but does not match the outer compound statement. @@ -1665,7 +1911,9 @@ AST_MATCHER_P(CompoundStmt, statementCountIs, unsigned, N) { /// \brief Matches literals that are equal to the given value. /// /// Example matches true (matcher = boolLiteral(equals(true))) +/// \code /// true +/// \endcode /// /// Usable as: Matcher, Matcher, /// Matcher, Matcher @@ -1681,7 +1929,9 @@ equals(const ValueT &Value) { /// unary). /// /// Example matches a || b (matcher = binaryOperator(hasOperatorName("||"))) +/// \code /// !(a || b) +/// \endcode AST_POLYMORPHIC_MATCHER_P(hasOperatorName, std::string, Name) { TOOLING_COMPILE_ASSERT( (llvm::is_base_of::value) || @@ -1693,7 +1943,9 @@ AST_POLYMORPHIC_MATCHER_P(hasOperatorName, std::string, Name) { /// \brief Matches the left hand side of binary operator expressions. /// /// Example matches a (matcher = binaryOperator(hasLHS())) +/// \code /// a || b +/// \endcode AST_MATCHER_P(BinaryOperator, hasLHS, internal::Matcher, InnerMatcher) { Expr *LeftHandSide = Node.getLHS(); @@ -1704,7 +1956,9 @@ AST_MATCHER_P(BinaryOperator, hasLHS, /// \brief Matches the right hand side of binary operator expressions. /// /// Example matches b (matcher = binaryOperator(hasRHS())) +/// \code /// a || b +/// \endcode AST_MATCHER_P(BinaryOperator, hasRHS, internal::Matcher, InnerMatcher) { Expr *RightHandSide = Node.getRHS(); @@ -1722,7 +1976,9 @@ inline internal::Matcher hasEitherOperand( /// \brief Matches if the operand of a unary operator matches. /// /// Example matches true (matcher = hasOperand(boolLiteral(equals(true)))) +/// \code /// !true +/// \endcode AST_MATCHER_P(UnaryOperator, hasUnaryOperand, internal::Matcher, InnerMatcher) { const Expr * const Operand = Node.getSubExpr(); @@ -1734,7 +1990,7 @@ AST_MATCHER_P(UnaryOperator, hasUnaryOperand, /// /// Example: matches "a string" (matcher = /// hasSourceExpression(constructorCall())) -/// +/// \code /// class URL { URL(string); }; /// URL url = "a string"; AST_MATCHER_P(CastExpr, hasSourceExpression, @@ -1766,7 +2022,9 @@ AST_MATCHER_P(ImplicitCastExpr, hasImplicitDestinationType, /// \brief Matches the true branch expression of a conditional operator. /// /// Example matches a +/// \code /// condition ? a : b +/// \endcode AST_MATCHER_P(ConditionalOperator, hasTrueExpression, internal::Matcher, InnerMatcher) { Expr *Expression = Node.getTrueExpr(); @@ -1777,7 +2035,9 @@ AST_MATCHER_P(ConditionalOperator, hasTrueExpression, /// \brief Matches the false branch expression of a conditional operator. /// /// Example matches b +/// \code /// condition ? a : b +/// \endcode AST_MATCHER_P(ConditionalOperator, hasFalseExpression, internal::Matcher, InnerMatcher) { Expr *Expression = Node.getFalseExpr(); @@ -1788,12 +2048,14 @@ AST_MATCHER_P(ConditionalOperator, hasFalseExpression, /// \brief Matches if a declaration has a body attached. /// /// Example matches A, va, fa +/// \code /// class A {}; /// class B; // Doesn't match, as it has no body. /// int va; /// extern int vb; // Doesn't match, as it doesn't define the variable. /// void fa() {} /// void fb(); // Doesn't match, as it has no body. +/// \endcode /// /// Usable as: Matcher, Matcher, Matcher inline internal::PolymorphicMatcherWithParam0 @@ -1812,11 +2074,13 @@ isDefinition() { /// Example matches A() in the last line /// (matcher = constructorCall(hasDeclaration(method( /// ofClass(hasName("A")))))) +/// \code /// class A { /// public: /// A(); /// }; /// A a = A(); +/// \endcode AST_MATCHER_P(CXXMethodDecl, ofClass, internal::Matcher, InnerMatcher) { const CXXRecordDecl *Parent = Node.getParent(); @@ -1830,11 +2094,13 @@ AST_MATCHER_P(CXXMethodDecl, ofClass, /// Member calls on the implicit this pointer match as called with '->'. /// /// Given +/// \code /// class Y { /// void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; } /// int a; /// static int b; /// }; +/// \endcode /// memberExpression(isArrow()) /// matches this->x, x, y.x, a, this->b inline internal::Matcher isArrow() { @@ -1844,9 +2110,11 @@ inline internal::Matcher isArrow() { /// \brief Matches QualType nodes that are of integer type. /// /// Given +/// \code /// void a(int); /// void b(long); /// void c(double); +/// \endcode /// function(hasAnyParameter(hasType(isInteger()))) /// matches "a(int)", "b(long)", but not "c(double)". AST_MATCHER(QualType, isInteger) { @@ -1857,11 +2125,13 @@ AST_MATCHER(QualType, isInteger) { /// include "top-level" const. /// /// Given +/// \code /// void a(int); /// void b(int const); /// void c(const int); /// void d(const int*); /// void e(int const) {}; +/// \endcode /// function(hasAnyParameter(hasType(isConstQualified()))) /// matches "void b(int const)", "void c(const int)" and /// "void e(int const) {}". It does not match d as there @@ -1874,9 +2144,11 @@ inline internal::Matcher isConstQualified() { /// given matcher. /// /// Given +/// \code /// struct { int first, second; } first, second; /// int i(second.first); /// int j(first.second); +/// \endcode /// memberExpression(member(hasName("first"))) /// matches second.first /// but not first.second (because the member name there is "second"). @@ -1889,8 +2161,10 @@ AST_MATCHER_P(MemberExpr, member, /// matched by a given matcher. /// /// Given +/// \code /// struct X { int m; }; /// void f(X x) { x.m; m; } +/// \endcode /// memberExpression(hasObjectExpression(hasType(record(hasName("X"))))))) /// matches "x.m" and "m" /// with hasObjectExpression(...) @@ -1903,15 +2177,17 @@ AST_MATCHER_P(MemberExpr, hasObjectExpression, /// \brief Matches any using shadow declaration. /// /// Given +/// \code /// namespace X { void b(); } /// using X::b; +/// \endcode /// usingDecl(hasAnyUsingShadowDecl(hasName("b")))) /// matches \code using X::b \endcode AST_MATCHER_P(UsingDecl, hasAnyUsingShadowDecl, - internal::Matcher, Matcher) { + internal::Matcher, InnerMatcher) { for (UsingDecl::shadow_iterator II = Node.shadow_begin(); II != Node.shadow_end(); ++II) { - if (Matcher.matches(**II, Finder, Builder)) + if (InnerMatcher.matches(**II, Finder, Builder)) return true; } return false; @@ -1921,30 +2197,38 @@ AST_MATCHER_P(UsingDecl, hasAnyUsingShadowDecl, /// matched by the given matcher. /// /// Given +/// \code /// namespace X { int a; void b(); } /// using X::a; /// using X::b; +/// \endcode /// usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(function()))) /// matches \code using X::b \endcode /// but not \code using X::a \endcode AST_MATCHER_P(UsingShadowDecl, hasTargetDecl, - internal::Matcher, Matcher) { - return Matcher.matches(*Node.getTargetDecl(), Finder, Builder); + internal::Matcher, InnerMatcher) { + return InnerMatcher.matches(*Node.getTargetDecl(), Finder, Builder); } /// \brief Matches template instantiations of function, class, or static /// member variable template instantiations. /// /// Given +/// \code /// template class X {}; class A {}; X x; +/// \endcode /// or +/// \code /// template class X {}; class A {}; template class X; +/// \endcode /// record(hasName("::X"), isTemplateInstantiation()) /// matches the template instantiation of X. /// /// But given -/// template class X {}; class A {}; +/// \code +/// template class X {}; class A {}; /// template <> class X {}; X x; +/// \endcode /// record(hasName("::X"), isTemplateInstantiation()) /// does not match, as X is an explicit template specialization. /// @@ -1960,10 +2244,14 @@ isTemplateInstantiation() { /// static member variable template instantiations. /// /// Given +/// \code /// template void A(T t) { } /// template<> void A(int N) { } +/// \endcode /// function(isExplicitSpecialization()) /// matches the specialization A(). +/// +/// Usable as: Matcher, Matcher, Matcher inline internal::PolymorphicMatcherWithParam0< internal::IsExplicitTemplateSpecializationMatcher> isExplicitTemplateSpecialization() {