r254083 - Stop using SFINAE to detect whether a derived-class override of Traverse* can
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 25 11:33:20 PST 2015
Author: rsmith
Date: Wed Nov 25 13:33:20 2015
New Revision: 254083
URL: http://llvm.org/viewvc/llvm-project?rev=254083&view=rev
Log:
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.
Modified:
cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=254083&r1=254082&r2=254083&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Wed Nov 25 13:33:20 2015
@@ -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)))
More information about the cfe-commits
mailing list