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

David Blaikie dblaikie at gmail.com
Tue Sep 23 14:31:41 PDT 2014


On Tue, Sep 23, 2014 at 2:24 PM, Robinson, Paul <
Paul_Robinson at playstation.sony.com> wrote:

>  > One of the issues is that there's only /so/ different we can be from
>
> > GCC here before types/declarations/definitions won't match up in GDB.
>
>
>
> I think this might get to the nub of it:  I agree that GCC/GDB matters, I
> disagree that GCC/GDB is what matters.  GCC/GDB compatibility may be an
> important use-case but it is not the Reference Implementation of DWARF, and
> in particular GCC/GDB compatibility is completely irrelevant to my
> environment.  My environment is 100% Clang,
>

What do you use as a debugger? (or other DWARF consumers that might care
about whether two bits of DWARF describe the same type in the same sense
that the C++ language defines)


> and we care more about what the DWARF spec says than we do about whatever
> GCC/GDB might choose to do for one reason or another.  So, if GCC/GDB
> compatibility means diverging so noticeably from what the spec says (i.e.,
> that the name is as it is in the source program)  maybe this is a point
> worth identifying as one where a divergence occurs, and make the choice
> target-dependent.
>

Certainly it's possible to make this target-dependent - see DWARF2 support
for Darwin, etc.


>  In a way it feels somewhat analogous to choices in supporting
> extensions/dialects of C++.  For practical purposes it's very worthwhile to
> the community to support things that GCC supports, but that doesn't mean
> that GCC defines the standard.  In the case at hand, Clang has strayed from
> the letter of the DWARF spec, and we'd really like to see a way back toward
> it.
>

The DWARF spec doesn't really describe the world of templates in a complete
and useful manner. I think it's problematic to try to wedge the wording
into saying "DWARF says this is the one way to encode this info" - DWARF
makes some general suggestions about how certain constructs could be
mapped, but until there's a document like the C++ ABI that says "this is
the required lowering from C++ to DWARF" (and there's buy-in to conform to
this from both DWARF producers and consumers) a lot of this is going to
come down to "what do consumers and producers agree to".


