liblit/demangle-mode

c++filt -n

Closed this issue · 8 comments

I just tried demangle-mode, thank you for making and sharing it!. I was seeing symbols get the correct font-lock highlighting, but they weren't being replaced with the demangled symbol. I changed the call to start-process to call c++filt -n, which fixed the problem. I'm using "GNU Emacs 24.5.1 (x86_64-apple-darwin13.4.0, NS apple-appkit-1265.21) of 2015-04-10".

Thank you for the kind words; I’m glad you find demangle-mode useful.

Regarding the -n flag, I suspect this might be working around a different bug. If you can answer a few questions, that will help me make sure we fix this the right way:

  1. When you look at your raw buffer, with no demangling, do the mangled symbols start with one underscore (_Z or _GLOBAL__) or two underscores (__Z or __GLOBAL__)?
  2. Please temporarily remove the -n flag, and restart Emacs so we know that flag is not being used. Open up your file or buffer where you see the symbols not being demangled. Now type M-x font-lock-fontify-buffer. Do demangled symbols now appear as they should? Or are symbols still mangled?
  3. Please run the following command on your machine of interest and tell me the output: c++filt _Z4testv __Z4testv. Please note that the first argument to c++filt starts with just one underscore, while the second argument starts with two underscores.

Thanks for helping me help you!

  1. A single underscore: _Z

  2. I'm pretty sure I tried this, and it disabled the font lock styles, the symbols remained demangled (I'll try this again to double check)

kastiglione% c++filt _Z4testv __Z4testv
_Z4testv
test()

For a little extra info:

kastiglione% c++filt -n _Z4testv __Z4testv
test()
__Z4testv
kastiglione% c++filt -_ _Z4testv __Z4testv
_Z4testv
test()

and

kastiglione% c++filt -v       
GNU c++filt 070207 20070207

Odd. Your answer to my third question shows that c++filt expects each symbol to have an extra leading underscore. In other words, the default on your platform is --strip-underscore, not --no-strip-underscore. That’s why c++filt _Z4testv __Z4testv only demangled __Z4testv but did not demangle _Z4testv. However, your answer to my first question shows that the buffer content does not actually have the extra leading underscore. So that is a strange mismatch; I would have expected these to agree.

I think the robust fix here is to make two changes, one of which you already discovered. First, we should always run c++filt --no-strip-underscore so that we know exactly how it will behave, rather than depending on the platform-specific default. Second, we should revise demangle-font-lock-keywords to match and discard an optional extra leading underscore. So effectively, we will be doing the underscore stripping ourselves rather than relying on c++filt. That should let us correctly demangle both _Z4testv and __Z4testv regardless of whether or not c++filt thinks the given platform prepends underscores.

That should work correctly right out of the box, without requiring each user to customize some platform-specific setting. OK, let’s give that a try!

Sounds good! ✨

I would like to post a new stable release with this fix, but only once I know it does what it should. So please let me know once you have tried out the new code and found that it works correctly. A comment posted here in this issue log would be perfect. Thanks!

It's working 👍

Excellent. Stable release 1.1 contains this fix. Thanks for the confirmation!