From c63ce7cad67d8fcf5fa377454828dc6ea4506a52 Mon Sep 17 00:00:00 2001 From: Ivan Trofimov Date: Wed, 11 Oct 2023 18:33:22 +0300 Subject: [PATCH 1/2] [libc++] Split type_info header --- libcxx/include/CMakeLists.txt | 1 + libcxx/include/__typeinfo/typeinfo.h | 371 +++++++++++++++++++++++++++ libcxx/include/libcxx.imp | 1 + libcxx/include/module.modulemap.in | 5 + libcxx/include/typeinfo | 354 +------------------------ libcxx/utils/data/ignore_format.txt | 1 - 6 files changed, 379 insertions(+), 354 deletions(-) create mode 100644 libcxx/include/__typeinfo/typeinfo.h diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index 4d98b8eed1afd..bd4fb37d99834 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -832,6 +832,7 @@ set(files __type_traits/underlying_type.h __type_traits/unwrap_ref.h __type_traits/void_t.h + __typeinfo/typeinfo.h __undef_macros __utility/as_const.h __utility/auto_cast.h diff --git a/libcxx/include/__typeinfo/typeinfo.h b/libcxx/include/__typeinfo/typeinfo.h new file mode 100644 index 0000000000000..474b1f419f5db --- /dev/null +++ b/libcxx/include/__typeinfo/typeinfo.h @@ -0,0 +1,371 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPEINFO_TYPEINFO_H +#define _LIBCPP___TYPEINFO_TYPEINFO_H + +#include <__availability> +#include <__config> +#include <__exception/exception.h> +#include <__type_traits/is_constant_evaluated.h> +#include <__verbose_abort> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if defined(_LIBCPP_ABI_VCRUNTIME) +#include +#else + +namespace std // purposefully not using versioning namespace +{ + +#if defined(_LIBCPP_ABI_MICROSOFT) + +class _LIBCPP_EXPORTED_FROM_ABI type_info +{ + type_info& operator=(const type_info&); + type_info(const type_info&); + + mutable struct { + const char *__undecorated_name; + const char __decorated_name[1]; + } __data; + + int __compare(const type_info &__rhs) const _NOEXCEPT; + +public: + _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE + virtual ~type_info(); + + const char *name() const _NOEXCEPT; + + _LIBCPP_INLINE_VISIBILITY + bool before(const type_info& __arg) const _NOEXCEPT { + return __compare(__arg) < 0; + } + + size_t hash_code() const _NOEXCEPT; + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 + bool operator==(const type_info& __arg) const _NOEXCEPT { + // When evaluated in a constant expression, both type infos simply can't come + // from different translation units, so it is sufficient to compare their addresses. + if (__libcpp_is_constant_evaluated()) { + return this == &__arg; + } + return __compare(__arg) == 0; + } + +#if _LIBCPP_STD_VER <= 17 + _LIBCPP_INLINE_VISIBILITY + bool operator!=(const type_info& __arg) const _NOEXCEPT + { return !operator==(__arg); } +#endif +}; + +#else // !defined(_LIBCPP_ABI_MICROSOFT) + +// ========================================================================== // +// Implementations +// ========================================================================== // +// ------------------------------------------------------------------------- // +// Unique +// (_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION = 1) +// ------------------------------------------------------------------------- // +// This implementation of type_info assumes a unique copy of the RTTI for a +// given type inside a program. This is a valid assumption when abiding to the +// Itanium ABI (http://itanium-cxx-abi.github.io/cxx-abi/abi.html#vtable-components). +// Under this assumption, we can always compare the addresses of the type names +// to implement equality-comparison of type_infos instead of having to perform +// a deep string comparison. +// -------------------------------------------------------------------------- // +// NonUnique +// (_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION = 2) +// -------------------------------------------------------------------------- // +// This implementation of type_info does not assume there is always a unique +// copy of the RTTI for a given type inside a program. For various reasons +// the linker may have failed to merge every copy of a types RTTI +// (For example: -Bsymbolic or llvm.org/PR37398). Under this assumption, two +// type_infos are equal if their addresses are equal or if a deep string +// comparison is equal. +// -------------------------------------------------------------------------- // +// NonUniqueARMRTTIBit +// (_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION = 3) +// -------------------------------------------------------------------------- // +// This implementation is specific to ARM64 on Apple platforms. +// +// This implementation of type_info does not assume always a unique copy of +// the RTTI for a given type inside a program. When constructing the type_info, +// the compiler packs the pointer to the type name into a uintptr_t and reserves +// the high bit of that pointer, which is assumed to be free for use under that +// ABI. If that high bit is set, that specific copy of the RTTI can't be assumed +// to be unique within the program. If the high bit is unset, then the RTTI can +// be assumed to be unique within the program. +// +// When comparing type_infos, if both RTTIs can be assumed to be unique, it +// suffices to compare their addresses. If both the RTTIs can't be assumed to +// be unique, we must perform a deep string comparison of the type names. +// However, if one of the RTTIs is guaranteed unique and the other one isn't, +// then both RTTIs are necessarily not to be considered equal. +// +// The intent of this design is to remove the need for weak symbols. Specifically, +// if a type would normally have a default-visibility RTTI emitted as a weak +// symbol, it is given hidden visibility instead and the non-unique bit is set. +// Otherwise, types declared with hidden visibility are always considered to have +// a unique RTTI: the RTTI is emitted with linkonce_odr linkage and is assumed +// to be deduplicated by the linker within the linked image. Across linked image +// boundaries, such types are thus considered different types. + +// This value can be overriden in the __config_site. When it's not overriden, +// we pick a default implementation based on the platform here. +#ifndef _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION + + // Windows and AIX binaries can't merge typeinfos, so use the NonUnique implementation. +# if defined(_LIBCPP_OBJECT_FORMAT_COFF) || defined(_LIBCPP_OBJECT_FORMAT_XCOFF) +# define _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION 2 + + // On arm64 on Apple platforms, use the special NonUniqueARMRTTIBit implementation. +# elif defined(__APPLE__) && defined(__LP64__) && !defined(__x86_64__) +# define _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION 3 + + // On all other platforms, assume the Itanium C++ ABI and use the Unique implementation. +# else +# define _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION 1 +# endif +#endif + +struct __type_info_implementations { + struct __string_impl_base { + typedef const char* __type_name_t; + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + _LIBCPP_CONSTEXPR static const char* __type_name_to_string(__type_name_t __v) _NOEXCEPT { + return __v; + } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + _LIBCPP_CONSTEXPR static __type_name_t __string_to_type_name(const char* __v) _NOEXCEPT { + return __v; + } + }; + + struct __unique_impl : __string_impl_base { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + static size_t __hash(__type_name_t __v) _NOEXCEPT { + return reinterpret_cast(__v); + } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + static bool __eq(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { + return __lhs == __rhs; + } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + static bool __lt(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { + return __lhs < __rhs; + } + }; + + struct __non_unique_impl : __string_impl_base { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + static size_t __hash(__type_name_t __ptr) _NOEXCEPT { + size_t __hash = 5381; + while (unsigned char __c = static_cast(*__ptr++)) + __hash = (__hash * 33) ^ __c; + return __hash; + } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + static bool __eq(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { + return __lhs == __rhs || __builtin_strcmp(__lhs, __rhs) == 0; + } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + static bool __lt(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { + return __builtin_strcmp(__lhs, __rhs) < 0; + } + }; + + struct __non_unique_arm_rtti_bit_impl { + typedef uintptr_t __type_name_t; + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + static const char* __type_name_to_string(__type_name_t __v) _NOEXCEPT { + return reinterpret_cast(__v & + ~__non_unique_rtti_bit::value); + } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + static __type_name_t __string_to_type_name(const char* __v) _NOEXCEPT { + return reinterpret_cast<__type_name_t>(__v); + } + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + static size_t __hash(__type_name_t __v) _NOEXCEPT { + if (__is_type_name_unique(__v)) + return __v; + return __non_unique_impl::__hash(__type_name_to_string(__v)); + } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + static bool __eq(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { + if (__lhs == __rhs) + return true; + if (__is_type_name_unique(__lhs) || __is_type_name_unique(__rhs)) + // Either both are unique and have a different address, or one of them + // is unique and the other one isn't. In both cases they are unequal. + return false; + return __builtin_strcmp(__type_name_to_string(__lhs), __type_name_to_string(__rhs)) == 0; + } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + static bool __lt(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { + if (__is_type_name_unique(__lhs) || __is_type_name_unique(__rhs)) + return __lhs < __rhs; + return __builtin_strcmp(__type_name_to_string(__lhs), __type_name_to_string(__rhs)) < 0; + } + + private: + // The unique bit is the top bit. It is expected that __type_name_t is 64 bits when + // this implementation is actually used. + typedef integral_constant<__type_name_t, + (1ULL << ((__CHAR_BIT__ * sizeof(__type_name_t)) - 1))> __non_unique_rtti_bit; + + _LIBCPP_INLINE_VISIBILITY + static bool __is_type_name_unique(__type_name_t __lhs) _NOEXCEPT { + return !(__lhs & __non_unique_rtti_bit::value); + } + }; + + typedef +#if _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION == 1 + __unique_impl +#elif _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION == 2 + __non_unique_impl +#elif _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION == 3 + __non_unique_arm_rtti_bit_impl +#else +# error invalid configuration for _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION +#endif + __impl; +}; + +class _LIBCPP_EXPORTED_FROM_ABI type_info +{ + type_info& operator=(const type_info&); + type_info(const type_info&); + + protected: + typedef __type_info_implementations::__impl __impl; + + __impl::__type_name_t __type_name; + + _LIBCPP_INLINE_VISIBILITY + explicit type_info(const char* __n) + : __type_name(__impl::__string_to_type_name(__n)) {} + +public: + _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE + virtual ~type_info(); + + _LIBCPP_INLINE_VISIBILITY + const char* name() const _NOEXCEPT + { + return __impl::__type_name_to_string(__type_name); + } + + _LIBCPP_INLINE_VISIBILITY + bool before(const type_info& __arg) const _NOEXCEPT + { + return __impl::__lt(__type_name, __arg.__type_name); + } + + _LIBCPP_INLINE_VISIBILITY + size_t hash_code() const _NOEXCEPT + { + return __impl::__hash(__type_name); + } + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 + bool operator==(const type_info& __arg) const _NOEXCEPT + { + // When evaluated in a constant expression, both type infos simply can't come + // from different translation units, so it is sufficient to compare their addresses. + if (__libcpp_is_constant_evaluated()) { + return this == &__arg; + } + return __impl::__eq(__type_name, __arg.__type_name); + } + +#if _LIBCPP_STD_VER <= 17 + _LIBCPP_INLINE_VISIBILITY + bool operator!=(const type_info& __arg) const _NOEXCEPT + { return !operator==(__arg); } +#endif +}; +#endif // defined(_LIBCPP_ABI_MICROSOFT) + +class _LIBCPP_EXPORTED_FROM_ABI bad_cast + : public exception +{ + public: + bad_cast() _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI bad_cast(const bad_cast&) _NOEXCEPT = default; + _LIBCPP_HIDE_FROM_ABI bad_cast& operator=(const bad_cast&) _NOEXCEPT = default; + ~bad_cast() _NOEXCEPT override; + const char* what() const _NOEXCEPT override; +}; + +class _LIBCPP_EXPORTED_FROM_ABI bad_typeid + : public exception +{ + public: + bad_typeid() _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI bad_typeid(const bad_typeid&) _NOEXCEPT = default; + _LIBCPP_HIDE_FROM_ABI bad_typeid& operator=(const bad_typeid&) _NOEXCEPT = default; + ~bad_typeid() _NOEXCEPT override; + const char* what() const _NOEXCEPT override; +}; + +} // namespace std + +#endif // defined(_LIBCPP_ABI_VCRUNTIME) + +#if defined(_LIBCPP_ABI_VCRUNTIME) && _HAS_EXCEPTIONS == 0 + +namespace std { + +class bad_cast : public exception { +public: + bad_cast() _NOEXCEPT : exception("bad cast") {} + +private: + bad_cast(const char* const __message) _NOEXCEPT : exception(__message) {} +}; + +class bad_typeid : public exception { +public: + bad_typeid() _NOEXCEPT : exception("bad typeid") {} + +private: + bad_typeid(const char* const __message) _NOEXCEPT : exception(__message) {} +}; + +} // namespace std + +#endif // defined(_LIBCPP_ABI_VCRUNTIME) && _HAS_EXCEPTIONS == 0 + +_LIBCPP_BEGIN_NAMESPACE_STD +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY +void __throw_bad_cast() +{ +#ifndef _LIBCPP_HAS_NO_EXCEPTIONS + throw bad_cast(); +#else + _LIBCPP_VERBOSE_ABORT("bad_cast was thrown in -fno-exceptions mode"); +#endif +} +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPEINFO_TYPEINFO_H diff --git a/libcxx/include/libcxx.imp b/libcxx/include/libcxx.imp index 3eb2aa8493148..f7e906e024f33 100644 --- a/libcxx/include/libcxx.imp +++ b/libcxx/include/libcxx.imp @@ -48,6 +48,7 @@ { include: [ "@<__thread/.*>", "private", "", "public" ] }, { include: [ "@<__tuple/.*>", "private", "", "public" ] }, { include: [ "@<__type_traits/.*>", "private", "", "public" ] }, + { include: [ "@<__typeinfo/.*>", "private", "", "public" ] }, { include: [ "@<__utility/.*>", "private", "", "public" ] }, { include: [ "@<__variant/.*>", "private", "", "public" ] }, ] diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in index 09184af2732c8..b8885379fa7d5 100644 --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -1270,6 +1270,11 @@ module std_private_debug_utils_strict_weak_ordering_check [system] { export std_private_type_traits_is_constant_evaluated } +module std_private_typeinfo_typeinfo [system] { + header "__typeinfo/typeinfo.h" + export * +} + module std_private_exception_exception [system] { header "__exception/exception.h" } module std_private_exception_exception_ptr [system] { header "__exception/exception_ptr.h" diff --git a/libcxx/include/typeinfo b/libcxx/include/typeinfo index 59bc291454c3d..e869cd5e67507 100644 --- a/libcxx/include/typeinfo +++ b/libcxx/include/typeinfo @@ -57,365 +57,13 @@ public: */ #include <__assert> // all public C++ headers provide the assertion handler -#include <__availability> #include <__config> -#include <__exception/exception.h> -#include <__type_traits/is_constant_evaluated.h> -#include <__verbose_abort> -#include -#include +#include <__typeinfo/typeinfo.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif -#if defined(_LIBCPP_ABI_VCRUNTIME) -#include -#else - -namespace std // purposefully not using versioning namespace -{ - - -#if defined(_LIBCPP_ABI_MICROSOFT) - -class _LIBCPP_EXPORTED_FROM_ABI type_info -{ - type_info& operator=(const type_info&); - type_info(const type_info&); - - mutable struct { - const char *__undecorated_name; - const char __decorated_name[1]; - } __data; - - int __compare(const type_info &__rhs) const _NOEXCEPT; - -public: - _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE - virtual ~type_info(); - - const char *name() const _NOEXCEPT; - - _LIBCPP_INLINE_VISIBILITY - bool before(const type_info& __arg) const _NOEXCEPT { - return __compare(__arg) < 0; - } - - size_t hash_code() const _NOEXCEPT; - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 - bool operator==(const type_info& __arg) const _NOEXCEPT { - // When evaluated in a constant expression, both type infos simply can't come - // from different translation units, so it is sufficient to compare their addresses. - if (__libcpp_is_constant_evaluated()) { - return this == &__arg; - } - return __compare(__arg) == 0; - } - -#if _LIBCPP_STD_VER <= 17 - _LIBCPP_INLINE_VISIBILITY - bool operator!=(const type_info& __arg) const _NOEXCEPT - { return !operator==(__arg); } -#endif -}; - -#else // !defined(_LIBCPP_ABI_MICROSOFT) - -// ========================================================================== // -// Implementations -// ========================================================================== // -// ------------------------------------------------------------------------- // -// Unique -// (_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION = 1) -// ------------------------------------------------------------------------- // -// This implementation of type_info assumes a unique copy of the RTTI for a -// given type inside a program. This is a valid assumption when abiding to the -// Itanium ABI (http://itanium-cxx-abi.github.io/cxx-abi/abi.html#vtable-components). -// Under this assumption, we can always compare the addresses of the type names -// to implement equality-comparison of type_infos instead of having to perform -// a deep string comparison. -// -------------------------------------------------------------------------- // -// NonUnique -// (_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION = 2) -// -------------------------------------------------------------------------- // -// This implementation of type_info does not assume there is always a unique -// copy of the RTTI for a given type inside a program. For various reasons -// the linker may have failed to merge every copy of a types RTTI -// (For example: -Bsymbolic or llvm.org/PR37398). Under this assumption, two -// type_infos are equal if their addresses are equal or if a deep string -// comparison is equal. -// -------------------------------------------------------------------------- // -// NonUniqueARMRTTIBit -// (_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION = 3) -// -------------------------------------------------------------------------- // -// This implementation is specific to ARM64 on Apple platforms. -// -// This implementation of type_info does not assume always a unique copy of -// the RTTI for a given type inside a program. When constructing the type_info, -// the compiler packs the pointer to the type name into a uintptr_t and reserves -// the high bit of that pointer, which is assumed to be free for use under that -// ABI. If that high bit is set, that specific copy of the RTTI can't be assumed -// to be unique within the program. If the high bit is unset, then the RTTI can -// be assumed to be unique within the program. -// -// When comparing type_infos, if both RTTIs can be assumed to be unique, it -// suffices to compare their addresses. If both the RTTIs can't be assumed to -// be unique, we must perform a deep string comparison of the type names. -// However, if one of the RTTIs is guaranteed unique and the other one isn't, -// then both RTTIs are necessarily not to be considered equal. -// -// The intent of this design is to remove the need for weak symbols. Specifically, -// if a type would normally have a default-visibility RTTI emitted as a weak -// symbol, it is given hidden visibility instead and the non-unique bit is set. -// Otherwise, types declared with hidden visibility are always considered to have -// a unique RTTI: the RTTI is emitted with linkonce_odr linkage and is assumed -// to be deduplicated by the linker within the linked image. Across linked image -// boundaries, such types are thus considered different types. - -// This value can be overriden in the __config_site. When it's not overriden, -// we pick a default implementation based on the platform here. -#ifndef _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION - - // Windows and AIX binaries can't merge typeinfos, so use the NonUnique implementation. -# if defined(_LIBCPP_OBJECT_FORMAT_COFF) || defined(_LIBCPP_OBJECT_FORMAT_XCOFF) -# define _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION 2 - - // On arm64 on Apple platforms, use the special NonUniqueARMRTTIBit implementation. -# elif defined(__APPLE__) && defined(__LP64__) && !defined(__x86_64__) -# define _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION 3 - - // On all other platforms, assume the Itanium C++ ABI and use the Unique implementation. -# else -# define _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION 1 -# endif -#endif - -struct __type_info_implementations { - struct __string_impl_base { - typedef const char* __type_name_t; - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - _LIBCPP_CONSTEXPR static const char* __type_name_to_string(__type_name_t __v) _NOEXCEPT { - return __v; - } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - _LIBCPP_CONSTEXPR static __type_name_t __string_to_type_name(const char* __v) _NOEXCEPT { - return __v; - } - }; - - struct __unique_impl : __string_impl_base { - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - static size_t __hash(__type_name_t __v) _NOEXCEPT { - return reinterpret_cast(__v); - } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - static bool __eq(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { - return __lhs == __rhs; - } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - static bool __lt(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { - return __lhs < __rhs; - } - }; - - struct __non_unique_impl : __string_impl_base { - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - static size_t __hash(__type_name_t __ptr) _NOEXCEPT { - size_t __hash = 5381; - while (unsigned char __c = static_cast(*__ptr++)) - __hash = (__hash * 33) ^ __c; - return __hash; - } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - static bool __eq(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { - return __lhs == __rhs || __builtin_strcmp(__lhs, __rhs) == 0; - } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - static bool __lt(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { - return __builtin_strcmp(__lhs, __rhs) < 0; - } - }; - - struct __non_unique_arm_rtti_bit_impl { - typedef uintptr_t __type_name_t; - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - static const char* __type_name_to_string(__type_name_t __v) _NOEXCEPT { - return reinterpret_cast(__v & - ~__non_unique_rtti_bit::value); - } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - static __type_name_t __string_to_type_name(const char* __v) _NOEXCEPT { - return reinterpret_cast<__type_name_t>(__v); - } - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - static size_t __hash(__type_name_t __v) _NOEXCEPT { - if (__is_type_name_unique(__v)) - return __v; - return __non_unique_impl::__hash(__type_name_to_string(__v)); - } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - static bool __eq(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { - if (__lhs == __rhs) - return true; - if (__is_type_name_unique(__lhs) || __is_type_name_unique(__rhs)) - // Either both are unique and have a different address, or one of them - // is unique and the other one isn't. In both cases they are unequal. - return false; - return __builtin_strcmp(__type_name_to_string(__lhs), __type_name_to_string(__rhs)) == 0; - } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - static bool __lt(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { - if (__is_type_name_unique(__lhs) || __is_type_name_unique(__rhs)) - return __lhs < __rhs; - return __builtin_strcmp(__type_name_to_string(__lhs), __type_name_to_string(__rhs)) < 0; - } - - private: - // The unique bit is the top bit. It is expected that __type_name_t is 64 bits when - // this implementation is actually used. - typedef integral_constant<__type_name_t, - (1ULL << ((__CHAR_BIT__ * sizeof(__type_name_t)) - 1))> __non_unique_rtti_bit; - - _LIBCPP_INLINE_VISIBILITY - static bool __is_type_name_unique(__type_name_t __lhs) _NOEXCEPT { - return !(__lhs & __non_unique_rtti_bit::value); - } - }; - - typedef -#if _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION == 1 - __unique_impl -#elif _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION == 2 - __non_unique_impl -#elif _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION == 3 - __non_unique_arm_rtti_bit_impl -#else -# error invalid configuration for _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION -#endif - __impl; -}; - -class _LIBCPP_EXPORTED_FROM_ABI type_info -{ - type_info& operator=(const type_info&); - type_info(const type_info&); - - protected: - typedef __type_info_implementations::__impl __impl; - - __impl::__type_name_t __type_name; - - _LIBCPP_INLINE_VISIBILITY - explicit type_info(const char* __n) - : __type_name(__impl::__string_to_type_name(__n)) {} - -public: - _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE - virtual ~type_info(); - - _LIBCPP_INLINE_VISIBILITY - const char* name() const _NOEXCEPT - { - return __impl::__type_name_to_string(__type_name); - } - - _LIBCPP_INLINE_VISIBILITY - bool before(const type_info& __arg) const _NOEXCEPT - { - return __impl::__lt(__type_name, __arg.__type_name); - } - - _LIBCPP_INLINE_VISIBILITY - size_t hash_code() const _NOEXCEPT - { - return __impl::__hash(__type_name); - } - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 - bool operator==(const type_info& __arg) const _NOEXCEPT - { - // When evaluated in a constant expression, both type infos simply can't come - // from different translation units, so it is sufficient to compare their addresses. - if (__libcpp_is_constant_evaluated()) { - return this == &__arg; - } - return __impl::__eq(__type_name, __arg.__type_name); - } - -#if _LIBCPP_STD_VER <= 17 - _LIBCPP_INLINE_VISIBILITY - bool operator!=(const type_info& __arg) const _NOEXCEPT - { return !operator==(__arg); } -#endif -}; -#endif // defined(_LIBCPP_ABI_MICROSOFT) - -class _LIBCPP_EXPORTED_FROM_ABI bad_cast - : public exception -{ - public: - bad_cast() _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI bad_cast(const bad_cast&) _NOEXCEPT = default; - _LIBCPP_HIDE_FROM_ABI bad_cast& operator=(const bad_cast&) _NOEXCEPT = default; - ~bad_cast() _NOEXCEPT override; - const char* what() const _NOEXCEPT override; -}; - -class _LIBCPP_EXPORTED_FROM_ABI bad_typeid - : public exception -{ - public: - bad_typeid() _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI bad_typeid(const bad_typeid&) _NOEXCEPT = default; - _LIBCPP_HIDE_FROM_ABI bad_typeid& operator=(const bad_typeid&) _NOEXCEPT = default; - ~bad_typeid() _NOEXCEPT override; - const char* what() const _NOEXCEPT override; -}; - -} // namespace std - -#endif // defined(_LIBCPP_ABI_VCRUNTIME) - -#if defined(_LIBCPP_ABI_VCRUNTIME) && _HAS_EXCEPTIONS == 0 - -namespace std { - -class bad_cast : public exception { -public: - bad_cast() _NOEXCEPT : exception("bad cast") {} - -private: - bad_cast(const char* const __message) _NOEXCEPT : exception(__message) {} -}; - -class bad_typeid : public exception { -public: - bad_typeid() _NOEXCEPT : exception("bad typeid") {} - -private: - bad_typeid(const char* const __message) _NOEXCEPT : exception(__message) {} -}; - -} // namespace std - -#endif // defined(_LIBCPP_ABI_VCRUNTIME) && _HAS_EXCEPTIONS == 0 - -_LIBCPP_BEGIN_NAMESPACE_STD -_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY -void __throw_bad_cast() -{ -#ifndef _LIBCPP_HAS_NO_EXCEPTIONS - throw bad_cast(); -#else - _LIBCPP_VERBOSE_ABORT("bad_cast was thrown in -fno-exceptions mode"); -#endif -} -_LIBCPP_END_NAMESPACE_STD - #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 # include # include diff --git a/libcxx/utils/data/ignore_format.txt b/libcxx/utils/data/ignore_format.txt index 01038c75f4e13..7a1a26dcb5d10 100644 --- a/libcxx/utils/data/ignore_format.txt +++ b/libcxx/utils/data/ignore_format.txt @@ -464,7 +464,6 @@ libcxx/include/__tuple/tuple_like_ext.h libcxx/include/__tuple/tuple_size.h libcxx/include/__tuple/tuple_types.h libcxx/include/typeindex -libcxx/include/typeinfo libcxx/include/uchar.h libcxx/include/unordered_map libcxx/include/unordered_set From 722f03b8e240c41de08c6ad23e0e129ae5625789 Mon Sep 17 00:00:00 2001 From: Ivan Trofimov Date: Wed, 11 Oct 2023 18:55:06 +0300 Subject: [PATCH 2/2] + clang-format --- libcxx/include/__typeinfo/typeinfo.h | 253 ++++++++++++--------------- 1 file changed, 109 insertions(+), 144 deletions(-) diff --git a/libcxx/include/__typeinfo/typeinfo.h b/libcxx/include/__typeinfo/typeinfo.h index 474b1f419f5db..07b53af2b4785 100644 --- a/libcxx/include/__typeinfo/typeinfo.h +++ b/libcxx/include/__typeinfo/typeinfo.h @@ -23,57 +23,50 @@ #endif #if defined(_LIBCPP_ABI_VCRUNTIME) -#include +# include #else -namespace std // purposefully not using versioning namespace +namespace std // purposefully not using versioning namespace { -#if defined(_LIBCPP_ABI_MICROSOFT) +# if defined(_LIBCPP_ABI_MICROSOFT) -class _LIBCPP_EXPORTED_FROM_ABI type_info -{ - type_info& operator=(const type_info&); - type_info(const type_info&); +class _LIBCPP_EXPORTED_FROM_ABI type_info { + type_info& operator=(const type_info&); + type_info(const type_info&); - mutable struct { - const char *__undecorated_name; - const char __decorated_name[1]; - } __data; + mutable struct { + const char* __undecorated_name; + const char __decorated_name[1]; + } __data; - int __compare(const type_info &__rhs) const _NOEXCEPT; + int __compare(const type_info& __rhs) const _NOEXCEPT; public: - _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE - virtual ~type_info(); + _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE + virtual ~type_info(); - const char *name() const _NOEXCEPT; + const char* name() const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY - bool before(const type_info& __arg) const _NOEXCEPT { - return __compare(__arg) < 0; - } + _LIBCPP_INLINE_VISIBILITY bool before(const type_info& __arg) const _NOEXCEPT { return __compare(__arg) < 0; } - size_t hash_code() const _NOEXCEPT; + size_t hash_code() const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 - bool operator==(const type_info& __arg) const _NOEXCEPT { - // When evaluated in a constant expression, both type infos simply can't come - // from different translation units, so it is sufficient to compare their addresses. - if (__libcpp_is_constant_evaluated()) { - return this == &__arg; - } - return __compare(__arg) == 0; + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator==(const type_info& __arg) const _NOEXCEPT { + // When evaluated in a constant expression, both type infos simply can't come + // from different translation units, so it is sufficient to compare their addresses. + if (__libcpp_is_constant_evaluated()) { + return this == &__arg; } + return __compare(__arg) == 0; + } -#if _LIBCPP_STD_VER <= 17 - _LIBCPP_INLINE_VISIBILITY - bool operator!=(const type_info& __arg) const _NOEXCEPT - { return !operator==(__arg); } -#endif +# if _LIBCPP_STD_VER <= 17 + _LIBCPP_INLINE_VISIBILITY bool operator!=(const type_info& __arg) const _NOEXCEPT { return !operator==(__arg); } +# endif }; -#else // !defined(_LIBCPP_ABI_MICROSOFT) +# else // !defined(_LIBCPP_ABI_MICROSOFT) // ========================================================================== // // Implementations @@ -128,64 +121,62 @@ class _LIBCPP_EXPORTED_FROM_ABI type_info // This value can be overriden in the __config_site. When it's not overriden, // we pick a default implementation based on the platform here. -#ifndef _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION +# ifndef _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION - // Windows and AIX binaries can't merge typeinfos, so use the NonUnique implementation. -# if defined(_LIBCPP_OBJECT_FORMAT_COFF) || defined(_LIBCPP_OBJECT_FORMAT_XCOFF) -# define _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION 2 +// Windows and AIX binaries can't merge typeinfos, so use the NonUnique implementation. +# if defined(_LIBCPP_OBJECT_FORMAT_COFF) || defined(_LIBCPP_OBJECT_FORMAT_XCOFF) +# define _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION 2 - // On arm64 on Apple platforms, use the special NonUniqueARMRTTIBit implementation. -# elif defined(__APPLE__) && defined(__LP64__) && !defined(__x86_64__) -# define _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION 3 +// On arm64 on Apple platforms, use the special NonUniqueARMRTTIBit implementation. +# elif defined(__APPLE__) && defined(__LP64__) && !defined(__x86_64__) +# define _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION 3 - // On all other platforms, assume the Itanium C++ ABI and use the Unique implementation. -# else -# define _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION 1 -# endif -#endif +// On all other platforms, assume the Itanium C++ ABI and use the Unique implementation. +# else +# define _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION 1 +# endif +# endif struct __type_info_implementations { struct __string_impl_base { typedef const char* __type_name_t; - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - _LIBCPP_CONSTEXPR static const char* __type_name_to_string(__type_name_t __v) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR static const char* + __type_name_to_string(__type_name_t __v) _NOEXCEPT { return __v; } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - _LIBCPP_CONSTEXPR static __type_name_t __string_to_type_name(const char* __v) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR static __type_name_t + __string_to_type_name(const char* __v) _NOEXCEPT { return __v; } }; struct __unique_impl : __string_impl_base { - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - static size_t __hash(__type_name_t __v) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE static size_t __hash(__type_name_t __v) _NOEXCEPT { return reinterpret_cast(__v); } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - static bool __eq(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE static bool + __eq(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { return __lhs == __rhs; } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - static bool __lt(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE static bool + __lt(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { return __lhs < __rhs; } }; struct __non_unique_impl : __string_impl_base { - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - static size_t __hash(__type_name_t __ptr) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE static size_t __hash(__type_name_t __ptr) _NOEXCEPT { size_t __hash = 5381; while (unsigned char __c = static_cast(*__ptr++)) __hash = (__hash * 33) ^ __c; return __hash; } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - static bool __eq(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE static bool + __eq(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { return __lhs == __rhs || __builtin_strcmp(__lhs, __rhs) == 0; } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - static bool __lt(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE static bool + __lt(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { return __builtin_strcmp(__lhs, __rhs) < 0; } }; @@ -193,24 +184,22 @@ struct __type_info_implementations { struct __non_unique_arm_rtti_bit_impl { typedef uintptr_t __type_name_t; - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - static const char* __type_name_to_string(__type_name_t __v) _NOEXCEPT { - return reinterpret_cast(__v & - ~__non_unique_rtti_bit::value); + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE static const char* + __type_name_to_string(__type_name_t __v) _NOEXCEPT { + return reinterpret_cast(__v & ~__non_unique_rtti_bit::value); } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - static __type_name_t __string_to_type_name(const char* __v) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE static __type_name_t + __string_to_type_name(const char* __v) _NOEXCEPT { return reinterpret_cast<__type_name_t>(__v); } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - static size_t __hash(__type_name_t __v) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE static size_t __hash(__type_name_t __v) _NOEXCEPT { if (__is_type_name_unique(__v)) return __v; return __non_unique_impl::__hash(__type_name_to_string(__v)); } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - static bool __eq(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE static bool + __eq(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { if (__lhs == __rhs) return true; if (__is_type_name_unique(__lhs) || __is_type_name_unique(__rhs)) @@ -219,110 +208,88 @@ struct __type_info_implementations { return false; return __builtin_strcmp(__type_name_to_string(__lhs), __type_name_to_string(__rhs)) == 0; } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE - static bool __lt(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE static bool + __lt(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { if (__is_type_name_unique(__lhs) || __is_type_name_unique(__rhs)) return __lhs < __rhs; return __builtin_strcmp(__type_name_to_string(__lhs), __type_name_to_string(__rhs)) < 0; } - private: + private: // The unique bit is the top bit. It is expected that __type_name_t is 64 bits when // this implementation is actually used. - typedef integral_constant<__type_name_t, - (1ULL << ((__CHAR_BIT__ * sizeof(__type_name_t)) - 1))> __non_unique_rtti_bit; + typedef integral_constant<__type_name_t, (1ULL << ((__CHAR_BIT__ * sizeof(__type_name_t)) - 1))> + __non_unique_rtti_bit; - _LIBCPP_INLINE_VISIBILITY - static bool __is_type_name_unique(__type_name_t __lhs) _NOEXCEPT { + _LIBCPP_INLINE_VISIBILITY static bool __is_type_name_unique(__type_name_t __lhs) _NOEXCEPT { return !(__lhs & __non_unique_rtti_bit::value); } }; typedef -#if _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION == 1 - __unique_impl -#elif _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION == 2 - __non_unique_impl -#elif _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION == 3 - __non_unique_arm_rtti_bit_impl -#else -# error invalid configuration for _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION -#endif - __impl; +# if _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION == 1 + __unique_impl +# elif _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION == 2 + __non_unique_impl +# elif _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION == 3 + __non_unique_arm_rtti_bit_impl +# else +# error invalid configuration for _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION +# endif + __impl; }; -class _LIBCPP_EXPORTED_FROM_ABI type_info -{ +class _LIBCPP_EXPORTED_FROM_ABI type_info { type_info& operator=(const type_info&); type_info(const type_info&); - protected: - typedef __type_info_implementations::__impl __impl; +protected: + typedef __type_info_implementations::__impl __impl; - __impl::__type_name_t __type_name; + __impl::__type_name_t __type_name; - _LIBCPP_INLINE_VISIBILITY - explicit type_info(const char* __n) - : __type_name(__impl::__string_to_type_name(__n)) {} + _LIBCPP_INLINE_VISIBILITY explicit type_info(const char* __n) : __type_name(__impl::__string_to_type_name(__n)) {} public: - _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE - virtual ~type_info(); + _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE + virtual ~type_info(); - _LIBCPP_INLINE_VISIBILITY - const char* name() const _NOEXCEPT - { - return __impl::__type_name_to_string(__type_name); - } + _LIBCPP_INLINE_VISIBILITY const char* name() const _NOEXCEPT { return __impl::__type_name_to_string(__type_name); } - _LIBCPP_INLINE_VISIBILITY - bool before(const type_info& __arg) const _NOEXCEPT - { - return __impl::__lt(__type_name, __arg.__type_name); - } + _LIBCPP_INLINE_VISIBILITY bool before(const type_info& __arg) const _NOEXCEPT { + return __impl::__lt(__type_name, __arg.__type_name); + } - _LIBCPP_INLINE_VISIBILITY - size_t hash_code() const _NOEXCEPT - { - return __impl::__hash(__type_name); - } + _LIBCPP_INLINE_VISIBILITY size_t hash_code() const _NOEXCEPT { return __impl::__hash(__type_name); } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 - bool operator==(const type_info& __arg) const _NOEXCEPT - { - // When evaluated in a constant expression, both type infos simply can't come - // from different translation units, so it is sufficient to compare their addresses. - if (__libcpp_is_constant_evaluated()) { - return this == &__arg; - } - return __impl::__eq(__type_name, __arg.__type_name); + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 bool operator==(const type_info& __arg) const _NOEXCEPT { + // When evaluated in a constant expression, both type infos simply can't come + // from different translation units, so it is sufficient to compare their addresses. + if (__libcpp_is_constant_evaluated()) { + return this == &__arg; } + return __impl::__eq(__type_name, __arg.__type_name); + } -#if _LIBCPP_STD_VER <= 17 - _LIBCPP_INLINE_VISIBILITY - bool operator!=(const type_info& __arg) const _NOEXCEPT - { return !operator==(__arg); } -#endif +# if _LIBCPP_STD_VER <= 17 + _LIBCPP_INLINE_VISIBILITY bool operator!=(const type_info& __arg) const _NOEXCEPT { return !operator==(__arg); } +# endif }; -#endif // defined(_LIBCPP_ABI_MICROSOFT) +# endif // defined(_LIBCPP_ABI_MICROSOFT) -class _LIBCPP_EXPORTED_FROM_ABI bad_cast - : public exception -{ - public: +class _LIBCPP_EXPORTED_FROM_ABI bad_cast : public exception { +public: bad_cast() _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI bad_cast(const bad_cast&) _NOEXCEPT = default; + _LIBCPP_HIDE_FROM_ABI bad_cast(const bad_cast&) _NOEXCEPT = default; _LIBCPP_HIDE_FROM_ABI bad_cast& operator=(const bad_cast&) _NOEXCEPT = default; ~bad_cast() _NOEXCEPT override; const char* what() const _NOEXCEPT override; }; -class _LIBCPP_EXPORTED_FROM_ABI bad_typeid - : public exception -{ - public: +class _LIBCPP_EXPORTED_FROM_ABI bad_typeid : public exception { +public: bad_typeid() _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI bad_typeid(const bad_typeid&) _NOEXCEPT = default; + _LIBCPP_HIDE_FROM_ABI bad_typeid(const bad_typeid&) _NOEXCEPT = default; _LIBCPP_HIDE_FROM_ABI bad_typeid& operator=(const bad_typeid&) _NOEXCEPT = default; ~bad_typeid() _NOEXCEPT override; const char* what() const _NOEXCEPT override; @@ -357,13 +324,11 @@ class bad_typeid : public exception { #endif // defined(_LIBCPP_ABI_VCRUNTIME) && _HAS_EXCEPTIONS == 0 _LIBCPP_BEGIN_NAMESPACE_STD -_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY -void __throw_bad_cast() -{ +_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void __throw_bad_cast() { #ifndef _LIBCPP_HAS_NO_EXCEPTIONS - throw bad_cast(); + throw bad_cast(); #else - _LIBCPP_VERBOSE_ABORT("bad_cast was thrown in -fno-exceptions mode"); + _LIBCPP_VERBOSE_ABORT("bad_cast was thrown in -fno-exceptions mode"); #endif } _LIBCPP_END_NAMESPACE_STD