Skip to content

Commit 4e3e29a

Browse files
committed
Support DWARF tags for C++11 variadic templates
This patch adds support for DW_TAG_GNU_formal_parameter_pack and DW_TAG_GNU_template_parameter_pack, added to DWARF in March 2009 for C++11 variadic templates[1]. They are not currently emitted thanks to a typo[2] but the fix is trivial[3] and has been repeatedly submitted[4] to gcc; I'm not sure what else I can do to get it accepted; regardless, anyone building their own compiler can still make use of this. This implementation synthesizes type and parameter names as T#n, p#n e.g. Args#1, args#1. This is a pretty simple approach but it seems to work OK and is compatible with the old style type and parameter names emitted by old versions of gcc and when it's writing stabs+ format, meaning that any debugger scripts will continue to work. 1. http://wiki.dwarfstd.org/index.php?title=C%2B%2B0x:_Variadic_templates 2. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70536 3. ecatmur/gcc#5 4. https://gcc.gnu.org/pipermail/gcc-patches/2023-January/609659.html PR. https://sourceware.org/bugzilla/show_bug.cgi?id=17272
1 parent 6979017 commit 4e3e29a

File tree

1 file changed

+67
-4
lines changed

1 file changed

+67
-4
lines changed

gdb/dwarf2/read.c

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12103,7 +12103,8 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
1210312103
for (child_die = die->child; child_die; child_die = child_die->sibling)
1210412104
{
1210512105
if (child_die->tag == DW_TAG_template_type_param
12106-
|| child_die->tag == DW_TAG_template_value_param)
12106+
|| child_die->tag == DW_TAG_template_value_param
12107+
|| child_die->tag == DW_TAG_GNU_template_parameter_pack)
1210712108
{
1210812109
templ_func = new (&objfile->objfile_obstack) template_symbol;
1210912110
templ_func->subclass = SYMBOL_TEMPLATE;
@@ -12152,6 +12153,23 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
1215212153
if (arg != NULL)
1215312154
template_args.push_back (arg);
1215412155
}
12156+
else if (child_die->tag == DW_TAG_GNU_template_parameter_pack)
12157+
{
12158+
struct die_info *pack_die;
12159+
for (pack_die = child_die->child; pack_die; pack_die = pack_die->sibling)
12160+
{
12161+
struct symbol *arg = new_symbol (pack_die, NULL, cu);
12162+
12163+
if (arg != NULL)
12164+
template_args.push_back (arg);
12165+
}
12166+
}
12167+
else if (child_die->tag == DW_TAG_GNU_formal_parameter_pack)
12168+
{
12169+
struct die_info *pack_die;
12170+
for (pack_die = child_die->child; pack_die; pack_die = pack_die->sibling)
12171+
process_die (pack_die, cu);
12172+
}
1215512173
else
1215612174
process_die (child_die, cu);
1215712175
child_die = child_die->sibling;
@@ -16639,6 +16657,11 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
1663916657
{
1664016658
if (child_die->tag == DW_TAG_formal_parameter)
1664116659
nparams++;
16660+
else if (child_die->tag == DW_TAG_GNU_formal_parameter_pack)
16661+
{
16662+
child_die = child_die->child;
16663+
continue;
16664+
}
1664216665
else if (child_die->tag == DW_TAG_unspecified_parameters)
1664316666
ftype->set_has_varargs (true);
1664416667

@@ -16714,6 +16737,11 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
1671416737
ftype->field (iparams).set_type (arg_type);
1671516738
iparams++;
1671616739
}
16740+
else if (child_die->tag == DW_TAG_GNU_formal_parameter_pack)
16741+
{
16742+
child_die = child_die->child;
16743+
continue;
16744+
}
1671716745
child_die = child_die->sibling;
1671816746
}
1671916747
}
@@ -20847,13 +20875,16 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
2084720875
sym->set_type (type);
2084820876
else
2084920877
sym->set_type (die_type (die, cu));
20850-
attr = dwarf2_attr (die,
20878+
struct die_info *line_file_die = die;
20879+
if (die->tag == DW_TAG_formal_parameter && die->parent && die->parent->tag == DW_TAG_GNU_formal_parameter_pack)
20880+
line_file_die = die->parent;
20881+
attr = dwarf2_attr (line_file_die,
2085120882
inlined_func ? DW_AT_call_line : DW_AT_decl_line,
2085220883
cu);
2085320884
if (attr != nullptr)
2085420885
sym->set_line (attr->constant_value (0));
2085520886

20856-
attr = dwarf2_attr (die,
20887+
attr = dwarf2_attr (line_file_die,
2085720888
inlined_func ? DW_AT_call_file : DW_AT_decl_file,
2085820889
cu);
2085920890
if (attr != nullptr && attr->is_nonnegative ())
@@ -21073,6 +21104,8 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
2107321104
list_to_add = cu->list_in_scope;
2107421105
}
2107521106
break;
21107+
case DW_TAG_GNU_formal_parameter_pack:
21108+
break;
2107621109
case DW_TAG_unspecified_parameters:
2107721110
/* From varargs functions; gdb doesn't seem to have any
2107821111
interest in this information, so just ignore it for now.
@@ -22081,8 +22114,11 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
2208122114
if (attr_name == nullptr
2208222115
&& die->tag != DW_TAG_namespace
2208322116
&& die->tag != DW_TAG_class_type
22117+
&& die->tag != DW_TAG_formal_parameter
2208422118
&& die->tag != DW_TAG_interface_type
2208522119
&& die->tag != DW_TAG_structure_type
22120+
&& die->tag != DW_TAG_template_type_param
22121+
&& die->tag != DW_TAG_template_value_param
2208622122
&& die->tag != DW_TAG_namelist
2208722123
&& die->tag != DW_TAG_union_type
2208822124
&& die->tag != DW_TAG_template_type_param
@@ -22111,9 +22147,36 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
2211122147
return attr_name;
2211222148
return CP_ANONYMOUS_NAMESPACE_STR;
2211322149

22114-
/* DWARF does not actually require template tags to have a name. */
22150+
case DW_TAG_formal_parameter:
2211522151
case DW_TAG_template_type_param:
2211622152
case DW_TAG_template_value_param:
22153+
if (!attr
22154+
&& die->parent
22155+
&& (die->parent->tag == DW_TAG_GNU_formal_parameter_pack
22156+
|| die->parent->tag == DW_TAG_GNU_template_parameter_pack))
22157+
{
22158+
const char *parent_name;
22159+
int ordinal = 0;
22160+
struct die_info *child_die;
22161+
size_t size;
22162+
char *name;
22163+
parent_name = dwarf2_name(die->parent, cu);
22164+
if (!parent_name)
22165+
return NULL;
22166+
for (child_die = die->parent->child; child_die != die; child_die = child_die->sibling)
22167+
++ordinal;
22168+
size = snprintf(NULL, 0, "%s#%d", parent_name, ordinal) + 1;
22169+
name = ((char *) obstack_alloc (&cu->per_objfile->per_bfd->obstack, size));
22170+
snprintf(name, size, "%s#%d", parent_name, ordinal);
22171+
return name;
22172+
}
22173+
if (die->tag == DW_TAG_formal_parameter)
22174+
{
22175+
if (!attr || attr_name == NULL)
22176+
return NULL;
22177+
break;
22178+
}
22179+
/* DWARF does not actually require template tags to have a name. */
2211722180
if (attr_name == nullptr)
2211822181
return unnamed_template_tag_name (die, cu);
2211922182
/* FALLTHROUGH. */

0 commit comments

Comments
 (0)