diff options
-rw-r--r-- | include/clang/ASTMatchers/ASTMatchFinder.h | 141 | ||||
-rw-r--r-- | include/clang/ASTMatchers/ASTMatchers.h | 1403 | ||||
-rw-r--r-- | include/clang/ASTMatchers/ASTMatchersInternal.h | 888 | ||||
-rw-r--r-- | include/clang/ASTMatchers/ASTMatchersMacros.h | 224 | ||||
-rw-r--r-- | lib/ASTMatchers/ASTMatchFinder.cpp | 556 | ||||
-rw-r--r-- | lib/ASTMatchers/ASTMatchersInternal.cpp | 102 | ||||
-rw-r--r-- | lib/ASTMatchers/CMakeLists.txt | 7 | ||||
-rw-r--r-- | lib/ASTMatchers/Makefile | 15 | ||||
-rw-r--r-- | lib/CMakeLists.txt | 1 | ||||
-rwxr-xr-x | lib/Makefile | 2 | ||||
-rw-r--r-- | unittests/ASTMatchers/ASTMatchersTest.cpp | 1979 | ||||
-rw-r--r-- | unittests/ASTMatchers/ASTMatchersTest.h | 128 | ||||
-rw-r--r-- | unittests/ASTMatchers/CMakeLists.txt | 5 | ||||
-rw-r--r-- | unittests/ASTMatchers/Makefile | 19 | ||||
-rw-r--r-- | unittests/CMakeLists.txt | 1 | ||||
-rw-r--r-- | unittests/Makefile | 2 |
16 files changed, 5471 insertions, 2 deletions
diff --git a/include/clang/ASTMatchers/ASTMatchFinder.h b/include/clang/ASTMatchers/ASTMatchFinder.h new file mode 100644 index 0000000000..dd237eece3 --- /dev/null +++ b/include/clang/ASTMatchers/ASTMatchFinder.h @@ -0,0 +1,141 @@ +//===--- ASTMatchFinder.h - Structural query framework ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Provides a way to construct an ASTConsumer that runs given matchers +// over the AST and invokes a given callback on every match. +// +// The general idea is to construct a matcher expression that describes a +// subtree match on the AST. Next, a callback that is executed every time the +// expression matches is registered, and the matcher is run over the AST of +// some code. Matched subexpressions can be bound to string IDs and easily +// be accessed from the registered callback. The callback can than use the +// AST nodes that the subexpressions matched on to output information about +// the match or construct changes that can be applied to the code. +// +// Example: +// class HandleMatch : public MatchFinder::MatchCallback { +// public: +// virtual void Run(const MatchFinder::MatchResult &Result) { +// const CXXRecordDecl *Class = +// Result.Nodes.GetDeclAs<CXXRecordDecl>("id"); +// ... +// } +// }; +// +// int main(int argc, char **argv) { +// ClangTool Tool(argc, argv); +// MatchFinder finder; +// finder.AddMatcher(Id("id", record(hasName("::a_namespace::AClass"))), +// new HandleMatch); +// return Tool.Run(newFrontendActionFactory(&finder)); +// } +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_MATCHERS_AST_MATCH_FINDER_H +#define LLVM_CLANG_AST_MATCHERS_AST_MATCH_FINDER_H + +#include "clang/ASTMatchers/ASTMatchers.h" + +namespace clang { + +namespace ast_matchers { + +/// \brief A class to allow finding matches over the Clang AST. +/// +/// After creation, you can add multiple matchers to the MatchFinder via +/// calls to addMatcher(...). +/// +/// Once all matchers are added, newASTConsumer() returns an ASTConsumer +/// that will trigger the callbacks specified via addMatcher(...) when a match +/// is found. +/// +/// See ASTMatchers.h for more information about how to create matchers. +/// +/// Not intended to be subclassed. +class MatchFinder { +public: + /// \brief Contains all information for a given match. + /// + /// Every time a match is found, the MatchFinder will invoke the registered + /// MatchCallback with a MatchResult containing information about the match. + struct MatchResult { + MatchResult(const BoundNodes &Nodes, clang::ASTContext *Context); + + /// \brief Contains the nodes bound on the current match. + /// + /// This allows user code to easily extract matched AST nodes. + const BoundNodes Nodes; + + /// \brief Utilities for interpreting the matched AST structures. + /// @{ + clang::ASTContext * const Context; + clang::SourceManager * const SourceManager; + /// @} + }; + + /// \brief Called when the Match registered for it was successfully found + /// in the AST. + class MatchCallback { + public: + virtual ~MatchCallback(); + virtual void run(const MatchResult &Result) = 0; + }; + + /// \brief Called when parsing is finished. Intended for testing only. + class ParsingDoneTestCallback { + public: + virtual ~ParsingDoneTestCallback(); + virtual void run() = 0; + }; + + MatchFinder(); + ~MatchFinder(); + + /// \brief Adds a matcher to execute when running over the AST. + /// + /// Calls 'Action' with the BoundNodes on every match. + /// Adding more than one 'NodeMatch' allows finding different matches in a + /// single pass over the AST. + /// + /// Does not take ownership of 'Action'. + /// @{ + void addMatcher(const DeclarationMatcher &NodeMatch, + MatchCallback *Action); + void addMatcher(const TypeMatcher &NodeMatch, + MatchCallback *Action); + void addMatcher(const StatementMatcher &NodeMatch, + MatchCallback *Action); + /// @} + + /// \brief Creates a clang ASTConsumer that finds all matches. + clang::ASTConsumer *newASTConsumer(); + + /// \brief Registers a callback to notify the end of parsing. + /// + /// The provided closure is called after parsing is done, before the AST is + /// traversed. Useful for benchmarking. + /// Each call to FindAll(...) will call the closure once. + void registerTestCallbackAfterParsing(ParsingDoneTestCallback *ParsingDone); + +private: + /// \brief The MatchCallback*'s will be called every time the + /// UntypedBaseMatcher matches on the AST. + std::vector< std::pair< + const internal::UntypedBaseMatcher*, + MatchCallback*> > Triggers; + + /// \brief Called when parsing is done. + ParsingDoneTestCallback *ParsingDone; +}; + +} // end namespace ast_matchers +} // end namespace clang + +#endif // LLVM_CLANG_AST_MATCHERS_AST_MATCH_FINDER_H diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h new file mode 100644 index 0000000000..69e9c4b53d --- /dev/null +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -0,0 +1,1403 @@ +//===--- ASTMatchers.h - Structural query framework -------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements matchers to be used together with the MatchFinder to +// match AST nodes. +// +// Matchers are created by generator functions, which can be combined in +// a functional in-language DSL to express queries over the C++ AST. +// +// For example, to match a class with a certain name, one would call: +// record(hasName("MyClass")) +// which returns a matcher that can be used to find all AST nodes that declare +// a class named 'MyClass'. +// +// For more complicated match expressions we're often interested in accessing +// multiple parts of the matched AST nodes once a match is found. In that case, +// use the id(...) matcher around the match expressions that match the nodes +// you want to access. +// +// For example, when we're interested in child classes of a certain class, we +// would write: +// record(hasName("MyClass"), hasChild(id("child", record()))) +// When the match is found via the MatchFinder, a user provided callback will +// be called with a BoundNodes instance that contains a mapping from the +// strings that we provided for the id(...) calls to the nodes that were +// matched. +// In the given example, each time our matcher finds a match we get a callback +// where "child" is bound to the CXXRecordDecl node of the matching child +// class declaration. +// +// See ASTMatchersInternal.h for a more in-depth explanation of the +// implementation details of the matcher framework. +// +// See ASTMatchFinder.h for how to use the generated matchers to run over +// an AST. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_H +#define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_H + +#include "clang/ASTMatchers/ASTMatchersInternal.h" +#include "clang/ASTMatchers/ASTMatchersMacros.h" +#include "llvm/ADT/Twine.h" + +namespace clang { +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 instances of BoundNodes are created by 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 + /// it cannot be converted to the specified type. + /// FIXME: We'll need one of those for every base type. + /// @{ + template <typename T> + const T *getDeclAs(StringRef ID) const { + return getNodeAs<T>(DeclBindings, ID); + } + template <typename T> + const T *getStmtAs(StringRef ID) const { + return getNodeAs<T>(StmtBindings, ID); + } + /// @} + +private: + /// \brief Create BoundNodes from a pre-filled map of bindings. + BoundNodes(const std::map<std::string, const clang::Decl*> &DeclBindings, + const std::map<std::string, const clang::Stmt*> &StmtBindings) + : DeclBindings(DeclBindings), StmtBindings(StmtBindings) {} + + template <typename T, typename MapT> + const T *getNodeAs(const MapT &Bindings, StringRef ID) const { + typename MapT::const_iterator It = Bindings.find(ID); + if (It == Bindings.end()) { + return NULL; + } + return llvm::dyn_cast<T>(It->second); + } + + std::map<std::string, const clang::Decl*> DeclBindings; + std::map<std::string, const clang::Stmt*> StmtBindings; + + friend class internal::BoundNodesTree; +}; + +/// \brief If the provided matcher matches a node, binds the node to 'ID'. +/// +/// FIXME: Add example for accessing it. +template <typename T> +internal::Matcher<T> id(const std::string &ID, + const internal::Matcher<T> &InnerMatcher) { + return internal::Matcher<T>(new internal::IdMatcher<T>(ID, InnerMatcher)); +} + +/// \brief Types of matchers for the top-level classes in the AST class +/// hierarchy. +/// @{ +typedef internal::Matcher<clang::Decl> DeclarationMatcher; +typedef internal::Matcher<clang::QualType> TypeMatcher; +typedef internal::Matcher<clang::Stmt> StatementMatcher; +/// @} + +/// \brief 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 +/// to a internal::Matcher<> type such as TypeMatcher. +/// +/// Example: DeclarationMatcher(anything()) matches all declarations, e.g., +/// "int* p" and "void f()" in +/// int* p; +/// void f(); +inline internal::PolymorphicMatcherWithParam0<internal::TrueMatcher> anything() { + return internal::PolymorphicMatcherWithParam0<internal::TrueMatcher>(); +} + +/// \brief Matches a declaration of anything that could have a name. +/// +/// Example matches X, S, the anonymous union type, i, and U; +/// typedef int X; +/// struct S { +/// union { +/// int i; +/// } U; +/// }; +const internal::VariadicDynCastAllOfMatcher< + clang::Decl, + clang::NamedDecl> nameableDeclaration; + +/// \brief Matches C++ class declarations. +/// +/// Example matches X, Z +/// class X; +/// template<class T> class Z {}; +const internal::VariadicDynCastAllOfMatcher< + clang::Decl, + clang::CXXRecordDecl> record; + +/// \brief Matches C++ constructor declarations. +/// +/// Example matches Foo::Foo() and Foo::Foo(int) +/// class Foo { +/// public: +/// Foo(); +/// Foo(int); +/// int DoSomething(); +/// }; +const internal::VariadicDynCastAllOfMatcher< + clang::Decl, + clang::CXXConstructorDecl> constructor; + +/// \brief Matches method declarations. +/// +/// Example matches y +/// class X { void y() }; +const internal::VariadicDynCastAllOfMatcher< + clang::Decl, + clang::CXXMethodDecl> method; + +/// \brief Matches variable declarations. +/// +/// Note: this does not match declarations of member variables, which are +/// "field" declarations in Clang parlance. +/// +/// Example matches a +/// int a; +const internal::VariadicDynCastAllOfMatcher< + clang::Decl, + clang::VarDecl> variable; + +/// \brief Matches field declarations. +/// +/// Given +/// class X { int m; }; +/// field() +/// matches 'm'. +const internal::VariadicDynCastAllOfMatcher< + clang::Decl, + clang::FieldDecl> field; + +/// \brief Matches function declarations. +/// +/// Example matches f +/// void f(); +const internal::VariadicDynCastAllOfMatcher< + clang::Decl, + clang::FunctionDecl> function; + + +/// \brief Matches statements. +/// +/// Given +/// { ++a; } +/// statement() +/// matches both the compound statement '{ ++a; }' and '++a'. +const internal::VariadicDynCastAllOfMatcher<clang::Stmt, clang::Stmt> statement; + +/// \brief Matches declaration statements. +/// +/// Given +/// int a; +/// declarationStatement() +/// matches 'int a'. +const internal::VariadicDynCastAllOfMatcher< + clang::Stmt, + clang::DeclStmt> declarationStatement; + +/// \brief Matches member expressions. +/// +/// Given +/// class Y { +/// void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; } +/// int a; static int b; +/// }; +/// memberExpression() +/// matches this->x, x, y.x, a, this->b +const internal::VariadicDynCastAllOfMatcher< + clang::Stmt, + clang::MemberExpr> memberExpression; + +/// \brief Matches call expressions. +/// +/// Example matches x.y() +/// X x; +/// x.y(); +const internal::VariadicDynCastAllOfMatcher<clang::Stmt, clang::CallExpr> call; + +/// \brief Matches constructor call expressions (including implicit ones). +/// +/// Example matches string(ptr, n) and ptr within arguments of f +/// (matcher = constructorCall()) +/// void f(const string &a, const string &b); +/// char *ptr; +/// int n; +/// f(string(ptr, n), ptr); +const internal::VariadicDynCastAllOfMatcher< + clang::Stmt, + clang::CXXConstructExpr> constructorCall; + +/// \brief Matches nodes where temporaries are created. +/// +/// Example matches FunctionTakesString(GetStringByValue()) +/// (matcher = bindTemporaryExpr()) +/// FunctionTakesString(GetStringByValue()); +/// FunctionTakesStringByPointer(GetStringPointer()); +const internal::VariadicDynCastAllOfMatcher< + clang::Stmt, + clang::CXXBindTemporaryExpr> bindTemporaryExpression; + +/// \brief Matches new expressions. +/// +/// Given +/// new X; +/// newExpression() +/// matches 'new X'. +const internal::VariadicDynCastAllOfMatcher< + clang::Stmt, + clang::CXXNewExpr> newExpression; + +/// \brief 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) +/// (matcher = defaultArgument()) +/// void f(int x, int y = 0); +/// f(42); +const internal::VariadicDynCastAllOfMatcher< + clang::Stmt, + clang::CXXDefaultArgExpr> defaultArgument; + +/// \brief Matches overloaded operator calls. +/// +/// Note that if an operator isn't overloaded, it won't match. Instead, use +/// binaryOperator matcher. +/// Currently it does not match operators such as new delete. +/// FIXME: figure out why these do not match? +/// +/// Example matches both operator<<((o << b), c) and operator<<(o, b) +/// (matcher = overloadedOperatorCall()) +/// ostream &operator<< (ostream &out, int i) { }; +/// ostream &o; int b = 1, c = 1; +/// o << b << c; +const internal::VariadicDynCastAllOfMatcher< + clang::Stmt, + clang::CXXOperatorCallExpr> overloadedOperatorCall; + +/// \brief Matches expressions. +/// +/// Example matches x() +/// void f() { x(); } +const internal::VariadicDynCastAllOfMatcher< + clang::Stmt, + clang::Expr> expression; + +/// \brief Matches expressions that refer to declarations. +/// +/// Example matches x in if (x) +/// bool x; +/// if (x) {} +const internal::VariadicDynCastAllOfMatcher< + clang::Stmt, + clang::DeclRefExpr> declarationReference; + +/// \brief Matches if statements. +/// +/// Example matches 'if (x) {}' +/// if (x) {} +const internal::VariadicDynCastAllOfMatcher<clang::Stmt, clang::IfStmt> ifStmt; + +/// \brief Matches for statements. +/// +/// Example matches 'for (;;) {}' +/// for (;;) {} +const internal::VariadicDynCastAllOfMatcher< + clang::Stmt, clang::ForStmt> forStmt; + +/// \brief Matches while statements. +/// +/// Given +/// while (true) {} +/// whileStmt() +/// matches 'while (true) {}'. +const internal::VariadicDynCastAllOfMatcher< + clang::Stmt, + clang::WhileStmt> whileStmt; + +/// \brief Matches do statements. +/// +/// Given +/// do {} while (true); +/// doStmt() +/// matches 'do {} while(true)' +const internal::VariadicDynCastAllOfMatcher<clang::Stmt, clang::DoStmt> doStmt; + +/// \brief Matches case and default statements inside switch statements. +/// +/// Given +/// switch(a) { case 42: break; default: break; } +/// switchCase() +/// matches 'case 42: break;' and 'default: break;'. +const internal::VariadicDynCastAllOfMatcher< + clang::Stmt, + clang::SwitchCase> switchCase; + +/// \brief Matches compound statements. +/// +/// Example matches '{}' and '{{}}'in 'for (;;) {{}}' +/// for (;;) {{}} +const internal::VariadicDynCastAllOfMatcher< + clang::Stmt, + clang::CompoundStmt> compoundStatement; + +/// \brief Matches bool literals. +/// +/// Example matches true +/// true +const internal::VariadicDynCastAllOfMatcher< + clang::Expr, + clang::CXXBoolLiteralExpr> boolLiteral; + +/// \brief Matches string literals (also matches wide string literals). +/// +/// Example matches "abcd", L"abcd" +/// char *s = "abcd"; wchar_t *ws = L"abcd" +const internal::VariadicDynCastAllOfMatcher< + clang::Expr, + clang::StringLiteral> stringLiteral; + +/// \brief Matches character literals (also matches wchar_t). +/// +/// Not matching Hex-encoded chars (e.g. 0x1234, which is a IntegerLiteral), +/// though. +/// +/// Example matches 'a', L'a' +/// char ch = 'a'; wchar_t chw = L'a'; +const internal::VariadicDynCastAllOfMatcher< + clang::Expr, + clang::CharacterLiteral> characterLiteral; + +/// \brief Matches integer literals of all sizes / encodings. +/// +/// Not matching character-encoded integers such as L'a'. +/// +/// Example matches 1, 1L, 0x1, 1U +const internal::VariadicDynCastAllOfMatcher< + clang::Expr, + clang::IntegerLiteral> integerLiteral; + +/// \brief Matches binary operator expressions. +/// +/// Example matches a || b +/// !(a || b) +const internal::VariadicDynCastAllOfMatcher< + clang::Stmt, + clang::BinaryOperator> binaryOperator; + +/// \brief Matches unary operator expressions. +/// +/// Example matches !a +/// !a || b +const internal::VariadicDynCastAllOfMatcher< + clang::Stmt, + clang::UnaryOperator> unaryOperator; + +/// \brief Matches conditional operator expressions. +/// +/// Example matches a ? b : c +/// (a ? b : c) + 42 +const internal::VariadicDynCastAllOfMatcher< + clang::Stmt, + clang::ConditionalOperator> conditionalOperator; + +/// \brief 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 +/// more readable. +/// +/// Example matches reinterpret_cast<char*>(&p) in +/// void* p = reinterpret_cast<char*>(&p); +const internal::VariadicDynCastAllOfMatcher< + clang::Expr, + clang::CXXReinterpretCastExpr> reinterpretCast; + +/// \brief Matches a C++ static_cast expression. +/// +/// \see hasDestinationType +/// \see reinterpretCast +/// +/// Example: +/// staticCast() +/// matches +/// static_cast<long>(8) +/// in +/// long eight(static_cast<long>(8)); +const internal::VariadicDynCastAllOfMatcher< + clang::Expr, + clang::CXXStaticCastExpr> staticCast; + +/// \brief Matches a dynamic_cast expression. +/// +/// Example: +/// dynamicCast() +/// matches +/// dynamic_cast<D*>(&b); +/// in +/// struct B { virtual ~B() {} }; struct D : B {}; +/// B b; +/// D* p = dynamic_cast<D*>(&b); +const internal::VariadicDynCastAllOfMatcher< + clang::Expr, + clang::CXXDynamicCastExpr> dynamicCast; + +/// \brief Matches a const_cast expression. +/// +/// Example: Matches const_cast<int*>(&r) in +/// int n = 42; +/// const int& r(n); +/// int* p = const_cast<int*>(&r); +const internal::VariadicDynCastAllOfMatcher< + clang::Expr, + clang::CXXConstCastExpr> constCast; + +/// \brief 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. +/// +/// Does not match implicit conversions. +/// +/// Note: the name "explicitCast" is chosen to match Clang's terminology, as +/// Clang uses the term "cast" to apply to implicit conversions as well as to +/// actual cast expressions. +/// +/// \see hasDestinationType. +/// +/// Example: matches all five of the casts in +/// int((int)(reinterpret_cast<int>(static_cast<int>(const_cast<int>(42))))) +/// but does not match the implicit conversion in +/// long ell = 42; +const internal::VariadicDynCastAllOfMatcher< + clang::Expr, + clang::ExplicitCastExpr> explicitCast; + +/// \brief 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. +const internal::VariadicDynCastAllOfMatcher< + clang::Expr, + clang::ImplicitCastExpr> implicitCast; + +/// \brief Matches functional cast expressions +/// +/// Example: Matches Foo(bar); +/// Foo f = bar; +/// Foo g = (Foo) bar; +/// Foo h = Foo(bar); +const internal::VariadicDynCastAllOfMatcher< + clang::Expr, + clang::CXXFunctionalCastExpr> functionalCast; + +/// \brief Various overloads for the anyOf matcher. +/// @{ +template<typename C1, typename C2> +internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C1, C2> +anyOf(const C1 &P1, const C2 &P2) { + return internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, + C1, C2 >(P1, P2); +} +template<typename C1, typename C2, typename C3> +internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C1, + internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C2, C3> > +anyOf(const C1 &P1, const C2 &P2, const C3 &P3) { + return anyOf(P1, anyOf(P2, P3)); +} +template<typename C1, typename C2, typename C3, typename C4> +internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C1, + internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C2, + internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, + C3, C4> > > +anyOf(const C1 &P1, const C2 &P2, const C3 &P3, const C4 &P4) { + return AnyOf(P1, AnyOf(P2, AnyOf(P3, P4))); +} +template<typename C1, typename C2, typename C3, typename C4, typename C5> +internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C1, + internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C2, + internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C3, + internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, + C4, C5> > > > +anyOf(const C1& P1, const C2& P2, const C3& P3, const C4& P4, const C5& P5) { + return anyOf(P1, anyOf(P2, anyOf(P3, anyOf(P4, P5)))); +} +/// @} + +/// \brief Various overloads for the allOf matcher. +/// @{ +template<typename C1, typename C2> +internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, C1, C2> +allOf(const C1 &P1, const C2 &P2) { + return internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, + C1, C2>(P1, P2); +} +template<typename C1, typename C2, typename C3> +internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, C1, + internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, C2, C3> > +allOf(const C1& P1, const C2& P2, const C3& P3) { + return AllOf(P1, AllOf(P2, P3)); +} +/// @} + +/// \brief Matches NamedDecl nodes that have the specified name. +/// +/// Supports specifying enclosing namespaces or classes by prefixing the name +/// with '<enclosing>::'. +/// Does not match typedefs of an underlying type with the given name. +/// +/// Example matches X (Name == "X") +/// class X; +/// +/// Example matches X (Name is one of "::a::b::X", "a::b::X", "b::X", "X") +/// namespace a { namespace b { class X; } } +AST_MATCHER_P(clang::NamedDecl, hasName, std::string, Name) { + assert(!Name.empty()); + const std::string FullNameString = "::" + Node.getQualifiedNameAsString(); + const llvm::StringRef FullName = FullNameString; + const llvm::StringRef Pattern = Name; + if (Pattern.startswith("::")) { + return FullName == Pattern; + } else { + return FullName.endswith(("::" + Pattern).str()); + } +} + +/// \brief Matches overloaded operator names. +/// +/// Matches overloaded operator names specified in strings without the +/// "operator" prefix, such as "<<", for OverloadedOperatorCall's. +/// +/// Example matches a << b +/// (matcher == overloadedOperatorCall(hasOverloadedOperatorName("<<"))) +/// a << b; +/// c && d; // assuming both operator<< +/// // and operator&& are overloaded somewhere. +AST_MATCHER_P(clang::CXXOperatorCallExpr, + hasOverloadedOperatorName, std::string, Name) { + return clang::getOperatorSpelling(Node.getOperator()) == Name; +} + +/// \brief Matches C++ classes that are directly or indirectly derived from +/// the given base class. +/// +/// Note that a class is considered to be also derived from itself. +/// The parameter specified the name of the base type (either a class or a +/// typedef), and does not allow structural matches for namespaces or template +/// type parameters. +/// +/// Example matches X, Y, Z, C (Base == "X") +/// 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 +/// +/// In the following example, Bar matches isDerivedFrom("X"): +/// class Foo; +/// typedef Foo X; +/// class Bar : public Foo {}; // derived from a type that X is a typedef of +AST_MATCHER_P(clang::CXXRecordDecl, isDerivedFrom, std::string, Base) { + assert(!Base.empty()); + return Finder->classIsDerivedFrom(&Node, Base); +} + +/// \brief Matches AST nodes that have child AST nodes that match the +/// provided matcher. +/// +/// Example matches X, Y (matcher = record(has(record(hasName("X"))) +/// 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. +/// +/// ChildT must be an AST base type. +template <typename ChildT> +internal::ArgumentAdaptingMatcher<internal::HasMatcher, ChildT> has( + const internal::Matcher<ChildT> &ChildMatcher) { + return internal::ArgumentAdaptingMatcher<internal::HasMatcher, + ChildT>(ChildMatcher); +} + +/// \brief Matches AST nodes that have descendant AST nodes that match the +/// provided matcher. +/// +/// Example matches X, Y, Z +/// (matcher = record(hasDescendant(record(hasName("X"))))) +/// 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 {}; }; }; +/// +/// DescendantT must be an AST base type. +template <typename DescendantT> +internal::ArgumentAdaptingMatcher<internal::HasDescendantMatcher, DescendantT> +hasDescendant(const internal::Matcher<DescendantT> &DescendantMatcher) { + return internal::ArgumentAdaptingMatcher< + internal::HasDescendantMatcher, + DescendantT>(DescendantMatcher); +} + + +/// \brief Matches AST nodes that have child AST nodes that match the +/// provided matcher. +/// +/// Example matches X, Y (matcher = record(forEach(record(hasName("X"))) +/// 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. +/// +/// 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. +template <typename ChildT> +internal::ArgumentAdaptingMatcher<internal::ForEachMatcher, ChildT> forEach( + const internal::Matcher<ChildT>& ChildMatcher) { + return internal::ArgumentAdaptingMatcher< + internal::ForEachMatcher, + ChildT>(ChildMatcher); +} + +/// \brief Matches AST nodes that have descendant AST nodes that match the +/// provided matcher. +/// +/// Example matches X, A, B, C +/// (matcher = record(forEachDescendant(record(hasName("X"))))) +/// 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 {}; }; }; +/// +/// DescendantT must be an AST base type. +/// +/// As opposed to 'hasDescendant', 'forEachDescendant' will cause a match for +/// each result that matches instead of only on the first one. +/// +/// Note: Recursively combined ForEachDescendant can cause many matches: +/// record(forEachDescendant(record(forEachDescendant(record())))) +/// will match 10 times (plus injected class name matches) on: +/// class A { class B { class C { class D { class E {}; }; }; }; }; +template <typename DescendantT> +internal::ArgumentAdaptingMatcher<internal::ForEachDescendantMatcher, DescendantT> +forEachDescendant( + const internal::Matcher<DescendantT>& DescendantMatcher) { + return internal::ArgumentAdaptingMatcher< + internal::ForEachDescendantMatcher, + DescendantT>(DescendantMatcher); +} + +/// \brief Matches if the provided matcher does not match. +/// +/// Example matches Y (matcher = record(unless(hasName("X")))) +/// class X {}; +/// class Y {}; +template <typename M> +internal::PolymorphicMatcherWithParam1<internal::NotMatcher, M> unless(const M &InnerMatcher) { + return internal::PolymorphicMatcherWithParam1< + internal::NotMatcher, M>(InnerMatcher); +} + +/// \brief Matches a type if the declaration of the type matches the given +/// matcher. +inline internal::PolymorphicMatcherWithParam1< internal::HasDeclarationMatcher, + internal::Matcher<clang::Decl> > + hasDeclaration(const internal::Matcher<clang::Decl> &InnerMatcher) { + return internal::PolymorphicMatcherWithParam1< + internal::HasDeclarationMatcher, + internal::Matcher<clang::Decl> >(InnerMatcher); +} + +/// \brief Matches on the implicit object argument of a member call expression. +/// +/// Example matches y.x() (matcher = call(on(hasType(record(hasName("Y")))))) +/// class Y { public: void x(); }; +/// void z() { Y y; y.x(); }", +/// +/// FIXME: Overload to allow directly matching types? +AST_MATCHER_P(clang::CXXMemberCallExpr, on, internal::Matcher<clang::Expr>, + InnerMatcher) { + const clang::Expr *ExprNode = const_cast<clang::CXXMemberCallExpr&>(Node) + .getImplicitObjectArgument() + ->IgnoreParenImpCasts(); + return (ExprNode != NULL && + InnerMatcher.matches(*ExprNode, Finder, Builder)); +} + +/// \brief Matches if the call expression's callee expression matches. +/// +/// Given +/// class Y { void x() { this->x(); x(); Y y; y.x(); } }; +/// void f() { f(); } +/// call(callee(expression())) +/// matches this->x(), x(), y.x(), f() +/// with callee(...) +/// matching this->x, x, y.x, f respectively +/// +/// Note: Callee cannot take the more general internal::Matcher<clang::Expr> +/// because this introduces ambiguous overloads with calls to Callee taking a +/// internal::Matcher<clang::Decl>, as the matcher hierarchy is purely +/// implemented in terms of implicit casts. +AST_MATCHER_P(cl |