[CRT]
authorThomas Faber <thomas.faber@reactos.org>
Fri, 25 Apr 2014 20:01:08 +0000 (20:01 +0000)
committerThomas Faber <thomas.faber@reactos.org>
Fri, 25 Apr 2014 20:01:08 +0000 (20:01 +0000)
- Sync get_this_pointer with Wine. Fixes crash in msvcrt_winetest:cpp
- Sync undname.c with Wine. Fixes assertion failure in msvcrt_winetest:cpp

svn path=/trunk/; revision=62967

reactos/lib/sdk/crt/except/cpp.c
reactos/lib/sdk/crt/include/internal/wine/cppexcept.h
reactos/lib/sdk/crt/include/internal/wine/msvcrt.h
reactos/lib/sdk/crt/wine/undname.c

index 402734e..f54e8a7 100644 (file)
@@ -604,7 +604,7 @@ const char * __stdcall MSVCRT_type_info_name(type_info * _this)
      * Is this '.' really part of the mangled name, or has it some other meaning ?
      */
     char* name = __unDName(0, _this->mangled + 1, 0,
-                           MSVCRT_malloc, MSVCRT_free, 0x2800);
+                           MSVCRT_malloc, MSVCRT_free, UNDNAME_NO_ARGUMENTS | UNDNAME_32_BIT_DECODE);
     if (name)
     {
       size_t len = strlen(name);
index d1b60c3..d4dbbee 100644 (file)
@@ -164,20 +164,21 @@ static inline const char *dbgstr_type_info( const type_info *info )
 /* compute the this pointer for a base class of a given type */
 static inline void *get_this_pointer( const this_ptr_offsets *off, void *object )
 {
-    void *this_ptr;
-    int *offset_ptr;
-
     if (!object) return NULL;
-    this_ptr = (char *)object + off->this_offset;
+
     if (off->vbase_descr >= 0)
     {
+        int *offset_ptr;
+
         /* move this ptr to vbase descriptor */
-        this_ptr = (char *)this_ptr + off->vbase_descr;
+        object = (char *)object + off->vbase_descr;
         /* and fetch additional offset from vbase descriptor */
-        offset_ptr = (int *)(*(char **)this_ptr + off->vbase_offset);
-        this_ptr = (char *)this_ptr + *offset_ptr;
+        offset_ptr = (int *)(*(char **)object + off->vbase_offset);
+        object = (char *)object + *offset_ptr;
     }
-    return this_ptr;
+
+    object = (char *)object + off->this_offset;
+    return object;
 }
 
 #endif /* __MSVCRT_CPPEXCEPT_H */
index f4d30aa..319075a 100644 (file)
@@ -81,9 +81,6 @@ void __cdecl MSVCRT_operator_delete(void*);
 typedef void* (__cdecl *malloc_func_t)(size_t);
 typedef void  (__cdecl *free_func_t)(void*);
 
-extern char* __cdecl __unDName(char *,const char*,int,malloc_func_t,free_func_t,unsigned short int);
-extern char* __cdecl __unDNameEx(char *,const char*,int,malloc_func_t,free_func_t,void *,unsigned short int);
-
 /* Setup and teardown multi threaded locks */
 extern void msvcrt_init_mt_locks(void);
 extern void msvcrt_free_mt_locks(void);
@@ -119,6 +116,28 @@ extern unsigned create_io_inherit_block(WORD*, BYTE**);
 #define MSVCRT__OUT_TO_MSGBOX  2
 #define MSVCRT__REPORT_ERRMODE 3
 
+extern char* __cdecl __unDName(char *,const char*,int,malloc_func_t,free_func_t,unsigned short int);
+
+/* __unDName/__unDNameEx flags */
+#define UNDNAME_COMPLETE                 (0x0000)
+#define UNDNAME_NO_LEADING_UNDERSCORES   (0x0001) /* Don't show __ in calling convention */
+#define UNDNAME_NO_MS_KEYWORDS           (0x0002) /* Don't show calling convention at all */
+#define UNDNAME_NO_FUNCTION_RETURNS      (0x0004) /* Don't show function/method return value */
+#define UNDNAME_NO_ALLOCATION_MODEL      (0x0008)
+#define UNDNAME_NO_ALLOCATION_LANGUAGE   (0x0010)
+#define UNDNAME_NO_MS_THISTYPE           (0x0020)
+#define UNDNAME_NO_CV_THISTYPE           (0x0040)
+#define UNDNAME_NO_THISTYPE              (0x0060)
+#define UNDNAME_NO_ACCESS_SPECIFIERS     (0x0080) /* Don't show access specifier (public/protected/private) */
+#define UNDNAME_NO_THROW_SIGNATURES      (0x0100)
+#define UNDNAME_NO_MEMBER_TYPE           (0x0200) /* Don't show static/virtual specifier */
+#define UNDNAME_NO_RETURN_UDT_MODEL      (0x0400)
+#define UNDNAME_32_BIT_DECODE            (0x0800)
+#define UNDNAME_NAME_ONLY                (0x1000) /* Only report the variable/method name */
+#define UNDNAME_NO_ARGUMENTS             (0x2000) /* Don't show method arguments */
+#define UNDNAME_NO_SPECIAL_SYMS          (0x4000)
+#define UNDNAME_NO_COMPLEX_TYPE          (0x8000)
+
 typedef void (*float_handler)(int, int);
 void _default_handler(int signal);
 typedef struct _sig_element
index 71956f6..4d64a4a 100644 (file)
@@ -33,25 +33,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
  * - back-port this new code into tools/winedump/msmangle.c
  */
 
-#define UNDNAME_COMPLETE                 (0x0000)
-#define UNDNAME_NO_LEADING_UNDERSCORES   (0x0001) /* Don't show __ in calling convention */
-#define UNDNAME_NO_MS_KEYWORDS           (0x0002) /* Don't show calling convention at all */
-#define UNDNAME_NO_FUNCTION_RETURNS      (0x0004) /* Don't show function/method return value */
-#define UNDNAME_NO_ALLOCATION_MODEL      (0x0008)
-#define UNDNAME_NO_ALLOCATION_LANGUAGE   (0x0010)
-#define UNDNAME_NO_MS_THISTYPE           (0x0020)
-#define UNDNAME_NO_CV_THISTYPE           (0x0040)
-#define UNDNAME_NO_THISTYPE              (0x0060)
-#define UNDNAME_NO_ACCESS_SPECIFIERS     (0x0080) /* Don't show access specifier (public/protected/private) */
-#define UNDNAME_NO_THROW_SIGNATURES      (0x0100)
-#define UNDNAME_NO_MEMBER_TYPE           (0x0200) /* Don't show static/virtual specifier */
-#define UNDNAME_NO_RETURN_UDT_MODEL      (0x0400)
-#define UNDNAME_32_BIT_DECODE            (0x0800)
-#define UNDNAME_NAME_ONLY                (0x1000) /* Only report the variable/method name */
-#define UNDNAME_NO_ARGUMENTS             (0x2000) /* Don't show method arguments */
-#define UNDNAME_NO_SPECIAL_SYMS          (0x4000)
-#define UNDNAME_NO_COMPLEX_TYPE          (0x8000)
-
 /* How data types modifiers are stored:
  * M (in the following definitions) is defined for
  * 'A', 'B', 'C' and 'D' as follows
@@ -267,7 +248,7 @@ static char* str_printf(struct parsed_symbol* sym, const char* format, ...)
             {
             case 's': t = va_arg(args, char*); if (t) len += (int)strlen(t); break;
             case 'c': (void)va_arg(args, int); len++; break;
-            default: i--; /* fall thru */
+            default: i--; /* fall through */
             case '%': len++; break;
             }
         }
