Module: wine Branch: master Commit: f24a96cc5d0c47edf7ca2c43c9fb82158fa4ac41 URL: https://gitlab.winehq.org/wine/wine/-/commit/f24a96cc5d0c47edf7ca2c43c9fb821...
Author: Eric Pouech epouech@codeweavers.com Date: Wed May 15 10:44:02 2024 +0200
msvcrt: Don't consider end of list encoding as real data types.
This allows while unmangling: - to avoid considering them as "real" datatypes in other contexts - to handle better void (which is only supported as single argument in function args list, while is a fully acceptable datatype in template args list)
Signed-off-by: Eric Pouech epouech@codeweavers.com
---
dlls/msvcrt/tests/cpp.c | 6 ++++-- dlls/msvcrt/undname.c | 24 ++++++++++++++++-------- 2 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/dlls/msvcrt/tests/cpp.c b/dlls/msvcrt/tests/cpp.c index 028af05b2e0..bed1a5d4530 100644 --- a/dlls/msvcrt/tests/cpp.c +++ b/dlls/msvcrt/tests/cpp.c @@ -1330,11 +1330,13 @@ static void test_demangle(void) "__ptr64 __cdecl std::forward<struct `private: static int __cdecl FFIFunctionBinder::call(struct lua_State " "* __ptr64)'::`2'::FFIValue & __ptr64>(struct `private: static int __cdecl FFIFunctionBinder::call(struct " "xlua_State * __ptr64)'::`2'::FFIValue & __ptr64)"}, +/* 153 */ {"?$AAA@XX", "AAA<void,void>"}, +/* 154 */ {"?$AAA@", "AAA<>"}, }; - int i, num_test = ARRAY_SIZE(test); + int i; char* name;
- for (i = 0; i < num_test; i++) + for (i = 0; i < ARRAY_SIZE(test); i++) { name = p__unDName(0, test[i].in, 0, malloc, free, test[i].flags); ok(name != NULL, "%u: unDName failed\n", i); diff --git a/dlls/msvcrt/undname.c b/dlls/msvcrt/undname.c index 55661f21e2b..74856504685 100644 --- a/dlls/msvcrt/undname.c +++ b/dlls/msvcrt/undname.c @@ -365,6 +365,12 @@ static char* get_args(struct parsed_symbol* sym, BOOL z_term, unsigned int i; const char *p;
+ if (z_term && sym->current[0] == 'X' && sym->current[1] == 'Z') + { + sym->current += 2; + return str_printf(sym, "%cvoid%c", open_char, close_char); + } + str_array_init(&arg_collect);
/* Now come the function arguments */ @@ -378,6 +384,13 @@ static char* get_args(struct parsed_symbol* sym, BOOL z_term, sym->current++; break; } + if (z_term && sym->current[0] == 'Z') + { + sym->current++; + if (!str_array_push(sym, "...", -1, &arg_collect)) + return NULL; + break; + } /* Handle empty list in variadic template */ if (!z_term && sym->current[0] == '$' && sym->current[1] == '$' && sym->current[2] == 'V') { @@ -386,12 +399,9 @@ static char* get_args(struct parsed_symbol* sym, BOOL z_term, } if (!demangle_datatype(sym, &ct, IN_ARGS)) return NULL; - /* 'void' terminates an argument list in a function */ - if (z_term && !strcmp(ct.left, "void")) break; if (!str_array_push(sym, str_printf(sym, "%s%s", ct.left, ct.right), -1, &arg_collect)) return NULL; - if (!strcmp(ct.left, "...")) break; if (z_term && sym->current - p > 1 && sym->args.num < 20) { if (!str_array_push(sym, ct.left ? ct.left : "", -1, &sym->args) || @@ -404,9 +414,7 @@ static char* get_args(struct parsed_symbol* sym, BOOL z_term, */ if (z_term && *sym->current++ != 'Z') return NULL;
- if (arg_collect.num == 0 || - (arg_collect.num == 1 && !strcmp(arg_collect.elts[0], "void"))) - return str_printf(sym, "%cvoid%c", open_char, close_char); + if (!arg_collect.num) return str_printf(sym, "%c%c", open_char, close_char); for (i = 1; i < arg_collect.num; i++) { args_str = str_printf(sym, "%s,%s", args_str, arg_collect.elts[i]); @@ -859,7 +867,7 @@ static const char* get_simple_type(char c) case 'N': type_string = "double"; break; case 'O': type_string = "long double"; break; case 'X': type_string = "void"; break; - case 'Z': type_string = "..."; break; +/* case 'Z': (...) variadic function arguments. Handled in get_args() */ default: type_string = NULL; break; } return type_string; @@ -910,7 +918,7 @@ static BOOL get_function_signature(struct parsed_symbol* sym, struct function_si if (!get_calling_convention(*sym->current++, &fs->call_conv, &fs->exported, sym->flags & ~UNDNAME_NO_ALLOCATION_LANGUAGE) || - !demangle_datatype(sym, &fs->return_ct, FALSE)) + !demangle_datatype(sym, &fs->return_ct, 0)) return FALSE;
if (!(fs->arguments = get_args(sym, TRUE, '(', ')')))