How to deal with STL type names in C++ code?

Hi,

I am using LLDB C++ API to create custom debugger and trying to dump variables with their types. To do that I am using SBValue.GetTypeName() API. Some types are OK, but some others - especially ones related to STL - are quite unreadable:

(gdb) p value.GetTypeName()

$1 = 0x7fffe419be40 “std::__1::unique_ptr<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char”…

(gdb) p value.GetDisplayTypeName()

$2 = 0x7fffe419be40 “std::__1::unique_ptr<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char”…

(gdb)

So, is there any way to convert them into some more human-friendly form?

Thanks,
Eugene

Hi Eugene,

Hi,

I am using LLDB C++ API to create custom debugger and trying to dump variables with their types. To do that I am using SBValue.GetTypeName() API. Some types are OK, but some others - especially ones related to STL - are quite unreadable:

those type names are the actual fully-specialized STL type names. I am not sure how to control GDB to stop truncating your string formatting, but after the “…” there actually is more text
It looks like what you have is std::unique_ptr<std::vectorstd::string > > and those templates all take more arguments which are defaulted so you don’t have to type them in code - but are reflected in the type name

(gdb) p value.GetTypeName()

$1 = 0x7fffe419be40 “std::__1::unique_ptr<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char”…

(gdb) p value.GetDisplayTypeName()

$2 = 0x7fffe419be40 “std::__1::unique_ptr<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char”…

(gdb)

So, is there any way to convert them into some more human-friendly form?

Not currently. What one would have to do is hook into the C++ type printing logic such that it would know to leave out these extra template arguments when they have a default value

Thanks,
Eugene


lldb-dev mailing list
lldb-dev@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev

Thanks,
- Enrico
:envelope_with_arrow: egranata@.com :phone: 27683

Hi Enrico,

I was thinking about the same issue today. Could we add a concept
called "TypeNameModifier" and provide ability to define modifiers in
scripts and command line? With this, a name like
std::__1::basic_string<...> can be modified into a more friendly name
like std::string? We could ofcourse have more complex modifications.

I think it is doable, but what is your (and the community's) opinion
about adding such a feature? If you are OK, I would like to take up
adding such a feature.

Thanks,
Siva Chandra

FWIW, GDB has a similar concept called type-printers:

To be honest, my favorite approach would be to modify clang’s TypePrinter to do this, and then hooking up GetDisplayTypeName() to use whatever flags would be necessary to invoke that bit of magic

To be honest, my favorite approach would be to modify clang’s TypePrinter
to do this, and then hooking up GetDisplayTypeName() to use whatever flags
would be necessary to invoke that bit of magic

Do you mean that clang's "pretty printer" should be made extensible by a
script?

Nope, what I am imagining is not an extensible system

When LLDB goes to print a type it asks the compiler “what is the name of this type that I should display?”
By default, clang prints the fully specialized template, including type arguments that have their default value. My theory is that we would want to add a mode to the type printer to say “simplify type name”, and that would do sensible things to get a display name that is more compact

That seems more interesting than a set of regular expression heuristics on the type name, which is probably all you could do without specialized compiler-y knowledge of types

Thanks,
- Enrico
:envelope_with_arrow: egranata@.com :phone: 27683

To be honest, my favorite approach would be to modify clang’s TypePrinter
to do this, and then hooking up GetDisplayTypeName() to use whatever flags
would be necessary to invoke that bit of magic

Do you mean that clang's "pretty printer" should be made extensible by a
script?

Nope, what I am imagining is not an extensible system

When LLDB goes to print a type it asks the compiler “what is the name of
this type that I should display?”
By default, clang prints the fully specialized template, including type
arguments that have their default value. My theory is that we would want to
add a mode to the type printer to say “simplify type name”, and that would
do sensible things to get a display name that is more compact

So, how would clang know about the "simplified" or "friendly" name for a
type? Even in case of standard library types, the underlying types (with
unfriendly type names) could be anything. For example, libstdc++ and
STLport have different underlying naming conventions. So does libc++ I
would imagine (I have not spent enough time yet staring at libc++ code).

Nope, what I am imagining is not an extensible system

When LLDB goes to print a type it asks the compiler “what is the name of this type that I should display?”
By default, clang prints the fully specialized template, including type arguments that have their default value. My theory is that we would want to add a mode to the type printer to say “simplify type name”, and that would do sensible things to get a display name that is more compact

So, how would clang know about the “simplified” or “friendly” name for a type? Even in case of standard library types, the underlying types (with unfriendly type names) could be anything. For example, libstdc++ and STLport have different underlying naming conventions. So does libc++ I would imagine (I have not spent enough time yet staring at libc++ code).

The obvious mechanism is that the compiler has knowledge of the structure of the type - so it can make printing decisions based on that type structure
In this case, I imagine a viable approach would be having rules like omitting the values of template arguments that have a default value, omit inlined namespaces, …

That seems more interesting than a set of regular expression heuristics on the type name, which is probably all you could do without specialized compiler-y knowledge of types

Thanks,
- Enrico
:envelope_with_arrow: egranata@.com :phone: 27683

Thanks,
- Enrico
:envelope_with_arrow: egranata@.com :phone: 27683

OK. I will be on vacation next week. Will give this idea a shot after
getting back.

Awesome! Looking very much forward to that!

Thanks,
- Enrico
:envelope_with_arrow: egranata@.com :phone: 27683

I have spent time yesterday and today looking into how this can be
done. I still could not come up with a way to make the compiler/clang
replace a name like "basic_string" with "string" by using a print
option.

About inlined namespaces: None of the compilers I tested with
(clang-3.5, clang ToT, gcc-4.8) emit the "inline" attribute for an
inlined namespace in the DWARF. So, we will have to first "fix" this
in the compilers before we can build an option around this.

About default template arguments: Again, none of the compilers I
tested with emit an attribute in the DWARF to convey that a template
argument is taking the default value. I am not sure there is an
attribute available here that we can use readily. I could think of
DW_AT_artificial, but default template arguments are really not
artificial. Another is DW_AT_explicit. However, this could potentially
lead to an increase in DWARF size as each and every template argument
should now carry this attribute.

Am I thinking about this "feature" correctly? As in, in the same way
as you are thinking about it?