This series fixes a couple of issue in msvcrt's C++ unmangler.
-- v3: 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 | 31 ++++++++++++++++++------------- 2 files changed, 31 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..a22138889cb 100644 --- a/dlls/ucrtbase/tests/cpp.c +++ b/dlls/ucrtbase/tests/cpp.c @@ -192,19 +192,24 @@ 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; const char *broken;} 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)", + "??__K_l@@YA?AUCC@@I@Z" /* W10 1507 fails on this :-( */}, + }; + 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) || + (broken(und_tests[i].broken && !strcmp(und_tests[i].broken, name))), + "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;
On Sat Jul 16 09:58:11 2022 +0000, Piotr Caban wrote:
It looks like __K is not supported in older versions of ucrtbase.
yesssss... I tested the next version for W10, not this one... pushing a V3
V3: - added broken support in ucrtbase/tests for handling failures in early version of ucrtbase in W10
This merge request was approved by Piotr Caban.