Add __CxxDetectRethrow(),  __CxxQueryExceptionSize().
Constify parameters (enabling static RTTI).
Move type definitions into a header for sharing with cpp.c objects.

diff --git a/dlls/msvcrt/cppexcept.c b/dlls/msvcrt/cppexcept.c
index 851e5f1..b0437f7 100644
--- a/dlls/msvcrt/cppexcept.c
+++ b/dlls/msvcrt/cppexcept.c
@@ -32,102 +32,10 @@
 #include "excpt.h"
 #include "wine/debug.h"
 
+#include "cppexcept.h"
+
 WINE_DEFAULT_DEBUG_CHANNEL(seh);
 
-#define CXX_FRAME_MAGIC    0x19930520
-#define CXX_EXCEPTION      0xe06d7363
-
-typedef struct __type_info
-{
-  void *vtable;
-  void *data;
-  char name[1];
-} type_info;
-
-/* the exception frame used by CxxFrameHandler */
-typedef struct __cxx_exception_frame
-{
-    EXCEPTION_FRAME  frame;    /* the standard exception frame */
-    int              trylevel;
-    DWORD            ebp;
-} cxx_exception_frame;
-
-/* info about a single catch {} block */
-typedef struct __catchblock_info
-{
-    UINT       flags;         /* flags (see below) */
-    type_info *type_info;     /* C++ type caught by this block */
-    int        offset;        /* stack offset to copy exception object to */
-    void     (*handler)();    /* catch block handler code */
-} catchblock_info;
-#define TYPE_FLAG_CONST      1
-#define TYPE_FLAG_VOLATILE   2
-#define TYPE_FLAG_REFERENCE  8
-
-/* info about a single try {} block */
-typedef struct __tryblock_info
-{
-    int              start_level;      /* start trylevel of that block */
-    int              end_level;        /* end trylevel of that block */
-    int              catch_level;      /* initial trylevel of the catch block */
-    int              catchblock_count; /* count of catch blocks in array */
-    catchblock_info *catchblock;       /* array of catch blocks */
-} tryblock_info;
-
-/* info about the unwind handler for a given trylevel */
-typedef struct __unwind_info
-{
-    int    prev;          /* prev trylevel unwind handler, to run after this one */
-    void (*handler)();    /* unwind handler */
-} unwind_info;
-
-/* descriptor of all try blocks of a given function */
-typedef struct __cxx_function_descr
-{
-    UINT           magic;          /* must be CXX_FRAME_MAGIC */
-    UINT           unwind_count;   /* number of unwind handlers */
-    unwind_info   *unwind_table;   /* array of unwind handlers */
-    UINT           tryblock_count; /* number of try blocks */
-    tryblock_info *tryblock;       /* array of try blocks */
-    UINT           unknown[3];
-} cxx_function_descr;
-
-/* complete information about a C++ type */
-typedef struct __cxx_type_info
-{
-    UINT        flags;         /* flags (see CLASS_* flags below) */
-    type_info  *type_info;     /* C++ type info */
-    int         this_offset;   /* offset of base class this pointer from start of object */
-    int         vbase_descr;   /* offset of virtual base class descriptor */
-    int         vbase_offset;  /* offset of this pointer offset in virtual base class descriptor */
-    size_t      size;          /* object size */
-    void      (*copy_ctor)();  /* copy constructor */
-} cxx_type_info;
-#define CLASS_IS_SIMPLE_TYPE          1
-#define CLASS_HAS_VIRTUAL_BASE_CLASS  4
-
-/* table of C++ types that apply for a given object */
-typedef struct __cxx_type_info_table
-{
-    UINT           count;     /* number of types */
-    cxx_type_info *info[1];   /* array of types */
-} cxx_type_info_table;
-
-typedef DWORD (*cxx_exc_custom_handler)( PEXCEPTION_RECORD, cxx_exception_frame*,
-                                         PCONTEXT, struct __EXCEPTION_FRAME**,
-                                         cxx_function_descr*, int nested_trylevel,
-                                         EXCEPTION_FRAME *nested_frame, DWORD unknown3 );
-
-/* type information for an exception object */
-typedef struct __cxx_exception_type
-{
-    UINT                   flags;            /* TYPE_FLAG flags */
-    void                 (*destructor)();    /* exception object destructor */
-    cxx_exc_custom_handler custom_handler;   /* custom handler for this exception */
-    cxx_type_info_table   *type_info_table;  /* list of types for this exception object */
-} cxx_exception_type;
-
-
 #ifdef __i386__  /* CxxFrameHandler is not supported on non-i386 */
 
 static DWORD cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame,
@@ -163,18 +71,17 @@
     __asm__ __volatile__("call *%0" : : "r" (func), "c" (object) : "eax", "edx", "memory" );
 }
 
-
-static void dump_type( cxx_type_info *type )
+static void dump_type( const cxx_type_info *type )
 {
     DPRINTF( "flags %x type %p", type->flags, type->type_info );
-    if (type->type_info) DPRINTF( " (%p %s)", type->type_info->data, type->type_info->name );
+    if (type->type_info) DPRINTF( " (%p %s)", type->type_info->name, type->type_info->mangled );
     DPRINTF( " offset %d vbase %d,%d size %d copy ctor %p\n", type->this_offset,
              type->vbase_descr, type->vbase_offset, type->size, type->copy_ctor );
 }
 
