[RFC][PATCH] Keep un-canonicalized template types in the debug information

Frédéric Riss friss at apple.com
Fri Sep 5 13:01:06 PDT 2014

I couldn’t even find a subject expressing exactly what this patch is about… First of all, it’s meant to start a discussion, and I’m not proposing it for inclusion right now.

The issue I’m trying to address is that template types are always canonicalized when emitted in the debug information (this is the desugar() call in UnwrapTypeForDebugInformation).

This means that if the developer writes:

typedef int A;
template <typename T>
struct S {};

S<A> var;

The variable var will have type S<int> and not S<A>. In this simple example, it’s not that much of an issue, but for heavily templated code, the full expansion might be really different from the original declaration.

The attached patch makes us emit an intermediate typedef for the variable’s type:

0x0000002a:   DW_TAG_variable [2]  
                DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000032] = “var")
                DW_AT_type [DW_FORM_ref4]       (cu + 0x0040 => {0x00000040})
                DW_AT_external [DW_FORM_flag]   (0x01)
                DW_AT_decl_file [DW_FORM_data1] (0x01)
                DW_AT_decl_line [DW_FORM_data1] (8)
                DW_AT_location [DW_FORM_block1] (<0x09> 03 70 6c 00 00 00 00 00 00 )

0x00000040:   DW_TAG_typedef [3]  
                DW_AT_type [DW_FORM_ref4]       (cu + 0x004b => {0x0000004b})
                DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000035] = “S<A>")
                DW_AT_decl_file [DW_FORM_data1] (0x01)
                DW_AT_decl_line [DW_FORM_data1] (6)

0x0000004b:   DW_TAG_structure_type [4] *
                DW_AT_name [DW_FORM_strp]       ( .debug_str[0x0000003e] = “S<int>")
                DW_AT_byte_size [DW_FORM_data1] (0x01)
                DW_AT_decl_file [DW_FORM_data1] (0x01)
                DW_AT_decl_line [DW_FORM_data1] (6)

Which basically is what I want, although I don’t like that it introduces a typedef where there is none in the code. I’d prefer that to be:

  DW_AT_type: -> DW_TAG_structure_type
                   DW_AT_name: S<A>
                   DW_AT_specification: -> DW_TAG_structure_type
                                             DW_AT_name: S<int>

The patch also has the nice property of omitting the defaulted template arguments in the first level typedef. For example you get vector<A> instead of vector<int, std::__1::allocator<int> >.

Now there is one thing I really don’t like about the patch. In order not to emit typedefs for types that don’t need it, I use string comparison between the desugared and the original type. I haven’t quantified anything, but doing the construction of the type name for every template type and then comparing it to decide to use it or not seems like a big waste.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: template-arg-typedefs.diff
Type: application/octet-stream
Size: 1940 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140905/eba94338/attachment.obj>
-------------- next part --------------


More information about the llvm-commits mailing list