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))) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits