diff options
| author | Tim Northover <tnorthover@apple.com> | 2014-03-30 11:34:26 +0000 |
|---|---|---|
| committer | Tim Northover <tnorthover@apple.com> | 2014-03-30 11:34:26 +0000 |
| commit | 0090e657cb3a477ace4db59a6b5ae80baffec4c5 (patch) | |
| tree | 91758f66791d95f2ce310fec5365bcbc927bee5d /libcxx/include/typeinfo | |
| parent | c3a57e91ef32a57e54a16f5271e89a76a121bde1 (diff) | |
| download | bcm5719-llvm-0090e657cb3a477ace4db59a6b5ae80baffec4c5.tar.gz bcm5719-llvm-0090e657cb3a477ace4db59a6b5ae80baffec4c5.zip | |
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
Diffstat (limited to 'libcxx/include/typeinfo')
| -rw-r--r-- | libcxx/include/typeinfo | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/libcxx/include/typeinfo b/libcxx/include/typeinfo index 6ffee0f8a3c..7fcc8244068 100644 --- a/libcxx/include/typeinfo +++ b/libcxx/include/typeinfo @@ -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 |

