From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/msvcrt/tests/cpp.c | 6 +++++ dlls/msvcrt/undname.c | 56 ++++++++++++++++++++++++++++++----------- 2 files changed, 47 insertions(+), 15 deletions(-)
diff --git a/dlls/msvcrt/tests/cpp.c b/dlls/msvcrt/tests/cpp.c index 14d4cfac84a..c96561c5a66 100644 --- a/dlls/msvcrt/tests/cpp.c +++ b/dlls/msvcrt/tests/cpp.c @@ -1298,6 +1298,12 @@ static void test_demangle(void) /* 136 */ {"??$?0AEAVzzz@BB4@AA@@AEAV012@$0A@@?$pair@Vzzz@BB4@AA@@V123@@std@@QEAA@AEAVzzz@BB4@AA@@0@Z", "public: __cdecl std::pair<class AA::BB4::zzz,class AA::BB4::zzz>::pair<class AA::BB4::zzz,class AA::BB4::zzz><class AA::BB4::zzz & __ptr64,class AA::BB4::zzz & __ptr64,0>(class AA::BB4::zzz & __ptr64,class AA::BB4::zzz & __ptr64) __ptr64"}, /* 137 */ {"??Bcastop@@QAEHXZ", "public: __thiscall castop::operator int(void)"}, +/* 138 */ {"?pfield@@3PTAA@@DT1@", "char const volatile AA::* const volatile pfield"}, +/* 139 */ {"?ptititi1@@3PEQtititi@@IEQ1@", "unsigned int tititi::* __ptr64 __ptr64 ptititi1"}, +/* 140 */ {"?ptititi2@@3PERtititi@@IER1@", "unsigned int const tititi::* __ptr64 const __ptr64 ptititi2"}, +/* 141 */ {"?ptititi3@@3PEStititi@@IES1@", "unsigned int volatile tititi::* __ptr64 volatile __ptr64 ptititi3"}, +/* 142 */ {"?ptititi4@@3PETtititi@@IET1@", "unsigned int const volatile tititi::* __ptr64 const volatile __ptr64 ptititi4"}, +/* 143 */ {"?ptititi4v@@3RETtititi@@IET1@", "unsigned int const volatile tititi::* __ptr64 const volatile __ptr64 ptititi4v"}, }; int i, num_test = ARRAY_SIZE(test); char* name; diff --git a/dlls/msvcrt/undname.c b/dlls/msvcrt/undname.c index 8c361643b0b..40ed7051e60 100644 --- a/dlls/msvcrt/undname.c +++ b/dlls/msvcrt/undname.c @@ -85,6 +85,7 @@ struct datatype_t };
static BOOL symbol_demangle(struct parsed_symbol* sym); +static char* get_class_name(struct parsed_symbol* sym);
/****************************************************************** * und_alloc @@ -473,31 +474,50 @@ static void get_extended_modifier(struct parsed_symbol *sym, struct datatype_t * * get_modifier * Parses the type modifier. Always returns static strings. */ -static BOOL get_modifier(struct parsed_symbol *sym, struct datatype_t *xdt) +static BOOL get_modifier(struct parsed_symbol *sym, struct datatype_t *xdt, const char** pclass) { const char* mod; + char ch;
get_extended_modifier(sym, xdt); - switch (*sym->current++) + switch (ch = *sym->current++) { case 'A': mod = NULL; break; case 'B': mod = "const"; break; case 'C': mod = "volatile"; break; case 'D': mod = "const volatile"; break; + case 'Q': mod = NULL; break; + case 'R': mod = "const"; break; + case 'S': mod = "volatile"; break; + case 'T': mod = "const volatile"; break; default: return FALSE; } xdt->left = str_build(sym, "%s%S", xdt->left, mod); + if (ch >= 'Q' && ch <= 'T') /* pointer to member, fetch class */ + { + const char* class = get_class_name(sym); + if (!class) return FALSE; + if (!pclass) + { + FIXME("Got pointer to class %s member without storage\n", class); + return FALSE; + } + *pclass = class; + } + else if (pclass) *pclass = NULL; return TRUE; }
static BOOL get_modified_type(struct datatype_t *ct, struct parsed_symbol* sym, struct array *pmt_ref, char modif, BOOL in_args) { - struct datatype_t xdt; + struct datatype_t xdt1; + struct datatype_t xdt2; const char* ref; const char* str_modif; + const char* class;
- get_extended_modifier(sym, &xdt); + get_extended_modifier(sym, &xdt1);
switch (modif) { @@ -511,14 +531,17 @@ static BOOL get_modified_type(struct datatype_t *ct, struct parsed_symbol* sym, case '$': ref = "&&"; str_modif = NULL; break; default: return FALSE; } - ct->left = str_build(sym, "%s%S%S%S", xdt.left, ref, xdt.right, str_modif); ct->right = NULL;
- if (get_modifier(sym, &xdt)) + if (get_modifier(sym, &xdt2, &class)) { unsigned mark = sym->stack.num; struct datatype_t sub_ct;
+ if (class) + ct->left = str_build(sym, "%s%S%s%s%S%s", xdt1.left, class, class ? "::" : NULL, ref, xdt1.right, str_modif); + else + ct->left = str_build(sym, "%s%S%S%S", xdt1.left, ref, xdt1.right, str_modif); /* multidimensional arrays */ if (*sym->current == 'Y') { @@ -529,9 +552,9 @@ static BOOL get_modified_type(struct datatype_t *ct, struct parsed_symbol* sym, if (!(n1 = get_number(sym))) return FALSE; num = atoi(n1);
- ct->left = str_build(sym, "(%s%S", xdt.left, ct->left); + ct->left = str_build(sym, "(%s%S", xdt2.left, ct->left); ct->right = ")"; - xdt.left = NULL; + xdt2.left = NULL;
while (num--) ct->right = str_build(sym, "%s[%s]", ct->right, get_number(sym)); @@ -543,15 +566,17 @@ static BOOL get_modified_type(struct datatype_t *ct, struct parsed_symbol* sym, /* don't insert a space between duplicate '*' */ if (!in_args && sub_ct.left && sub_ct.left[0] && sub_ct.left[strlen(sub_ct.left) - 1] == '*' && - !xdt.left && + !xdt2.left && ct->left && ct->left[0] == '*') ct->left = str_build(sym, "%s%s", sub_ct.left, ct->left); else - ct->left = str_build(sym, "%s%S%S", sub_ct.left, xdt.left, ct->left); + ct->left = str_build(sym, "%s%S%S", sub_ct.left, xdt2.left, ct->left);
ct->right = str_build(sym, "%s%s", ct->right, sub_ct.right); sym->stack.num = mark; } + else + ct->left = str_build(sym, "%s%S%S%S", xdt1.left, ref, xdt1.right, str_modif); return TRUE; }
@@ -929,7 +954,7 @@ static BOOL demangle_datatype(struct parsed_symbol* sym, struct datatype_t* ct,
if (!(class = get_class_name(sym))) goto done; - if (!get_modifier(sym, &xdt)) + if (!get_modifier(sym, &xdt, NULL)) goto done; if (!get_calling_convention(*sym->current++, &call_conv, &exported, @@ -1072,7 +1097,7 @@ static BOOL demangle_datatype(struct parsed_symbol* sym, struct datatype_t* ct, struct datatype_t xdt;
sym->current++; - if (!get_modifier(sym, &xdt)) goto done; + if (!get_modifier(sym, &xdt, NULL)) goto done; if (!demangle_datatype(sym, ct, pmt_ref, in_args)) goto done; ct->left = str_build(sym, "%s %s", ct->left, xdt.left); } @@ -1150,11 +1175,12 @@ static BOOL handle_data(struct parsed_symbol* sym) { unsigned mark = sym->stack.num; struct array pmt; + const char* class;
str_array_init(&pmt);
if (!demangle_datatype(sym, &ct, &pmt, FALSE)) goto done; - if (!get_modifier(sym, &xdt)) goto done; + if (!get_modifier(sym, &xdt, &class)) goto done; xdt.left = str_build(sym, "%s%S", xdt.left, xdt.right); sym->stack.num = mark; } @@ -1162,7 +1188,7 @@ static BOOL handle_data(struct parsed_symbol* sym) case '6' : /* compiler generated static */ case '7' : /* compiler generated static */ ct.left = ct.right = NULL; - if (!get_modifier(sym, &xdt)) goto done; + if (!get_modifier(sym, &xdt, NULL)) goto done; if (*sym->current != '@') { char* cls = NULL; @@ -1329,7 +1355,7 @@ static BOOL handle_method(struct parsed_symbol* sym, BOOL cast_op) { /* Implicit 'this' pointer */ /* If there is an implicit this pointer, const modifier follows */ - if (!get_modifier(sym, &xdt)) goto done; + if (!get_modifier(sym, &xdt, NULL)) goto done; xdt.left = str_build(sym, "%s%s%s", xdt.left, xdt.left || xdt.right ? " " : NULL, xdt.right); }