Skip to content

Commit

Permalink
include/qom/object.h: New OBJECT_DEFINE_SIMPLE_TYPE{, _WITH_INTERFACE…
Browse files Browse the repository at this point in the history
…S} 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>
  • Loading branch information
pm215 committed Feb 27, 2024
1 parent e41f32f commit e54c243
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 22 deletions.
34 changes: 29 additions & 5 deletions docs/devel/qom.rst
Original file line number Diff line number Diff line change
Expand Up @@ -348,12 +348,14 @@ used. This does the same as OBJECT_DECLARE_SIMPLE_TYPE(), but without
the 'struct MyDeviceClass' definition.

To implement the type, the OBJECT_DEFINE macro family is available.
In the simple case the OBJECT_DEFINE_TYPE macro is suitable:
For the simplest case of a leaf class which doesn't need any of its
own virtual functions (i.e. which was declared with OBJECT_DECLARE_SIMPLE_TYPE)
the OBJECT_DEFINE_SIMPLE_TYPE macro is suitable:

.. code-block:: c
:caption: Defining a simple type
OBJECT_DEFINE_TYPE(MyDevice, my_device, MY_DEVICE, DEVICE)
OBJECT_DEFINE_SIMPLE_TYPE(MyDevice, my_device, MY_DEVICE, DEVICE)
This is equivalent to the following:

Expand All @@ -370,7 +372,6 @@ This is equivalent to the following:
.instance_size = sizeof(MyDevice),
.instance_init = my_device_init,
.instance_finalize = my_device_finalize,
.class_size = sizeof(MyDeviceClass),
.class_init = my_device_class_init,
};
Expand All @@ -385,13 +386,36 @@ This is sufficient to get the type registered with the type
system, and the three standard methods now need to be implemented
along with any other logic required for the type.

If the class needs its own virtual methods, or has some other
per-class state it needs to store in its own class struct,
then you can use the OBJECT_DEFINE_TYPE macro. This does the
same thing as OBJECT_DEFINE_SIMPLE_TYPE, but it also sets the
class_size of the type to the size of the class struct.

.. code-block:: c
:caption: Defining a type which needs a class struct
OBJECT_DEFINE_TYPE(MyDevice, my_device, MY_DEVICE, DEVICE)
If the type needs to implement one or more interfaces, then the
OBJECT_DEFINE_TYPE_WITH_INTERFACES() macro can be used instead.
This accepts an array of interface type names.
OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES() and
OBJECT_DEFINE_TYPE_WITH_INTERFACES() macros can be used instead.
These accept an array of interface type names. The difference between
them is that the former is for simple leaf classes that don't need
a class struct, and the latter is for when you will be defining
a class struct.

.. code-block:: c
:caption: Defining a simple type implementing interfaces
OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(MyDevice, my_device,
MY_DEVICE, DEVICE,
{ TYPE_USER_CREATABLE },
{ NULL })
.. code-block:: c
:caption: Defining a type implementing interfaces
OBJECT_DEFINE_TYPE_WITH_INTERFACES(MyDevice, my_device,
MY_DEVICE, DEVICE,
{ TYPE_USER_CREATABLE },
Expand Down
96 changes: 79 additions & 17 deletions include/qom/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,31 +259,23 @@ struct Object


/**
* OBJECT_DEFINE_TYPE_EXTENDED:
* 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 macro is typically used in a source file, and will:
*
* - declare prototypes for _finalize, _class_init and _init methods
* - declare the TypeInfo struct instance
* - provide the constructor to register the type
*
* After using this macro, implementations of the _finalize, _class_init,
* and _init methods need to be written. Any of these can be zero-line
* no-op impls if no special logic is required for a given type.
*
* This macro should rarely be used, instead one of the more specialized
* macros is usually a better choice.
* This is the base macro used to implement all the OBJECT_DEFINE_*
* macros. It should never be used directly in a source file.
*/
#define OBJECT_DEFINE_TYPE_EXTENDED(ModuleObjName, module_obj_name, \
MODULE_OBJ_NAME, PARENT_MODULE_OBJ_NAME, \
ABSTRACT, ...) \
#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 \
Expand All @@ -298,7 +290,7 @@ struct Object
.instance_align = __alignof__(ModuleObjName), \
.instance_init = module_obj_name##_init, \
.instance_finalize = module_obj_name##_finalize, \
.class_size = sizeof(ModuleObjName##Class), \
.class_size = CLASS_SIZE, \
.class_init = module_obj_name##_class_init, \
.abstract = ABSTRACT, \
.interfaces = (InterfaceInfo[]) { __VA_ARGS__ } , \
Expand All @@ -311,6 +303,37 @@ struct Object
} \
type_init(module_obj_name##_register_types);

/**
* 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
* @...: list of initializers for "InterfaceInfo" to declare implemented interfaces
*
* This macro is typically used in a source file, and will:
*
* - declare prototypes for _finalize, _class_init and _init methods
* - declare the TypeInfo struct instance
* - provide the constructor to register the type
*
* After using this macro, implementations of the _finalize, _class_init,
* and _init methods need to be written. Any of these can be zero-line
* no-op impls if no special logic is required for a given type.
*
* This macro should rarely be used, instead one of the more specialized
* macros is usually a better choice.
*/
#define OBJECT_DEFINE_TYPE_EXTENDED(ModuleObjName, module_obj_name, \
MODULE_OBJ_NAME, PARENT_MODULE_OBJ_NAME, \
ABSTRACT, ...) \
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:
* @ModuleObjName: the object name with initial caps
Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit e54c243

Please sign in to comment.