From: James Y Knight Date: Tue, 29 Dec 2015 04:34:11 +0000 (+0000) Subject: [TrailingObjects] Use a different technique to determine if a getDecl X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=31781479cbe627d89b4006752aa2c77ce2dddd87;p=clang [TrailingObjects] Use a different technique to determine if a getDecl member function exists on a class. The previous trick depended on inheriting from the class it was checking, which will fail when I start marking things 'final'. Hopefully this actually builds with all supported compilers... git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@256534 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h index 22068b48e7..816dc435a4 100644 --- a/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -558,22 +558,19 @@ bool matchesFirstInPointerRange(const MatcherT &Matcher, IteratorT Start, return false; } -/// \brief Metafunction to determine if type T has a member called getDecl. -template struct has_getDecl { - struct Default { int getDecl; }; - struct Derived : T, Default { }; - - template struct CheckT; - - // If T::getDecl exists, an ambiguity arises and CheckT will - // not be instantiable. This makes f(...) the only available - // overload. - template - static char (&f(CheckT*))[1]; - template static char (&f(...))[2]; - - static bool const value = sizeof(f(nullptr)) == 2; -}; +/// 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 struct type_sink_to_void { typedef void type; }; +template struct has_getDecl : std::false_type {}; +template +struct has_getDecl< + T, typename type_sink_to_void().getDecl())>::type> + : std::true_type {}; /// \brief Matches overloaded operators with a specific name. ///