diff options
| author | Daniel Jasper <djasper@google.com> | 2012-09-20 09:24:58 +0000 |
|---|---|---|
| committer | Daniel Jasper <djasper@google.com> | 2012-09-20 09:24:58 +0000 |
| commit | d2247528f5e8dd92ec16b0d95e6f896f8cd9e12e (patch) | |
| tree | 4769c5f4aa6e306579aad0dfc78553dedd7ecb3a | |
| parent | 841c9a84d0a016f110b36b37cfa2debc8118acdf (diff) | |
| download | bcm5719-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.h | 32 |
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; |

