Skip to content

Commit

Permalink
dwarf_loader: Initial support for DW_TAG_template_type_param tag
Browse files Browse the repository at this point in the history
We don't really need to pretty print these, as the names of the classes
already come with it, for instance:

  ⬢[acme@toolbox zzam@gentoo.org]$ pdwtags popup.cpp.o  | grep ^'struct integral_constant' -A11
  die__process_class: tag not supported 0x30 (template_value_parameter) at <5f0>!
  die__process_function: tag not supported 0x2f (template_type_parameter) at <1417>!
  die__process_class: tag not supported 0x4107 (GNU_template_parameter_pack) at <f1d8>!
  die__process_function: tag not supported 0x4108 (GNU_formal_parameter_pack) at <69aea>!
  struct integral_constant<bool, true> {
  	typedef bool value_type;

  	value_type operator std::integral_constant<bool, true>::value_type(const struct integral_constant<bool, true>  *);

  	value_type operator()(const struct integral_constant<bool, true>  *);

  	/* size: 1, cachelines: 0, members: 0 */
  	/* padding: 1 */
  	/* last cacheline: 1 bytes */
  }; /* size: 0 */
  --
  struct integral_constant<bool, false> {
  	typedef bool value_type;

  	value_type operator std::integral_constant<bool, false>::value_type(const struct integral_constant<bool, false>  *);

  	value_type operator()(const struct integral_constant<bool, false>  *);

  	/* size: 1, cachelines: 0, members: 0 */
  	/* padding: 1 */
  	/* last cacheline: 1 bytes */
  }; /* size: 0 */
  ⬢[acme@toolbox zzam@gentoo.org]$

But lets collect this info, that only shows up in C++ (maybe other
languages, Rust?), we'll end up using it maybe for using them for
looking up all templates, or all templates of a given type or value,
etc.

I'll do the same for DW_TAG_template_value_parameter and support both in
DW_TAG_subprogram.

DW_TAG_GNU_template_parameter_pack must be some variation on this
theme...

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
acmel committed Jul 18, 2024
1 parent 24009d1 commit 8a1e023
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 1 deletion.
22 changes: 21 additions & 1 deletion dwarf_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -1082,6 +1082,18 @@ static void arch__set_register_params(const GElf_Ehdr *ehdr, struct cu *cu)
}
}

static struct template_type_param *template_type_param__new(Dwarf_Die *die, struct cu *cu, struct conf_load *conf)
{
struct template_type_param *ttparm = tag__alloc(cu, sizeof(*ttparm));

if (ttparm != NULL) {
tag__init(&ttparm->tag, cu, die);
ttparm->name = attr_string(die, DW_AT_name, conf);
}

return ttparm;
}

static struct parameter *parameter__new(Dwarf_Die *die, struct cu *cu,
struct conf_load *conf, int param_idx)
{
Expand Down Expand Up @@ -1800,7 +1812,6 @@ static int die__process_class(Dwarf_Die *die, struct type *class,
case DW_TAG_GNU_template_parameter_pack:
case DW_TAG_GNU_template_template_param:
#endif
case DW_TAG_template_type_parameter:
case DW_TAG_template_value_parameter:
/*
* FIXME: probably we'll have to attach this as a list of
Expand All @@ -1811,6 +1822,15 @@ static int die__process_class(Dwarf_Die *die, struct type *class,
*/
tag__print_not_supported(die);
continue;
case DW_TAG_template_type_parameter: {
struct template_type_param *ttparm = template_type_param__new(die, cu, conf);

if (ttparm == NULL)
return -ENOMEM;

type__add_template_type_param(class, ttparm);
continue;
}
case DW_TAG_inheritance:
case DW_TAG_member: {
struct class_member *member = class_member__new(die, cu, is_union, conf);
Expand Down
6 changes: 6 additions & 0 deletions dwarves.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ void __type__init(struct type *type)
{
INIT_LIST_HEAD(&type->node);
INIT_LIST_HEAD(&type->type_enum);
INIT_LIST_HEAD(&type->template_type_params);
type->sizeof_member = NULL;
type->member_prefix = NULL;
type->member_prefix_len = 0;
Expand Down Expand Up @@ -1329,6 +1330,11 @@ void type__add_member(struct type *type, struct class_member *member)
namespace__add_tag(&type->namespace, &member->tag);
}

void type__add_template_type_param(struct type *type, struct template_type_param *ttparam)
{
list_add_tail(&ttparam->tag.node, &type->template_type_params);
}

struct class_member *type__last_member(struct type *type)
{
struct class_member *pos;
Expand Down
12 changes: 12 additions & 0 deletions dwarves.h
Original file line number Diff line number Diff line change
Expand Up @@ -1121,6 +1121,15 @@ static __pure inline int tag__is_class_member(const struct tag *tag)
return tag->tag == DW_TAG_member;
}

/* struct template_type_param - parameters to a template, stored in 'struct type'
*/
struct template_type_param {
struct tag tag;
const char *name;
};

void template_type_param__delete(struct template_type_param *ttparam);

int tag__is_base_type(const struct tag *tag, const struct cu *cu);
bool tag__is_array(const struct tag *tag, const struct cu *cu);

Expand Down Expand Up @@ -1172,6 +1181,7 @@ struct type {
uint8_t fwd_decl_emitted:1;
uint8_t resized:1;
uint8_t is_signed_enum:1;
struct list_head template_type_params;
};

void __type__init(struct type *type);
Expand Down Expand Up @@ -1289,6 +1299,8 @@ static inline struct class_member *class_member__next(struct class_member *membe
list_for_each_entry_safe_reverse(pos, n, &(type)->namespace.tags, tag.node)

void type__add_member(struct type *type, struct class_member *member);
void type__add_template_type_param(struct type *type, struct template_type_param *ttparm);

struct class_member *
type__find_first_biggest_size_base_type_member(struct type *type,
const struct cu *cu);
Expand Down

0 comments on commit 8a1e023

Please sign in to comment.