Em Tue, Dec 07, 2021 at 05:31:48PM +0000, Douglas RAILLARD escreveu: > From: Douglas Raillard <douglas.raillard@xxxxxxx> > > Use (struct tag).visited member to track what type has been printed This doesn't match the patch, where you ended up using a new tar.printed field, have you tried with .visited and ended up finding out .printed was needed? - Arnaldo > already to avoid printing it twice. This allows producing a valid C > header along with --expand_types. > > Signed-off-by: Douglas Raillard <douglas.raillard@xxxxxxx> > --- > dwarves.h | 3 ++- > dwarves_fprintf.c | 22 ++++++++++++++++------ > pahole.c | 34 ++++++++++++++++++---------------- > 3 files changed, 36 insertions(+), 23 deletions(-) > > diff --git a/dwarves.h b/dwarves.h > index 52d162d..fc5b3fa 100644 > --- a/dwarves.h > +++ b/dwarves.h > @@ -413,6 +413,7 @@ struct tag { > type_id_t type; > uint16_t tag; > bool visited; > + bool printed; > bool top_level; > bool has_btf_type_tag; > uint16_t recursivity_level; > @@ -1370,7 +1371,7 @@ static inline const char *enumerator__name(const struct enumerator *enumerator) > > void enumeration__delete(struct type *type); > void enumeration__add(struct type *type, struct enumerator *enumerator); > -size_t enumeration__fprintf(const struct tag *tag_enum, > +size_t enumeration__fprintf(struct tag *tag_enum, > const struct conf_fprintf *conf, FILE *fp); > > int dwarves__init(void); > diff --git a/dwarves_fprintf.c b/dwarves_fprintf.c > index c5921d7..2c5dce6 100644 > --- a/dwarves_fprintf.c > +++ b/dwarves_fprintf.c > @@ -278,8 +278,8 @@ size_t typedef__fprintf(const struct tag *tag, const struct cu *cu, > { > struct type *type = tag__type(tag); > const struct conf_fprintf *pconf = conf ?: &conf_fprintf__defaults; > - const struct tag *tag_type; > - const struct tag *ptr_type; > + struct tag *tag_type; > + struct tag *ptr_type; > char bf[512]; > int is_pointer = 0; > size_t printed; > @@ -394,13 +394,14 @@ out: > return type->max_tag_name_len; > } > > -size_t enumeration__fprintf(const struct tag *tag, const struct conf_fprintf *conf, FILE *fp) > +size_t enumeration__fprintf(struct tag *tag, const struct conf_fprintf *conf, FILE *fp) > { > struct type *type = tag__type(tag); > struct enumerator *pos; > int max_entry_name_len = enumeration__max_entry_name_len(type); > size_t printed = fprintf(fp, "enum%s%s {\n", type__name(type) ? " " : "", type__name(type) ?: ""); > int indent = conf->indent; > + tag->printed = 1; > > if (indent >= (int)sizeof(tabs)) > indent = sizeof(tabs) - 1; > @@ -651,10 +652,14 @@ static size_t type__fprintf(struct tag *type, const struct cu *cu, > size_t printed = 0; > int expand_types = conf->expand_types; > int suppress_offset_comment = conf->suppress_offset_comment; > + bool type_printed; > > if (type == NULL) > goto out_type_not_found; > > + type_printed = type->printed; > + type->printed = 1; > + > if (conf->expand_pointers) { > int nr_indirections = 0; > > @@ -794,7 +799,7 @@ print_default: > case DW_TAG_structure_type: > ctype = tag__type(type); > > - if (type__name(ctype) != NULL && !expand_types) { > + if (type__name(ctype) != NULL && (!expand_types || type_printed)) { > printed += fprintf(fp, "%s %-*s %s", > (type->tag == DW_TAG_class_type && > !tconf.classes_as_structs) ? "class" : "struct", > @@ -813,7 +818,7 @@ print_default: > case DW_TAG_union_type: > ctype = tag__type(type); > > - if (type__name(ctype) != NULL && !expand_types) { > + if (type__name(ctype) != NULL && (!expand_types || type_printed)) { > printed += fprintf(fp, "union %-*s %s", tconf.type_spacing - 6, type__name(ctype), name ?: ""); > } else { > tconf.type_spacing -= 8; > @@ -823,7 +828,7 @@ print_default: > case DW_TAG_enumeration_type: > ctype = tag__type(type); > > - if (type__name(ctype) != NULL) > + if (type__name(ctype) != NULL || type_printed) > printed += fprintf(fp, "enum %-*s %s", tconf.type_spacing - 5, type__name(ctype), name ?: ""); > else > printed += enumeration__fprintf(type, &tconf, fp); > @@ -1000,6 +1005,8 @@ static size_t union__fprintf(struct type *type, const struct cu *cu, > uint32_t initial_union_cacheline; > uint32_t cacheline = 0; /* This will only be used if this is the outermost union */ > > + type__tag(type)->printed = 1; > + > if (indent >= (int)sizeof(tabs)) > indent = sizeof(tabs) - 1; > > @@ -1394,6 +1401,8 @@ static size_t __class__fprintf(struct class *class, const struct cu *cu, > type__name(type) ?: ""); > int indent = cconf.indent; > > + class__tag(class)->printed = 1; > + > if (indent >= (int)sizeof(tabs)) > indent = sizeof(tabs) - 1; > > @@ -1856,6 +1865,7 @@ size_t tag__fprintf(struct tag *tag, const struct cu *cu, > size_t printed = 0; > struct conf_fprintf tconf; > const struct conf_fprintf *pconf = conf; > + tag->printed = 1; > > if (conf == NULL) { > tconf = conf_fprintf__defaults; > diff --git a/pahole.c b/pahole.c > index f3a51cb..42ba110 100644 > --- a/pahole.c > +++ b/pahole.c > @@ -2964,22 +2964,24 @@ out_btf: > goto dump_it; > } > > - if (class) > - class__find_holes(tag__class(class)); > - if (reorganize) { > - if (class && tag__is_struct(class)) > - do_reorg(class, cu); > - } else if (find_containers) > - print_containers(cu, class_id, 0); > - else if (find_pointers_in_structs) > - print_structs_with_pointer_to(cu, class_id); > - else if (class) { > - /* > - * We don't need to print it for every compile unit > - * but the previous options need > - */ > - tag__fprintf(class, cu, &conf, stdout); > - putchar('\n'); > + if (!class->printed) { > + if (class) > + class__find_holes(tag__class(class)); > + if (reorganize) { > + if (class && tag__is_struct(class)) > + do_reorg(class, cu); > + } else if (find_containers) > + print_containers(cu, class_id, 0); > + else if (find_pointers_in_structs) > + print_structs_with_pointer_to(cu, class_id); > + else if (class) { > + /* > + * We don't need to print it for every compile unit > + * but the previous options need > + */ > + tag__fprintf(class, cu, &conf, stdout); > + putchar('\n'); > + } > } > } > > -- > 2.25.1 -- - Arnaldo