This series fixes a couple of issue in msvcrt's C++ unmangler.
-- v2: dlls/msvcrt: fix demangling of variables being an array dlls/msvcrt: add support for restrict and unaligned qualifiers in demangling dlls/msvcrt: fix and cleanup undecoration of templatized functions and methods msvcrt: add support for C++11 operator "" in demangling msvcrt: fix demangling of RTTI type descriptor
From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/msvcrt/tests/cpp.c | 1 + dlls/msvcrt/undname.c | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-)
diff --git a/dlls/msvcrt/tests/cpp.c b/dlls/msvcrt/tests/cpp.c index 15105ca60dd..8c6b059e788 100644 --- a/dlls/msvcrt/tests/cpp.c +++ b/dlls/msvcrt/tests/cpp.c @@ -1291,6 +1291,7 @@ static void test_demangle(void) "??$run@XVTask_Render_Preview@@@QtConcurrent@@YA?AV?$QFuture@X@@PEAVTask_Render_Preview@@P82@EAAXXZ@Z"}, /* 130 */ {"??_E?$TStrArray@$$BY0BAA@D$0BA@@@UAEPAXI@Z", "public: virtual void * __thiscall TStrArray<char [256],16>::`vector deleting destructor'(unsigned int)"}, +/* 131 */ {"??_R0?AVCC@DD@@@8", "class DD::CC `RTTI Type Descriptor'"}, }; int i, num_test = ARRAY_SIZE(test); char* name; diff --git a/dlls/msvcrt/undname.c b/dlls/msvcrt/undname.c index bee171de42f..d71738efd5f 100644 --- a/dlls/msvcrt/undname.c +++ b/dlls/msvcrt/undname.c @@ -1452,11 +1452,8 @@ static BOOL symbol_demangle(struct parsed_symbol* sym) case '0': { struct datatype_t ct; - struct array pmt;
sym->current++; - str_array_init(&pmt); - demangle_datatype(sym, &ct, &pmt, FALSE); if (!demangle_datatype(sym, &ct, NULL, FALSE)) goto done; function_name = str_printf(sym, "%s%s `RTTI Type Descriptor'",
From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/msvcrt/undname.c | 13 +++++++++++++ dlls/ucrtbase/tests/cpp.c | 28 +++++++++++++++------------- 2 files changed, 28 insertions(+), 13 deletions(-)
diff --git a/dlls/msvcrt/undname.c b/dlls/msvcrt/undname.c index d71738efd5f..b07fbeb068e 100644 --- a/dlls/msvcrt/undname.c +++ b/dlls/msvcrt/undname.c @@ -1488,6 +1488,19 @@ static BOOL symbol_demangle(struct parsed_symbol* sym) case 'V': function_name = "operator delete[]"; break; case 'X': function_name = "`placement delete closure'"; break; case 'Y': function_name = "`placement delete[] closure'"; break; + case '_': + switch (*++sym->current) + { + case 'K': + sym->current++; + function_name = str_printf(sym, "operator "" %s", get_literal_string(sym)); + --sym->current; + break; + default: + FIXME("Unknown operator: __%c\n", *sym->current); + return FALSE; + } + break; default: ERR("Unknown operator: _%c\n", *sym->current); return FALSE; diff --git a/dlls/ucrtbase/tests/cpp.c b/dlls/ucrtbase/tests/cpp.c index 77b06e7cd42..fcc95629f7e 100644 --- a/dlls/ucrtbase/tests/cpp.c +++ b/dlls/ucrtbase/tests/cpp.c @@ -192,19 +192,21 @@ static void test___std_type_info(void)
static void test___unDName(void) { - char *name; - - name = p___unDName(0, "??4QDnsDomainNameRecord@@QAEAAV0@$$QAV0@@Z", 0, malloc, free, 0); - ok(!strcmp(name, "public: class QDnsDomainNameRecord & __thiscall " - "QDnsDomainNameRecord::operator=(class QDnsDomainNameRecord &&)"), - "unDName returned %s\n", wine_dbgstr_a(name)); - free(name); - - name = p___unDName(0, "??4QDnsDomainNameRecord@@QAEAAV0@$$QEAV0@@Z", 0, malloc, free, 0); - ok(!strcmp(name, "public: class QDnsDomainNameRecord & __thiscall " - "QDnsDomainNameRecord::operator=(class QDnsDomainNameRecord && __ptr64)"), - "unDName returned %s\n", wine_dbgstr_a(name)); - free(name); + static struct {const char *in; const char *out;} und_tests[] = + { +/* 1 */ {"??4QDnsDomainNameRecord@@QAEAAV0@$$QAV0@@Z", + "public: class QDnsDomainNameRecord & __thiscall QDnsDomainNameRecord::operator=(class QDnsDomainNameRecord &&)"}, +/* 2 */ {"??4QDnsDomainNameRecord@@QAEAAV0@$$QEAV0@@Z", + "public: class QDnsDomainNameRecord & __thiscall QDnsDomainNameRecord::operator=(class QDnsDomainNameRecord && __ptr64)"}, +/* 3 */ {"??__K_l@@YA?AUCC@@I@Z", "struct CC __cdecl operator "" _l(unsigned int)"}, + }; + unsigned i; + for (i = 0; i < ARRAY_SIZE(und_tests); i++) + { + char *name = p___unDName(0, und_tests[i].in, 0, malloc, free, 0); + ok(!strcmp(name, und_tests[i].out), "unDName returned %s for #%u\n", wine_dbgstr_a(name), i); + free(name); + } }
START_TEST(cpp)
From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/msvcrt/tests/cpp.c | 1 + dlls/msvcrt/undname.c | 18 +++++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/dlls/msvcrt/tests/cpp.c b/dlls/msvcrt/tests/cpp.c index 8c6b059e788..c97669ffc72 100644 --- a/dlls/msvcrt/tests/cpp.c +++ b/dlls/msvcrt/tests/cpp.c @@ -1292,6 +1292,7 @@ static void test_demangle(void) /* 130 */ {"??_E?$TStrArray@$$BY0BAA@D$0BA@@@UAEPAXI@Z", "public: virtual void * __thiscall TStrArray<char [256],16>::`vector deleting destructor'(unsigned int)"}, /* 131 */ {"??_R0?AVCC@DD@@@8", "class DD::CC `RTTI Type Descriptor'"}, +/* 132 */ {"??$meth@FD@DD@CC@@QAE_NK@Z", "public: bool __thiscall CC::DD::meth<short,char>(unsigned long)"}, }; int i, num_test = ARRAY_SIZE(test); char* name; diff --git a/dlls/msvcrt/undname.c b/dlls/msvcrt/undname.c index b07fbeb068e..a19f374016a 100644 --- a/dlls/msvcrt/undname.c +++ b/dlls/msvcrt/undname.c @@ -1368,13 +1368,13 @@ static BOOL symbol_demangle(struct parsed_symbol* sym) sym->current++;
/* Then function name or operator code */ - if (*sym->current == '?' && (sym->current[1] != '$' || sym->current[2] == '?')) + if (*sym->current == '?') { const char* function_name = NULL;
- if (sym->current[1] == '$') + if (sym->current[1] == '$' && sym->current[2] == '?') { - do_after = 6; + do_after = 5; sym->current += 2; }
@@ -1506,6 +1506,11 @@ static BOOL symbol_demangle(struct parsed_symbol* sym) return FALSE; } break; + case '$': + sym->current++; + if (!(function_name = get_template_name(sym))) goto done; + --sym->current; + break; default: /* FIXME: Other operators */ ERR("Unknown operator: %c\n", *sym->current); @@ -1522,7 +1527,7 @@ static BOOL symbol_demangle(struct parsed_symbol* sym) sym->result = (char*)function_name; ret = TRUE; goto done; - case 6: + case 5: { char *args; struct array array_pmt; @@ -1547,8 +1552,6 @@ static BOOL symbol_demangle(struct parsed_symbol* sym) ret = (sym->result = get_template_name(sym)) != NULL; goto done; } - else if (*sym->current == '?' && sym->current[1] == '$') - do_after = 5;
/* Either a class name, or '@' if the symbol is not a class member */ switch (*sym->current) @@ -1577,9 +1580,6 @@ static BOOL symbol_demangle(struct parsed_symbol* sym) case 3: sym->flags &= ~UNDNAME_NO_FUNCTION_RETURNS; break; - case 5: - sym->names.start++; - break; }
/* Function/Data type and access level */
From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/msvcrt/tests/cpp.c | 1 + dlls/msvcrt/undname.c | 166 +++++++++++++++++++++------------------- 2 files changed, 89 insertions(+), 78 deletions(-)
diff --git a/dlls/msvcrt/tests/cpp.c b/dlls/msvcrt/tests/cpp.c index c97669ffc72..79ea9d75c6b 100644 --- a/dlls/msvcrt/tests/cpp.c +++ b/dlls/msvcrt/tests/cpp.c @@ -1293,6 +1293,7 @@ static void test_demangle(void) "public: virtual void * __thiscall TStrArray<char [256],16>::`vector deleting destructor'(unsigned int)"}, /* 131 */ {"??_R0?AVCC@DD@@@8", "class DD::CC `RTTI Type Descriptor'"}, /* 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)"}, }; int i, num_test = ARRAY_SIZE(test); char* name; diff --git a/dlls/msvcrt/undname.c b/dlls/msvcrt/undname.c index a19f374016a..4b53ac459fb 100644 --- a/dlls/msvcrt/undname.c +++ b/dlls/msvcrt/undname.c @@ -394,67 +394,85 @@ static char* get_args(struct parsed_symbol* sym, struct array* pmt_ref, BOOL z_t return args_str; }
-/****************************************************************** - * get_modifier - * Parses the type modifier. Always returns static strings. - */ -static BOOL get_modifier(struct parsed_symbol *sym, const char **ret, const char **ptr_modif) +static void append_extended_modifier(struct parsed_symbol *sym, const char **where, const char *str) +{ + if (!(sym->flags & UNDNAME_NO_MS_KEYWORDS)) + { + if (sym->flags & UNDNAME_NO_LEADING_UNDERSCORES) + str += 2; + *where = *where ? str_printf(sym, "%s %s", *where, str) : str; + } +} + +static void get_extended_modifier(struct parsed_symbol *sym, struct datatype_t *xdt) { - *ptr_modif = NULL; - if (*sym->current == 'E') + xdt->left = xdt->right = NULL; + for (;;) { - if (!(sym->flags & UNDNAME_NO_MS_KEYWORDS)) + switch (*sym->current) { - *ptr_modif = "__ptr64"; - if (sym->flags & UNDNAME_NO_LEADING_UNDERSCORES) - *ptr_modif = *ptr_modif + 2; + case 'E': append_extended_modifier(sym, &xdt->right, "__ptr64"); break; + case 'F': append_extended_modifier(sym, &xdt->left, "__unaligned"); break; + case 'I': append_extended_modifier(sym, &xdt->right, "__restrict"); break; + default: return; } sym->current++; } +} + +/****************************************************************** + * get_modifier + * Parses the type modifier. Always returns static strings. + */ +static BOOL get_modifier(struct parsed_symbol *sym, struct datatype_t *xdt) +{ + const char* mod; + + get_extended_modifier(sym, xdt); switch (*sym->current++) { - case 'A': *ret = NULL; break; - case 'B': *ret = "const"; break; - case 'C': *ret = "volatile"; break; - case 'D': *ret = "const volatile"; break; + case 'A': mod = NULL; break; + case 'B': mod = "const"; break; + case 'C': mod = "volatile"; break; + case 'D': mod = "const volatile"; break; default: return FALSE; } + if (xdt->left && mod) + xdt->left = str_printf(sym, "%s %s", xdt->left, mod); + else if (mod) + xdt->left = mod; return TRUE; }
static BOOL get_modified_type(struct datatype_t *ct, struct parsed_symbol* sym, struct array *pmt_ref, char modif, BOOL in_args) { - const char* modifier; + struct datatype_t xdt; + const char* ref; const char* str_modif; - const char *ptr_modif = "";
- if (*sym->current == 'E') - { - if (!(sym->flags & UNDNAME_NO_MS_KEYWORDS)) - { - if (sym->flags & UNDNAME_NO_LEADING_UNDERSCORES) - ptr_modif = " ptr64"; - else - ptr_modif = " __ptr64"; - } - sym->current++; - } + get_extended_modifier(sym, &xdt);
switch (modif) { - case 'A': str_modif = str_printf(sym, " &%s", ptr_modif); break; - case 'B': str_modif = str_printf(sym, " &%s volatile", ptr_modif); break; - case 'P': str_modif = str_printf(sym, " *%s", ptr_modif); break; - case 'Q': str_modif = str_printf(sym, " *%s const", ptr_modif); break; - case 'R': str_modif = str_printf(sym, " *%s volatile", ptr_modif); break; - case 'S': str_modif = str_printf(sym, " *%s const volatile", ptr_modif); break; - case '?': str_modif = ""; break; - case '$': str_modif = str_printf(sym, " &&%s", ptr_modif); break; + case 'A': ref = "&"; str_modif = NULL; break; + case 'B': ref = "&"; str_modif = "volatile"; break; + case 'P': ref = "*"; str_modif = NULL; break; + case 'Q': ref = "*"; str_modif = "const"; break; + case 'R': ref = "*"; str_modif = "volatile"; break; + case 'S': ref = "*"; str_modif = "const volatile"; break; + case '?': ref = NULL; str_modif = NULL; break; + case '$': ref = "&&"; str_modif = NULL; break; default: return FALSE; } - - if (get_modifier(sym, &modifier, &ptr_modif)) + if (ref || str_modif || xdt.left || xdt.right) + str_modif = str_printf(sym, " %s%s%s%s%s%s%s", + xdt.left, + xdt.left && ref ? " " : NULL, ref, + (xdt.left || ref) && xdt.right ? " " : NULL, xdt.right, + (xdt.left || ref || xdt.right) && str_modif ? " " : NULL, str_modif); + + if (get_modifier(sym, &xdt)) { unsigned mark = sym->stack.num; struct datatype_t sub_ct; @@ -469,16 +487,11 @@ static BOOL get_modified_type(struct datatype_t *ct, struct parsed_symbol* sym, if (!(n1 = get_number(sym))) return FALSE; num = atoi(n1);
- if (str_modif[0] == ' ' && !modifier) + if (str_modif[0] == ' ' && !xdt.left) str_modif++;
- if (modifier) - { - str_modif = str_printf(sym, " (%s%s)", modifier, str_modif); - modifier = NULL; - } - else - str_modif = str_printf(sym, " (%s)", str_modif); + str_modif = str_printf(sym, " (%s%s)", xdt.left, str_modif); + xdt.left = NULL;
while (num--) str_modif = str_printf(sym, "%s[%s]", str_modif, get_number(sym)); @@ -487,12 +500,12 @@ static BOOL get_modified_type(struct datatype_t *ct, struct parsed_symbol* sym, /* Recurse to get the referred-to type */ if (!demangle_datatype(sym, &sub_ct, pmt_ref, FALSE)) return FALSE; - if (modifier) - ct->left = str_printf(sym, "%s %s%s", sub_ct.left, modifier, str_modif ); + if (xdt.left) + ct->left = str_printf(sym, "%s %s%s", sub_ct.left, xdt.left, str_modif); else { /* don't insert a space between duplicate '*' */ - if (!in_args && str_modif[0] && str_modif[1] == '*' && sub_ct.left[strlen(sub_ct.left)-1] == '*') + if (!in_args && str_modif && str_modif[0] && str_modif[1] == '*' && sub_ct.left[strlen(sub_ct.left)-1] == '*') str_modif++; ct->left = str_printf(sym, "%s%s", sub_ct.left, str_modif ); } @@ -872,19 +885,18 @@ static BOOL demangle_datatype(struct parsed_symbol* sym, struct datatype_t* ct, struct datatype_t sub_ct; unsigned mark = sym->stack.num; const char* class; - const char* modifier; - const char* ptr_modif; + struct datatype_t xdt;
sym->current++;
if (!(class = get_class_name(sym))) goto done; - if (!get_modifier(sym, &modifier, &ptr_modif)) + if (!get_modifier(sym, &xdt)) goto done; - if (modifier) - modifier = str_printf(sym, "%s %s", modifier, ptr_modif); - else if(ptr_modif) - modifier = str_printf(sym, " %s", ptr_modif); + if (xdt.left) + xdt.left = str_printf(sym, "%s %s", xdt.left, xdt.right); + else if (xdt.right) + xdt.left = str_printf(sym, " %s", xdt.right); if (!get_calling_convention(*sym->current++, &call_conv, &exported, sym->flags & ~UNDNAME_NO_ALLOCATION_LANGUAGE)) @@ -898,7 +910,7 @@ static BOOL demangle_datatype(struct parsed_symbol* sym, struct datatype_t* ct,
ct->left = str_printf(sym, "%s%s (%s %s::*", sub_ct.left, sub_ct.right, call_conv, class); - ct->right = str_printf(sym, ")%s%s", args, modifier); + ct->right = str_printf(sym, ")%s%s", args, xdt.left); } else if (*sym->current == '6') { @@ -1025,12 +1037,12 @@ static BOOL demangle_datatype(struct parsed_symbol* sym, struct datatype_t* ct, } else if (*sym->current == 'C') { - const char *ptr, *ptr_modif; + struct datatype_t xdt;
sym->current++; - if (!get_modifier(sym, &ptr, &ptr_modif)) goto done; + if (!get_modifier(sym, &xdt)) goto done; if (!demangle_datatype(sym, ct, pmt_ref, in_args)) goto done; - ct->left = str_printf(sym, "%s %s", ct->left, ptr); + ct->left = str_printf(sym, "%s %s", ct->left, xdt.left); } else if (*sym->current == 'Q') { @@ -1065,8 +1077,7 @@ static BOOL handle_data(struct parsed_symbol* sym) { const char* access = NULL; const char* member_type = NULL; - const char* modifier = NULL; - const char* ptr_modif; + struct datatype_t xdt = {NULL}; struct datatype_t ct; char* name = NULL; BOOL ret = FALSE; @@ -1111,16 +1122,16 @@ static BOOL handle_data(struct parsed_symbol* sym) str_array_init(&pmt);
if (!demangle_datatype(sym, &ct, &pmt, FALSE)) goto done; - if (!get_modifier(sym, &modifier, &ptr_modif)) goto done; - if (modifier && ptr_modif) modifier = str_printf(sym, "%s %s", modifier, ptr_modif); - else if (!modifier) modifier = ptr_modif; + if (!get_modifier(sym, &xdt)) goto done; + if (xdt.left && xdt.right) xdt.left = str_printf(sym, "%s %s", xdt.left, xdt.right); + else if (!xdt.left) xdt.left = xdt.right; sym->stack.num = mark; } break; case '6' : /* compiler generated static */ case '7' : /* compiler generated static */ ct.left = ct.right = NULL; - if (!get_modifier(sym, &modifier, &ptr_modif)) goto done; + if (!get_modifier(sym, &xdt)) goto done; if (*sym->current != '@') { char* cls = NULL; @@ -1132,16 +1143,16 @@ static BOOL handle_data(struct parsed_symbol* sym) break; case '8': case '9': - modifier = ct.left = ct.right = NULL; + xdt.left = ct.left = ct.right = NULL; break; default: goto done; } - if (sym->flags & UNDNAME_NAME_ONLY) ct.left = ct.right = modifier = NULL; + if (sym->flags & UNDNAME_NAME_ONLY) ct.left = ct.right = xdt.left = NULL;
sym->result = str_printf(sym, "%s%s%s%s%s%s%s%s", access, - member_type, ct.left, - modifier && ct.left ? " " : NULL, modifier, - modifier || ct.left ? " " : NULL, name, ct.right); + member_type, ct.left, + xdt.left && ct.left ? " " : NULL, xdt.left, + xdt.left || ct.left ? " " : NULL, name, ct.right); ret = TRUE; done: return ret; @@ -1160,7 +1171,7 @@ static BOOL handle_method(struct parsed_symbol* sym, BOOL cast_op) const char* member_type = NULL; struct datatype_t ct_ret; const char* call_conv; - const char* modifier = NULL; + struct datatype_t xdt = {NULL}; const char* exported; const char* args_str = NULL; const char* name = NULL; @@ -1288,11 +1299,10 @@ static BOOL handle_method(struct parsed_symbol* sym, BOOL cast_op) if (has_args && (accmem == '$' || (accmem <= 'X' && (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); + if (!get_modifier(sym, &xdt)) goto done; + if (xdt.left || xdt.right) xdt.left = str_printf(sym, "%s %s", xdt.left, xdt.right); }
if (!get_calling_convention(*sym->current++, &call_conv, &exported, @@ -1323,8 +1333,8 @@ static BOOL handle_method(struct parsed_symbol* sym, BOOL cast_op)
mark = sym->stack.num; 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; + if (sym->flags & UNDNAME_NAME_ONLY) args_str = xdt.left = NULL; + if (sym->flags & UNDNAME_NO_THISTYPE) xdt.left = NULL; sym->stack.num = mark;
/* Note: '()' after 'Z' means 'throws', but we don't care here @@ -1334,7 +1344,7 @@ static BOOL handle_method(struct parsed_symbol* sym, BOOL cast_op) access, member_type, ct_ret.left, (ct_ret.left && !ct_ret.right) ? " " : NULL, call_conv, call_conv ? " " : NULL, exported, - name, args_str, modifier, ct_ret.right); + name, args_str, xdt.left, ct_ret.right); ret = TRUE; done: return ret;
From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/msvcrt/tests/cpp.c | 1 + dlls/msvcrt/undname.c | 32 ++++++++++++++++++-------------- 2 files changed, 19 insertions(+), 14 deletions(-)
diff --git a/dlls/msvcrt/tests/cpp.c b/dlls/msvcrt/tests/cpp.c index 79ea9d75c6b..58ecd1327a5 100644 --- a/dlls/msvcrt/tests/cpp.c +++ b/dlls/msvcrt/tests/cpp.c @@ -1294,6 +1294,7 @@ static void test_demangle(void) /* 131 */ {"??_R0?AVCC@DD@@@8", "class DD::CC `RTTI Type Descriptor'"}, /* 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]"}, }; int i, num_test = ARRAY_SIZE(test); char* name; diff --git a/dlls/msvcrt/undname.c b/dlls/msvcrt/undname.c index 4b53ac459fb..acfe96fe436 100644 --- a/dlls/msvcrt/undname.c +++ b/dlls/msvcrt/undname.c @@ -466,11 +466,14 @@ static BOOL get_modified_type(struct datatype_t *ct, struct parsed_symbol* sym, default: return FALSE; } if (ref || str_modif || xdt.left || xdt.right) - str_modif = str_printf(sym, " %s%s%s%s%s%s%s", - xdt.left, - xdt.left && ref ? " " : NULL, ref, - (xdt.left || ref) && xdt.right ? " " : NULL, xdt.right, - (xdt.left || ref || xdt.right) && str_modif ? " " : NULL, str_modif); + ct->left = str_printf(sym, " %s%s%s%s%s%s%s", + xdt.left, + xdt.left && ref ? " " : NULL, ref, + (xdt.left || ref) && xdt.right ? " " : NULL, xdt.right, + (xdt.left || ref || xdt.right) && str_modif ? " " : NULL, str_modif); + else + ct->left = NULL; + ct->right = NULL;
if (get_modifier(sym, &xdt)) { @@ -487,29 +490,30 @@ static BOOL get_modified_type(struct datatype_t *ct, struct parsed_symbol* sym, if (!(n1 = get_number(sym))) return FALSE; num = atoi(n1);
- if (str_modif[0] == ' ' && !xdt.left) - str_modif++; + if (ct->left && ct->left[0] == ' ' && !xdt.left) + ct->left++;
- str_modif = str_printf(sym, " (%s%s)", xdt.left, str_modif); + ct->left = str_printf(sym, " (%s%s", xdt.left, ct->left); + ct->right = ")"; xdt.left = NULL;
while (num--) - str_modif = str_printf(sym, "%s[%s]", str_modif, get_number(sym)); + ct->right = str_printf(sym, "%s[%s]", ct->right, get_number(sym)); }
/* Recurse to get the referred-to type */ if (!demangle_datatype(sym, &sub_ct, pmt_ref, FALSE)) return FALSE; if (xdt.left) - ct->left = str_printf(sym, "%s %s%s", sub_ct.left, xdt.left, str_modif); + ct->left = str_printf(sym, "%s %s%s", sub_ct.left, xdt.left, ct->left); else { /* don't insert a space between duplicate '*' */ - if (!in_args && str_modif && str_modif[0] && str_modif[1] == '*' && sub_ct.left[strlen(sub_ct.left)-1] == '*') - str_modif++; - ct->left = str_printf(sym, "%s%s", sub_ct.left, str_modif ); + if (!in_args && ct->left && ct->left[0] && ct->left[1] == '*' && sub_ct.left[strlen(sub_ct.left)-1] == '*') + ct->left++; + ct->left = str_printf(sym, "%s%s", sub_ct.left, ct->left); } - ct->right = sub_ct.right; + if (sub_ct.right) ct->right = str_printf(sym, "%s%s", ct->right, sub_ct.right); sym->stack.num = mark; } return TRUE;
V2 pushed: - includes Piotr's comments - move test failing in msvcrt/tests into ucrtbase/tests
On Fri Jul 15 17:23:31 2022 +0000, Piotr Caban wrote:
Could you please remove the "likely many others missing here" comment and change ERR to FIXME?
fixed in v2 (thx for the review)
BTW, concerning the ERR vs FIXME thingie. I agree that FIXME is better in this case (from Internet sources, all letters from A to Z are used)
But I wonder what to do with the rest of file undname.c which heavily uses ERR...
in lots of case we're in a gray area: not precisely knowing if the given input is really a valid input (and FIXME is to be used) or if it's an invalid input (and ERR should be used)
On Sat Jul 16 07:48:14 2022 +0000, eric pouech wrote:
fixed in v2 (thx for the review) BTW, concerning the ERR vs FIXME thingie. I agree that FIXME is better in this case (from Internet sources, all letters from A to Z are used) But I wonder what to do with the rest of file undname.c which heavily uses ERR... in lots of case we're in a gray area: not precisely knowing if the given input is really a valid input (and FIXME is to be used) or if it's an invalid input (and ERR should be used)
The function behavior is changing so it kind of makes sense to use FIXME instead of ERR in many places (I guess that e.g. operator "" support will be added to msvcrt in future updates). In theory we can try to guess what parts are likely to change (and use FIXME there) and parts that should use ERR but that doesn't look doable. I would vote for leaving it as is unless the code is changed for other reasons (and than it can be decided on case by case basis).
On Sat Jul 16 07:57:59 2022 +0000, **** wrote:
Marvin replied on the mailing list:
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=119164 Your paranoid android. === w1064v1507 (32 bit report) === ucrtbase: cpp.c:207: Test failed: unDName returned "??__K_l@@YA?AUCC@@I@Z" for #2 === w1064v1507 (64 bit report) === ucrtbase: cpp.c:207: Test failed: unDName returned "??__K_l@@YA?AUCC@@I@Z" for #2
It looks like __K is not supported in older versions of ucrtbase.