forked from OSchip/llvm-project
ARM64: compare RTTI names as strings
ARM64 generates RTTI with hidden visibility, which means that typeinfo must be compared char-by-char since it's not guaranteed to be uniqued across the whole program. llvm-svn: 205139
This commit is contained in:
parent
c3a57e91ef
commit
0090e657cb
|
@ -568,6 +568,10 @@ template <unsigned> struct __static_assert_check {};
|
|||
#define _LIBCPP_EXTERN_TEMPLATE2(...) extern template __VA_ARGS__;
|
||||
#endif
|
||||
|
||||
#if __APPLE__ && defined(__LP64__) && !defined(__x86_64__)
|
||||
#define _LIBCPP_NONUNIQUE_RTTI_BIT (1ULL << 63)
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(_WIN32) || defined(__sun__) || defined(__NetBSD__)
|
||||
#define _LIBCPP_LOCALE__L_EXTENSIONS 1
|
||||
#endif
|
||||
|
|
|
@ -60,6 +60,7 @@ public:
|
|||
#include <__config>
|
||||
#include <exception>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
#pragma GCC system_header
|
||||
|
@ -73,32 +74,83 @@ class _LIBCPP_EXCEPTION_ABI type_info
|
|||
type_info& operator=(const type_info&);
|
||||
type_info(const type_info&);
|
||||
protected:
|
||||
#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
|
||||
const char* __type_name;
|
||||
#else
|
||||
// A const char* with the non-unique RTTI bit possibly set.
|
||||
uintptr_t __type_name;
|
||||
#endif
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
explicit type_info(const char* __n)
|
||||
#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
|
||||
: __type_name(__n) {}
|
||||
#else
|
||||
: __type_name(reinterpret_cast<uintptr_t>(__n)) {}
|
||||
#endif
|
||||
|
||||
public:
|
||||
virtual ~type_info();
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
const char* name() const _NOEXCEPT {return __type_name;}
|
||||
const char* name() const _NOEXCEPT
|
||||
#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
|
||||
{return __type_name;}
|
||||
#else
|
||||
{return reinterpret_cast<const char*>(__type_name & ~_LIBCPP_NONUNIQUE_RTTI_BIT);}
|
||||
#endif
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool before(const type_info& __arg) const _NOEXCEPT
|
||||
#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
|
||||
{return __type_name < __arg.__type_name;}
|
||||
#else
|
||||
{if (!((__type_name & __arg.__type_name) & _LIBCPP_NONUNIQUE_RTTI_BIT))
|
||||
return __type_name < __arg.__type_name;
|
||||
return __compare_nonunique_names(__arg) < 0;}
|
||||
#endif
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
size_t hash_code() const _NOEXCEPT
|
||||
#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
|
||||
{return *reinterpret_cast<const size_t*>(&__type_name);}
|
||||
#else
|
||||
{if (!(__type_name & _LIBCPP_NONUNIQUE_RTTI_BIT)) return __type_name;
|
||||
const char *__ptr = __name_for_load();
|
||||
size_t __hash = 5381;
|
||||
while (unsigned char __c = static_cast<unsigned char>(*__ptr++))
|
||||
__hash = (__hash * 33) ^ __c;
|
||||
return __hash;}
|
||||
#endif
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool operator==(const type_info& __arg) const _NOEXCEPT
|
||||
#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
|
||||
{return __type_name == __arg.__type_name;}
|
||||
#else
|
||||
{if (__type_name == __arg.__type_name) return true;
|
||||
if (!((__type_name & __arg.__type_name) & _LIBCPP_NONUNIQUE_RTTI_BIT))
|
||||
return false;
|
||||
return __compare_nonunique_names(__arg) == 0;}
|
||||
#endif
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool operator!=(const type_info& __arg) const _NOEXCEPT
|
||||
{return !operator==(__arg);}
|
||||
|
||||
#ifdef _LIBCPP_NONUNIQUE_RTTI_BIT
|
||||
private:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
int __compare_nonunique_names(const type_info &__arg) const _NOEXCEPT
|
||||
{return __builtin_strcmp(__name_for_load(), __arg.__name_for_load());}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
const char *__name_for_load() const _NOEXCEPT
|
||||
{uintptr_t __data = __type_name;
|
||||
#if 1
|
||||
__data &= ~_LIBCPP_NONUNIQUE_RTTI_BIT;
|
||||
#endif
|
||||
return reinterpret_cast<const char*>(__data);}
|
||||
#endif
|
||||
};
|
||||
|
||||
class _LIBCPP_EXCEPTION_ABI bad_cast
|
||||
|
|
Loading…
Reference in New Issue