Module: wine Branch: master Commit: ecfe99af150e636d50cf47316a320996601f84b0 URL: https://gitlab.winehq.org/wine/wine/-/commit/ecfe99af150e636d50cf47316a32099...
Author: Eric Pouech epouech@codeweavers.com Date: Fri May 17 09:30:44 2024 +0200
msvcrt: Correctly unmangle qualified pointer to function/method.
Signesd-off-by: Eric Pouech epouech@codeweavers.com
---
dlls/msvcrt/tests/cpp.c | 4 ++-- dlls/msvcrt/undname.c | 28 ++++++++++++++++++---------- 2 files changed, 20 insertions(+), 12 deletions(-)
diff --git a/dlls/msvcrt/tests/cpp.c b/dlls/msvcrt/tests/cpp.c index bed1a5d4530..29bb126bcda 100644 --- a/dlls/msvcrt/tests/cpp.c +++ b/dlls/msvcrt/tests/cpp.c @@ -1177,7 +1177,7 @@ static void test_demangle(void) /* 23 */ {"??0streambuf@@QAE@ABV0@@Z", "public: __thiscall streambuf::streambuf(class streambuf const &)"}, /* 24 */ {"??0strstreambuf@@QAE@ABV0@@Z", "public: __thiscall strstreambuf::strstreambuf(class strstreambuf const &)"}, /* 25 */ {"??0strstreambuf@@QAE@H@Z", "public: __thiscall strstreambuf::strstreambuf(int)"}, -/* 26 */ {"??0strstreambuf@@QAE@P6APAXJ@ZP6AXPAX@Z@Z", "public: __thiscall strstreambuf::strstreambuf(void * (__cdecl*)(long),void (__cdecl*)(void *))"}, +/* 26 */ {"??0strstreambuf@@QAE@Q6APAXJ@ZS6AXPAX@Z@Z", "public: __thiscall strstreambuf::strstreambuf(void * (__cdecl*const)(long),void (__cdecl*const volatile)(void *))"}, /* 27 */ {"??0strstreambuf@@QAE@PADH0@Z", "public: __thiscall strstreambuf::strstreambuf(char *,int,char *)"}, /* 28 */ {"??0strstreambuf@@QAE@PAEH0@Z", "public: __thiscall strstreambuf::strstreambuf(unsigned char *,int,unsigned char *)"}, /* 29 */ {"??0strstreambuf@@QAE@XZ", "public: __thiscall strstreambuf::strstreambuf(void)"}, @@ -1212,7 +1212,7 @@ static void test_demangle(void) /* 58 */ {"?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAJ@Z", "protected: virtual class std::istreambuf_iterator<char,struct std::char_traits<char> > __thiscall std::num_get<char,class std::istreambuf_iterator<char,struct std::char_traits<char> > >::do_get(class std::istreambuf_iterator<char,struct std::char_traits<char> >,class std::istreambuf_iterator<char,struct std::char_traits<char> >,class std::ios_base &,int &,long &)const "}, /* 59 */ {"?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAK@Z", "protected: virtual class std::istreambuf_iterator<char,struct std::char_traits<char> > __thiscall std::num_get<char,class std::istreambuf_iterator<char,struct std::char_traits<char> > >::do_get(class std::istreambuf_iterator<char,struct std::char_traits<char> >,class std::istreambuf_iterator<char,struct std::char_traits<char> >,class std::ios_base &,int &,unsigned long &)const "}, /* 60 */ {"?do_get@?$num_get@DV?$istreambuf_iterator@DU?$char_traits@D@std@@@std@@@std@@MBE?AV?$istreambuf_iterator@DU?$char_traits@D@std@@@2@V32@0AAVios_base@2@AAHAAM@Z", "protected: virtual class std::istreambuf_iterator<char,struct std::char_traits<char> > __thiscall std::num_get<char,class std::istreambuf_iterator<char,struct std::char_traits<char> > >::do_get(class std::istreambuf_iterator<char,struct std::char_traits<char> >,class std::istreambuf_iterator<char,struct std::char_traits<char> >,class std::ios_base &,int &,float &)const "}, -/* 61 */ {"?_query_new_handler@@YAP6AHI@ZXZ", "int (__cdecl*__cdecl _query_new_handler(void))(unsigned int)"}, +/* 61 */ {"?_query_new_handler@@YAR6AHI@ZXZ", "int (__cdecl*__cdecl _query_new_handler(void))(unsigned int)"}, /* 62 */ {"?register_callback@ios_base@std@@QAEXP6AXW4event@12@AAV12@H@ZH@Z", "public: void __thiscall std::ios_base::register_callback(void (__cdecl*)(enum std::ios_base::event,class std::ios_base &,int),int)"}, /* 63 */ {"?seekg@?$basic_istream@DU?$char_traits@D@std@@@std@@QAEAAV12@JW4seekdir@ios_base@2@@Z", "public: class std::basic_istream<char,struct std::char_traits<char> > & __thiscall std::basic_istream<char,struct std::char_traits<char> >::seekg(long,enum std::ios_base::seekdir)"}, /* 64 */ {"?seekg@?$basic_istream@DU?$char_traits@D@std@@@std@@QAEAAV12@V?$fpos@H@2@@Z", "public: class std::basic_istream<char,struct std::char_traits<char> > & __thiscall std::basic_istream<char,struct std::char_traits<char> >::seekg(class std::fpos<int>)"}, diff --git a/dlls/msvcrt/undname.c b/dlls/msvcrt/undname.c index 74856504685..923ec67d363 100644 --- a/dlls/msvcrt/undname.c +++ b/dlls/msvcrt/undname.c @@ -997,14 +997,22 @@ static BOOL demangle_datatype(struct parsed_symbol* sym, struct datatype_t* ct, case 'B': /* volatile reference */ if (!get_qualified_type(ct, sym, dt, flags)) goto done; break; + case 'P': /* Pointer */ case 'Q': /* const pointer */ case 'R': /* volatile pointer */ case 'S': /* const volatile pointer */ - if (!get_qualified_type(ct, sym, (flags & IN_ARGS) ? dt : 'P', flags)) goto done; - break; - case 'P': /* Pointer */ + if (!(flags & IN_ARGS)) dt = 'P'; if (isdigit(*sym->current)) - { + { + const char *ptr_qualif; + switch (dt) + { + default: + case 'P': ptr_qualif = NULL; break; + case 'Q': ptr_qualif = "const"; break; + case 'R': ptr_qualif = "volatile"; break; + case 'S': ptr_qualif = "const volatile"; break; + } /* FIXME: * P6 = Function pointer * P8 = Member function pointer @@ -1022,10 +1030,10 @@ static BOOL demangle_datatype(struct parsed_symbol* sym, struct datatype_t* ct, if (!get_function_qualifier(sym, &function_qualifier)) goto done; if (!get_function_signature(sym, &fs)) - goto done; + goto done;
- ct->left = str_printf(sym, "%s%s (%s %s::*", - fs.return_ct.left, fs.return_ct.right, fs.call_conv, class); + ct->left = str_printf(sym, "%s%s (%s %s::*%s", + fs.return_ct.left, fs.return_ct.right, fs.call_conv, class, ptr_qualif); ct->right = str_printf(sym, ")%s%s", fs.arguments, function_qualifier); } else if (*sym->current == '6') @@ -1037,14 +1045,14 @@ static BOOL demangle_datatype(struct parsed_symbol* sym, struct datatype_t* ct, if (!get_function_signature(sym, &fs)) goto done;
- ct->left = str_printf(sym, "%s%s (%s*", - fs.return_ct.left, fs.return_ct.right, fs.call_conv); + ct->left = str_printf(sym, "%s%s (%s*%s", + fs.return_ct.left, fs.return_ct.right, fs.call_conv, ptr_qualif); ct->flags = DT_NO_LEADING_WS; ct->right = str_printf(sym, ")%s", fs.arguments); } else goto done; } - else if (!get_qualified_type(ct, sym, 'P', flags)) goto done; + else if (!get_qualified_type(ct, sym, dt, flags)) goto done; break; case 'W': if (*sym->current == '4')