[libcxx] r313344 - typeinfo: provide a partial implementation for Win32

Saleem Abdulrasool via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 14 22:42:39 PDT 2017


Author: compnerd
Date: Thu Sep 14 22:42:39 2017
New Revision: 313344

URL: http://llvm.org/viewvc/llvm-project?rev=313344&view=rev
Log:
typeinfo: provide a partial implementation for Win32

The RTTI structure is different on Windows when building under MS ABI.
Update the definition to reflect this. The structure itself contains an
area for caching the undecorated name (which is 0-initialized). The
decorated name has a bitfield followed by the linkage name. When
std::type_info::name is invoked for the first time, the runtime should
undecorate the name, cache it, and return the undecorated name. This
requires access to an implementation of __unDName. For now, return
the raw name.

This uses the fnv-1a hash to hash the name of the RTTI. We could use an
alternate hash (murmur? city?), but, this was the quickest to throw
together.

Modified:
    libcxx/trunk/include/typeinfo
    libcxx/trunk/src/support/runtime/exception_msvc.ipp
    libcxx/trunk/src/typeinfo.cpp

Modified: libcxx/trunk/include/typeinfo
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/typeinfo?rev=313344&r1=313343&r2=313344&view=diff
==============================================================================
--- libcxx/trunk/include/typeinfo (original)
+++ libcxx/trunk/include/typeinfo Thu Sep 14 22:42:39 2017
@@ -69,18 +69,17 @@ public:
 #pragma GCC system_header
 #endif
 
-#if defined(_LIBCPP_ABI_MICROSOFT)
-#include <vcruntime_typeinfo.h>
-#elif defined(_LIBCPP_NONUNIQUE_RTTI_BIT)
+#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
 {
 
-#if !defined(_LIBCPP_ABI_MICROSOFT)
 class _LIBCPP_EXCEPTION_ABI type_info
 {
     type_info& operator=(const type_info&);
@@ -92,7 +91,17 @@ class _LIBCPP_EXCEPTION_ABI type_info
     { return __builtin_strcmp(name(), __arg.name()); }
 #endif
 
+#if defined(_LIBCPP_ABI_MICROSOFT)
+    mutable struct {
+      const char *__undecorated_name;
+      const char __decorated_name[1];
+    } __data;
+
+    int __compare(const struct type_info &__rhs) const _NOEXCEPT;
+#endif // _LIBCPP_ABI_MICROSOFT
+
 protected:
+#if !defined(_LIBCPP_ABI_MICROSOFT)
 #if defined(_LIBCPP_HAS_NONUNIQUE_TYPEINFO)
     // A const char* with the non-unique RTTI bit possibly set.
     uintptr_t __type_name;
@@ -106,11 +115,27 @@ protected:
     _LIBCPP_INLINE_VISIBILITY
     explicit type_info(const char* __n) : __type_name(__n) {}
 #endif
+#endif // ! _LIBCPP_ABI_MICROSOFT
 
 public:
     _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE
     virtual ~type_info();
 
+#if defined(_LIBCPP_ABI_MICROSOFT)
+    const char *name() const _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool before(const type_info& __arg) const _NOEXCEPT {
+      return __compare(__arg) < 0;
+    }
+
+    size_t hash_code() const _NOEXCEPT;
+
+    _LIBCPP_INLINE_VISIBILITY
+    bool operator==(const type_info& __arg) const _NOEXCEPT {
+      return __compare(__arg) == 0;
+    }
+#else
 #if defined(_LIBCPP_HAS_NONUNIQUE_TYPEINFO)
     _LIBCPP_INLINE_VISIBILITY
     const char* name() const _NOEXCEPT
@@ -167,6 +192,7 @@ public:
     bool operator==(const type_info& __arg) const _NOEXCEPT
     { return __type_name == __arg.__type_name; }
 #endif
+#endif // _LIBCPP_ABI_MICROSOFT
 
     _LIBCPP_INLINE_VISIBILITY
     bool operator!=(const type_info& __arg) const _NOEXCEPT
@@ -191,8 +217,6 @@ public:
     virtual const char* what() const _NOEXCEPT;
 };
 
-#endif // !_LIBCPP_ABI_MICROSOFT
-
 }  // std
 
 _LIBCPP_BEGIN_NAMESPACE_STD

Modified: libcxx/trunk/src/support/runtime/exception_msvc.ipp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/support/runtime/exception_msvc.ipp?rev=313344&r1=313343&r2=313344&view=diff
==============================================================================
--- libcxx/trunk/src/support/runtime/exception_msvc.ipp (original)
+++ libcxx/trunk/src/support/runtime/exception_msvc.ipp Thu Sep 14 22:42:39 2017
@@ -86,4 +86,32 @@ bad_array_length::what() const _NOEXCEPT
     return "bad_array_length";
 }
 
+bad_cast::bad_cast() _NOEXCEPT
+{
+}
+
+bad_cast::~bad_cast() _NOEXCEPT
+{
+}
+
+const char *
+bad_cast::what() const _NOEXCEPT
+{
+  return "std::bad_cast";
+}
+
+bad_typeid::bad_typeid() _NOEXCEPT
+{
+}
+
+bad_typeid::~bad_typeid() _NOEXCEPT
+{
+}
+
+const char *
+bad_typeid::what() const _NOEXCEPT
+{
+  return "std::bad_typeid";
+}
+
 } // namespace std

Modified: libcxx/trunk/src/typeinfo.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/typeinfo.cpp?rev=313344&r1=313343&r2=313344&view=diff
==============================================================================
--- libcxx/trunk/src/typeinfo.cpp (original)
+++ libcxx/trunk/src/typeinfo.cpp Thu Sep 14 22:42:39 2017
@@ -9,11 +9,48 @@
 
 #include "typeinfo"
 
+#if defined(_LIBCPP_ABI_MICROSOFT)
+#include <string.h>
+
+int std::type_info::__compare(const type_info &__rhs) const _NOEXCEPT {
+  if (&__data == &__rhs.__data)
+    return 0;
+  return strcmp(&__data.__decorated_name[1], &__rhs.__data.__decorated_name[1]);
+}
+
+const char *std::type_info::name() const _NOEXCEPT {
+  // TODO(compnerd) cache demangled &__data.__decorated_name[1]
+  return &__data.__decorated_name[1];
+}
+
+size_t std::type_info::hash_code() const _NOEXCEPT {
+#if defined(_WIN64)
+  constexpr size_t fnv_offset_basis = 14695981039346656037ull;
+  constexpr size_t fnv_prime = 10995116282110ull;
+#else
+  constexpr size_t fnv_offset_basis = 2166136261ull;
+  constexpr 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;
+}
+#endif // _LIBCPP_ABI_MICROSOFT
+
 // FIXME: Remove __APPLE__ default here once buildit is gone.
-#if (!defined(_LIBCPP_ABI_MICROSOFT) && !defined(LIBCXX_BUILDING_LIBCXXABI) && \
-    !defined(LIBCXXRT) && !defined(__GLIBCXX__) && \
-    !defined(__APPLE__)) || \
-    defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) // FIXME: remove this configuration.
+// FIXME: Remove the _LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY configuration.
+#if (!defined(LIBCXX_BUILDING_LIBCXXABI) && !defined(LIBCXXRT) &&              \
+     !defined(__GLIBCXX__) && !defined(__APPLE__)) ||                          \
+    defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY)
 std::type_info::~type_info()
 {
 }




More information about the cfe-commits mailing list