4

I'm working on a debugging/memory tool. I want to display symbols coming from C++, the problem is that they are very verbose. At the moment I'm just using __cxa_demangle, but this often results in huge strings of more than 500 characters, due to the inclusion of default template parameters.

clang++ can clearly do clever things when it reports symbols, is there any way I can take advantage of it?

As a simple example, let's take:

std::map<std::string const, unsigned int, std::less<std::string const>, std::allocator<std::pair<std::string const, unsigned int> > >::find(std::string const&)

Which clearly could be reported as:

std::map<std::string const, unsigned int>::find(std::string const&)

.. if I had a smart enough tool. It's clear that this is hard to do in general without additional knowledge (like the includes which were originally used - I can potentially get at these), but I'd be grateful for any pointers.

So far I've been pointed at libcxxabi, but apart from not having a public interface to the parse tree (which wouldn't stop me by itself), it seems like I'd have to do the hard work determining which parameters were defaults. It would be great if I could somehow trick clang into doing this for me.

pwaller
  • 601
  • 6
  • 10
  • 4
    I think we all wish for a better debugging experience with templates. I remember having to dig into `boost::ptr_map` for debugging and it was hell because of all those default parameters suddenly showing up and filling pages. Still, the pragmatic in me would probably go for a built-in list of default parameters for a couple types, and elision based on this list. – Matthieu M. Sep 01 '12 at 12:34
  • You could write your own logic: Parse the argument list into arguments, supply default mappings for the templates you care about, and check whether the arguments match the default mapping (starting from the back). – Kerrek SB Sep 03 '12 at 10:49
  • Somehow your simple example is already lucky one since you show `std::string const` instead of `std::basic_string,std::allocator > const`. Appears that you already take advantage of typedefs and specializations? – Öö Tiib Sep 15 '12 at 18:55
  • @ÖöTiib: That's just a feature of the mangling scheme and the demangler. A `std::string` is represented with a couple of characters in the mangled output, and the demangler just comes back with `std::string`. – pwaller Sep 16 '12 at 16:34
  • Have you looked at http://www.mixtion.org/gccfilter/ ? – Seg Fault Sep 24 '12 at 22:31
  • Thanks for the suggestion, but gccfilter seems to primarily remove parts of gcc's error output. It also seems to remove template arguments entirely, which is not what I'm looking for. – pwaller Sep 26 '12 at 09:47
  • clang++ is able to "optimise" away the default parameters because it has the complete parse tree available when going through the source code. Basically it knows what parameters were user supplied and which ones were template defaults. Unfortunately when you are going in reverse you don't have that luxury. – X-Istence Oct 31 '12 at 05:15

1 Answers1

5

STLFilt could help you. There are two perl scripts, STLFilt.pl (for Visual C++) and gSTLFilt.p (for gcc). It's designed to be used for error messages simplification, but I've already used it for postprocessing __cxa_demangle's output.

Used on your simple example without any options:

echo "std::map<std::string const, unsigned int, std::less<std::string const>, std::allocator<std::pair<std::string const, unsigned int> > >::find(std::string const&)" \
| perl ./gSTLFilt.pl

Gets output:

BD Software STL Message Decryptor v3.10 for gcc 2/3/4
map<string const, unsigned int>::find(string const &)

If you want to play with it's options, you should be able to get customized reformating (I haven't tried it).

Mi-La
  • 685
  • 10
  • 18