<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Sep 18, 2014 at 5:57 PM, Robinson, Paul <span dir="ltr"><<a href="mailto:Paul_Robinson@playstation.sony.com" target="_blank">Paul_Robinson@playstation.sony.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div lang="EN-US" link="blue" vlink="purple">
<div>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">The (limited) feedback I've had from the committee is along these lines.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">If the program uses the type name "S<A>" for something, the DWARF should fully describe the type named "S<A>" because that's the name as-in-the-source-program. </span><span style="color:rgb(31,73,125);font-family:Calibri,sans-serif;font-size:11pt"> If you use both S<A> and S<int> in the program in different places, then you need to describe both in the DWARF.</span></p></div></div></blockquote><div><br></div><div>To the best of my knowledge, having spent the better part of 6 months studying the size of LLVM's debug info, this is simply not a workable solution. I doubt any DWARF producer of C++ would make this the default behavior.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="purple"><div><p class="MsoNormal"><span style="color:rgb(31,73,125);font-family:Calibri,sans-serif;font-size:11pt"> There is sadly no standard way to associate the two as aliases. Yes in C++ they are the same; in standard DWARF they are not.</span></p></div></div></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="purple">
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">The typedef S<A> => S<int> hack might work [if the debugger can tolerate that]. It is obviously not a real typedef. You could mark it artificial as an indication
that something funny is going on (artificial typedefs being highly atypical).<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">The DW_AT_specification hack is just wrong, because neither S<A> nor S<int> is completing the other.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">I need to step back from the typedef hack. I believe our debugger throws away the <brackets> on the theory that it can reconstruct them from template-parameter
children; that is, the <bracket> part of the name is redundant. The typedef hack does not provide those children, and the <brackets> are not redundant, so this is likely to be a problem for us. Feh. I'd forgotten about that detail when I started liking the
typedef hack. Yes, this means I don't have a suggestion, apart from emitting things redundantly as needed to preserve as-in-the-source-program.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">Here's a bizarre data point. Going back to at least 3.2, Clang has emitted S<int> instead of S<A>. But with my vector example, it used to use the typedef
name up through 3.4. That changed in 3.5, where the type name 'int4' has entirely disappeared from the DWARF. </span></p></div></blockquote><div><br></div><div>Yep, I think maybe I fixed that somewhere along the way - debug size used to be a real problem for LLVM. I think I fixed that before I was looking at size though, just because it broke GDB test cases - the names were different so basic debugger expressions didn't work between translation units, IIRC. I'd have to go back & check what the particular failure/bug/motivation was, but I think it was a name mismatch between libstdc++ (built with GCC) debug info and clang debug info since we weren't using the canonical name.<br><br>[Yeah, went and checked - the issue was that clang would produce a declaration of "basic_string<char>" which, since it had a distinct name from the debug info for the definition (compiled into libstdc++, built by GCC) for "basic_string<char, traits and allocator goop>" the debugger didn't identify these as being the same type and thus printing an expression of the declared type couldn't find the guts of how basic_string works and the pretty printer would fail]</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="purple"><div><p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">Clearly that's a bug; the type name needs to be in there somewhere.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">One more thing:<u></u><u></u></span></p><span>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"><u></u> <u></u></span></p>
<p class="MsoNormal" style="margin-left:0.5in">it'd be good to figure out how to deal with all possible names for the type, even the ones the user hasn't written (eg: typedef int A; typedef int B; and make sure that the debugger can handle S<int>, S<A> and S<B>
in their code, even though the user only wrote one of those in the source).<u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"><u></u> <u></u></span></p>
</span><p class="MsoNormal"><a name="1488b81cbd783109_1488b69db0a1b2e8__MailEndCompose"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">The answer to this "how to deal" question is with debugger smarts, not more complicated DWARF. DWARF is about the program as-written
and as-compiled, not about anything-the-user-might-conceivably-try-to-write-in-the-debugger. Handling this in DWARF is a combinatorial nightmare, for completely speculative purposes. Not gonna happen.</span></a></p></div></div></blockquote><div><br></div><div>The question is whether the debugger needs more information from the DWARF to do its job. (& whether the compiler/linker/etc will have trouble due to excessively large debug info... and whether clang debug info interoperates with GCC debug info (at least for libstdc++, generally compiled with GCC, this is extra important))</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="purple"><div><p class="MsoNormal"><a name="1488b81cbd783109_1488b69db0a1b2e8__MailEndCompose"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"><u></u><u></u></span></a></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">--paulr<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"><u></u> <u></u></span></p>
<div style="border-style:none none none solid;border-left-color:blue;border-left-width:1.5pt;padding:0in 0in 0in 4pt">
<div>
<div style="border-style:solid none none;border-top-color:rgb(181,196,223);border-top-width:1pt;padding:3pt 0in 0in">
<p class="MsoNormal"><b><span style="font-size:10pt;font-family:Tahoma,sans-serif">From:</span></b><span style="font-size:10pt;font-family:Tahoma,sans-serif"> David Blaikie [mailto:<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>]
<br>
<b>Sent:</b> Thursday, September 18, 2014 4:03 PM</span></p><div><div><br>
<b>To:</b> Robinson, Paul<br>
<b>Cc:</b> <a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a>; Greg Clayton; Frédéric Riss; <a href="mailto:lldb-dev@cs.uiuc.edu" target="_blank">lldb-dev@cs.uiuc.edu</a>; <a href="mailto:jingham@apple.com" target="_blank">jingham@apple.com</a><br>
<b>Subject:</b> Re: [lldb-dev] [RFC][PATCH] Keep un-canonicalized template types in the debug information<u></u><u></u></div></div><p></p>
</div>
</div><div><div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p class="MsoNormal">On Thu, Sep 18, 2014 at 2:40 PM, Robinson, Paul <<a href="mailto:Paul_Robinson@playstation.sony.com" target="_blank">Paul_Robinson@playstation.sony.com</a>> wrote:<u></u><u></u></p>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">David,</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">Sorry, thought you were protesting the typedef idea as interfering with deduplication or type-unit
commonality.</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> </span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">So to recap, if we have source like this:</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> </span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">typedef int A;</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">template<typename T> struct S { T member; };</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">S<A> s_a;</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> </span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">then we'll get</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> </span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">DW_TAG_typedef</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> DW_AT_name "A"</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> DW_AT_type -> int</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> </span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">DW_TAG_structure_type</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> DW_AT_name "S<A>"</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> DW_TAG_member</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> DW_AT_name "member"</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> DW_AT_type -> int // or the typedef for "A" ?</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> DW_TAG_template_type_parameter</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> DW_AT_name "T"</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> DW_AT_type -> (the typedef for "A")</span><u></u><u></u></p>
</div>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Are you suggesting putting the rest of S<int> here too? Or how would S<A> refer to S<int> for the rest of the implementation?<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<blockquote style="border-style:none none none solid;border-left-color:rgb(204,204,204);border-left-width:1pt;padding:0in 0in 0in 6pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> </span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">DW_TAG_variable</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> DW_AT_name "s_a"</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> DW_AT_type -> (the above structure_type)</span><u></u><u></u></p>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:12pt">Ah, no - just a typedef of the template:<br>
<br>
1: DW_TAG_structure_type // the debug info we already produce today (S<int>)<br>
...<br>
<br>
2: DW_TAG_typedef<br>
DW_AT_name "S<A>"<br>
DW_AT_type (1)<br>
<br>
And honestly, the variable would still be of type (1).<br>
<br>
Duplicating the entire type for each way of naming the same type is, I'm fairly sure, not going to work for debuggers today. If someone wants to propose a way of encoding this that will need new code/support from debuggers, etc, then I feel the right venue
to discuss that is the DWARF committee - because you'll need buy-in from producers and consumers. Without having that discussion, I believe just providing a typedef of the template specialization is probably a benefit to users.<br>
<br>
If we want to talk about a 'right' representation of this for DWARF that would necessitate more substantial changes to both DWARF producers and consumers... I think it'll be a bit more involved than even what you're proposing. If we're going to deal with that,
it'd be good to figure out how to deal with all possible names for the type, even the ones the user hasn't written (eg: typedef int A; typedef int B; and make sure that the debugger can handle S<int>, S<A> and S<B> in their code, even though the user only
wrote one of those in the source).<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<blockquote style="border-style:none none none solid;border-left-color:rgb(204,204,204);border-left-width:1pt;padding:0in 0in 0in 6pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> </span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">Yes?</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">--paulr</span><u></u><u></u></p>
<p class="MsoNormal"><a name="1488b81cbd783109_1488b69db0a1b2e8_1488ab547f3e38d4__MailEndCompose"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"> </span></a><u></u><u></u></p>
<div style="border-style:none none none solid;border-left-color:blue;border-left-width:1.5pt;padding:0in 0in 0in 4pt">
<div>
<div style="border-style:solid none none;border-top-color:rgb(181,196,223);border-top-width:1pt;padding:3pt 0in 0in">
<p class="MsoNormal"><b><span style="font-size:10pt;font-family:Tahoma,sans-serif">From:</span></b><span style="font-size:10pt;font-family:Tahoma,sans-serif"> David Blaikie [mailto:<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>]
<br>
<b>Sent:</b> Thursday, September 18, 2014 1:09 PM<br>
<b>To:</b> Robinson, Paul<br>
<b>Cc:</b> <a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a>; Greg Clayton; Frédéric Riss;
<a href="mailto:lldb-dev@cs.uiuc.edu" target="_blank">lldb-dev@cs.uiuc.edu</a>; <a href="mailto:jingham@apple.com" target="_blank">
jingham@apple.com</a><br>
<b>Subject:</b> Re: [lldb-dev] [RFC][PATCH] Keep un-canonicalized template types in the debug information</span><u></u><u></u></p>
</div>
</div>
<p class="MsoNormal"> <u></u><u></u></p>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
<div>
<p class="MsoNormal">On Thu, Sep 18, 2014 at 1:05 PM, David Blaikie <<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>> wrote:<u></u><u></u></p>
<div>
<div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
<div>
<div>
<div>
<p class="MsoNormal">On Thu, Sep 18, 2014 at 1:00 PM, Robinson, Paul <<a href="mailto:Paul_Robinson@playstation.sony.com" target="_blank">Paul_Robinson@playstation.sony.com</a>> wrote:<u></u><u></u></p>
<div>
<div>
<p class="MsoNormal" style="margin-bottom:12pt">>From: David Blaikie [mailto:<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>]<br>
>On Wed, Sep 17, 2014 at 11:54 AM, Robinson, Paul <<a href="mailto:Paul_Robinson@playstation.sony.com" target="_blank">Paul_Robinson@playstation.sony.com</a>> wrote:<br>
>> From: David Blaikie [mailto:<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>]<br>
>> > On Wed, Sep 17, 2014 at 7:45 AM, Robinson, Paul <<a href="mailto:Paul_Robinson@playstation.sony.com" target="_blank">Paul_Robinson@playstation.sony.com</a>> wrote:<br>
>> > > From: David Blaikie [mailto:<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>]<br>
>> > > On Sat, Sep 13, 2014 at 6:54 PM, Robinson, Paul <<a href="mailto:Paul_Robinson@playstation.sony.com" target="_blank">Paul_Robinson@playstation.sony.com</a>> wrote:<br>
>> > > > > > On 09 Sep 2014, at 00:01, <a href="mailto:jingham@apple.com" target="_blank">
jingham@apple.com</a> wrote:<br>
>> > > > > > ><br>
>> > > > > > > From the debugger's standpoint, the functional concern is that if you do<br>
>> > > > > > something more real, like:<br>
>> > > > > > ><br>
>> > > > > > > typedef int A;<br>
>> > > > > > > template <typename T><br>
>> > > > > > > struct S<br>
>> > > > > > > {<br>
>> > > > > > > T my_t;<br>
>> > > > > > > };<br>
>> > > > > > ><br>
>> > > > > > > I want to make sure that the type of my_t is given as "A" not as "int".<br>
>> > > > > > The reason for that is that it is not uncommon to have data formatters<br>
>> > > > > > that trigger off the typedef name. This happens when you use some common<br>
>> > > > > > underlying type like "int" but the value has some special meaning when it<br>
>> > > > > > is formally an "A", and you want to use the data formatters to give it an<br>
>> > > > > > appropriate presentation. Since the data formatters work by matching type<br>
>> > > > > > name, starting from the most specific on down, it is important that the<br>
>> > > > > > typedef name be preserved.<br>
>> > > > > > ><br>
>> > > > > > > However, it would be really odd to see:<br>
>> > > > > > ><br>
>> > > > > > > (lldb) expr -T -- my_s<br>
>> > > > > > > (S<int>) $1 = {<br>
>> > > > > > > (A) my_t = 5<br>
>> > > > > > > }<br>
>> > > > > > ><br>
>> > > > > > > instead of:<br>
>> > > > > > ><br>
>> > > > > > > (lldb) expr -T -- my_s<br>
>> > > > > > > (S<A>) $1 = {<br>
>> > > > > > > (A) my_t = 5<br>
>> > > > > > > }<br>
>> > > > > > ><br>
>> > > > > > > so I am in favor of presenting the template parameter type with the most<br>
>> > > > > > specific name it was given in the overall template type name.<br>
>> > > > > ><br>
>> > > > > > OK, we get this wrong today. I’ll try to look into it.<br>
>> > > > > ><br>
>> > > > > > What’s your take on the debug info representation for the templated class<br>
>> > > > > > type? The tentative patch introduces a typedef that declares S<A> as a<br>
>> > > > > > typedef for S<int>. The typedef doesn’t exist in the code, thus I find it<br>
>> > > > > > a bit of a lie to the debugger. I was more in favour of something like :<br>
>> > > > > ><br>
>> > > > > > DW_TAG_variable<br>
>> > > > > > DW_AT_type: -> DW_TAG_structure_type<br>
>> > > > > > DW_AT_name: S<A><br>
>> > > > > > DW_AT_specification: -> DW_TAG_structure_type<br>
>> > > > > > DW_AT_name: S<int><br>
>> > > > > ><br>
>> > > > > > This way the canonical type is kept in the debug information, and the<br>
>> > > > > > declaration type is a real class type aliasing the canonical type. But I’m<br>
>> > > > > > not sure debuggers can digest this kind of aliasing.<br>
>> > > > > ><br>
>> > > > > > Fred<br>
>> > > > ><br>
>> > > > > Why introduce the extra typedef? S<A> should have a template parameter<br>
>> > > > > entry pointing to A which points to int. The info should all be there<br>
>> > > > > without any extra stuff. Or if you think something is missing, please<br>
>> > > > > provide a more complete example.<br>
>> > > > My immediate concern here would be either loss of information or bloat<br>
>> > > > when using that with type units (either bloat because each instantiation<br>
>> > > > with differently spelled (but identical) parameters is treated as a separate<br>
>> > > > type - or loss when the types are considered the same and all but one are<br>
>> > > > dropped at link time)<br>
>> > > You'll need to unpack that more because I'm not following the concern.<br>
>> > > If the typedefs are spelled differently, don't they count as different types?<br>
>> > > DWARF wants to describe the program as-written, and there's no S<int> written<br>
>> > > in the program.<br>
>> > ><br>
>> > > Maybe not in this TU, but possibly in another TU? Or by the user.<br>
>> > ><br>
>> > > void func(S<int>);<br>
>> > > ...<br>
>> > > typedef int A;<br>
>> > > S<A> s;<br>
>> > > func(s); // calls the same function<br>
>> > ><br>
>> > > The user probably wants to be able to call void func with S<int> or S<A><br>
>> > Sure.<br>
>> ><br>
>> > > (and, actually, in theory, with S<B> where B is another typedef of int, but<br>
>> > > that'll /really/ require DWARF consumer support and/or new DWARF wording).<br>
>> ><br>
>> > Not DWARF wording. DWARF doesn't say when you can and can't call something;<br>
>> > that's a debugger feature and therefore a debugger decision.<br>
>> ><br>
>> What I mean is we'd need some new DWARF to help explain which types are<br>
>> equivalent (or the debugger would have to do a lot of spelunking to try<br>
>> to find structurally equivalent types - "S<B>" and "S<A>", go look through<br>
>> their DW_TAG_template_type_params, see if they are typedefs to the same<br>
>> underlying type, etc... )<br>
>> ><br>
>> ><br>
>> > > We can't emit these as completely independent types - it would be verbose<br>
>> > > (every instantiation with different typedefs would be a whole separate type<br>
>> > > in the DWARF, not deduplicated by type units, etc) and wrong<br>
>> ><br>
>> > Yes, "typedef int A;" creates a synonym/alias not a new type, so S<A> and S<int><br>
>> > describe the same type from the C++ perspective, so you don't want two complete<br>
>> > descriptions with different names, because that really would be describing them<br>
>> > as separate types. What wrinkles my brow is having S<int> be the "real"<br>
>> > description even though it isn't instantiated that way in the program. I wonder<br>
>> > if it should be marked artificial... but if you do instantiate S<int> in another<br>
>> > TU then you don't want that. Huh. It also seems weird to have this:<br>
>> > DW_TAG_typedef<br>
>> > DW_AT_name "S<A>"<br>
>> > DW_AT_type -> S<int><br>
>> > but I seem to be coming around to thinking that's the most viable way to have<br>
>> > a single actual instantiated type, and still have the correct names of things<br>
>*mostly* correct; this still loses "A" as the type of the data member.<br>
><br>
>For the DW_TAG_template_type_parameter, you mean? No, it wouldn't.<br>
><br>
> (as a side note, if you do actually have a data member (or any other mention) of<br>
>the template parameter type, neither Clang nor GCC really get that 'right' -<br>
>"template<typename T> struct foo { T t; }; foo<int> f;" - in both Clang and GCC,<br>
>the type of the 't' member of foo<int> is a direct reference to the "int" DIE, not<br>
>to the DW_TAG_template_type_parameter for "T" -> int)<u></u><u></u></p>
</div>
</div>
<p class="MsoNormal">Huh. And DWARF doesn't say you should point to the template_type_parameter...<br>
I thought it did, but no. Okay, so nothing is lost, but it feels desirable<br>
to me, that uses of the template parameter should cite it in the DWARF as well.<br>
But I guess we can leave that part of the debate for another time.<br>
<br>
> <br>
>Crud.<br>
>But I haven't come up with a way to get that back without basically instantiating<br>
>S<A> and S<int> separately.<br>
><br>
>> ><br>
>> Yep - it's the only way I can think of giving this information in a way that's<br>
>> likely to work with existing consumers. It would probably be harmless to add<br>
>> DW_AT_artificial to the DW_TAG_typedef, if that's any help to any debug info<br>
>> consumer.<br>
><br>
>Hmmm no, S<A> is not the artificial name;<br>
><br>
>It's not the artificial name, but it is an artificial typedef.<br>
<br>
If the source only says S<A>, then the entire S<int> description is artificial,<br>
because *that's not what the user wrote*. So both the typedef and the class type<br>
are artificial. Gah. Let's forget artificial here.<br>
<br>
> <br>
>some debuggers treat DW_AT_artificial<br>
>as meaning "don't show this to the user."<br>
><br>
>In some sense that's what I want - we never wrote the typedef in the source<br>
>so I wouldn't want to see it rendered in the "list of typedefs" (or even<br>
>probably in the list of types, maybe).<br>
> <br>
>But S<A> is the name we *do* want to<br>
>show to the user.<br>
><br>
>Maybe. Sometimes. But there could be many such aliases for the type. (& many<br>
>more that were never written in the source code, but are still valid in the<br>
>source language (every other typedef of int, every other way to name the int<br>
>type (decltype, etc)))<br>
<br>
But you *lose* cases where the typedef is the *same* *everywhere*. And in<br>
many cases that typedef is a valuable thing, not the trivial rename we've<br>
been bandying about. This is a more real example:<br>
<br>
typedef int int4 __attribute__((ext_vector_type(4)));<br>
template<typename T> struct TypeTraits {};<br>
template<><br>
struct TypeTraits<int4> {<br>
static unsigned MysteryNumber;<br>
};<br>
unsigned TypeTraits<int4>::MysteryNumber = 3U;<br>
<br>
Displaying "TypeTraits<int __attribute__((ext_vector_type(4)))>" is much<br>
worse than "TypeTraits<int4>" (and not just because it's shorter).<br>
More to the point, having the debugger *complain* when the user says<br>
something like "ptype TypeTraits<int4>" is a problem.<br>
<br>
Reducing debug-info size is a worthy goal, but don't degrade the debugging<br>
experience to get there.<u></u><u></u></p>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
</div>
</div>
<div>
<p class="MsoNormal">I'm not sure which part of what I've said seemed like a suggestion to degrade the debugging experience to minimize debug info size (the proposition that we should use a typedef
or other alias on top of the canonical type? It wouldn't cause "ptype TypeTraits<int4>" to complain - indeed for GDB ptyping a typedef gives /exactly/ the same output as if you ptype the underlying type - it doesn't even mention that there's a typedef involved:<br>
<br>
typedef fooA foo<int>;<u></u><u></u></p>
</div>
</div>
</div>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">(keyboard shortcuts are hard - accidentally sent before I finished)<u></u><u></u></p>
<div>
<div>
<p class="MsoNormal">(gdb) ptype fooA<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">type = struct foo<int> [with T = int] {<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <no data fields><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">}<br>
<br>
But in any case, I think what I'm saying boils down to:<br>
<br>
Short of changing debug info consumers, I think the only thing we can do is DW_TAG_typedef. That'll work for existing consumers.<br>
<br>
Anything else will need possibly new DWARF wording, or at least an agreement between a variety of debug info consumers and producers that some new cliche/use of existing DWARF be used to describe these situations.<br>
<br>
I could be wrong - if someone wants to try prototyping the DW_TAG_structure_type proposal Fred had and see if existing debuggers work with that, sure.<br>
<br>
I'm not opposed to someone coming up with a standardizable more descriptive form than DW_TAG_typedef, but that conversation probably needs to happen with the DWARF Committee more than the LLVM community.<br>
<br>
- David<u></u><u></u></p>
</div>
</div>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<blockquote style="border-style:none none none solid;border-left-color:rgb(204,204,204);border-left-width:1pt;padding:0in 0in 0in 6pt;margin:5pt 0in 5pt 4.8pt">
<div>
<div>
<div>
<div>
<p class="MsoNormal" style="margin-bottom:12pt"> <u></u><u></u></p>
</div>
<div>
<div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<blockquote style="border-style:none none none solid;border-left-color:rgb(204,204,204);border-left-width:1pt;padding:0in 0in 0in 6pt;margin:5pt 0in 5pt 4.8pt">
<p class="MsoNormal">--paulr<u></u><u></u></p>
<div>
<div>
<p class="MsoNormal" style="margin-bottom:12pt"><br>
> <br>
><br>
>> That said, I'm not opposed to proposing something to DWARF to define some more<br>
>> 'proper' way to describe this.<br>
><br>
>Yah. I've been thinking about the DW_AT_specification idea too, which would be<br>
>something like this:<br>
> DW_TAG_class_type<br>
> DW_AT_name "S<A>"<br>
> DW_AT_specification -> S<int><br>
><br>
> DW_TAG_template_type_parameter<br>
> DW_AT_name "T"<br>
> DW_AT_type -> A<br>
><br>
>The problem with this is you don't know where T is used in the template, so<br>
>you *still* don't know when to use A as the type of "field". Also it's kind<br>
>of an abuse of DW_AT_specification. If we can't get A as the type of "field"<br>
>then the typedef is more straightforward and understandable.<br>
><br>
>It's still a lot of DWARF to emit for every way the user has named the template<br>
>& I'm not sure how much value it provides - are there use cases you have in mind<br>
>that would benefit from the increased fidelity of knowing which template argument<br>
>corresponds to the way the user wrote the type.<br>
><br>
> (& what would we emit if the user named the type in some other more exotic way:<br>
>int func(); template<typename T> struct S { }; ... S<decltype(func())> s; )<br>
> <br>
><br>
>Maybe I'll pop a note to the DWARF committee for a broader set of opinions.<br>
><br>
>><br>
>> One other open question is then, when, if ever, to reference the DW_TAG_typedef<br>
>> rather than the underlying type? Do we just reference it whenever the user<br>
>> writes using that name?<br>
>><br>
>> void f(S<A>);<br>
>> ...<br>
>> void f(S<B>) { ... }<br>
>><br>
>> etc... (this would be just as possible/we could maybe treat it the same as if<br>
>> the user wrote "void f(A); ... void f(B) { ... }")<br>
><br>
>That's what I would do, and I think is more conformant to the DWARF spec.<br>
>--paulr<br>
><br>
>> <br>
>> > (because DWARF is all about the name "as it appears in the source program.")<br>
>> ><br>
>> > > (the debugger wouldn't know these are actually the same type so wouldn't<br>
>> > > allow function calls, etc).<br>
>> > ><br>
>> > > - David<br>
>> > ><br>
>> > > ><br>
>> > > ><br>
>> > > > > Jim<br>
>> > > > ><br>
>> > > >> On Sep 8, 2014, at 12:38 PM, Frédéric Riss <<a href="mailto:friss@apple.com" target="_blank">friss@apple.com</a>> wrote:<br>
>> > > >><br>
>> > > >><br>
>> > > >>> On 08 Sep 2014, at 19:31, Greg Clayton <<a href="mailto:gclayton@apple.com" target="_blank">gclayton@apple.com</a>> wrote:<br>
>> > > >>><br>
>> > > >>> This means you will see "S<A>" as the type for your variables in the<br>
>> > > debugger when you view variables or children of structs/unions/classes. I<br>
>> > > think this is not what the user would want to see. I would rather see<br>
>> > > "S<int>" as the type for my variable than see "S<A>”.<br>
>> > > >><br>
>> > > >> I find it more accurate for the debugger to report what has actually<br>
>> > > been put in the code. Moreover when a typedef is used, it’s usually to<br>
>> > > make things more readable not to hide information, thus I guess it would<br>
>> > > usually be as informative while being more compact. The debugger needs to<br>
>> > > have a way to describe the real type behind the abbreviated name though,<br>
>> > > we must not have less information compared to what we have today.<br>
>> > > >><br>
>> > > >> Another point: this allows the debugger to know what S<A> actually is.<br>
>> > > Without it, the debugger only knows the canonical type. This means that<br>
>> > > currently you can’t copy/paste a piece of code that references that kind<br>
>> > > of template names and have it parse correctly. I /think/ that having this<br>
>> > > information in the debug info will allow more of this to work.<br>
>> > > >><br>
>> > > >> But we can agree to disagree :-) It would be great to have more people<br>
>> > > chime and give their opinion.<br>
>> > > >><br>
>> > > >> Fred<br>
>> > > >><br>
>> > > >>>> On Sep 5, 2014, at 4:00 PM, Adrian Prantl <<a href="mailto:aprantl@apple.com" target="_blank">aprantl@apple.com</a>> wrote:<br>
>> > > >>>><br>
>> > > >>>><br>
>> > > >>>>> On Sep 5, 2014, at 3:49 PM, Eric Christopher <<a href="mailto:echristo@gmail.com" target="_blank">echristo@gmail.com</a>><br>
>> > > wrote:<br>
>> > > >>>>><br>
>> > > >>>>><br>
>> > > >>>>><br>
>> > > >>>>><br>
>> > > >>>>> On Fri, Sep 5, 2014 at 3:43 PM, Duncan P. N. Exon Smith<br>
>> > > <<a href="mailto:dexonsmith@apple.com" target="_blank">dexonsmith@apple.com</a>> wrote:<br>
>> > > >>>>><br>
>> > > >>>>>> On 2014 Sep 5, at 16:01, Frédéric Riss <<a href="mailto:friss@apple.com" target="_blank">friss@apple.com</a>> wrote:<br>
>> > > >>>>>><br>
>> > > >>>>>> I couldn’t even find a subject expressing exactly what this patch<br>
>> > > is about… First of all, it’s meant to start a discussion, and I’m not<br>
>> > > proposing it for inclusion right now.<br>
>> > > >>>>>><br>
>> > > >>>>>> The issue I’m trying to address is that template types are always<br>
>> > > canonicalized when emitted in the debug information (this is the desugar()<br>
>> > > call in UnwrapTypeForDebugInformation).<br>
>> > > >>>>>><br>
>> > > >>>>>> This means that if the developer writes:<br>
>> > > >>>>>><br>
>> > > >>>>>> typedef int A;<br>
>> > > >>>>>> template <typename T><br>
>> > > >>>>>> struct S {};<br>
>> > > >>>>>><br>
>> > > >>>>>> S<A> var;<br>
>> > > >>>>>><br>
>> > > >>>>>> The variable var will have type S<int> and not S<A>. In this simple<br>
>> > > example, it’s not that much of an issue, but for heavily templated code,<br>
>> > > the full expansion might be really different from the original<br>
>> > > declaration.<br>
>> > > >>>>>><br>
>> > > >>>>>> The attached patch makes us emit an intermediate typedef for the<br>
>> > > variable’s type:<br>
>> > > >>>>>><br>
>> > > >>>>>> 0x0000002a: DW_TAG_variable [2]<br>
>> > > >>>>>> DW_AT_name [DW_FORM_strp] (<br>
>> > > .debug_str[0x00000032] = “var")<br>
>> > > >>>>>> DW_AT_type [DW_FORM_ref4] (cu + 0x0040 =><br>
>> > > {0x00000040})<br>
>> > > >>>>>> DW_AT_external [DW_FORM_flag] (0x01)<br>
>> > > >>>>>> DW_AT_decl_file [DW_FORM_data1] (0x01)<br>
>> > > >>>>>> DW_AT_decl_line [DW_FORM_data1] (8)<br>
>> > > >>>>>> DW_AT_location [DW_FORM_block1] (<0x09> 03 70 6c 00 00<br>
>> > > 00 00 00 00 )<br>
>> > > >>>>>><br>
>> > > >>>>>> 0x00000040: DW_TAG_typedef [3]<br>
>> > > >>>>>> DW_AT_type [DW_FORM_ref4] (cu + 0x004b =><br>
>> > > {0x0000004b})<br>
>> > > >>>>>> DW_AT_name [DW_FORM_strp] (<br>
>> > >.debug_str[0x00000035] = “S<A>")<br>
>> > > >>>>>> DW_AT_decl_file [DW_FORM_data1] (0x01)<br>
>> > > >>>>>> DW_AT_decl_line [DW_FORM_data1] (6)<br>
>> > > >>>>>><br>
>> > > >>>>>> 0x0000004b: DW_TAG_structure_type [4] *<br>
>> > > >>>>>> DW_AT_name [DW_FORM_strp] (<br>
>> > >.debug_str[0x0000003e] = “S<int>")<br>
>> > > >>>>>> DW_AT_byte_size [DW_FORM_data1] (0x01)<br>
>> > > >>>>>> DW_AT_decl_file [DW_FORM_data1] (0x01)<br>
>> > > >>>>>> DW_AT_decl_line [DW_FORM_data1] (6)<br>
>> > > >>>>>><br>
>> > > >>>>>><br>
>> > > >>>>>> Which basically is what I want, although I don’t like that it<br>
>> > > introduces a typedef where there is none in the code. I’d prefer that to<br>
>> > > be:<br>
>> > > >>>>>><br>
>> > > >>>>>> DW_TAG_variable<br>
>> > > >>>>>> DW_AT_type: -> DW_TAG_structure_type<br>
>> > > >>>>>> DW_AT_name: S<A><br>
>> > > >>>>>> DW_AT_specification: -> DW_TAG_structure_type<br>
>> > > >>>>>> DW_AT_name: S<int><br>
>> > > >>>>>> …<br>
>> > > >>>>>><br>
>> > > >>>>>> The patch also has the nice property of omitting the defaulted<br>
>> > > template arguments in the first level typedef. For example you get<br>
>> > > vector<A> instead of vector<int, std::__1::allocator<int> >.<br>
>> > > >>>>><br>
>> > > >>>>> If you specify `vector<int>` in C++ do you get that instead of<br>
>> > > >>>>> `vector<int, std::__1::allocator<int>>`?<br>
>> > > >>>>><br>
>> > > >>>>> Yeah, I mentioned this as possibly causing problems with debuggers<br>
>> > > or other consumers, but I don't have any proof past "ooooo scary!”.<br>
>> > > >>>><br>
>> > > >>>> Well, [+lldb-dev], could this confuse debuggers? :-)<br>
>> > > >>>><br>
>> > > >>>> -- adrian<br>
>> > > >>>>><br>
>> > > >>>>> That said, I like the idea personally :)<br>
>> > > >>>>><br>
>> > > >>>>> -eric<br>
>> > > >>>>><br>
>> > > >>>>><br>
>> > > >>>>>> Now there is one thing I really don’t like about the patch. In<br>
>> > > order not to emit typedefs for types that don’t need it, I use string<br>
>> > > comparison between the desugared and the original type. I haven’t<br>
>> > > quantified anything, but doing the construction of the type name for every<br>
>> > > template type and then comparing it to decide to use it or not seems like<br>
>> > > a big waste.<br>
>> > > >>>>><br>
>> > > >>>>> Maybe someone on cfe-dev knows a better way.<br>
>> > > >>>>><br>
>> > > >>>>>><br>
>> > > >>>>>> Thoughts?<br>
>> > > >>>>>><br>
>> > > >>>>>> <template-arg-typedefs.diff><br>
>> > > >>>>>><br>
>> > > >>>>>> Fred<br>
>> > > >>>>>><br>
>> > > >>>>>><br>
>> > > >>>>>><br>
>> > > >>>>>><br>
>> > > >>>>>><br>
>> > > >>>>>> _______________________________________________<br>
>> > > >>>>>> llvm-commits mailing list<br>
>> > > >>>>>> <a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
>> > > >>>>>> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
>> > > >>>>><br>
>> > > >>>>><br>
>> > > >>>><br>
>> > > >>>> _______________________________________________<br>
>> > > >>>> lldb-dev mailing list<br>
>> > > >>>> <a href="mailto:lldb-dev@cs.uiuc.edu" target="_blank">lldb-dev@cs.uiuc.edu</a><br>
>> > > >>>> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev" target="_blank">
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev</a><br>
>> > > >>><br>
>> > > >><br>
>> > > >><br>
>> > > >> _______________________________________________<br>
>> > > >> lldb-dev mailing list<br>
>> > > >> <a href="mailto:lldb-dev@cs.uiuc.edu" target="_blank">lldb-dev@cs.uiuc.edu</a><br>
>> > > >> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev" target="_blank">
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev</a><br>
>> > > ><br>
>> > ><br>
>> > ><br>
>> > > _______________________________________________<br>
>> > > llvm-commits mailing list<br>
>> > > <a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
>> > > <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
>> ><br>
>> > _______________________________________________<br>
>> > llvm-commits mailing list<br>
>> > <a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
>> > <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><u></u><u></u></p>
</div>
</div>
</blockquote>
</div>
</div>
</div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
</div>
</blockquote>
</div>
</div>
</div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
</div>
</div></div></div>
</div>
</div>
</blockquote></div><br></div></div>