// ---- 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
// 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)))