This is an archive of the discontinued LLVM Phabricator instance.

[MS Demangler] Demangle pointers to member functions
ClosedPublic

Authored by zturner on Jul 21 2018, 1:53 PM.

Details

Summary

After this we should have full coverage of mangle-ms.cpp, minus clang extensions like blocks.

Diff Detail

Repository
rL LLVM

Event Timeline

zturner created this revision.Jul 21 2018, 1:53 PM
zturner updated this revision to Diff 156694.Jul 21 2018, 4:11 PM

I had forgotten to re-enable all of the member pointer tests. When I did re-enable them, a few were still broken, so I fixed them up. All member pointer tests now pass.

In doing so, we now differ from undname with regards to function return values. If you have this code:

typedef int (*fun)();
fun (B::* volatile memptrtofun7)();

This will be mangled as ?memptrtofun7@@3R8B@@EAAP6AHXZXZEQ1@. undname will undecorate this as int (__cdecl*(__cdecl B::* __ptr64 memptrtofun7)(void) __ptr64)(void). I find the multiple levels of nesting pretty difficult to read here, and I find it makes more sense when the return value is entirely on the left. So I've implemented that change here, and now we will print int __cdecl (*)(void) __cdecl (B::*volatile memptrtofun7)(void) which is much more similar to how the code actually looks.

Also, I was wrong in my original commit message. We're still not at 100% - clang extensions. This patch still has some failing tests regarding extern c functions and static locals. I'll consider those low priority though and work on getting major functionality working first.

ruiu added a comment.Jul 23 2018, 9:57 AM

Even though int __cdecl (*)(void) __cdecl (B::*volatile memptrtofun7)(void) is easier to read, it is not a valid piece of code, no? It is unfortunate that the C type declaration is so hard to read, but I believe people expect that demangler emits function declaration not in some "improved" form but in the regular C grammar.

rnk added a comment.Jul 23 2018, 10:20 AM

Even though int __cdecl (*)(void) __cdecl (B::*volatile memptrtofun7)(void) is easier to read, it is not a valid piece of code, no? It is unfortunate that the C type declaration is so hard to read, but I believe people expect that demangler emits function declaration not in some "improved" form but in the regular C grammar.

+1

In D49639#1171949, @rnk wrote:

Even though int __cdecl (*)(void) __cdecl (B::*volatile memptrtofun7)(void) is easier to read, it is not a valid piece of code, no? It is unfortunate that the C type declaration is so hard to read, but I believe people expect that demangler emits function declaration not in some "improved" form but in the regular C grammar.

+1

I guess another option would be to print something like:

T1 (__cdecl B::*volatile memptrtofun7)(void)
with
[
    T1 = int (__cdecl *)(void);
]

but that would be a little strange as a default since, as you said, usually people just want 1 declaration. But perhaps it would be an interesting thing to put behind a command line option in case you want a readable declaration rather than a pedantically legal declaration. It could make some types of symbols significantly easier to read, especially when the same parameter is repeated multiple times. (which should be easy to identify from the mangling).

(And for now, I'll just change it to print the one-line declaration that is legal according to the grammar, and leave any command-line options and/or extended output mode for the future.)

rnk added inline comments.Jul 26 2018, 12:53 PM
llvm/lib/Demangle/MicrosoftDemangle.cpp
1295 ↗(On Diff #156694)

Don't need this cast anymore

llvm/test/Demangle/ms-mangle.test
102 ↗(On Diff #156694)

Is there a way to get the calling convention inside the parentheses? Undname produces names like:
Undecoration of :- "?memptrtofun5@@3P8B@@EAA?CHXZEQ1@"
is :- "int volatile (cdecl B::* ptr64 memptrtofun5)(void) __ptr64"

I believe that's where you have to write the calling convention if you want it to parse.

If it's too difficult to do in this patch, that's fine.

zturner added inline comments.Jul 26 2018, 12:56 PM
llvm/test/Demangle/ms-mangle.test
102 ↗(On Diff #156694)

I have this working in a followup patch, but it pollutes this patch a bit too much IMO, so after I get this and the others in, I'll submit that in a followup. That said, I still need to update this patch to print the grammatically legal form of a member function pointer, so I'll update this patch soon with that piece, and do the calling convention part later.

zturner updated this revision to Diff 157555.EditedJul 26 2018, 1:11 PM

Mangled Name: ?memptrtofun7@@3R8B@@EAAP6AHXZXZEQ1@
Previous Undecoration: int __cdecl (*)(void) __cdecl (B::*volatile memptrtofun7)(void)
New Undecoration: int __cdecl (* __cdecl (B::*volatile memptrtofun7)(void))(void)

Note that the calling convention is in the wrong place, but as mentioned in the comments, I will address this in a followup. I already have the patch that does it, but it requires some more functional changes that I think should be separate since it also affects non-member function pointers, and this patch is specifically about member function pointers.

rnk accepted this revision.Jul 26 2018, 1:14 PM

lgtm

This revision is now accepted and ready to land.Jul 26 2018, 1:14 PM
This revision was automatically updated to reflect the committed changes.