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