-static void dump_exception_type( cxx_exception_type *type )
+static void dump_exception_type( const cxx_exception_type *type )
 {
-    int i;
+    UINT i;
 
     DPRINTF( "exception type:\n" );
     DPRINTF( "flags %x destr %p handler %p type info %p\n",
@@ -186,9 +93,10 @@
     }
 }
 
-static void dump_function_descr( cxx_function_descr *descr, cxx_exception_type *info )
+static void dump_function_descr( const cxx_function_descr *descr, const cxx_exception_type *info )
 {
-    int i, j;
+    UINT i;
+    int j;
 
     DPRINTF( "function descr:\n" );
     DPRINTF( "magic %x\n", descr->magic );
@@ -210,14 +118,14 @@
             catchblock_info *ptr = &descr->tryblock[i].catchblock[j];
             DPRINTF( "        %d: flags %x offset %d handler %p type %p",
                      j, ptr->flags, ptr->offset, ptr->handler, ptr->type_info );
-            if (ptr->type_info) DPRINTF( " (%p %s)", ptr->type_info->data, ptr->type_info->name );
+            if (ptr->type_info) DPRINTF( " (%p %s)", ptr->type_info->name, ptr->type_info->mangled );
             DPRINTF( "\n" );
         }
     }
 }
 
 /* compute the this pointer for a base class of a given type */
-static void *get_this_pointer( cxx_type_info *type, void *object )
+static void *get_this_pointer( const cxx_type_info *type, void *object )
 {
     void *this_ptr;
     int *offset_ptr;
@@ -236,18 +144,18 @@
 }
 
 /* check if the exception type is caught by a given catch block, and return the type that matched */
-static cxx_type_info *find_caught_type( cxx_exception_type *exc_type, catchblock_info *catchblock )
+static const cxx_type_info *find_caught_type( cxx_exception_type *exc_type, catchblock_info *catchblock )
 {
     UINT i;
 
     for (i = 0; i < exc_type->type_info_table->count; i++)
     {
-        cxx_type_info *type = exc_type->type_info_table->info[i];
+        const cxx_type_info *type = exc_type->type_info_table->info[i];
 
         if (!catchblock->type_info) return type;   /* catch(...) matches any type */
         if (catchblock->type_info != type->type_info)
         {
-            if (strcmp( catchblock->type_info->name, type->type_info->name )) continue;
+            if (strcmp( catchblock->type_info->mangled, type->type_info->mangled )) continue;
         }
         /* type is the same, now check the flags */
         if ((exc_type->flags & TYPE_FLAG_CONST) &&
@@ -262,11 +170,11 @@
 
 /* copy the exception object where the catch block wants it */
 static void copy_exception( void *object, cxx_exception_frame *frame,
-                            catchblock_info *catchblock, cxx_type_info *type )
+                            catchblock_info *catchblock, const cxx_type_info *type )
 {
     void **dest_ptr;
 
-    if (!catchblock->type_info || !catchblock->type_info->name[0]) return;
+    if (!catchblock->type_info || !catchblock->type_info->mangled[0]) return;
     if (!catchblock->offset) return;
     dest_ptr = (void **)((char *)&frame->ebp + catchblock->offset);
 
@@ -351,7 +259,8 @@
                                       cxx_function_descr *descr, int nested_trylevel,
                                       cxx_exception_type *info )
 {
-    int i, j;
+    UINT i;
+    int j;
     void *addr, *object = (void *)rec->ExceptionInformation[1];
     struct catch_func_nested_frame nested_frame;
     int trylevel = frame->trylevel;
@@ -368,7 +277,7 @@
         for (j = 0; j < tryblock->catchblock_count; j++)
         {
             catchblock_info *catchblock = &tryblock->catchblock[j];
-            cxx_type_info *type = find_caught_type( info, catchblock );
+            const cxx_type_info *type = find_caught_type( info, catchblock );
             if (!type) continue;
 
             TRACE( "matched type %p in tryblock %d catchblock %d\n", type, i, j );
@@ -484,7 +393,7 @@
 /*********************************************************************
  *		_CxxThrowException (MSVCRT.@)
  */
-void _CxxThrowException( void *object, cxx_exception_type *type )
+void _CxxThrowException( void *object, const cxx_exception_type *type )
 {
     DWORD args[3];
 
@@ -493,3 +402,34 @@
     args[2] = (DWORD)type;
     RaiseException( CXX_EXCEPTION, EH_NONCONTINUABLE, 3, args );
 }
+
+/*********************************************************************
+ *		__CxxDetectRethrow (MSVCRT.@)
+ */
+BOOL __CxxDetectRethrow(PEXCEPTION_POINTERS ptrs)
+{
+  PEXCEPTION_RECORD rec;
+
+  if (!ptrs)
+    return FALSE;
+
+  rec = ptrs->ExceptionRecord;
+
+  if (rec->ExceptionCode == CXX_EXCEPTION &&
+      rec->NumberParameters == 3 &&
+      rec->ExceptionInformation[0] == CXX_FRAME_MAGIC &&
+      rec->ExceptionInformation[2])
+  {
+    ptrs->ExceptionRecord = msvcrt_get_thread_data()->exc_record;
+    return TRUE;
+  }
+  return (msvcrt_get_thread_data()->exc_record == rec);
+}
+
+/*********************************************************************
+ *		__CxxQueryExceptionSize (MSVCRT.@)
+ */
+unsigned int __CxxQueryExceptionSize(void)
+{
+  return sizeof(cxx_exception_type);
+}