Eduardo Habkost <ehabk...@redhat.com> writes: > Instead of requiring every architecture to implement a > class_by_name function, let them set a format string at > CPUClass::class_name_format. > > This will let us get rid of at least 16 class_by_name functions > in the next commits. > > Signed-off-by: Eduardo Habkost <ehabk...@redhat.com> > --- > include/qom/cpu.h | 12 ++++++++++++ > qom/cpu.c | 18 ++++++++++++++++-- > 2 files changed, 28 insertions(+), 2 deletions(-) > > diff --git a/include/qom/cpu.h b/include/qom/cpu.h > index fefd5c26b0..eda6a46b82 100644 > --- a/include/qom/cpu.h > +++ b/include/qom/cpu.h > @@ -163,7 +163,19 @@ typedef struct CPUClass { > DeviceClass parent_class; > /*< public >*/ > > + /* The following fields configure CPU model name -> QOM type > translation: */ > + > + /* > + * arch-specific CPU model -> QOM type translation function. > + * Optional if @class_name_format is set. > + */ > ObjectClass *(*class_by_name)(const char *cpu_model); > + /* > + * Format string for g_strdup_printf(), used to generate the CPU > + * class name.
Please document acceptable conversion specifiers. > + */ > + const char *class_name_format; > + > void (*parse_features)(const char *typename, char *str, Error **errp); > > void (*reset)(CPUState *cpu); > diff --git a/qom/cpu.c b/qom/cpu.c > index b971a56242..1fa64941b6 100644 > --- a/qom/cpu.c > +++ b/qom/cpu.c > @@ -286,9 +286,23 @@ static bool cpu_common_has_work(CPUState *cs) > CPUClass *cpu_class_by_name(const char *typename, const char *cpu_model) > { > CPUClass *cc = CPU_CLASS(object_class_by_name(typename)); > + ObjectClass *oc; > + char *class_name; > > - assert(cpu_model && cc->class_by_name); > - return CPU_CLASS(cc->class_by_name(cpu_model)); > + assert(cpu_model); > + if (cc->class_by_name) { > + return CPU_CLASS(cc->class_by_name(cpu_model)); > + } > + > + assert(cc->class_name_format); > + class_name = g_strdup_printf(cc->class_name_format, cpu_model); Defeats -Wformat. Triggers -Wformat-nonliteral, which we don't use, I presume. Observation, not objection. cc->class_name_format must contain exactly one conversion specifier, which must take a char *. > + oc = object_class_by_name(class_name); > + g_free(class_name); > + if (!oc || !object_class_dynamic_cast(oc, typename) || > + object_class_is_abstract(oc)) { > + return NULL; > + } > + return CPU_CLASS(oc); > } > > static void cpu_common_parse_features(const char *typename, char *features,