Module: wine Branch: master Commit: 49864b084d298221a79b9945424f3c4ec1acb3dd URL: http://source.winehq.org/git/wine.git/?a=commit;h=49864b084d298221a79b994542...
Author: Alexandre Julliard julliard@winehq.org Date: Wed Oct 10 19:52:16 2007 +0200
msvcrt: Fix demangling of function pointers by maintaining the left/right distinction for type references.
---
dlls/msvcrt/tests/cpp.c | 6 +++++- dlls/msvcrt/undname.c | 46 +++++++++++++++++++++++++++++----------------- 2 files changed, 34 insertions(+), 18 deletions(-)
diff --git a/dlls/msvcrt/tests/cpp.c b/dlls/msvcrt/tests/cpp.c index 5ffc27f..fea9885 100644 --- a/dlls/msvcrt/tests/cpp.c +++ b/dlls/msvcrt/tests/cpp.c @@ -979,6 +979,8 @@ static void test_demangle(void) {"?$aaa@Vbbb@ccc@@Vddd@2@", "aaa<class ccc::bbb,class ccc::ddd>"}, { "??0?$Foo@P6GHPAX0@Z@@QAE@PAD@Z", "public: __thiscall Foo<int (__stdcall*)(void *,void *)>::Foo<int (__stdcall*)(void *,void *)>(char *)"}, { "??0?$Foo@P6GHPAX0@Z@@QAE@PAD@Z", "__thiscall Foo<int (__stdcall*)(void *,void *)>::Foo<int (__stdcall*)(void *,void *)>(char *)", 0x880}, +{ "?Qux@Bar@@0PAP6AHPAV1@AAH1PAH@ZA", "private: static int (__cdecl** Bar::Qux)(class Bar *,int &,int &,int *)" }, +{ "?Qux@Bar@@0PAP6AHPAV1@AAH1PAH@ZA", "Bar::Qux", 0x1800}, }; int i, num_test = (sizeof(test)/sizeof(test[0])); char* name; @@ -987,7 +989,9 @@ static void test_demangle(void) { name = p__unDName(0, test[i].in, 0, pmalloc, pfree, test[i].flags); ok(name != NULL && !strcmp_space(test[i].out, name), - "Got name "%s" for %d\n", name, i); + "Got name "%s" for %d\n", name, i ); + ok(name != NULL && !strcmp_space(test[i].out, name), + "Expected "%s"\n", test[i].out ); pfree(name); } } diff --git a/dlls/msvcrt/undname.c b/dlls/msvcrt/undname.c index c48e9ab..2816bfb 100644 --- a/dlls/msvcrt/undname.c +++ b/dlls/msvcrt/undname.c @@ -180,7 +180,7 @@ static void str_array_init(struct array* a) * str_array_push * Adding a new string to an array */ -static void str_array_push(struct parsed_symbol* sym, const char* ptr, size_t len, +static void str_array_push(struct parsed_symbol* sym, const char* ptr, int len, struct array* a) { assert(ptr); @@ -366,10 +366,10 @@ static BOOL get_modifier(char ch, const char** ret) return TRUE; }
-static const char* get_modified_type(struct parsed_symbol* sym, char modif) +static BOOL get_modified_type(struct datatype_t *ct, struct parsed_symbol* sym, + struct array *pmt_ref, char modif) { const char* modifier; - const char* ret = NULL; const char* str_modif;
switch (modif) @@ -381,7 +381,7 @@ static const char* get_modified_type(struct parsed_symbol* sym, char modif) case 'R': str_modif = " * volatile"; break; case 'S': str_modif = " * const volatile"; break; case '?': str_modif = ""; break; - default: return NULL; + default: return FALSE; }
if (get_modifier(*sym->current++, &modifier)) @@ -390,14 +390,21 @@ static const char* get_modified_type(struct parsed_symbol* sym, char modif) struct datatype_t sub_ct;
/* Recurse to get the referred-to type */ - if (!demangle_datatype(sym, &sub_ct, NULL, FALSE)) - return NULL; - ret = str_printf(sym, "%s%s%s%s%s", - sub_ct.left, sub_ct.left && modifier ? " " : NULL, - modifier, sub_ct.right, str_modif); + 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 ); + else + { + /* don't insert a space between duplicate '*' */ + if (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 ); + } + ct->right = sub_ct.right; sym->stack.num = mark; } - return ret; + return TRUE; }
/****************************************************************** @@ -707,16 +714,16 @@ static BOOL demangle_datatype(struct parsed_symbol* sym, struct datatype_t* ct, break; case '?': /* not all the time is seems */ - if (!(ct->left = get_modified_type(sym, '?'))) goto done; + if (!get_modified_type(ct, sym, pmt_ref, '?')) goto done; break; case 'A': /* reference */ case 'B': /* volatile reference */ - if (!(ct->left = get_modified_type(sym, dt))) goto done; + if (!get_modified_type(ct, sym, pmt_ref, dt)) goto done; break; case 'Q': /* const pointer */ case 'R': /* volatile pointer */ case 'S': /* const volatile pointer */ - if (!(ct->left = get_modified_type(sym, in_args ? dt : 'P'))) goto done; + if (!get_modified_type(ct, sym, pmt_ref, in_args ? dt : 'P')) goto done; break; case 'P': /* Pointer */ if (isdigit(*sym->current)) @@ -746,7 +753,7 @@ static BOOL demangle_datatype(struct parsed_symbol* sym, struct datatype_t* ct, } else goto done; } - else if (!(ct->left = get_modified_type(sym, 'P'))) goto done; + else if (!get_modified_type(ct, sym, pmt_ref, 'P')) goto done; break; case 'W': if (*sym->current == '4') @@ -765,7 +772,9 @@ static BOOL demangle_datatype(struct parsed_symbol* sym, struct datatype_t* ct, case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* Referring back to previously parsed type */ - ct->left = str_array_get_ref(pmt_ref, dt - '0'); + /* left and right are pushed as two separate strings */ + ct->left = str_array_get_ref(pmt_ref, (dt - '0') * 2); + ct->right = str_array_get_ref(pmt_ref, (dt - '0') * 2 + 1); if (!ct->left) goto done; add_pmt = FALSE; break; @@ -804,8 +813,11 @@ static BOOL demangle_datatype(struct parsed_symbol* sym, struct datatype_t* ct, break; } if (add_pmt && pmt_ref && in_args) - str_array_push(sym, str_printf(sym, "%s%s", ct->left, ct->right), - -1, pmt_ref); + { + /* left and right are pushed as two separate strings */ + str_array_push(sym, ct->left ? ct->left : "", -1, pmt_ref); + str_array_push(sym, ct->right ? ct->right : "", -1, pmt_ref); + } done:
return ct->left != NULL;