From 86f8bbced497389de5d35f0d6728ad9d846347b4 Mon Sep 17 00:00:00 2001 From: Manuel Klimek Date: Tue, 24 Jul 2012 13:37:29 +0000 Subject: [PATCH] Introduces a new concept for binding results to matchers as per Chandler's request: - introduces a new matcher base type BindableMatcher that provides the bind() call - makes all dynamic-cast matcher creation functions return BindableMatchers; the special case about dynamic-cast matchers is that the node they match on and the node their child matchers match on are the same node, just casted to a different type; thus, there is no ambiguity on what bind() matches on; additionally, those are the matchers that we name with nouns in the matcher language, so it's easy for users to intuitively know which matchers are bindable To make this change possible, we got rid of a non-orthogonal implementation of thisPointerType, which had an implicit dynamic-cast matcher from CallExpr to CXXMemberCallExpr; as alternative, we now provide a memberCall dynamic-cast matcher and thisPointerType is a predicate on CXXMemberCallExpr. Last, the ArgumentAdaptingMatcher is actually not required for the implementation of makeDynCastAllOfComposite - this simplification makes it more obvious where the bind() call can be used based on the matcher creation function types. llvm-svn: 160673 --- clang/include/clang/ASTMatchers/ASTMatchers.h | 18 +++-- .../clang/ASTMatchers/ASTMatchersInternal.h | 68 +++++++++++-------- .../unittests/ASTMatchers/ASTMatchersTest.cpp | 41 +++++------ 3 files changed, 74 insertions(+), 53 deletions(-) diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index d2ff604946fb..61571e5fa0b4 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -104,8 +104,8 @@ private: /// FIXME: Add example for accessing it. template internal::Matcher id(const std::string &ID, - const internal::Matcher &InnerMatcher) { - return internal::Matcher(new internal::IdMatcher(ID, InnerMatcher)); + const internal::BindableMatcher &InnerMatcher) { + return InnerMatcher.bind(ID); } /// \brief Types of matchers for the top-level classes in the AST class @@ -338,11 +338,19 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches call expressions. /// -/// Example matches x.y() +/// Example matches x.y() and y() /// X x; /// x.y(); +/// y(); const internal::VariadicDynCastAllOfMatcher call; +/// \brief Matches member call expressions. +/// +/// Example matches x.y() +/// X x; +/// x.y(); +const internal::VariadicDynCastAllOfMatcher memberCall; + /// \brief Matches init list expressions. /// /// Given @@ -1120,14 +1128,14 @@ AST_MATCHER_P(CXXMemberCallExpr, onImplicitObjectArgument, /// \brief Matches if the expression's type either matches the specified /// matcher, or is a pointer to a type that matches the InnerMatcher. -inline internal::Matcher thisPointerType( +inline internal::Matcher thisPointerType( const internal::Matcher &InnerMatcher) { return onImplicitObjectArgument( anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher)))); } /// \brief Overloaded to match the type's declaration. -inline internal::Matcher thisPointerType( +inline internal::Matcher thisPointerType( const internal::Matcher &InnerMatcher) { return onImplicitObjectArgument( anyOf(hasType(InnerMatcher), hasType(pointsTo(InnerMatcher)))); diff --git a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h index 4d044018a998..3f5568521c0e 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -440,20 +440,19 @@ public: BindKind Bind) = 0; }; -/// \brief Converts a Matcher to a matcher of desired type To by "adapting" -/// a To into a T. +/// \brief Converts a \c Matcher to a matcher of desired type \c To by +/// "adapting" a \c To into a \c T. /// -/// The ArgumentAdapterT argument specifies how the adaptation is done. +/// The \c ArgumentAdapterT argument specifies how the adaptation is done. /// /// For example: -/// ArgumentAdaptingMatcher(InnerMatcher); -/// returns a matcher that can be used where a Matcher is required, if -/// To and T are in the same type hierarchy, and thus dyn_cast can be -/// called to convert a To to a T. +/// \c ArgumentAdaptingMatcher(InnerMatcher); +/// Given that \c InnerMatcher is of type \c Matcher, this returns a matcher +/// that is convertible into any matcher of type \c To by constructing +/// \c HasMatcher(InnerMatcher). /// -/// FIXME: Make sure all our applications of this class actually require -/// knowledge about the inner type. DynCastMatcher obviously does, but the -/// Has *matchers require the inner type solely for COMPILE_ASSERT purposes. +/// If a matcher does not need knowledge about the inner type, prefer to use +/// PolymorphicMatcherWithParam1. template