summaryrefslogtreecommitdiff
path: root/bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx')
-rw-r--r--bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx79
1 files changed, 70 insertions, 9 deletions
diff --git a/bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx b/bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx
index 0908c7666b50..577c318c5767 100644
--- a/bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx
@@ -18,6 +18,10 @@
*/
+#include <sal/config.h>
+
+#include <typeinfo>
+
#include <malloc.h>
#include <com/sun/star/uno/genfunc.hxx>
@@ -124,23 +128,80 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 1) * sizeof (Slot) + slotCount * codeSnippetSize;
}
+namespace {
+
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti {};
+
+// The following vtable RTTI data is based on how the code at
+// <https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/MicrosoftCXXABI.cpp> computes
+// such data:
+
+struct RttiClassHierarchyDescriptor;
+
+#pragma warning (push)
+#pragma warning (disable: 4324) // "structure was padded due to alignment specifier"
+
+struct alignas(16) RttiBaseClassDescriptor {
+ sal_uInt32 n0 = reinterpret_cast<sal_uInt32>(&typeid(ProxyRtti));
+ sal_uInt32 n1 = 0;
+ sal_uInt32 n2 = 0;
+ sal_uInt32 n3 = 0xFFFFFFFF;
+ sal_uInt32 n4 = 0;
+ sal_uInt32 n5 = 0x40;
+ sal_uInt32 n6;
+ RttiBaseClassDescriptor(RttiClassHierarchyDescriptor const * chd):
+ n6(reinterpret_cast<sal_uInt32>(chd)) {}
+};
+
+struct alignas(4) RttiBaseClassArray {
+ sal_uInt32 n0;
+ sal_uInt32 n1 = 0;
+ RttiBaseClassArray(RttiBaseClassDescriptor const * bcd): n0(reinterpret_cast<sal_uInt32>(bcd))
+ {}
+};
+
+struct alignas(4) RttiClassHierarchyDescriptor {
+ sal_uInt32 n0 = 0;
+ sal_uInt32 n1 = 0;
+ sal_uInt32 n2 = 1;
+ sal_uInt32 n3;
+ RttiClassHierarchyDescriptor(RttiBaseClassArray const * bca):
+ n3(reinterpret_cast<sal_uInt32>(bca)) {}
+};
+
+struct alignas(16) RttiCompleteObjectLocator {
+ sal_uInt32 n0 = 0;
+ sal_uInt32 n1 = 0;
+ sal_uInt32 n2 = 0;
+ sal_uInt32 n3 = reinterpret_cast<sal_uInt32>(&typeid(ProxyRtti));
+ sal_uInt32 n4;
+ RttiCompleteObjectLocator(RttiClassHierarchyDescriptor const * chd):
+ n4(reinterpret_cast<sal_uInt32>(chd)) {}
+};
+
+struct Rtti {
+ RttiBaseClassDescriptor bcd;
+ RttiBaseClassArray bca;
+ RttiClassHierarchyDescriptor chd;
+ RttiCompleteObjectLocator col;
+ Rtti(): bcd(&chd), bca(&bcd), chd(&bca), col(&chd) {}
+};
+
+#pragma warning (pop)
+
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
- struct Rtti {
- sal_Int32 n0, n1, n2;
- type_info * rtti;
- Rtti():
- n0(0), n1(0), n2(0),
- rtti(RTTInfos::get("com.sun.star.uno.XInterface"))
- {}
- };
static Rtti rtti;
Slot * slots = mapBlockToVtable(block);
- slots[-1].fn = &rtti;
+ slots[-1].fn = &rtti.col;
return slots + slotCount;
}