include/qom/object.h: New OBJECT_DEFINE_SIMPLE_TYPE{, _WITH_INTERFACES} macros

We have an OBJECT_DEFINE_TYPE_EXTENDED macro, plus several variations
on it, which emits the boilerplate for the TypeInfo and ensures it is
registered with the type system.  However, all the existing macros
insist that the type being defined has its own FooClass struct, so
they aren't useful for the common case of a simple leaf class which
doesn't have any new methods or any other need for its own class
struct (that is, for the kind of type that OBJECT_DECLARE_SIMPLE_TYPE
declares).

Pull the actual implementation of OBJECT_DEFINE_TYPE_EXTENDED out
into a new DO_OBJECT_DEFINE_TYPE_EXTENDED which parameterizes the
value we use for the class_size field.  This lets us add a new
OBJECT_DEFINE_SIMPLE_TYPE which does the same job as the various
existing OBJECT_DEFINE_*_TYPE_* family macros for this kind of simple
type, and the variant OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES for
when the type will implement some interfaces.

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20240220160622.114437-5-peter.maydell@linaro.org
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
This commit is contained in:
Peter Maydell 2024-02-20 16:06:16 +00:00
parent e41f32fe82
commit e54c24339f
2 changed files with 117 additions and 31 deletions

View file

@ -258,6 +258,51 @@ struct Object
DECLARE_INSTANCE_CHECKER(InstanceType, MODULE_OBJ_NAME, TYPE_##MODULE_OBJ_NAME)
/**
* DO_OBJECT_DEFINE_TYPE_EXTENDED:
* @ModuleObjName: the object name with initial caps
* @module_obj_name: the object name in lowercase with underscore separators
* @MODULE_OBJ_NAME: the object name in uppercase with underscore separators
* @PARENT_MODULE_OBJ_NAME: the parent object name in uppercase with underscore
* separators
* @ABSTRACT: boolean flag to indicate whether the object can be instantiated
* @CLASS_SIZE: size of the type's class
* @...: list of initializers for "InterfaceInfo" to declare implemented interfaces
*
* This is the base macro used to implement all the OBJECT_DEFINE_*
* macros. It should never be used directly in a source file.
*/
#define DO_OBJECT_DEFINE_TYPE_EXTENDED(ModuleObjName, module_obj_name, \
MODULE_OBJ_NAME, \
PARENT_MODULE_OBJ_NAME, \
ABSTRACT, CLASS_SIZE, ...) \
static void \
module_obj_name##_finalize(Object *obj); \
static void \
module_obj_name##_class_init(ObjectClass *oc, void *data); \
static void \
module_obj_name##_init(Object *obj); \
\
static const TypeInfo module_obj_name##_info = { \
.parent = TYPE_##PARENT_MODULE_OBJ_NAME, \
.name = TYPE_##MODULE_OBJ_NAME, \
.instance_size = sizeof(ModuleObjName), \
.instance_align = __alignof__(ModuleObjName), \
.instance_init = module_obj_name##_init, \
.instance_finalize = module_obj_name##_finalize, \
.class_size = CLASS_SIZE, \
.class_init = module_obj_name##_class_init, \
.abstract = ABSTRACT, \
.interfaces = (InterfaceInfo[]) { __VA_ARGS__ } , \
}; \
\
static void \
module_obj_name##_register_types(void) \
{ \
type_register_static(&module_obj_name##_info); \
} \
type_init(module_obj_name##_register_types);
/**
* OBJECT_DEFINE_TYPE_EXTENDED:
* @ModuleObjName: the object name with initial caps
@ -284,32 +329,10 @@ struct Object
#define OBJECT_DEFINE_TYPE_EXTENDED(ModuleObjName, module_obj_name, \
MODULE_OBJ_NAME, PARENT_MODULE_OBJ_NAME, \
ABSTRACT, ...) \
static void \
module_obj_name##_finalize(Object *obj); \
static void \
module_obj_name##_class_init(ObjectClass *oc, void *data); \
static void \
module_obj_name##_init(Object *obj); \
\
static const TypeInfo module_obj_name##_info = { \
.parent = TYPE_##PARENT_MODULE_OBJ_NAME, \
.name = TYPE_##MODULE_OBJ_NAME, \
.instance_size = sizeof(ModuleObjName), \
.instance_align = __alignof__(ModuleObjName), \
.instance_init = module_obj_name##_init, \
.instance_finalize = module_obj_name##_finalize, \
.class_size = sizeof(ModuleObjName##Class), \
.class_init = module_obj_name##_class_init, \
.abstract = ABSTRACT, \
.interfaces = (InterfaceInfo[]) { __VA_ARGS__ } , \
}; \
\
static void \
module_obj_name##_register_types(void) \
{ \
type_register_static(&module_obj_name##_info); \
} \
type_init(module_obj_name##_register_types);
DO_OBJECT_DEFINE_TYPE_EXTENDED(ModuleObjName, module_obj_name, \
MODULE_OBJ_NAME, PARENT_MODULE_OBJ_NAME, \
ABSTRACT, sizeof(ModuleObjName##Class), \
__VA_ARGS__)
/**
* OBJECT_DEFINE_TYPE:
@ -368,6 +391,45 @@ struct Object
MODULE_OBJ_NAME, PARENT_MODULE_OBJ_NAME, \
true, { NULL })
/**
* OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES:
* @ModuleObjName: the object name with initial caps
* @module_obj_name: the object name in lowercase with underscore separators
* @MODULE_OBJ_NAME: the object name in uppercase with underscore separators
* @PARENT_MODULE_OBJ_NAME: the parent object name in uppercase with underscore
* separators
*
* This is a variant of OBJECT_DEFINE_TYPE_EXTENDED, which is suitable for
* the case of a non-abstract type, with interfaces, and with no requirement
* for a class struct.
*/
#define OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(ModuleObjName, \
module_obj_name, \
MODULE_OBJ_NAME, \
PARENT_MODULE_OBJ_NAME, ...) \
DO_OBJECT_DEFINE_TYPE_EXTENDED(ModuleObjName, module_obj_name, \
MODULE_OBJ_NAME, PARENT_MODULE_OBJ_NAME, \
false, 0, __VA_ARGS__)
/**
* OBJECT_DEFINE_SIMPLE_TYPE:
* @ModuleObjName: the object name with initial caps
* @module_obj_name: the object name in lowercase with underscore separators
* @MODULE_OBJ_NAME: the object name in uppercase with underscore separators
* @PARENT_MODULE_OBJ_NAME: the parent object name in uppercase with underscore
* separators
*
* This is a variant of OBJECT_DEFINE_TYPE_EXTENDED, which is suitable for
* the common case of a non-abstract type, without any interfaces, and with
* no requirement for a class struct. If you declared your type with
* OBJECT_DECLARE_SIMPLE_TYPE then this is probably the right choice for
* defining it.
*/
#define OBJECT_DEFINE_SIMPLE_TYPE(ModuleObjName, module_obj_name, \
MODULE_OBJ_NAME, PARENT_MODULE_OBJ_NAME) \
OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(ModuleObjName, module_obj_name, \
MODULE_OBJ_NAME, PARENT_MODULE_OBJ_NAME, { NULL })
/**
* struct TypeInfo:
* @name: The name of the type.