@@ -294,7 +275,7 @@ static char* str_printf(struct parsed_symbol* sym, const char* format, ...)
             case 'c':
                 *p++ = (char)va_arg(args, int);
                 break;
-            default: i--; /* fall thru */
+            default: i--; /* fall through */
             case '%': *p++ = '%'; break;
             }
         }
@@ -348,7 +329,7 @@ static const char* get_number(struct parsed_symbol* sym)
         if (*sym->current != '@') return NULL;
 
         ptr = und_alloc(sym, 17);
-        sprintf(ptr, "%s%d", sgn ? "-" : "", ret);
+        sprintf(ptr, "%s%u", sgn ? "-" : "", ret);
         sym->current++;
     }
     else return NULL;
@@ -423,7 +404,12 @@ static BOOL get_modifier(struct parsed_symbol *sym, const char **ret, const char
     *ptr_modif = NULL;
     if (*sym->current == 'E')
     {
-        *ptr_modif = "__ptr64";
+        if (!(sym->flags & UNDNAME_NO_MS_KEYWORDS))
+        {
+            *ptr_modif = "__ptr64";
+            if (sym->flags & UNDNAME_NO_LEADING_UNDERSCORES)
+                *ptr_modif = *ptr_modif + 2;
+        }
         sym->current++;
     }
     switch (*sym->current++)
@@ -446,7 +432,13 @@ static BOOL get_modified_type(struct datatype_t *ct, struct parsed_symbol* sym,
 
     if (*sym->current == 'E')
     {
-        ptr_modif = " __ptr64";
+        if (!(sym->flags & UNDNAME_NO_MS_KEYWORDS))
+        {
+            if (sym->flags & UNDNAME_NO_LEADING_UNDERSCORES)
+                ptr_modif = " ptr64";
+            else
+                ptr_modif = " __ptr64";
+        }
         sym->current++;
     }
 
@@ -556,8 +548,10 @@ static char* get_template_name(struct parsed_symbol* sym)
     struct array array_pmt;
 
     sym->names.start = sym->names.num;
-    if (!(name = get_literal_string(sym)))
+    if (!(name = get_literal_string(sym))) {
+        sym->names.start = start_mark;
         return FALSE;
+    }
     str_array_init(&array_pmt);
     args = get_args(sym, &array_pmt, FALSE, '<', '>');
     if (args != NULL)
@@ -1082,6 +1076,7 @@ static BOOL handle_method(struct parsed_symbol* sym, BOOL cast_op)
 {
     char                accmem;
     const char*         access = NULL;
+    int                 access_id = -1;
     const char*         member_type = NULL;
     struct datatype_t   ct_ret;
     const char*         call_conv;
@@ -1089,7 +1084,7 @@ static BOOL handle_method(struct parsed_symbol* sym, BOOL cast_op)
     const char*         exported;
     const char*         args_str = NULL;
     const char*         name = NULL;
-    BOOL                ret = FALSE;
+    BOOL                ret = FALSE, has_args = TRUE, has_ret = TRUE;
     unsigned            mark;
     struct array        array_pmt;
 
@@ -1120,50 +1115,104 @@ static BOOL handle_method(struct parsed_symbol* sym, BOOL cast_op)
      * 'X' public: thunk
      * 'Y'
      * 'Z'
+     * "$0" private: thunk vtordisp
+     * "$1" private: thunk vtordisp
+     * "$2" protected: thunk vtordisp
+     * "$3" protected: thunk vtordisp
+     * "$4" public: thunk vtordisp
+     * "$5" public: thunk vtordisp
+     * "$B" vcall thunk
+     * "$R" thunk vtordispex
      */
     accmem = *sym->current++;
-    if (accmem < 'A' || accmem > 'Z') goto done;
+    if (accmem == '$')
+    {
+        if (*sym->current >= '0' && *sym->current <= '5')
+            access_id = (*sym->current - '0') / 2;
+        else if (*sym->current == 'R')
+            access_id = (sym->current[1] - '0') / 2;
+        else if (*sym->current != 'B')
+            goto done;
+    }
+    else if (accmem >= 'A' && accmem <= 'Z')
+        access_id = (accmem - 'A') / 8;
+    else
+        goto done;
 
-    if (!(sym->flags & UNDNAME_NO_ACCESS_SPECIFIERS))
+    switch (access_id)
     {
-        switch ((accmem - 'A') / 8)
-        {
-        case 0: access = "private: "; break;
-        case 1: access = "protected: "; break;
-        case 2: access = "public: "; break;
-        }
+    case 0: access = "private: "; break;
+    case 1: access = "protected: "; break;
+    case 2: access = "public: "; break;
     }
-    if (!(sym->flags & UNDNAME_NO_MEMBER_TYPE))
+    if (accmem == '$' || (accmem - 'A') % 8 == 6 || (accmem - 'A') % 8 == 7)
+        access = str_printf(sym, "[thunk]:%s", access ? access : " ");
+
+    if (accmem == '$' && *sym->current != 'B')
+        member_type = "virtual ";
+    else if (accmem <= 'X')
     {
-        if (accmem <= 'X')
+        switch ((accmem - 'A') % 8)
         {
-            switch ((accmem - 'A') % 8)
-            {
-            case 2: case 3: member_type = "static "; break;
-            case 4: case 5: member_type = "virtual "; break;
-            case 6: case 7:
-                access = str_printf(sym, "[thunk]:%s", access);
-                member_type = "virtual ";
-                break;
-            }
+        case 2: case 3: member_type = "static "; break;
+        case 4: case 5: case 6: case 7: member_type = "virtual "; break;
         }
     }
 
+    if (sym->flags & UNDNAME_NO_ACCESS_SPECIFIERS)
+        access = NULL;
+    if (sym->flags & UNDNAME_NO_MEMBER_TYPE)
+        member_type = NULL;
+
     name = get_class_string(sym, 0);
 
-    if ((accmem - 'A') % 8 == 6 || (accmem - '8') % 8 == 7) /* a thunk */
+    if (accmem == '$' && *sym->current == 'B') /* vcall thunk */
+    {
+        const char *n;
+
+        sym->current++;
+        n = get_number(sym);
+
+        if(!n || *sym->current++ != 'A') goto done;
+        name = str_printf(sym, "%s{%s,{flat}}' }'", name, n);
+        has_args = FALSE;
+        has_ret = FALSE;
+    }
+    else if (accmem == '$' && *sym->current == 'R') /* vtordispex thunk */
+    {
+        const char *n1, *n2, *n3, *n4;
+
+        sym->current += 2;
+        n1 = get_number(sym);
+        n2 = get_number(sym);
+        n3 = get_number(sym);
+        n4 = get_number(sym);
+
+        if(!n1 || !n2 || !n3 || !n4) goto done;
+        name = str_printf(sym, "%s`vtordispex{%s,%s,%s,%s}' ", name, n1, n2, n3, n4);
+    }
+    else if (accmem == '$') /* vtordisp thunk */
+    {
+        const char *n1, *n2;
+
+        sym->current++;
+        n1 = get_number(sym);
+        n2 = get_number(sym);
+
+        if (!n1 || !n2) goto done;
+        name = str_printf(sym, "%s`vtordisp{%s,%s}' ", name, n1, n2);
+    }
+    else if ((accmem - 'A') % 8 == 6 || (accmem - 'A') % 8 == 7) /* a thunk */
         name = str_printf(sym, "%s`adjustor{%s}' ", name, get_number(sym));
 
-    if (accmem <= 'X')
+    if (has_args && (accmem == '$' ||
+                (accmem <= 'X' && (accmem - 'A') % 8 != 2 && (accmem - 'A') % 8 != 3)))
     {
-        if (((accmem - 'A') % 8) != 2 && ((accmem - 'A') % 8) != 3)
-        {
-            const char *ptr_modif;
-            /* Implicit 'this' pointer */
-            /* If there is an implicit this pointer, const modifier follows */
-            if (!get_modifier(sym, &modifier, &ptr_modif)) goto done;
-            if (modifier || ptr_modif) modifier = str_printf(sym, "%s %s", modifier, ptr_modif);
-        }
+        const char *ptr_modif;
+        /* Implicit 'this' pointer */
+        /* If there is an implicit this pointer, const modifier follows */
+        if (!get_modifier(sym, &modifier, &ptr_modif)) goto done;
+        if (modifier || ptr_modif) modifier = str_printf(sym, "%s %s", modifier, ptr_modif);
     }
 
     if (!get_calling_convention(*sym->current++, &call_conv, &exported,
@@ -1173,18 +1222,18 @@ static BOOL handle_method(struct parsed_symbol* sym, BOOL cast_op)
     str_array_init(&array_pmt);
 
     /* Return type, or @ if 'void' */
-    if (*sym->current == '@')
+    if (has_ret && *sym->current == '@')
     {
         ct_ret.left = "void";
         ct_ret.right = NULL;
         sym->current++;
     }
-    else
+    else if (has_ret)
     {
         if (!demangle_datatype(sym, &ct_ret, &array_pmt, FALSE))
             goto done;
     }
-    if (sym->flags & UNDNAME_NO_FUNCTION_RETURNS)
+    if (!has_ret || sym->flags & UNDNAME_NO_FUNCTION_RETURNS)
         ct_ret.left = ct_ret.right = NULL;
     if (cast_op)
     {
@@ -1193,8 +1242,9 @@ static BOOL handle_method(struct parsed_symbol* sym, BOOL cast_op)
     }
 
     mark = sym->stack.num;
-    if (!(args_str = get_args(sym, &array_pmt, TRUE, '(', ')'))) goto done;
+    if (has_args && !(args_str = get_args(sym, &array_pmt, TRUE, '(', ')'))) goto done;
     if (sym->flags & UNDNAME_NAME_ONLY) args_str = modifier = NULL;
+    if (sym->flags & UNDNAME_NO_THISTYPE) modifier = NULL;
     sym->stack.num = mark;
 
     /* Note: '()' after 'Z' means 'throws', but we don't care here
@@ -1210,23 +1260,6 @@ done:
     return ret;
 }
 
-/******************************************************************
- *             handle_template
- * Does the final parsing and handling for a name with templates
- */
-static BOOL handle_template(struct parsed_symbol* sym)
-{
-    const char* name;
-    const char* args;
-
-    assert(*sym->current == '$');
-    sym->current++;
-    if (!(name = get_literal_string(sym))) return FALSE;
-    if (!(args = get_args(sym, NULL, FALSE, '<', '>'))) return FALSE;
-    sym->result = str_printf(sym, "%s%s", name, args);
-    return TRUE;
-}
-
 /*******************************************************************
  *         symbol_demangle
  * Demangle a C++ linker symbol
@@ -1460,10 +1493,8 @@ static BOOL symbol_demangle(struct parsed_symbol* sym)
     /* Function/Data type and access level */
     if (*sym->current >= '0' && *sym->current <= '9')
         ret = handle_data(sym);
-    else if (*sym->current >= 'A' && *sym->current <= 'Z')
+    else if ((*sym->current >= 'A' && *sym->current <= 'Z') || *sym->current == '$')
         ret = handle_method(sym, do_after == 3);
-    else if (*sym->current == '$')
-        ret = handle_template(sym);
     else ret = FALSE;
 done:
     if (ret) assert(sym->result);