diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-11-25 19:33:20 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-11-25 19:33:20 +0000 |
commit | 3275813d3590f9c45fbb55dd38719e2dc78da4ea (patch) | |
tree | 0df7425beb31dcb11a8f1175d788ff15224a7cf5 | |
parent | f1f46b5766d72eace16bc0bd6a91ab6e14f19f53 (diff) | |
download | bcm5719-llvm-3275813d3590f9c45fbb55dd38719e2dc78da4ea.tar.gz bcm5719-llvm-3275813d3590f9c45fbb55dd38719e2dc78da4ea.zip |
Stop using SFINAE to detect whether a derived-class override of Traverse* can
take a queue; some supported versions of GCC believe that this substitution
failure is an error. Instead, use a partial specialization to detect the type
of a pointer to the corresponding member. This is less general, but good enough
for our uses.
llvm-svn: 254083
-rw-r--r-- | clang/include/clang/AST/RecursiveASTVisitor.h | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 3c5a343e8d6..d94930f25b5 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -276,14 +276,11 @@ public: // ---- Methods on Stmts ---- private: - // Determine if the specified derived-class member M can be passed a - // DataRecursionQueue* argument. - template<typename P> - std::false_type callableWithQueue(...); - template<typename P, typename M> - std::true_type callableWithQueue(M m, Derived *d = nullptr, P *p = nullptr, - DataRecursionQueue *q = nullptr, - decltype((d->*m)(p, q)) = false); + template<typename T, typename U> + struct has_same_member_pointer_type : std::false_type {}; + template<typename T, typename U, typename R, typename... P> + struct has_same_member_pointer_type<R (T::*)(P...), R (U::*)(P...)> + : std::true_type {}; // Traverse the given statement. If the most-derived traverse function takes a // data recursion queue, pass it on; otherwise, discard it. Note that the @@ -291,10 +288,13 @@ private: // class can take a queue, so if we're taking the second arm, make the first // arm call our function rather than the derived class version. #define TRAVERSE_STMT_BASE(NAME, CLASS, VAR, QUEUE) \ - (decltype(callableWithQueue<CLASS>(&Derived::Traverse##NAME))::value \ + (has_same_member_pointer_type<decltype( \ + &RecursiveASTVisitor::Traverse##NAME), \ + decltype(&Derived::Traverse##NAME)>::value \ ? static_cast<typename std::conditional< \ - decltype( \ - callableWithQueue<CLASS>(&Derived::Traverse##NAME))::value, \ + has_same_member_pointer_type< \ + decltype(&RecursiveASTVisitor::Traverse##NAME), \ + decltype(&Derived::Traverse##NAME)>::value, \ Derived &, RecursiveASTVisitor &>::type>(*this) \ .Traverse##NAME(static_cast<CLASS *>(VAR), QUEUE) \ : getDerived().Traverse##NAME(static_cast<CLASS *>(VAR))) |