diff --git a/libcxx/include/__config b/libcxx/include/__config --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -1259,6 +1259,12 @@ # define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) static_assert(true, "") #endif +// TODO(varconst): currently, there are bugs in Clang's intrinsics when handling Objective-C++ `id`, so don't use +// compiler intrinsics in the Objective-C++ mode. +#ifndef __OBJC__ +#define _LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS +#endif + #endif // __cplusplus #endif // _LIBCPP___CONFIG diff --git a/libcxx/include/__type_traits/add_lvalue_reference.h b/libcxx/include/__type_traits/add_lvalue_reference.h --- a/libcxx/include/__type_traits/add_lvalue_reference.h +++ b/libcxx/include/__type_traits/add_lvalue_reference.h @@ -18,7 +18,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if __has_builtin(__add_lvalue_reference) +#if defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__add_lvalue_reference) template using __add_lvalue_reference_t = __add_lvalue_reference(_Tp); @@ -37,7 +37,7 @@ template using __add_lvalue_reference_t = typename __add_lvalue_reference_impl<_Tp>::type; -#endif // __has_builtin(__add_lvalue_reference) +#endif // defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__add_lvalue_reference) template struct add_lvalue_reference { diff --git a/libcxx/include/__type_traits/add_pointer.h b/libcxx/include/__type_traits/add_pointer.h --- a/libcxx/include/__type_traits/add_pointer.h +++ b/libcxx/include/__type_traits/add_pointer.h @@ -22,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if __has_builtin(__add_pointer) +#if defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__add_pointer) template using __add_pointer_t = __add_pointer(_Tp); @@ -39,7 +39,7 @@ template using __add_pointer_t = typename __add_pointer_impl<_Tp>::type; -#endif // __has_builtin(__add_pointer) +#endif // defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__add_pointer) template struct add_pointer { diff --git a/libcxx/include/__type_traits/add_rvalue_reference.h b/libcxx/include/__type_traits/add_rvalue_reference.h --- a/libcxx/include/__type_traits/add_rvalue_reference.h +++ b/libcxx/include/__type_traits/add_rvalue_reference.h @@ -18,7 +18,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if __has_builtin(__add_rvalue_reference) +#if defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__add_rvalue_reference) template using __add_rvalue_reference_t = __add_rvalue_reference(_Tp); @@ -37,7 +37,7 @@ template using __add_rvalue_reference_t = typename __add_rvalue_reference_impl<_Tp>::type; -#endif // __has_builtin(__add_rvalue_reference) +#endif // defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__add_rvalue_reference) template struct add_rvalue_reference { diff --git a/libcxx/include/__type_traits/decay.h b/libcxx/include/__type_traits/decay.h --- a/libcxx/include/__type_traits/decay.h +++ b/libcxx/include/__type_traits/decay.h @@ -25,7 +25,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if __has_builtin(__decay) +#if defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__decay) template struct decay { using type _LIBCPP_NODEBUG = __decay(_Tp); @@ -60,7 +60,7 @@ public: typedef _LIBCPP_NODEBUG typename __decay<_Up, __libcpp_is_referenceable<_Up>::value>::type type; }; -#endif // __has_builtin(__decay) +#endif // defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__decay) #if _LIBCPP_STD_VER >= 14 template using decay_t = typename decay<_Tp>::type; diff --git a/libcxx/include/__type_traits/is_referenceable.h b/libcxx/include/__type_traits/is_referenceable.h --- a/libcxx/include/__type_traits/is_referenceable.h +++ b/libcxx/include/__type_traits/is_referenceable.h @@ -19,7 +19,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if __has_builtin(__is_referenceable) +#if defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__is_referenceable) template struct __libcpp_is_referenceable : integral_constant {}; #else @@ -34,7 +34,7 @@ struct __libcpp_is_referenceable : integral_constant(0)), false_type>::value> { }; -#endif // __has_builtin(__is_referenceable) +#endif // defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__is_referenceable) _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__type_traits/make_signed.h b/libcxx/include/__type_traits/make_signed.h --- a/libcxx/include/__type_traits/make_signed.h +++ b/libcxx/include/__type_traits/make_signed.h @@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if __has_builtin(__make_signed) +#if defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__make_signed) template using __make_signed_t = __make_signed(_Tp); @@ -70,7 +70,7 @@ template using __make_signed_t = typename __apply_cv<_Tp, typename __make_signed<__remove_cv_t<_Tp> >::type>::type; -#endif // __has_builtin(__make_signed) +#endif // defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__make_signed) template struct make_signed { diff --git a/libcxx/include/__type_traits/make_unsigned.h b/libcxx/include/__type_traits/make_unsigned.h --- a/libcxx/include/__type_traits/make_unsigned.h +++ b/libcxx/include/__type_traits/make_unsigned.h @@ -25,7 +25,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if __has_builtin(__make_unsigned) +#if defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__make_unsigned) template using __make_unsigned_t = __make_unsigned(_Tp); @@ -72,7 +72,7 @@ template using __make_unsigned_t = typename __apply_cv<_Tp, typename __make_unsigned<__remove_cv_t<_Tp> >::type>::type; -#endif // __has_builtin(__make_unsigned) +#endif // defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__make_unsigned) template struct make_unsigned { diff --git a/libcxx/include/__type_traits/remove_all_extents.h b/libcxx/include/__type_traits/remove_all_extents.h --- a/libcxx/include/__type_traits/remove_all_extents.h +++ b/libcxx/include/__type_traits/remove_all_extents.h @@ -18,7 +18,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if __has_builtin(__remove_all_extents) +#if defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__remove_all_extents) template struct remove_all_extents { using type _LIBCPP_NODEBUG = __remove_all_extents(_Tp); @@ -36,7 +36,7 @@ template using __remove_all_extents_t = typename remove_all_extents<_Tp>::type; -#endif // __has_builtin(__remove_all_extents) +#endif // defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__remove_all_extents) #if _LIBCPP_STD_VER >= 14 template using remove_all_extents_t = __remove_all_extents_t<_Tp>; diff --git a/libcxx/include/__type_traits/remove_const.h b/libcxx/include/__type_traits/remove_const.h --- a/libcxx/include/__type_traits/remove_const.h +++ b/libcxx/include/__type_traits/remove_const.h @@ -17,7 +17,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if __has_builtin(__remove_const) +#if defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__remove_const) template struct remove_const { using type _LIBCPP_NODEBUG = __remove_const(_Tp); @@ -31,7 +31,7 @@ template using __remove_const_t = typename remove_const<_Tp>::type; -#endif // __has_builtin(__remove_const) +#endif // defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__remove_const) #if _LIBCPP_STD_VER >= 14 template using remove_const_t = __remove_const_t<_Tp>; diff --git a/libcxx/include/__type_traits/remove_cv.h b/libcxx/include/__type_traits/remove_cv.h --- a/libcxx/include/__type_traits/remove_cv.h +++ b/libcxx/include/__type_traits/remove_cv.h @@ -19,7 +19,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if __has_builtin(__remove_cv) +#if defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__remove_cv) template struct remove_cv { using type _LIBCPP_NODEBUG = __remove_cv(_Tp); @@ -33,7 +33,7 @@ template using __remove_cv_t = __remove_volatile_t<__remove_const_t<_Tp> >; -#endif // __has_builtin(__remove_cv) +#endif // defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__remove_cv) #if _LIBCPP_STD_VER >= 14 template using remove_cv_t = __remove_cv_t<_Tp>; diff --git a/libcxx/include/__type_traits/remove_cvref.h b/libcxx/include/__type_traits/remove_cvref.h --- a/libcxx/include/__type_traits/remove_cvref.h +++ b/libcxx/include/__type_traits/remove_cvref.h @@ -20,13 +20,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if __has_builtin(__remove_cvref) +#if defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__remove_cvref) template using __remove_cvref_t _LIBCPP_NODEBUG = __remove_cvref(_Tp); #else template using __remove_cvref_t _LIBCPP_NODEBUG = __remove_cv_t<__libcpp_remove_reference_t<_Tp> >; -#endif // __has_builtin(__remove_cvref) +#endif // defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__remove_cvref) template struct __is_same_uncvref : _IsSame<__remove_cvref_t<_Tp>, __remove_cvref_t<_Up> > {}; diff --git a/libcxx/include/__type_traits/remove_extent.h b/libcxx/include/__type_traits/remove_extent.h --- a/libcxx/include/__type_traits/remove_extent.h +++ b/libcxx/include/__type_traits/remove_extent.h @@ -18,7 +18,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if __has_builtin(__remove_extent) +#if defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__remove_extent) template struct remove_extent { using type _LIBCPP_NODEBUG = __remove_extent(_Tp); @@ -36,7 +36,7 @@ template using __remove_extent_t = typename remove_extent<_Tp>::type; -#endif // __has_builtin(__remove_extent) +#endif // defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__remove_extent) #if _LIBCPP_STD_VER >= 14 template using remove_extent_t = __remove_extent_t<_Tp>; diff --git a/libcxx/include/__type_traits/remove_pointer.h b/libcxx/include/__type_traits/remove_pointer.h --- a/libcxx/include/__type_traits/remove_pointer.h +++ b/libcxx/include/__type_traits/remove_pointer.h @@ -17,7 +17,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if __has_builtin(__remove_pointer) +#if defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__remove_pointer) template struct remove_pointer { using type _LIBCPP_NODEBUG = __remove_pointer(_Tp); @@ -34,7 +34,7 @@ template using __remove_pointer_t = typename remove_pointer<_Tp>::type; -#endif // __has_builtin(__remove_pointer) +#endif // defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__remove_pointer) #if _LIBCPP_STD_VER >= 14 template using remove_pointer_t = __remove_pointer_t<_Tp>; diff --git a/libcxx/include/__type_traits/remove_reference.h b/libcxx/include/__type_traits/remove_reference.h --- a/libcxx/include/__type_traits/remove_reference.h +++ b/libcxx/include/__type_traits/remove_reference.h @@ -18,7 +18,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if __has_builtin(__remove_reference_t) +#if defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__remove_reference_t) template struct remove_reference { using type _LIBCPP_NODEBUG = __remove_reference_t(_Tp); @@ -33,7 +33,7 @@ template using __libcpp_remove_reference_t = typename remove_reference<_Tp>::type; -#endif // __has_builtin(__remove_reference_t) +#endif // defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__remove_reference_t) #if _LIBCPP_STD_VER >= 14 template using remove_reference_t = __libcpp_remove_reference_t<_Tp>; diff --git a/libcxx/include/__type_traits/remove_volatile.h b/libcxx/include/__type_traits/remove_volatile.h --- a/libcxx/include/__type_traits/remove_volatile.h +++ b/libcxx/include/__type_traits/remove_volatile.h @@ -17,7 +17,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if __has_builtin(__remove_volatile) +#if defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__remove_volatile) template struct remove_volatile { using type _LIBCPP_NODEBUG = __remove_volatile(_Tp); @@ -31,7 +31,7 @@ template using __remove_volatile_t = typename remove_volatile<_Tp>::type; -#endif // __has_builtin(__remove_volatile) +#endif // defined(_LIBCPP_USING_TYPE_TRAITS_COMPILER_INTRINSICS) && __has_builtin(__remove_volatile) #if _LIBCPP_STD_VER >= 14 template using remove_volatile_t = __remove_volatile_t<_Tp>; diff --git a/libcxx/test/std/utilities/meta/meta.trans/objc_support.pass.mm b/libcxx/test/std/utilities/meta/meta.trans/objc_support.pass.mm new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/meta/meta.trans/objc_support.pass.mm @@ -0,0 +1,99 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// Simple test to check that type traits support Objective-C types. + +#include +#include "test_macros.h" + +@interface I; +@end + +// add_pointer +static_assert(std::is_same::type, id*>::value, ""); +static_assert(std::is_same::type, I*>::value, ""); + +// add_lvalue_reference +static_assert(std::is_same::type, id&>::value, ""); +static_assert(std::is_same::type, I&>::value, ""); + +// add_rvalue_reference +static_assert(std::is_same::type, id&&>::value, ""); +static_assert(std::is_same::type, I&&>::value, ""); + +// decay +static_assert(std::is_same::type, id>::value, ""); +static_assert(std::is_same::type, I>::value, ""); +static_assert(std::is_same::type, id*>::value, ""); + +// __libcpp_is_referenceable +LIBCPP_STATIC_ASSERT(std::__libcpp_is_referenceable::value, ""); +LIBCPP_STATIC_ASSERT(std::__libcpp_is_referenceable::value, ""); +LIBCPP_STATIC_ASSERT(std::__libcpp_is_referenceable::value, ""); +LIBCPP_STATIC_ASSERT(std::__libcpp_is_referenceable::value, ""); +LIBCPP_STATIC_ASSERT(std::__libcpp_is_referenceable::value, ""); +LIBCPP_STATIC_ASSERT(std::__libcpp_is_referenceable::value, ""); +LIBCPP_STATIC_ASSERT(std::__libcpp_is_referenceable::value, ""); +LIBCPP_STATIC_ASSERT(std::__libcpp_is_referenceable::value, ""); + +// remove_all_extents +static_assert(std::is_same::type, id>::value, ""); +static_assert(std::is_same::type, id>::value, ""); +static_assert(std::is_same::type, id>::value, ""); +static_assert(std::is_same::type, I>::value, ""); + +// remove_const +static_assert(std::is_same::type, id>::value, ""); +static_assert(std::is_same::type, id>::value, ""); +static_assert(std::is_same::type, I>::value, ""); +static_assert(std::is_same::type, I>::value, ""); + +// remove_cv +static_assert(std::is_same::type, id>::value, ""); +static_assert(std::is_same::type, id>::value, ""); +static_assert(std::is_same::type, I>::value, ""); +static_assert(std::is_same::type, I>::value, ""); + +// remove_cvref +static_assert(std::is_same::type, id>::value, ""); +static_assert(std::is_same::type, id>::value, ""); +static_assert(std::is_same::type, id>::value, ""); +static_assert(std::is_same::type, I>::value, ""); +static_assert(std::is_same::type, I>::value, ""); +static_assert(std::is_same::type, I>::value, ""); + +// remove_extent +static_assert(std::is_same::type, id>::value, ""); +static_assert(std::is_same::type, id>::value, ""); +static_assert(std::is_same::type, I>::value, ""); + +// remove_pointer +// The result of removing and readding pointer to `id` should be still `id`. +static_assert(std::is_same::type*, id>::value, ""); + +// remove_reference +static_assert(std::is_same::type, id>::value, ""); +static_assert(std::is_same::type, id>::value, ""); +static_assert(std::is_same::type, const id>::value, ""); +static_assert(std::is_same::type, id>::value, ""); +static_assert(std::is_same::type, const id>::value, ""); +static_assert(std::is_same::type, I>::value, ""); +static_assert(std::is_same::type, I>::value, ""); +static_assert(std::is_same::type, const I>::value, ""); +static_assert(std::is_same::type, I>::value, ""); +static_assert(std::is_same::type, const I>::value, ""); + +// remove_volatile +static_assert(std::is_same::type, id>::value, ""); +static_assert(std::is_same::type, id>::value, ""); +static_assert(std::is_same::type, I>::value, ""); +static_assert(std::is_same::type, I>::value, ""); + +int main(int, char**) { + return 0; +}