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

Reply via email to