EricWF removed rL LLVM as the repository for this revision.
EricWF updated this revision to Diff 82825.
EricWF added a comment.
Update with the prefered style changes. @compnerd please still this revision
back when ready.
https://reviews.llvm.org/D28212
Files:
include/typeinfo
src/typeinfo.cpp
Index: src/typeinfo.cpp
===================================================================
--- src/typeinfo.cpp
+++ src/typeinfo.cpp
@@ -14,13 +14,51 @@
#endif
#include "typeinfo"
+#include "cstring"
#if defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY)
std::type_info::~type_info()
{
}
#endif
+#if defined(_LIBCPP_HAS_WINDOWS_TYPEINFO)
+
+const char *std::type_info::__name(std::type_info::__data_t *__data) {
+ // TODO(compnerd) cache demangled &__data.__decorated_name[1]
+ return &__data->__decorated_name[1];
+}
+
+size_t std::type_info::__hash(const std::type_info::__data_t *__data) {
+#if defined(_WIN64)
+ static constexpr const size_t fnv_offset_basis = 14695981039346656037ull;
+ static constexpr const size_t fnv_prime = 10995116282110ull;
+#else
+ static constexpr const size_t fnv_offset_basis = 2166136261ull;
+ static constexpr const size_t fnv_prime = 16777619ull;
+#endif
+
+ size_t value = fnv_offset_basis;
+ for (const char *c = &__data->__decorated_name[1]; *c; ++c) {
+ value ^= static_cast<size_t>(static_cast<unsigned char>(*c));
+ value *= fnv_prime;
+ }
+
+#if defined(_WIN64)
+ value ^= value >> 32;
+#endif
+
+ return value;
+}
+
+int std::type_info::__compare(const std::type_info::__data_t *__lhs,
+ const std::type_info::__data_t *__rhs) {
+ if (__lhs == __rhs)
+ return 0;
+ return strcmp(&__lhs->__decorated_name[1], &__rhs->__decorated_name[1]);
+}
+#endif // _LIBCPP_HAS_WINDOWS_TYPEINFO
+
#if !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION)
std::bad_cast::bad_cast() _NOEXCEPT
Index: include/typeinfo
===================================================================
--- include/typeinfo
+++ include/typeinfo
@@ -69,86 +69,147 @@
#pragma GCC system_header
#endif
+#ifdef _LIBCPP_NONUNIQUE_RTTI_BIT
+#define _LIBCPP_HAS_NONUNIQUE_TYPEINFO
+#elif defined(_WIN32)
+#define _LIBCPP_HAS_WINDOWS_TYPEINFO
+#else
+#define _LIBCPP_HAS_UNIQUE_TYPEINFO
+#endif
+
namespace std // purposefully not using versioning namespace
{
class _LIBCPP_EXCEPTION_ABI type_info
{
type_info& operator=(const type_info&);
type_info(const type_info&);
+#if defined(_LIBCPP_HAS_WINDOWS_TYPEINFO)
+ static const char *__name(type_info::__data_t *__data);
+ static size_t __hash(const type_info::__data_t *__data);
+ static int __compare(const type_info::__data_t *__l,
+ const type_info::__data_t *__r);
+
+ mutable struct __data_t {
+ const char *__undecorated_name;
+ const char __decorated_name[1];
+ } __data;
+
+#elif defined(_LIBCPP_HAS_NONUNIQUE_TYPEINFO)
+ _LIBCPP_INLINE_VISIBILITY
+ int __compare_nonunique_names(const type_info &__arg) const _NOEXCEPT
+ { return __builtin_strcmp(name(), __arg.name()); }
+
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
+ uintptr_t __type_name // A const char* with the non-unique RTTI bit possibly set.
- _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)) {}
+protected:
+ const char* __type_name;
#endif
+protected:
+ inline _LIBCPP_INLINE_VISIBILITY
+ explicit type_info(const char* __n);
+
public:
- virtual ~type_info();
+ virtual ~type_info();
- _LIBCPP_INLINE_VISIBILITY
- 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
+ inline _LIBCPP_INLINE_VISIBILITY
+ const char* name() const _NOEXCEPT;
- _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
+ inline _LIBCPP_INLINE_VISIBILITY
+ bool before(const type_info& __arg) const _NOEXCEPT;
- _LIBCPP_INLINE_VISIBILITY
- size_t hash_code() const _NOEXCEPT
-#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
- {return reinterpret_cast<size_t>(__type_name);}
-#else
- {if (!(__type_name & _LIBCPP_NONUNIQUE_RTTI_BIT)) return __type_name;
- const char *__ptr = name();
- size_t __hash = 5381;
- while (unsigned char __c = static_cast<unsigned char>(*__ptr++))
- __hash = (__hash * 33) ^ __c;
- return __hash;}
-#endif
+ inline _LIBCPP_INLINE_VISIBILITY
+ size_t hash_code() const _NOEXCEPT;
- _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);}
+ inline _LIBCPP_INLINE_VISIBILITY
+ bool operator==(const type_info& __arg) const _NOEXCEPT;
-#ifdef _LIBCPP_NONUNIQUE_RTTI_BIT
- private:
- _LIBCPP_INLINE_VISIBILITY
- int __compare_nonunique_names(const type_info &__arg) const _NOEXCEPT
- {return __builtin_strcmp(name(), __arg.name());}
-#endif
+ _LIBCPP_INLINE_VISIBILITY
+ bool operator!=(const type_info& __arg) const _NOEXCEPT
+ { return !operator==(__arg); }
};
+#if defined(_LIBCPP_HAS_WINDOWS_TYPEINFO)
+
+// FIXME(compnerd): What should be done about this constructor?
+type_info::type_info(const char* __n)
+ : __data{__n} {}
+
+const char* type_info::name() const _NOEXCEPT {
+ return __name(&__data);
+}
+
+bool type_info::before(const type_info& __arg) const _NOEXCEPT {
+ return __compare(&__data, &__arg.__data) < 0;
+}
+
+size_t type_info::hash_code() const _NOEXCEPT {
+ return __hash(&__data);
+}
+
+bool type_info::operator==(const type_info& __arg) const _NOEXCEPT {
+ return __compare(&__data, &__arg.__data) == 0;
+}
+
+#elif defined(_LIBCPP_HAS_NONUNIQUE_TYPEINFO)
+
+type_info::type_info(const char* __n)
+ : __type_name(reinterpret_cast<uintptr_t>(__n)) {}
+
+const char* type_info::name() const _NOEXCEPT {
+ return reinterpret_cast<const char*>(__type_name & ~_LIBCPP_NONUNIQUE_RTTI_BIT);
+}
+
+bool type_info::before(const type_info& __arg) const _NOEXCEPT {
+ if (!((__type_name & __arg.__type_name) & _LIBCPP_NONUNIQUE_RTTI_BIT))
+ return __type_name < __arg.__type_name;
+ return __compare_nonunique_names(__arg) < 0;
+}
+
+size_t type_info::hash_code() const _NOEXCEPT {
+ if (!(__type_name & _LIBCPP_NONUNIQUE_RTTI_BIT))
+ return __type_name;
+ const char *__ptr = name();
+ size_t __hash = 5381;
+ while (unsigned char __c = static_cast<unsigned char>(*__ptr++))
+ __hash = (__hash * 33) ^ __c;
+ return __hash;
+}
+
+bool type_info::operator==(const type_info& __arg) const _NOEXCEPT {
+ 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;
+}
+
+#else
+
+type_info::type_info(const char* __n)
+ : __type_name(__n) {}
+
+const char* type_info::name() const _NOEXCEPT {
+ return __type_name;
+}
+
+bool type_info::before(const type_info& __arg) const _NOEXCEPT {
+ return __type_name < __arg.__type_name;
+}
+
+size_t type_info::hash_code() const _NOEXCEPT {
+ return reinterpret_cast<size_t>(__type_name);
+}
+
+bool type_info::operator==(const type_info& __arg) const _NOEXCEPT {
+ return __type_name == __arg.__type_name;
+}
+#endif // _LIBCPP_HAS_WINDOWS_TYPEINFO
+
class _LIBCPP_EXCEPTION_ABI bad_cast
: public exception
{
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits