summaryrefslogtreecommitdiffstats
path: root/libcxx/include/typeinfo
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2014-03-30 11:34:26 +0000
committerTim Northover <tnorthover@apple.com>2014-03-30 11:34:26 +0000
commit0090e657cb3a477ace4db59a6b5ae80baffec4c5 (patch)
tree91758f66791d95f2ce310fec5365bcbc927bee5d /libcxx/include/typeinfo
parentc3a57e91ef32a57e54a16f5271e89a76a121bde1 (diff)
downloadbcm5719-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/typeinfo54
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
OpenPOWER on IntegriCloud