compnerd set the repository for this revision to rL LLVM. compnerd updated this revision to Diff 83326.
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,45 @@ #include "typeinfo" +#if defined(_LIBCPP_HAS_MS_ABI_TYPEINFO) +#include <string.h> + +const char *std::type_info::__name(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 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 std::type_info::__data* __lhs, + const 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,15 @@ #pragma GCC system_header #endif +#if defined(_LIBCPP_ABI_MS) +#define _LIBCPP_HAS_MS_ABI_TYPEINFO +#else #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 +93,21 @@ { return __builtin_strcmp(name(), __arg.name()); } #endif +#if defined(_LIBCPP_HAS_MS_ABI_TYPEINFO) + mutable struct __data { + const char *__undecorated_name; + const char __decorated_name[1]; + } __data; + + static const char *__name(const type_info::__data *__data); + static size_t __hash(const type_info:__data *__data); + static int compare(const type_info::__data* __lhs, + const type_info::__data* __rhs); +#endif + protected: +#if defined(_LIBCPP_HAS_MS_ABI_TYPEINFO) +#else #if defined(_LIBCPP_HAS_NONUNIQUE_TYPEINFO) // A const char* with the non-unique RTTI bit possibly set. uintptr_t __type_name; @@ -102,10 +120,28 @@ _LIBCPP_INLINE_VISIBILITY type_info(const char* __n) : __type_name(__n) {} #endif +#endif public: virtual ~type_info(); +#if defined(_LIBCPP_HAS_MS_ABI_TYPEINFO) + _LIBCPP_INLINE_VISIBILITY + const char *name() const _NOEXCEPT + { return __name(&__data); } + + _LIBCPP_INLINE_VISIBILITY + bool before(const type_info& __arg) const _NOEXCEPT + { return __compre(&__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 +198,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