compnerd updated this revision to Diff 83489. compnerd added a comment. Rebase for r291329.
Repository: rL LLVM https://reviews.llvm.org/D28212 Files: include/typeinfo src/typeinfo.cpp
Index: src/typeinfo.cpp =================================================================== --- src/typeinfo.cpp +++ src/typeinfo.cpp @@ -15,6 +15,47 @@ #include "typeinfo" +#if defined(_LIBCPP_ABI_MICROSOFT) +#include <string.h> + +const char* std::type_info::__name(const struct std::type_info::__data* __data) +{ + // TODO(compnerd) cache demangled &__data.__decorated_name[1] + return &__data->__decorated_name[1]; +} + +size_t std::type_info::__hash(const struct std::type_info::__data* __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 struct std::type_info::__data* __lhs, + const struct std::type_info::__data* __rhs) +{ + if (__lhs == __rhs) + return 0; + return strcmp(&__lhs->__decorated_name[1], &__rhs->__decorated_name[1]); +} +#endif + #if defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) std::type_info::~type_info() { Index: include/typeinfo =================================================================== --- include/typeinfo +++ include/typeinfo @@ -69,11 +69,13 @@ #pragma GCC system_header #endif +#if !defined(_LIBCPP_ABI_MICROSOFT) #if defined(_LIBCPP_NONUNIQUE_RTTI_BIT) #define _LIBCPP_HAS_NONUNIQUE_TYPEINFO #else #define _LIBCPP_HAS_UNIQUE_TYPEINFO #endif +#endif namespace std // purposefully not using versioning namespace { @@ -89,7 +91,21 @@ { return __builtin_strcmp(name(), __arg.name()); } #endif +#if defined(_LIBCPP_ABI_MICROSOFT) + mutable struct __data { + const char *__undecorated_name; + const char __decorated_name[1]; + } __data; + + static const char *__name(const struct type_info::__data *__data); + static size_t __hash(const struct type_info::__data *__data); + static int __compare(const struct type_info::__data* __lls, + const struct type_info::__data* __rhs); +#endif + protected: +#if defined(_LIBCPP_ABI_MICROSOFT) +#else #if defined(_LIBCPP_HAS_NONUNIQUE_TYPEINFO) // A const char* with the non-unique RTTI bit possibly set. uintptr_t __type_name; @@ -102,10 +118,28 @@ _LIBCPP_INLINE_VISIBILITY type_info(const char* __n) : __type_name(__n) {} #endif +#endif public: virtual ~type_info(); +#if defined(_LIBCPP_ABI_MICROSOFT) + _LIBCPP_INLINE_VISIBILITY + const char *name() const _NOEXCEPT + { return __name(&__data); } + + _LIBCPP_INLINE_VISIBILITY + bool before(const type_info& __arg) const _NOEXCEPT + { return __compare(&__data, &__arg.__data) < 0; } + + _LIBCPP_INLINE_VISIBILITY + size_t hash_code() const _NOEXCEPT + { return __hash(&__data); } + + _LIBCPP_INLINE_VISIBILITY + bool operator==(const type_info& __arg) const _NOEXCEPT + { return __compare(&__data, &__arg.__data) == 0; } +#else #if defined(_LIBCPP_HAS_NONUNIQUE_TYPEINFO) _LIBCPP_INLINE_VISIBILITY const char* name() const _NOEXCEPT @@ -162,6 +196,7 @@ bool operator==(const type_info& __arg) const _NOEXCEPT { return __type_name == __arg.__type_name; } #endif +#endif _LIBCPP_INLINE_VISIBILITY bool operator!=(const type_info& __arg) const _NOEXCEPT
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits