From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/msvcrt/tests/cpp.c | 2 ++ dlls/msvcrt/undname.c | 36 ++++++++++++++++-------------------- 2 files changed, 18 insertions(+), 20 deletions(-)
diff --git a/dlls/msvcrt/tests/cpp.c b/dlls/msvcrt/tests/cpp.c index 58ecd1327a5..aee9980cd2d 100644 --- a/dlls/msvcrt/tests/cpp.c +++ b/dlls/msvcrt/tests/cpp.c @@ -1295,6 +1295,8 @@ static void test_demangle(void) /* 132 */ {"??$meth@FD@DD@CC@@QAE_NK@Z", "public: bool __thiscall CC::DD::meth<short,char>(unsigned long)"}, /* 133 */ {"?func@@YAXPIFAH@Z", "void __cdecl func(int __unaligned * __restrict)"}, /* 135 */ {"?x@@3PAY02HA", "int (* x)[3]"}, +/* 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"}, }; int i, num_test = ARRAY_SIZE(test); char* name; diff --git a/dlls/msvcrt/undname.c b/dlls/msvcrt/undname.c index acfe96fe436..be736631626 100644 --- a/dlls/msvcrt/undname.c +++ b/dlls/msvcrt/undname.c @@ -1362,7 +1362,6 @@ static BOOL symbol_demangle(struct parsed_symbol* sym) { BOOL ret = FALSE; unsigned do_after = 0; - static CHAR dashed_null[] = "--null--";
/* FIXME seems wrong as name, as it demangles a simple data type */ if (sym->flags & UNDNAME_NO_ARGUMENTS) @@ -1385,18 +1384,19 @@ static BOOL symbol_demangle(struct parsed_symbol* sym) if (*sym->current == '?') { const char* function_name = NULL; + BOOL in_template = FALSE;
if (sym->current[1] == '$' && sym->current[2] == '?') { - do_after = 5; + in_template = TRUE; sym->current += 2; }
/* C++ operator code (one character, or two if the first is '_') */ switch (*++sym->current) { - case '0': do_after = 1; break; - case '1': do_after = 2; break; + case '0': function_name = ""; do_after = 1; break; + case '1': function_name = ""; do_after = 2; break; case '2': function_name = "operator new"; break; case '3': function_name = "operator delete"; break; case '4': function_name = "operator="; break; @@ -1531,26 +1531,22 @@ static BOOL symbol_demangle(struct parsed_symbol* sym) return FALSE; } sym->current++; + if (in_template) + { + const char *args; + struct array array_pmt; + + str_array_init(&array_pmt); + args = get_args(sym, &array_pmt, FALSE, '<', '>'); + if (args) function_name = function_name ? str_printf(sym, "%s%s", function_name, args) : args; + sym->names.num = 0; + } switch (do_after) { - case 1: case 2: - if (!str_array_push(sym, dashed_null, -1, &sym->stack)) - return FALSE; - break; case 4: sym->result = (char*)function_name; ret = TRUE; goto done; - case 5: - { - char *args; - struct array array_pmt; - - str_array_init(&array_pmt); - args = get_args(sym, &array_pmt, FALSE, '<', '>'); - if (args != NULL) function_name = str_printf(sym, "%s%s", function_name, args); - sym->names.num = 0; - } /* fall through */ default: if (!str_array_push(sym, function_name, -1, &sym->stack)) @@ -1585,9 +1581,9 @@ static BOOL symbol_demangle(struct parsed_symbol* sym) /* it's time to set the member name for ctor & dtor */ if (sym->stack.num <= 1) goto done; if (do_after == 1) - sym->stack.elts[0] = sym->stack.elts[1]; + sym->stack.elts[0] = str_printf(sym, "%s%s", sym->stack.elts[1], sym->stack.elts[0]); else - sym->stack.elts[0] = str_printf(sym, "~%s", sym->stack.elts[1]); + sym->stack.elts[0] = str_printf(sym, "~%s%s", sym->stack.elts[1], sym->stack.elts[0]); /* ctors and dtors don't have return type */ sym->flags |= UNDNAME_NO_FUNCTION_RETURNS; break;