From 32cc1481721c4b11d5ffd95f928360dfc386ad69 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 3 Feb 2022 11:30:34 -0300 Subject: [PATCH] fprintf: Consider enumerations without members as forward declarations To avoid emitting: enum x86_intercept_stage { }; Which isn't compilable. The DWARF info for this enum in the Linux kernel has the declaration flag set, but somehow this is not being available when loading from BTF. So do the best we can at this enumeration__fprintf() time, that is to just print zero members enumerations as a forward declaration. Signed-off-by: Arnaldo Carvalho de Melo --- dwarves_fprintf.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/dwarves_fprintf.c b/dwarves_fprintf.c index a98b9f2..c441c53 100644 --- a/dwarves_fprintf.c +++ b/dwarves_fprintf.c @@ -419,12 +419,21 @@ size_t enumeration__fprintf(const struct tag *tag, const struct conf_fprintf *co 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) ?: ""); + size_t printed = fprintf(fp, "enum%s%s", type__name(type) ? " " : "", type__name(type) ?: ""); int indent = conf->indent; if (indent >= (int)sizeof(tabs)) indent = sizeof(tabs) - 1; + if (type->nr_members) { + printed += fprintf(fp, " {\n"); + } else { + // enum x86_intercept_stage in the Linux kernel comes just as a forward + // declaration, but then BTF isn't setting the type->declaration to mark + // it as such, do the best we can and assume is a forward decl. + return printed; + } + type__for_each_enumerator(type, pos) { printed += fprintf(fp, "%.*s\t%-*s = ", indent, tabs, max_entry_name_len, enumerator__name(pos));