>  We're entirely willing to do work toward getting things realigned
> (admittedly I personally have been mostly MIA for the past year, but I am
> seeing an occasional photon from down the far end of my current tunnel)
> given that the primary contributor and code owner are willing to go along
> with it.
>
> Thanks,
>
> --paulr
>
>
>
> *From:* David Blaikie [mailto:dblaikie at gmail.com]
> *Sent:* Monday, September 22, 2014 3:47 PM
> *To:* Nick Lewycky
> *Cc:* Robinson, Paul; lldb-dev at cs.uiuc.edu; llvm-commits at cs.uiuc.edu
> *Subject:* Re: [lldb-dev] [RFC][PATCH] Keep un-canonicalized template
> types in the debug information
>
>
>
>
>
>
>
> On Mon, Sep 22, 2014 at 3:40 PM, Nick Lewycky <nicholas at mxc.ca> wrote:
>
> Robinson, Paul wrote:
>
> I think it comes down to how the information is planning to be used. A
> consumer with the dwarf information today could, in fact, get to the
> S<int> type from a user who types S<A> pretty easily right?
>
> If the typedef actually appears in the DWARF, the consumer could figure
> out what the user meant by typing S<A>, yes. In my experiments the
> typedef is not always present, which leaves the user up a creek with no
> paddle.
>
> How the debugger presents the types of things is also a consideration,
> however. This is more evident with a less trivial example, such as the
> vector typedef I described previously. It is clearly a step backward in
> the end-user debugging experience if people are used to seeing
>
> S<int4>
>
> which the debugger has been displaying all along, but suddenly they
> start seeing instead
>
> S<int __attribute__((ext_vector_type(4)))>
>
> which is what has started happening. Especially if 'int4' no longer
> appears as a typedef at all, this is Just Wrong.
>
>
> In clang, ConvertTypeToDiagnosticString deals with vectors specially. The
> rationale, I think, is to prevent the compiler from showing the internal
> implementation detail of how float4 and friends are defined. I think that
> this is the wrong approach and would have preferred a second attribute.
> Does attribute nodebug on a typedef have any meaning yet? Could we
> repurpose it to mean that you shouldn't look through this typedef for
> compiler diagnostics nor debug info? Any any case, our behaviour on
> diagnostics and debug info should probably match here.
>
>
>
> One of the issues is that there's only /so/ different we can be from GCC
> here before types/declarations/definitions won't match up in GDB. I believe
> GCC has some smarts to tolerate differences like S<0> versus S<0u> or
> S<'\0'> I think... at least some of those, but I don't know how it'll go
> with:
>
>   S<__attribute__((__vector_size__(4 * sizeof(int)))) int>
>
> V
>
>   S<__vector(4) int>
>
> (using a GCC-compatible syntax, vector_size(sizeof(int) * 4) rather than
> the ext_vector_type which isn't supported by GCC)
>
> Huh... apparently GDB ignores the entire adornment and allows
> func(S<__vector(4) int>) to be called with a variable of type
> S<__attribute__((__vector_size__(5 * sizeof(int)))) int> even... not sure
> what to make of any of that.
>
>
>
>
> Nick
>
> Wolfgang did some bisection and traced this change to r205447, and the
> intent of that change was centered on default template arguments. This
> de-referencing of typedefs appears to have been an *unintended side
> effect* of that patch.
>
> I want my typedef'd template parameters back please…
>
> --paulr
>
> *From:*Eric Christopher [mailto:echristo at gmail.com]
> *Sent:* Thursday, September 18, 2014 10:07 PM
> *To:* Robinson, Paul
> *Cc:* David Blaikie; lldb-dev at cs.uiuc.edu; llvm-commits at cs.uiuc.edu;
> Frédéric Riss
> *Subject:* Re: [lldb-dev] [RFC][PATCH] Keep un-canonicalized template
> types in the debug information
>
> On Thu, Sep 18, 2014 at 5:57 PM, Robinson, Paul
> <Paul_Robinson at playstation.sony.com
>
> <mailto:Paul_Robinson at playstation.sony.com>> wrote:
>
> The (limited) feedback I've had from the committee is along these lines.
>
>     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. If you use both S<A> and S<int> in the
>     program in different places, then you need to describe both in the
>     DWARF. 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.
>
> Yeah, I'm not sure I agree with this. I've seen the thread and I'm not
> sure I like the logic.
>
>     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).
>
>     The DW_AT_specification hack is just wrong, because neither S<A> nor
>     S<int> is completing the other.
>
>     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.
>
>     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.
>     Clearly that's a bug; the type name needs to be in there somewhere.
>
>     One more thing:
>
>     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).
>
>     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.
>
> I think it comes down to how the information is planning to be used. A
> consumer with the dwarf information today could, in fact, get to the
> S<int> type from a user who types S<A> pretty easily right? Now if you'd
> like a way to print out the textual representation of every type as it
> was used in the program that's likely to be less possible without some
> serious duplication of dwarf. You could use an unnamed type for the base
> and then use DW_AT_specification with just a bare DW_AT_name to avoid
> some of the unpleasantness of the specification hack, but then you come
> to the problem of template arguments etc. It's fairly crazy to consider,
> but a user could quite easily write:
>
> new std::vector<int, allocator>()
>
> with some allocator that was never used in the program with vector and
> expect the code to be generated at run time and the rest of the type to
> be found.
>
> Anyhow, I think the best bet is for the most general type to be left in
> the debug information and then the typedefs etc to be their own DIEs.
> Unless we have some use that we're not talking about here?
>
> -eric
>
>     --paulr
>
>     *From:*David Blaikie [mailto:dblaikie at gmail.com
>     <mailto:dblaikie at gmail.com>]
>     *Sent:* Thursday, September 18, 2014 4:03 PM
>
>
>     *To:* Robinson, Paul
>     *Cc:* llvm-commits at cs.uiuc.edu <mailto:llvm-commits at cs.uiuc.edu>;
>     Greg Clayton; Frédéric Riss; lldb-dev at cs.uiuc.edu
>     <mailto:lldb-dev at cs.uiuc.edu>; jingham at apple.com
>     <mailto:jingham at apple.com>
>     *Subject:* Re: [lldb-dev] [RFC][PATCH] Keep un-canonicalized
>     template types in the debug information
>
>     On Thu, Sep 18, 2014 at 2:40 PM, Robinson, Paul
>     <Paul_Robinson at playstation.sony.com
>
>     <mailto:Paul_Robinson at playstation.sony.com>> wrote:
>
>     David,
>
>     Sorry, thought you were protesting the typedef idea as interfering
>     with deduplication or type-unit commonality.
>
>     So to recap, if we have source like this:
>
>     typedef int A;
>
>     template<typename T> struct S { T member; };
>
>     S<A> s_a;
>
>     then we'll get
>
>     DW_TAG_typedef
>
>     DW_AT_name "A"
>
>     DW_AT_type -> int
>
>     DW_TAG_structure_type
>
>     DW_AT_name "S<A>"
>
>     DW_TAG_member
>
>     DW_AT_name "member"
>
>     DW_AT_type -> int // or the typedef for "A" ?
>
>     DW_TAG_template_type_parameter
>
>     DW_AT_name "T"
>
>     DW_AT_type -> (the typedef for "A")
>
>     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?
>
>         DW_TAG_variable
>
>         DW_AT_name "s_a"
>
>         DW_AT_type -> (the above structure_type)
>
>     Ah, no - just a typedef of the template:
>
>     1: DW_TAG_structure_type // the debug info we already produce today
>     (S<int>)
>     ...
>
>     2: DW_TAG_typedef
>     DW_AT_name "S<A>"
>     DW_AT_type (1)
>
>     And honestly, the variable would still be of type (1).
>
>     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.
>
>     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).
>
>         Yes?
>
>         --paulr
>
>         *From:*David Blaikie [mailto:dblaikie at gmail.com
>         <mailto:dblaikie at gmail.com>]
>         *Sent:* Thursday, September 18, 2014 1:09 PM
>         *To:* Robinson, Paul
>         *Cc:* llvm-commits at cs.uiuc.edu
>         <mailto:llvm-commits at cs.uiuc.edu>; Greg Clayton; Frédéric Riss;
>         lldb-dev at cs.uiuc.edu <mailto:lldb-dev at cs.uiuc.edu>;
>         jingham at apple.com <mailto:jingham at apple.com>
>         *Subject:* Re: [lldb-dev] [RFC][PATCH] Keep un-canonicalized
>         template types in the debug information
>
>         On Thu, Sep 18, 2014 at 1:05 PM, David Blaikie
>         <dblaikie at gmail.com <mailto:dblaikie at gmail.com>> wrote:
>
>         On Thu, Sep 18, 2014 at 1:00 PM, Robinson, Paul
>         <Paul_Robinson at playstation.sony.com
>         <mailto:Paul_Robinson at playstation.sony.com>> wrote:
>
>          >From: David Blaikie [mailto:dblaikie at gmail.com
>         <mailto:dblaikie at gmail.com>]
>          >On Wed, Sep 17, 2014 at 11:54 AM, Robinson, Paul
>         <Paul_Robinson at playstation.sony.com
>         <mailto:Paul_Robinson at playstation.sony.com>> wrote:
>          >> From: David Blaikie [mailto:dblaikie at gmail.com
>         <mailto:dblaikie at gmail.com>]
>          >> > On Wed, Sep 17, 2014 at 7:45 AM, Robinson, Paul
>         <Paul_Robinson at playstation.sony.com
>         <mailto:Paul_Robinson at playstation.sony.com>> wrote:
>          >> > > From: David Blaikie [mailto:dblaikie at gmail.com
>         <mailto:dblaikie at gmail.com>]
>          >> > > On Sat, Sep 13, 2014 at 6:54 PM, Robinson, Paul
>         <Paul_Robinson at playstation.sony.com
>         <mailto:Paul_Robinson at playstation.sony.com>> wrote:
>          >> > > > > > On 09 Sep 2014, at 00:01, jingham at apple.com
>
>         <mailto:jingham at apple.com> wrote:
>          >> > > > > > >
>          >> > > > > > > From the debugger's standpoint, the functional
>         concern is that if you do
>          >> > > > > > something more real, like:
>          >> > > > > > >
>          >> > > > > > > typedef int A;
>          >> > > > > > > template <typename T>
>          >> > > > > > > struct S
>          >> > > > > > > {
>          >> > > > > > > T my_t;
>          >> > > > > > > };
>          >> > > > > > >
>          >> > > > > > > I want to make sure that the type of my_t is
>         given as "A" not as "int".
>          >> > > > > > The reason for that is that it is not uncommon to
>         have data formatters
>          >> > > > > > that trigger off the typedef name. This happens
>         when you use some common
>          >> > > > > > underlying type like "int" but the value has some
>         special meaning when it
>          >> > > > > > is formally an "A", and you want to use the data
>         formatters to give it an
>          >> > > > > > appropriate presentation. Since the data
>         formatters work by matching type
>          >> > > > > > name, starting from the most specific on down, it
>         is important that the
>          >> > > > > > typedef name be preserved.
>          >> > > > > > >
>          >> > > > > > > However, it would be really odd to see:
>          >> > > > > > >
>          >> > > > > > > (lldb) expr -T -- my_s
>          >> > > > > > > (S<int>) $1 = {
>          >> > > > > > > (A) my_t = 5
>          >> > > > > > > }
>          >> > > > > > >
>          >> > > > > > > instead of:
>          >> > > > > > >
>          >> > > > > > > (lldb) expr -T -- my_s
>          >> > > > > > > (S<A>) $1 = {
>          >> > > > > > > (A) my_t = 5
>          >> > > > > > > }
>          >> > > > > > >
>          >> > > > > > > so I am in favor of presenting the template
>         parameter type with the most
>          >> > > > > > specific name it was given in the overall template
>         type name.
>          >> > > > > >
>          >> > > > > > OK, we get this wrong today. I’ll try to look into
> it.
>          >> > > > > >
>          >> > > > > > What’s your take on the debug info representation
>         for the templated class
>          >> > > > > > type? The tentative patch introduces a typedef
>         that declares S<A> as a
>          >> > > > > > typedef for S<int>. The typedef doesn’t exist in
>         the code, thus I find it
>          >> > > > > > a bit of a lie to the debugger. I was more in
>         favour of something like :
>          >> > > > > >
>          >> > > > > > DW_TAG_variable
>          >> > > > > > DW_AT_type: -> DW_TAG_structure_type
>          >> > > > > > DW_AT_name: S<A>
>          >> > > > > > DW_AT_specification: -> DW_TAG_structure_type
>          >> > > > > > DW_AT_name: S<int>
>          >> > > > > >
>          >> > > > > > This way the canonical type is kept in the debug
>         information, and the
>          >> > > > > > declaration type is a real class type aliasing the
>         canonical type. But I’m
>          >> > > > > > not sure debuggers can digest this kind of aliasing.
>          >> > > > > >
>          >> > > > > > Fred
>          >> > > > >
>          >> > > > > Why introduce the extra typedef? S<A> should have a
>         template parameter
>          >> > > > > entry pointing to A which points to int. The info
>         should all be there
>          >> > > > > without any extra stuff. Or if you think something
>         is missing, please
>          >> > > > > provide a more complete example.
>          >> > > > My immediate concern here would be either loss of
>         information or bloat
>          >> > > > when using that with type units (either bloat because
>         each instantiation
>          >> > > > with differently spelled (but identical) parameters is
>         treated as a separate
>          >> > > > type - or loss when the types are considered the same
>         and all but one are
>          >> > > > dropped at link time)
>          >> > > You'll need to unpack that more because I'm not
>         following the concern.
>          >> > > If the typedefs are spelled differently, don't they
>         count as different types?
>          >> > > DWARF wants to describe the program as-written, and
>         there's no S<int> written
>          >> > > in the program.
>          >> > >
>          >> > > Maybe not in this TU, but possibly in another TU? Or by
>         the user.
>          >> > >
>          >> > > void func(S<int>);
>          >> > > ...
>          >> > > typedef int A;
>          >> > > S<A> s;
>          >> > > func(s); // calls the same function
>          >> > >
>          >> > > The user probably wants to be able to call void func
>         with S<int> or S<A>
>          >> > Sure.
>          >> >
>          >> > > (and, actually, in theory, with S<B> where B is another
>         typedef of int, but
>          >> > > that'll /really/ require DWARF consumer support and/or
>         new DWARF wording).
>          >> >
>          >> > Not DWARF wording. DWARF doesn't say when you can and
>         can't call something;
>          >> > that's a debugger feature and therefore a debugger decision.
>          >> >
>          >> What I mean is we'd need some new DWARF to help explain
>         which types are
>          >> equivalent (or the debugger would have to do a lot of
>         spelunking to try
>          >> to find structurally equivalent types - "S<B>" and "S<A>",
>         go look through
>          >> their DW_TAG_template_type_params, see if they are typedefs
>         to the same
>          >> underlying type, etc... )
>          >> >
>          >> >
>          >> > > We can't emit these as completely independent types - it
>         would be verbose
>          >> > > (every instantiation with different typedefs would be a
>         whole separate type
>          >> > > in the DWARF, not deduplicated by type units, etc) and
> wrong
>          >> >
>          >> > Yes, "typedef int A;" creates a synonym/alias not a new
>         type, so S<A> and S<int>
>          >> > describe the same type from the C++ perspective, so you
>         don't want two complete
>          >> > descriptions with different names, because that really
>         would be describing them
>          >> > as separate types. What wrinkles my brow is having S<int>
>         be the "real"
>          >> > description even though it isn't instantiated that way in
>         the program. I wonder
>          >> > if it should be marked artificial... but if you do
>         instantiate S<int> in another
>          >> > TU then you don't want that. Huh. It also seems weird to
>         have this:
>          >> > DW_TAG_typedef
>          >> > DW_AT_name "S<A>"
>          >> > DW_AT_type -> S<int>
>          >> > but I seem to be coming around to thinking that's the most
>         viable way to have
>          >> > a single actual instantiated type, and still have the
>         correct names of things
>          >*mostly* correct; this still loses "A" as the type of the data
>         member.
>          >
>          >For the DW_TAG_template_type_parameter, you mean? No, it
> wouldn't.
>          >
>          > (as a side note, if you do actually have a data member (or
>         any other mention) of
>          >the template parameter type, neither Clang nor GCC really get
>         that 'right' -
>          >"template<typename T> struct foo { T t; }; foo<int> f;" - in
>         both Clang and GCC,
>          >the type of the 't' member of foo<int> is a direct reference
>         to the "int" DIE, not
>          >to the DW_TAG_template_type_parameter for "T" -> int)
>
>         Huh. And DWARF doesn't say you should point to the
>         template_type_parameter...
>         I thought it did, but no. Okay, so nothing is lost, but it feels
>         desirable
>         to me, that uses of the template parameter should cite it in the
>         DWARF as well.
>         But I guess we can leave that part of the debate for another time.
>
>          >
>          >Crud.
>          >But I haven't come up with a way to get that back without
>         basically instantiating
>          >S<A> and S<int> separately.
>          >
>          >> >
>          >> Yep - it's the only way I can think of giving this
>         information in a way that's
>          >> likely to work with existing consumers. It would probably be
>         harmless to add
>          >> DW_AT_artificial to the DW_TAG_typedef, if that's any help
>         to any debug info
>          >> consumer.
>          >
>          >Hmmm no, S<A> is not the artificial name;
>          >
>          >It's not the artificial name, but it is an artificial typedef.
>
>         If the source only says S<A>, then the entire S<int> description
>         is artificial,
>         because *that's not what the user wrote*. So both the typedef
>         and the class type
>         are artificial. Gah. Let's forget artificial here.
>
>          >
>          >some debuggers treat DW_AT_artificial
>          >as meaning "don't show this to the user."
>          >
>          >In some sense that's what I want - we never wrote the typedef
>         in the source
>          >so I wouldn't want to see it rendered in the "list of
>         typedefs" (or even
>          >probably in the list of types, maybe).
>          >
>          >But S<A> is the name we *do* want to
>          >show to the user.
>          >
>          >Maybe. Sometimes. But there could be many such aliases for the
>         type. (& many
>          >more that were never written in the source code, but are still
>         valid in the
>          >source language (every other typedef of int, every other way
>         to name the int
>          >type (decltype, etc)))
>
>         But you *lose* cases where the typedef is the *same*
>         *everywhere*. And in
>         many cases that typedef is a valuable thing, not the trivial
>         rename we've
>         been bandying about. This is a more real example:
>
>         typedef int int4 __attribute__((ext_vector_type(4)));
>         template<typename T> struct TypeTraits {};
>         template<>
>         struct TypeTraits<int4> {
>         static unsigned MysteryNumber;
>         };
>         unsigned TypeTraits<int4>::MysteryNumber = 3U;
>
>         Displaying "TypeTraits<int __attribute__((ext_vector_type(4)))>"
>         is much
>         worse than "TypeTraits<int4>" (and not just because it's shorter).
>         More to the point, having the debugger *complain* when the user
> says
>         something like "ptype TypeTraits<int4>" is a problem.
>
>         Reducing debug-info size is a worthy goal, but don't degrade the
>         debugging
>         experience to get there.
>
>         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:
>
>         typedef fooA foo<int>;
>
>         (keyboard shortcuts are hard - accidentally sent before I finished)
>
>         (gdb) ptype fooA
>
>         type = struct foo<int> [with T = int] {
>
>         <no data fields>
>
>         }
>
>         But in any case, I think what I'm saying boils down to:
>
>         Short of changing debug info consumers, I think the only thing
>         we can do is DW_TAG_typedef. That'll work for existing consumers.
>
>         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.
>
>         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.
>
>         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.
>
>         - David
>
>                 --paulr
>
>
>                  >
>                  >
>                  >> That said, I'm not opposed to proposing something to
>                 DWARF to define some more
>                  >> 'proper' way to describe this.
>                  >
>                  >Yah. I've been thinking about the DW_AT_specification
>                 idea too, which would be
>                  >something like this:
>                  > DW_TAG_class_type
>                  > DW_AT_name "S<A>"
>                  > DW_AT_specification -> S<int>
>                  >
>                  > DW_TAG_template_type_parameter
>                  > DW_AT_name "T"
>                  > DW_AT_type -> A
>                  >
>                  >The problem with this is you don't know where T is
>                 used in the template, so
>                  >you *still* don't know when to use A as the type of
>                 "field". Also it's kind
>                  >of an abuse of DW_AT_specification. If we can't get A
>                 as the type of "field"
>                  >then the typedef is more straightforward and
>                 understandable.
>                  >
>                  >It's still a lot of DWARF to emit for every way the
>                 user has named the template
>                  >& I'm not sure how much value it provides - are there
>                 use cases you have in mind
>                  >that would benefit from the increased fidelity of
>                 knowing which template argument
>                  >corresponds to the way the user wrote the type.
>                  >
>                  > (& what would we emit if the user named the type in
>                 some other more exotic way:
>                  >int func(); template<typename T> struct S { }; ...
>                 S<decltype(func())> s; )
>                  >
>                  >
>                  >Maybe I'll pop a note to the DWARF committee for a
>                 broader set of opinions.
>                  >
>                  >>
>                  >> One other open question is then, when, if ever, to
>                 reference the DW_TAG_typedef
>                  >> rather than the underlying type? Do we just
>                 reference it whenever the user
>                  >> writes using that name?
>                  >>
>                  >> void f(S<A>);
>                  >> ...
>                  >> void f(S<B>) { ... }
>                  >>
>                  >> etc... (this would be just as possible/we could
>                 maybe treat it the same as if
>                  >> the user wrote "void f(A); ... void f(B) { ... }")
>                  >
>                  >That's what I would do, and I think is more conformant
>                 to the DWARF spec.
>                  >--paulr
>                  >
>                  >>
>                  >> > (because DWARF is all about the name "as it
>                 appears in the source program.")
>                  >> >
>                  >> > > (the debugger wouldn't know these are actually
>                 the same type so wouldn't
>                  >> > > allow function calls, etc).
>                  >> > >
>                  >> > > - David
>                  >> > >
>                  >> > > >
>                  >> > > >
>                  >> > > > > Jim
>                  >> > > > >
>                  >> > > >> On Sep 8, 2014, at 12:38 PM, Frédéric Riss
>
>                 <friss at apple.com <mailto:friss at apple.com>> wrote:
>                  >> > > >>
>                  >> > > >>
>                  >> > > >>> On 08 Sep 2014, at 19:31, Greg Clayton
>
>                 <gclayton at apple.com <mailto:gclayton at apple.com>> wrote:
>                  >> > > >>>
>                  >> > > >>> This means you will see "S<A>" as the type
>                 for your variables in the
>                  >> > > debugger when you view variables or children of
>                 structs/unions/classes. I
>                  >> > > think this is not what the user would want to
>                 see. I would rather see
>                  >> > > "S<int>" as the type for my variable than see
>                 "S<A>”.
>                  >> > > >>
>                  >> > > >> I find it more accurate for the debugger to
>                 report what has actually
>                  >> > > been put in the code. Moreover when a typedef is
>                 used, it’s usually to
>                  >> > > make things more readable not to hide
>                 information, thus I guess it would
>                  >> > > usually be as informative while being more
>                 compact. The debugger needs to
>                  >> > > have a way to describe the real type behind the
>                 abbreviated name though,
>                  >> > > we must not have less information compared to
>                 what we have today.
>                  >> > > >>
>                  >> > > >> Another point: this allows the debugger to
>                 know what S<A> actually is.
>                  >> > > Without it, the debugger only knows the
>                 canonical type. This means that
>                  >> > > currently you can’t copy/paste a piece of code
>                 that references that kind
>                  >> > > of template names and have it parse correctly. I
>                 /think/ that having this
>                  >> > > information in the debug info will allow more of
>                 this to work.
>                  >> > > >>
>                  >> > > >> But we can agree to disagree :-) It would be
>                 great to have more people
>                  >> > > chime and give their opinion.
>                  >> > > >>
>                  >> > > >> Fred
>                  >> > > >>
>                  >> > > >>>> On Sep 5, 2014, at 4:00 PM, Adrian Prantl
>
>                 <aprantl at apple.com <mailto:aprantl at apple.com>> wrote:
>                  >> > > >>>>
>                  >> > > >>>>
>                  >> > > >>>>> On Sep 5, 2014, at 3:49 PM, Eric
>                 Christopher <echristo at gmail.com <mailto:echristo at gmail.com
> >>
>                  >> > > wrote:
>                  >> > > >>>>>
>                  >> > > >>>>>
>                  >> > > >>>>>
>                  >> > > >>>>>
>                  >> > > >>>>> On Fri, Sep 5, 2014 at 3:43 PM, Duncan P.
>                 N. Exon Smith
>                  >> > > <dexonsmith at apple.com
>                 <mailto:dexonsmith at apple.com>> wrote:
>                  >> > > >>>>>
>                  >> > > >>>>>> On 2014 Sep 5, at 16:01, Frédéric Riss
>
>                 <friss at apple.com <mailto:friss at apple.com>> wrote:
>                  >> > > >>>>>>
>                  >> > > >>>>>> 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_TAG_variable
>                  >> > > >>>>>> 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> >.
>                  >> > > >>>>>
>                  >> > > >>>>> If you specify `vector<int>` in C++ do you
>                 get that instead of
>                  >> > > >>>>> `vector<int, std::__1::allocator<int>>`?
>                  >> > > >>>>>
>                  >> > > >>>>> Yeah, I mentioned this as possibly causing
>                 problems with debuggers
>                  >> > > or other consumers, but I don't have any proof
>                 past "ooooo scary!”.
>                  >> > > >>>>
>                  >> > > >>>> Well, [+lldb-dev], could this confuse
>                 debuggers? :-)
>                  >> > > >>>>
>                  >> > > >>>> -- adrian
>                  >> > > >>>>>
>                  >> > > >>>>> That said, I like the idea personally :)
>                  >> > > >>>>>
>                  >> > > >>>>> -eric
>                  >> > > >>>>>
>                  >> > > >>>>>
>                  >> > > >>>>>> 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.
>                  >> > > >>>>>
>                  >> > > >>>>> Maybe someone on cfe-dev knows a better way.
>                  >> > > >>>>>
>                  >> > > >>>>>>
>                  >> > > >>>>>> Thoughts?
>                  >> > > >>>>>>
>                  >> > > >>>>>> <template-arg-typedefs.diff>
>                  >> > > >>>>>>
>                  >> > > >>>>>> Fred
>                  >> > > >>>>>>
>                  >> > > >>>>>>
>                  >> > > >>>>>>
>                  >> > > >>>>>>
>                  >> > > >>>>>>
>                  >> > > >>>>>>
>                 _______________________________________________
>                  >> > > >>>>>> llvm-commits mailing list
>                  >> > > >>>>>> llvm-commits at cs.uiuc.edu
>
>                 <mailto:llvm-commits at cs.uiuc.edu>
>                  >> > > >>>>>>
>                 http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>                  >> > > >>>>>
>                  >> > > >>>>>
>                  >> > > >>>>
>                  >> > > >>>>
> _______________________________________________
>                  >> > > >>>> lldb-dev mailing list
>                  >> > > >>>> lldb-dev at cs.uiuc.edu
>                 <mailto:lldb-dev at cs.uiuc.edu>
>                  >> > > >>>>
>                 http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
>                  >> > > >>>
>                  >> > > >>
>                  >> > > >>
>                  >> > > >> _______________________________________________
>                  >> > > >> lldb-dev mailing list
>                  >> > > >> lldb-dev at cs.uiuc.edu
>                 <mailto:lldb-dev at cs.uiuc.edu>
>                  >> > > >>
>                 http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
>                  >> > > >
>                  >> > >
>                  >> > >
>                  >> > > _______________________________________________
>                  >> > > llvm-commits mailing list
>                  >> > > llvm-commits at cs.uiuc.edu
>                 <mailto:llvm-commits at cs.uiuc.edu>
>                  >> > >
>                 http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>                  >> >
>                  >> > _______________________________________________
>                  >> > llvm-commits mailing list
>                  >> > llvm-commits at cs.uiuc.edu
>                 <mailto:llvm-commits at cs.uiuc.edu>
>                  >> >
>                 http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
>
>     _______________________________________________
>     lldb-dev mailing list
>     lldb-dev at cs.uiuc.edu <mailto:lldb-dev at cs.uiuc.edu>
>     http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140923/35e14dbe/attachment.html>


More information about the llvm-commits mailing list