>
> template<typename T> struct t1 {
> T n1;
> };
>
> template<typename T> struct t2 {
> T m1;
> t1<T> m2;
> };
>
> int main()
> {
> t2<int> v1;
> return 0;
> }
>
> Based on the current specification, the type of m1 should reference
> a template parameter entry. This is a bug in gcc which has already
> been described [1]. llvm/clang attempted to fix this in PR [2].
>
> Also for m2 we can see that there is no information that its type was
> originally described by a template type parameter of t2. However,
> there is no specification addressing this specific case in the DWARF
> Standard.
>
Like Ben, I'm not sure I see why this isn't possible given the current
spec. The type attribute for v1 should point to a type DIE for t2<int>,
which will have a template type parameter and two data members, m1 and m2.
Briefly:
L1: DW_TAG_structure_type (name: t2<int>)
L2: DW_TAG_template_type_parameter (name: T, type: ref to type int)
L3: DW_TAG_member (name: m1, type: ref to L2) [NOTE 1]
L4: DW_TAG_member (name: m2, type: ref to type t1<T>) [NOTE 2]
NOTE 1: This is the bug you point out where gcc and clang don't do what the
spec says, and put a ref to type int instead of to the template type
parameter entry.
NOTE 2: This is the part that may not be so obvious. We want a ref to a DIE
that represents the type t1<T> rather than t1<int>. I think we can have
that, but that new type entry will need to be a child of the t2<int> type.
Otherwise, it won't be able to reference the template type parameter entry
(technically, it *could*, but pointing from one type DIE into the interior
of another is ugly, and could conceivably cause problems down the road).
L1: DW_TAG_structure_type (name: t2<int>)
L2: DW_TAG_template_type_parameter (name: T, type: ref to type int)
L3: DW_TAG_member (name: m1, type: ref to L2)
L4: DW_TAG_member (name: m2, type: ref to L5)
L5: DW_TAG_structure_type (name: t1<T>)
L6: DW_TAG_template_type_parameter (name: T, type: ref to type int)
L7: DW_TAG_member (name: n1, type: ref to L6)
> Besides missing consumer support (e.g. GDB or LLDB), missing support for
> nested templates was one further reason why the llvm PR [2] was rejected
> by David Blaikie. I discussed this topic with him since I am working on
> the enablement in GDB and submitted a patch series [3] to support template
> type resolution based on the current DWARF specification. David Blaikie
> asked me to submit a DWARF issue for this, since we could not come up with
> a useful specification for the nested case (type of m2 in the example
> above).
>
In the PR, David noted:
That's basically my point, sorry, that v1 must be represented as
> "trait::type" (because it has to be canonical) and so if many uses, like
> this one, of a type in a template can't reference the
> DW_TAG_template_type_parameter, because it's non-canonical - I'm not sure
> there's a lot of value in making it work for the subset of cases where it
> is workable.
I guess I don't understand the part about "it has to be canonical". David,
can you explain why the approach I used above wouldn't work for the PR's
example with trait::type?
If we need something canonical (and if I understand what that means), could
we also have a canonical instantiation of the type for t1<int> at the
outermost scope, and add an attribute to the entry for t1<T> at L5 that
points to that canonical instantiation — maybe call it DW_AT_canonical_type?
There's also the concern that the compilers currently don't generate what
the DWARF spec says they should, and if they did, the debuggers wouldn't be
able to handle it. And if David's point above is right that we can
represent the simple case, but not the more complex ones, is it worth doing
it even for the simple cases? If the spec is calling for something that
can't be done in the general case, should we remove it from the spec?
-cary
--
Dwarf-discuss mailing list
[email protected]
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss