r256535 - Revert "[TrailingObjects] Use a different technique to determine if a getDecl"

James Y Knight via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 28 20:46:43 PST 2015


Author: jyknight
Date: Mon Dec 28 22:46:43 2015
New Revision: 256535

URL: http://llvm.org/viewvc/llvm-project?rev=256535&view=rev
Log:
Revert "[TrailingObjects] Use a different technique to determine if a getDecl"

This reverts commit r256534.

Failed to build on MSVC with error:
clang/ASTMatchers/ASTMatchersInternal.h(572): error C2228: left of '.getDecl' must have class/struct/union
        type is 'add_rvalue_reference<_Ty>::type'

(http://lab.llvm.org:8011/builders/lldb-x86-win7-msvc/builds/13873/steps/build/logs/stdio)

Modified:
    cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h?rev=256535&r1=256534&r2=256535&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h Mon Dec 28 22:46:43 2015
@@ -558,19 +558,22 @@ bool matchesFirstInPointerRange(const Ma
   return false;
 }
 
-/// Metafunction to determine if type T has a member called
-/// getDecl.
-///
-/// There is a default template inheriting from "false_type". Then, a
-/// partial specialization inherits from "true_type". However, this
-/// specialization will only exist when the call to getDecl() isn't an
-/// error -- it vanishes by SFINAE when the member doesn't exist.
-template <typename> struct type_sink_to_void { typedef void type; };
-template <typename T, typename = void> struct has_getDecl : std::false_type {};
-template <typename T>
-struct has_getDecl<
-    T, typename type_sink_to_void<decltype(std::declval<T>().getDecl())>::type>
-    : std::true_type {};
+/// \brief Metafunction to determine if type T has a member called getDecl.
+template <typename T> struct has_getDecl {
+  struct Default { int getDecl; };
+  struct Derived : T, Default { };
+
+  template<typename C, C> struct CheckT;
+
+  // If T::getDecl exists, an ambiguity arises and CheckT will
+  // not be instantiable. This makes f(...) the only available
+  // overload.
+  template<typename C>
+  static char (&f(CheckT<int Default::*, &C::getDecl>*))[1];
+  template<typename C> static char (&f(...))[2];
+
+  static bool const value = sizeof(f<Derived>(nullptr)) == 2;
+};
 
 /// \brief Matches overloaded operators with a specific name.
 ///




More information about the cfe-commits mailing list