[libcxx] Fix detection of __is_final.

Summary: Currently we only enable the use of __is_final(...) with Clang. GCC also provides __is_final(...) since 4.7 in all standard modes. This patch creates the macro _LIBCPP_HAS_IS_FINAL to note the availability of `__is_final`.

Reviewers: danalbert, mclow.lists

Reviewed By: mclow.lists

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D8795

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@239664 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eric Fiselier 2015-06-13 07:08:02 +00:00
parent 6d7a2cb57d
commit 3a0e430cd4
8 changed files with 42 additions and 49 deletions

View File

@ -77,10 +77,8 @@
#ifdef _WIN32 #ifdef _WIN32
# define _LIBCPP_LITTLE_ENDIAN 1 # define _LIBCPP_LITTLE_ENDIAN 1
# define _LIBCPP_BIG_ENDIAN 0 # define _LIBCPP_BIG_ENDIAN 0
// Compiler intrinsics (GCC or MSVC) // Compiler intrinsics (MSVC)
# if defined(__clang__) \ #if defined(_MSC_VER) && _MSC_VER >= 1400
|| (defined(_MSC_VER) && _MSC_VER >= 1400) \
|| (defined(__GNUC__) && _GNUC_VER > 403)
# define _LIBCPP_HAS_IS_BASE_OF # define _LIBCPP_HAS_IS_BASE_OF
# endif # endif
# if defined(_MSC_VER) && !defined(__clang__) # if defined(_MSC_VER) && !defined(__clang__)
@ -95,12 +93,6 @@
# endif # endif
#endif // _WIN32 #endif // _WIN32
#ifdef __linux__
# if defined(__GNUC__) && _GNUC_VER >= 403
# define _LIBCPP_HAS_IS_BASE_OF
# endif
#endif
#ifdef __sun__ #ifdef __sun__
# include <sys/isa_defs.h> # include <sys/isa_defs.h>
# ifdef _LITTLE_ENDIAN # ifdef _LITTLE_ENDIAN
@ -320,6 +312,10 @@ typedef __char32_t char32_t;
# define _LIBCPP_HAS_IS_BASE_OF # define _LIBCPP_HAS_IS_BASE_OF
#endif #endif
#if __has_feature(is_final)
# define _LIBCPP_HAS_IS_FINAL
#endif
// Objective-C++ features (opt-in) // Objective-C++ features (opt-in)
#if __has_feature(objc_arc) #if __has_feature(objc_arc)
#define _LIBCPP_HAS_OBJC_ARC #define _LIBCPP_HAS_OBJC_ARC
@ -403,6 +399,11 @@ namespace std {
#if _GNUC_VER >= 407 #if _GNUC_VER >= 407
#define _LIBCPP_UNDERLYING_TYPE(T) __underlying_type(T) #define _LIBCPP_UNDERLYING_TYPE(T) __underlying_type(T)
#define _LIBCPP_IS_LITERAL(T) __is_literal_type(T) #define _LIBCPP_IS_LITERAL(T) __is_literal_type(T)
#define _LIBCPP_HAS_IS_FINAL
#endif
#if defined(__GNUC__) && _GNUC_VER >= 403
# define _LIBCPP_HAS_IS_BASE_OF
#endif #endif
#if !__EXCEPTIONS #if !__EXCEPTIONS
@ -537,6 +538,7 @@ namespace std {
#define _LIBCPP_HAS_NO_NULLPTR #define _LIBCPP_HAS_NO_NULLPTR
#define _LIBCPP_HAS_NO_UNICODE_CHARS #define _LIBCPP_HAS_NO_UNICODE_CHARS
#define _LIBCPP_HAS_IS_BASE_OF #define _LIBCPP_HAS_IS_BASE_OF
#define _LIBCPP_HAS_IS_FINAL
#define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES #define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES
#if defined(_AIX) #if defined(_AIX)

View File

@ -195,9 +195,7 @@ void
throw_with_nested(_Tp&& __t, typename enable_if< throw_with_nested(_Tp&& __t, typename enable_if<
is_class<typename remove_reference<_Tp>::type>::value && is_class<typename remove_reference<_Tp>::type>::value &&
!is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value !is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value
#if _LIBCPP_STD_VER > 11 && __has_feature(is_final) && !__libcpp_is_final<typename remove_reference<_Tp>::type>::value
&& !is_final<typename remove_reference<_Tp>::type>::value
#endif
>::type* = 0) >::type* = 0)
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
throw_with_nested (_Tp& __t, typename enable_if< throw_with_nested (_Tp& __t, typename enable_if<
@ -217,9 +215,7 @@ void
throw_with_nested(_Tp&& __t, typename enable_if< throw_with_nested(_Tp&& __t, typename enable_if<
!is_class<typename remove_reference<_Tp>::type>::value || !is_class<typename remove_reference<_Tp>::type>::value ||
is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value
#if _LIBCPP_STD_VER > 11 && __has_feature(is_final) || __libcpp_is_final<typename remove_reference<_Tp>::type>::value
|| is_final<typename remove_reference<_Tp>::type>::value
#endif
>::type* = 0) >::type* = 0)
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
throw_with_nested (_Tp& __t, typename enable_if< throw_with_nested (_Tp& __t, typename enable_if<

View File

@ -203,6 +203,7 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
#include <__hash_table> #include <__hash_table>
#include <functional> #include <functional>
#include <stdexcept> #include <stdexcept>
#include <type_traits>
#include <ext/__hash> #include <ext/__hash>
#if __DEPRECATED #if __DEPRECATED
@ -213,16 +214,16 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
#endif #endif
#endif #endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header #pragma GCC system_header
#endif
namespace __gnu_cxx { namespace __gnu_cxx {
using namespace std; using namespace std;
template <class _Tp, class _Hash, bool = is_empty<_Hash>::value template <class _Tp, class _Hash,
#if __has_feature(is_final) bool = is_empty<_Hash>::value && !__libcpp_is_final<_Hash>::value
&& !__is_final(_Hash)
#endif
> >
class __hash_map_hasher class __hash_map_hasher
: private _Hash : private _Hash
@ -255,10 +256,8 @@ public:
{return __hash_(__x);} {return __hash_(__x);}
}; };
template <class _Tp, class _Pred, bool = is_empty<_Pred>::value template <class _Tp, class _Pred,
#if __has_feature(is_final) bool = is_empty<_Pred>::value && !__libcpp_is_final<_Pred>::value
&& !__is_final(_Pred)
#endif
> >
class __hash_map_equal class __hash_map_equal
: private _Pred : private _Pred

View File

@ -428,6 +428,7 @@ swap(multimap<Key, T, Compare, Allocator>& x,
#include <utility> #include <utility>
#include <functional> #include <functional>
#include <initializer_list> #include <initializer_list>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header #pragma GCC system_header
@ -435,10 +436,8 @@ swap(multimap<Key, T, Compare, Allocator>& x,
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Key, class _CP, class _Compare, bool = is_empty<_Compare>::value template <class _Key, class _CP, class _Compare,
#if __has_feature(is_final) bool = is_empty<_Compare>::value && !__libcpp_is_final<_Compare>::value
&& !__is_final(_Compare)
#endif
> >
class __map_value_compare class __map_value_compare
: private _Compare : private _Compare

View File

@ -1982,14 +1982,9 @@ public:
template <class _T1, class _T2, bool = is_same<typename remove_cv<_T1>::type, template <class _T1, class _T2, bool = is_same<typename remove_cv<_T1>::type,
typename remove_cv<_T2>::type>::value, typename remove_cv<_T2>::type>::value,
bool = is_empty<_T1>::value bool = is_empty<_T1>::value
#if __has_feature(is_final) && !__libcpp_is_final<_T1>::value,
&& !__is_final(_T1)
#endif
,
bool = is_empty<_T2>::value bool = is_empty<_T2>::value
#if __has_feature(is_final) && !__libcpp_is_final<_T2>::value
&& !__is_final(_T2)
#endif
> >
struct __libcpp_compressed_pair_switch; struct __libcpp_compressed_pair_switch;

View File

@ -161,10 +161,8 @@ using tuple_element_t = typename tuple_element <_Ip, _Tp...>::type;
// __tuple_leaf // __tuple_leaf
template <size_t _Ip, class _Hp, bool=is_empty<_Hp>::value template <size_t _Ip, class _Hp,
#if __has_feature(is_final) bool=is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value
&& !__is_final(_Hp)
#endif
> >
class __tuple_leaf; class __tuple_leaf;

View File

@ -803,7 +803,15 @@ template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_abstract : public __libcpp_
// is_final // is_final
#if _LIBCPP_STD_VER > 11 && __has_feature(is_final) #if defined(_LIBCPP_HAS_IS_FINAL)
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY
__libcpp_is_final : public integral_constant<bool, __is_final(_Tp)> {};
#else
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY
__libcpp_is_final : public false_type {};
#endif
#if defined(_LIBCPP_HAS_IS_FINAL) && _LIBCPP_STD_VER > 11
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY
is_final : public integral_constant<bool, __is_final(_Tp)> {}; is_final : public integral_constant<bool, __is_final(_Tp)> {};
#endif #endif

View File

@ -361,10 +361,8 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Key, class _Cp, class _Hash, bool = is_empty<_Hash>::value template <class _Key, class _Cp, class _Hash,
#if __has_feature(is_final) bool = is_empty<_Hash>::value && !__libcpp_is_final<_Hash>::value
&& !__is_final(_Hash)
#endif
> >
class __unordered_map_hasher class __unordered_map_hasher
: private _Hash : private _Hash
@ -412,10 +410,8 @@ public:
{return __hash_(__x);} {return __hash_(__x);}
}; };
template <class _Key, class _Cp, class _Pred, bool = is_empty<_Pred>::value template <class _Key, class _Cp, class _Pred,
#if __has_feature(is_final) bool = is_empty<_Pred>::value && !__libcpp_is_final<_Pred>::value
&& !__is_final(_Pred)
#endif
> >
class __unordered_map_equal class __unordered_map_equal
: private _Pred : private _Pred