summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Jasper <djasper@google.com>2012-09-20 09:24:58 +0000
committerDaniel Jasper <djasper@google.com>2012-09-20 09:24:58 +0000
commitd2247528f5e8dd92ec16b0d95e6f896f8cd9e12e (patch)
tree4769c5f4aa6e306579aad0dfc78553dedd7ecb3a
parent841c9a84d0a016f110b36b37cfa2debc8118acdf (diff)
downloadbcm5719-llvm-d2247528f5e8dd92ec16b0d95e6f896f8cd9e12e.tar.gz
bcm5719-llvm-d2247528f5e8dd92ec16b0d95e6f896f8cd9e12e.zip
Provide better error messages for incorrect matchers.
By changing the conversion operator into a conversion constructor, we can enabled based on the template parameters leading to better error messages. E.g.: stmt(decl()) will now create an error message including: note: candidate function not viable: no known conversion from 'clang::ast_matchers::internal::BindableMatcher<clang::Decl>' to 'const clang::ast_matchers::internal::Matcher<clang::Stmt>' for 1st argument llvm-svn: 164298
-rw-r--r--clang/include/clang/ASTMatchers/ASTMatchersInternal.h32
1 files changed, 17 insertions, 15 deletions
diff --git a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
index 38ffb2de757..41b56418dec 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -257,6 +257,16 @@ public:
explicit Matcher(MatcherInterface<T> *Implementation)
: Implementation(Implementation) {}
+ /// \brief Implicitly converts \c Other to a Matcher<T>.
+ ///
+ /// Requires \c T to be derived from \c From.
+ template <typename From>
+ Matcher(const Matcher<From> &Other,
+ typename llvm::enable_if_c<
+ llvm::is_base_of<From, T>::value &&
+ !llvm::is_same<From, T>::value >::type* = 0)
+ : Implementation(new ImplicitCastMatcher<From>(Other)) {}
+
/// \brief Forwards the call to the underlying MatcherInterface<T> pointer.
bool matches(const T &Node,
ASTMatchFinder *Finder,
@@ -264,14 +274,6 @@ public:
return Implementation->matches(Node, Finder, Builder);
}
- /// \brief Implicitly converts this object to a Matcher<Derived>.
- ///
- /// Requires Derived to be derived from T.
- template <typename Derived>
- operator Matcher<Derived>() const {
- return Matcher<Derived>(new ImplicitCastMatcher<Derived>(*this));
- }
-
/// \brief Returns an ID that uniquely identifies the matcher.
uint64_t getID() const {
/// FIXME: Document the requirements this imposes on matcher
@@ -289,22 +291,22 @@ public:
}
private:
- /// \brief Allows conversion from Matcher<T> to Matcher<Derived> if Derived
- /// is derived from T.
- template <typename Derived>
- class ImplicitCastMatcher : public MatcherInterface<Derived> {
+ /// \brief Allows conversion from Matcher<Base> to Matcher<T> if T
+ /// is derived from Base.
+ template <typename Base>
+ class ImplicitCastMatcher : public MatcherInterface<T> {
public:
- explicit ImplicitCastMatcher(const Matcher<T> &From)
+ explicit ImplicitCastMatcher(const Matcher<Base> &From)
: From(From) {}
- virtual bool matches(const Derived &Node,
+ virtual bool matches(const T &Node,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
return From.matches(Node, Finder, Builder);
}
private:
- const Matcher<T> From;
+ const Matcher<Base> From;
};
llvm::IntrusiveRefCntPtr< MatcherInterface<T> > Implementation;
OpenPOWER on IntegriCloud