Skip to content

[libc++] [NFC] Split typeinfo header #68812

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from

Conversation

itrofimow
Copy link
Contributor

@itrofimow itrofimow commented Oct 11, 2023

This PR splits typeinfo header into public and private parts, with the purpose of simplifying #65534, which should be rebased onto this patch

@itrofimow itrofimow changed the title [libc++] Split type_info header [libc++] [NFC] Split type_info header Oct 11, 2023
@github-actions
Copy link

github-actions bot commented Oct 11, 2023

✅ With the latest revision this PR passed the C/C++ code formatter.

@itrofimow itrofimow marked this pull request as ready for review October 11, 2023 19:21
@itrofimow itrofimow requested a review from a team as a code owner October 11, 2023 19:21
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Oct 11, 2023
@llvmbot
Copy link
Member

llvmbot commented Oct 11, 2023

@llvm/pr-subscribers-libcxx

Author: None (itrofimow)

Changes

This PR splits type_info header into public and private parts, with the purpose of simplifying #65534, which should be rebased onto this patch


Patch is 29.22 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/68812.diff

6 Files Affected:

  • (modified) libcxx/include/CMakeLists.txt (+1)
  • (added) libcxx/include/__typeinfo/typeinfo.h (+336)
  • (modified) libcxx/include/libcxx.imp (+1)
  • (modified) libcxx/include/module.modulemap.in (+5)
  • (modified) libcxx/include/typeinfo (+1-353)
  • (modified) libcxx/utils/data/ignore_format.txt (-1)
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 4d98b8eed1afd65..bd4fb37d99834aa 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 000000000000000..07b53af2b478588
--- /dev/null
+++ b/libcxx/include/__typeinfo/typeinfo.h
@@ -0,0 +1,336 @@
+// -*- 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 <cstddef>
+#include <cstdint>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if defined(_LIBCPP_ABI_VCRUNTIME)
+#  include <vcruntime_typeinfo.h>
+#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<size_t>(__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<unsigned char>(*__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<const char*>(__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 3eb2aa849314824..f7e906e024f33a4 100644
--- a/libcxx/include/libcxx.imp
+++ b/libcxx/include/libcxx.imp
@@ -48,6 +48,7 @@
   { include: [ "@<__thread/.*>", "private", "<thread>", "public" ] },
   { include: [ "@<__tuple/.*>", "private", "<tuple>", "public" ] },
   { include: [ "@<__type_traits/.*>", "private", "<type_traits>", "public" ] },
+  { include: [ "@<__typeinfo/.*>", "private", "<typeinfo>", "public" ] },
   { include: [ "@<__utility/.*>", "private", "<utility>", "public" ] },
   { include: [ "@<__variant/.*>", "private", "<variant>", "public" ] },
 ]
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 09184af2732c83f..b8885379fa7d525 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 59bc291454c3d90..e869cd5e6750787 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 <cstddef>
-#include <cstdint>
+#include <__typeinfo/typeinfo.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-#if defined(_LIBCPP_ABI_VCRUNTIME)
-#include <vcruntime_typeinfo.h>
-#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 on...
[truncated]

@itrofimow itrofimow changed the title [libc++] [NFC] Split type_info header [libc++] [NFC] Split typeinfo header Oct 12, 2023
@itrofimow
Copy link
Contributor Author

Hi @philnik777!
This is a header-split part of #65534 which you suggested to be a separate PR, could you please have a look?

@ldionne ldionne requested a review from philnik777 October 12, 2023 23:25
@philnik777
Copy link
Contributor

I'm a bit confused. This looks like you should just remove some transitive include that we kept for compatibility. I think our current stance on include cycles that break us is to just remove the include and add a release note about it.

@itrofimow
Copy link
Contributor Author

itrofimow commented Oct 17, 2023

Sorry for confusing you, i'm not that familiar with how such things are handled.

Do i understand you correctly, that instead of splitting the header i should just remove the conditional #include <exception> from typeinfo and reverse the dependency (now exception would include typeinfo) instead?

If that's the case i would just do that in #65534 and close this PR.

@philnik777
Copy link
Contributor

Sorry for confusing you, i'm not that familiar with how such things are handled.

Do i understand you correctly, that instead of splitting the header i should just remove the conditional #include <exception> from typeinfo and reverse the dependency (now exception would include typeinfo) instead?

If that's the case i would just do that in #65534 and close this PR.

Yes, that's at least what I would do. We don't have any exact policy on this I think, but this seems to me like a reasonable potentially breaking change. These headers aren't used that much compared to other headers anyways. Sorry that I didn't spot this earlier. @ldionne do you agree?

@itrofimow itrofimow closed this Oct 20, 2023
@ldionne
Copy link
Member

ldionne commented Oct 20, 2023

Sorry for confusing you, i'm not that familiar with how such things are handled.
Do i understand you correctly, that instead of splitting the header i should just remove the conditional #include <exception> from typeinfo and reverse the dependency (now exception would include typeinfo) instead?
If that's the case i would just do that in #65534 and close this PR.

Yes, that's at least what I would do. We don't have any exact policy on this I think, but this seems to me like a reasonable potentially breaking change. These headers aren't used that much compared to other headers anyways. Sorry that I didn't spot this earlier. @ldionne do you agree?

That sounds like a reasonable not-too-badly-breaking change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants