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 cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits