http://bugs.winehq.org/show_bug.cgi?id=34501
--- Comment #1 from Ivan Permyakov info@vmpsoft.com 2013-09-12 22:13:42 CDT --- Here is my version:
static BOOL handle_method(struct parsed_symbol* sym, BOOL cast_op) { char accmem; const char* access = NULL; const char* member_type = NULL; struct datatype_t ct_ret; const char* call_conv; const char* modifier = NULL; const char* exported; const char* args_str = NULL; const char* name = NULL; BOOL ret = FALSE; unsigned mark; struct array array_pmt; unsigned short flags = 0;
/* FIXME: why 2 possible letters for each option? * 'A' private: * 'B' private: * 'C' private: static * 'D' private: static * 'E' private: virtual * 'F' private: virtual * 'G' private: thunk * 'H' private: thunk * 'I' protected: * 'J' protected: * 'K' protected: static * 'L' protected: static * 'M' protected: virtual * 'N' protected: virtual * 'O' protected: thunk * 'P' protected: thunk * 'Q' public: * 'R' public: * 'S' public: static * 'T' public: static * 'U' public: virtual * 'V' public: virtual * 'W' public: thunk * '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 * "$R0" private: thunk vtordispex * "$R1" private: thunk vtordispex * "$R2" protected: thunk vtordispex * "$R3" protected: thunk vtordispex * "$R4" public: thunk vtordispex * "$R5" public: thunk vtordispex */
enum { FLAG_PRIVATE = 0x1, FLAG_PROTECTED = 0x2, FLAG_PUBLIC = 0x4, FLAG_STATIC = 0x8, FLAG_VIRTUAL = 0x10, FLAG_THUNK = 0x20, FLAG_THIS = 0x40, FLAG_VTORDISP = 0x80, FLAG_VTORDISPEX = 0x100, };
accmem = *sym->current++; if (accmem == '$') { accmem = *sym->current++; if (accmem == 'R') { flags |= FLAG_VTORDISPEX; accmem = *sym->current++; } if ((accmem >= '0' && accmem <= '5')) { flags |= FLAG_THUNK | FLAG_THIS; if ((flags & FLAG_VTORDISPEX) == 0) flags |= FLAG_VTORDISP; switch ((accmem - '0') & 6) { case 0: flags |= FLAG_PRIVATE; break; case 2: flags |= FLAG_PROTECTED; break; case 4: flags |= FLAG_PUBLIC; break; } } else goto done; } else if (accmem >= 'A' && accmem <= 'Z') { switch ((accmem - 'A') / 8) { case 0: flags |= FLAG_PRIVATE; break; case 1: flags |= FLAG_PROTECTED; break; case 2: flags |= FLAG_PUBLIC; break; } if (accmem <= 'X') { switch ((accmem - 'A') & 6) { case 2: flags |= FLAG_STATIC; break; case 4: flags |= FLAG_VIRTUAL | FLAG_THIS; break; case 6: flags |= FLAG_THUNK | FLAG_THIS; break; } } } else goto done;
if ((sym->flags & UNDNAME_NO_ACCESS_SPECIFIERS) == 0) { if (flags & FLAG_PRIVATE) access = "private: "; else if (flags & FLAG_PROTECTED) access = "protected: "; else if (flags & FLAG_PUBLIC) access = "public: "; }
if ((sym->flags & UNDNAME_NO_MEMBER_TYPE) == 0) { if (flags & FLAG_STATIC) member_type = "static "; else if (flags & (FLAG_VIRTUAL | FLAG_THUNK)) member_type = "virtual "; }
name = get_class_string(sym, 0);
if (flags & FLAG_THUNK) { access = str_printf(sym, "[thunk]:%s", access); if (flags & FLAG_VTORDISPEX) { const char *num1; const char *num2; const char *num3; const char *num4; if (!(num1 = get_number(sym))) goto done; if (!(num2 = get_number(sym))) goto done; if (!(num3 = get_number(sym))) goto done; if (!(num4 = get_number(sym))) goto done; name = str_printf(sym, "%s`vtordispex{%s,%s,%s,%s}' ", name, num1, num2, num3, num4); } else if (flags & FLAG_VTORDISP) { const char *num1; const char *num2; if (!(num1 = get_number(sym))) goto done; if (!(num2 = get_number(sym))) goto done; name = str_printf(sym, "%s`vtordisp{%s,%s}' ", name, num1, num2); } else { name = str_printf(sym, "%s`adjustor{%s}' ", name, get_number(sym)); } }
if (flags & FLAG_THIS) { 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 (sym->flags & UNDNAME_NO_THISTYPE) modifier = NULL; else if (modifier || ptr_modif) modifier = str_printf(sym, "%s %s", modifier, ptr_modif); }
...
Please check it