qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Eduardo Habkost <ehabkost@redhat.com>
To: qemu-devel@nongnu.org
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	"Daniel P. Berrange" <berrange@redhat.com>
Subject: [PATCH v3 55/74] qom: provide convenient macros for declaring and defining types
Date: Tue, 25 Aug 2020 15:20:51 -0400	[thread overview]
Message-ID: <20200825192110.3528606-56-ehabkost@redhat.com> (raw)
In-Reply-To: <20200825192110.3528606-1-ehabkost@redhat.com>

From: Daniel P. Berrangé <berrange@redhat.com>

When creating new QOM types, there is a lot of boilerplate code that
must be repeated using a standard pattern. This is tedious to write
and liable to suffer from subtle inconsistencies. Thus it would
benefit from some simple automation.

QOM was loosely inspired by GLib's GObject, and indeed GObject suffers
from the same burden of boilerplate code, but has long provided a set of
macros to eliminate this burden in the source implementation. More
recently it has also provided a set of macros to eliminate this burden
in the header declaration.

In GLib there are the G_DECLARE_* and G_DEFINE_* family of macros
for the header declaration and source implementation respectively:

  https://developer.gnome.org/gobject/stable/chapter-gobject.html
  https://developer.gnome.org/gobject/stable/howto-gobject.html

This patch takes inspiration from GObject to provide the equivalent
functionality for QOM.

In the header file, instead of:

    typedef struct MyDevice MyDevice;
    typedef struct MyDeviceClass MyDeviceClass;

    G_DEFINE_AUTOPTR_CLEANUP_FUNC(MyDeviceClass, object_unref)

    #define MY_DEVICE_GET_CLASS(void *obj) \
            OBJECT_GET_CLASS(MyDeviceClass, obj, TYPE_MY_DEVICE)
    #define MY_DEVICE_CLASS(void *klass) \
            OBJECT_CLASS_CHECK(MyDeviceClass, klass, TYPE_MY_DEVICE)
    #define MY_DEVICE(void *obj)
            OBJECT_CHECK(MyDevice, obj, TYPE_MY_DEVICE)

    struct MyDeviceClass {
        DeviceClass parent_class;
    };

We now have

    OBJECT_DECLARE_SIMPLE_TYPE(MyDevice, my_device, MY_DEVICE, DEVICE)

In cases where the class needs some virtual methods, it can be left
to be implemented manually using

    OBJECT_DECLARE_TYPE(MyDevice, my_device, MY_DEVICE)

Note that these macros are including support for g_autoptr() for the
object types, which is something previously only supported for variables
declared as the base Object * type.

Meanwhile in the source file, instead of:

    static void my_device_finalize(Object *obj);
    static void my_device_class_init(ObjectClass *oc, void *data);
    static void my_device_init(Object *obj);

    static const TypeInfo my_device_info = {
        .parent = TYPE_DEVICE,
        .name = TYPE_MY_DEVICE,
        .instance_size = sizeof(MyDevice),
        .instance_init = my_device_init,
        .instance_finalize = my_device_finalize,
        .class_size = sizeof(MyDeviceClass),
        .class_init = my_device_class_init,
    };

    static void
    my_device_register_types(void)
    {
        type_register_static(&my_device_info);
    }
    type_init(my_device_register_types);

We now have

    OBJECT_DEFINE_TYPE(MyDevice, my_device, MY_DEVICE, DEVICE)

Or, if a class needs to implement interfaces:

    OBJECT_DEFINE_TYPE_WITH_INTERFACES(MyDevice, my_device, MY_DEVICE, DEVICE,
                                       { TYPE_USER_CREATABLE }, { NULL })

Or, if a class needs to be abstract

    OBJECT_DEFINE_ABSTRACT_TYPE(MyDevice, my_device, MY_DEVICE, DEVICE)

IOW, in both cases the maintainer now only has to think about the
interesting part of the code which implements useful functionality
and avoids much of the boilerplate.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-Id: <20200723181410.3145233-3-berrange@redhat.com>
[ehabkost: Fix G_DEFINE_AUTOPTR_CLEANUP_FUNC usage]
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Changes v2 -> v3: none

Changes v1 -> v2:
* Squashed "Fix G_DEFINE_AUTOPTR_CLEANUP_FUNC" into this patch
---
 include/qom/object.h | 277 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 277 insertions(+)

diff --git a/include/qom/object.h b/include/qom/object.h
index 1f8aa2d48e..f515230f61 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -304,6 +304,119 @@ typedef struct InterfaceInfo InterfaceInfo;
  *
  * The first example of such a QOM method was #CPUClass.reset,
  * another example is #DeviceClass.realize.
+ *
+ * # Standard type declaration and definition macros #
+ *
+ * A lot of the code outlined above follows a standard pattern and naming
+ * convention. To reduce the amount of boilerplate code that needs to be
+ * written for a new type there are two sets of macros to generate the
+ * common parts in a standard format.
+ *
+ * A type is declared using the OBJECT_DECLARE macro family. In types
+ * which do not require any virtual functions in the class, the
+ * OBJECT_DECLARE_SIMPLE_TYPE macro is suitable, and is commonly placed
+ * in the header file:
+ *
+ * <example>
+ *   <title>Declaring a simple type</title>
+ *   <programlisting>
+ *     OBJECT_DECLARE_SIMPLE_TYPE(MyDevice, my_device, MY_DEVICE, DEVICE)
+ *   </programlisting>
+ * </example>
+ *
+ * This is equivalent to the following:
+ *
+ * <example>
+ *   <title>Expansion from declaring a simple type</title>
+ *   <programlisting>
+ *     typedef struct MyDevice MyDevice;
+ *     typedef struct MyDeviceClass MyDeviceClass;
+ *
+ *     G_DEFINE_AUTOPTR_CLEANUP_FUNC(MyDeviceClass, object_unref)
+ *
+ *     #define MY_DEVICE_GET_CLASS(void *obj) \
+ *             OBJECT_GET_CLASS(MyDeviceClass, obj, TYPE_MY_DEVICE)
+ *     #define MY_DEVICE_CLASS(void *klass) \
+ *             OBJECT_CLASS_CHECK(MyDeviceClass, klass, TYPE_MY_DEVICE)
+ *     #define MY_DEVICE(void *obj)
+ *             OBJECT_CHECK(MyDevice, obj, TYPE_MY_DEVICE)
+ *
+ *     struct MyDeviceClass {
+ *         DeviceClass parent_class;
+ *     };
+ *   </programlisting>
+ * </example>
+ *
+ * The 'struct MyDevice' needs to be declared separately.
+ * If the type requires virtual functions to be declared in the class
+ * struct, then the alternative OBJECT_DECLARE_TYPE() macro can be
+ * 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:
+ *
+ * <example>
+ *   <title>Defining a simple type</title>
+ *   <programlisting>
+ *     OBJECT_DEFINE_TYPE(MyDevice, my_device, MY_DEVICE, DEVICE)
+ *   </programlisting>
+ * </example>
+ *
+ * This is equivalent to the following:
+ *
+ * <example>
+ *   <title>Expansion from defining a simple type</title>
+ *   <programlisting>
+ *     static void my_device_finalize(Object *obj);
+ *     static void my_device_class_init(ObjectClass *oc, void *data);
+ *     static void my_device_init(Object *obj);
+ *
+ *     static const TypeInfo my_device_info = {
+ *         .parent = TYPE_DEVICE,
+ *         .name = TYPE_MY_DEVICE,
+ *         .instance_size = sizeof(MyDevice),
+ *         .instance_init = my_device_init,
+ *         .instance_finalize = my_device_finalize,
+ *         .class_size = sizeof(MyDeviceClass),
+ *         .class_init = my_device_class_init,
+ *     };
+ *
+ *     static void
+ *     my_device_register_types(void)
+ *     {
+ *         type_register_static(&my_device_info);
+ *     }
+ *     type_init(my_device_register_types);
+ *   </programlisting>
+ * </example>
+ *
+ * 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 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.
+ *
+ * <example>
+ *   <title>Defining a simple type implementing interfaces</title>
+ *   <programlisting>
+ *     OBJECT_DEFINE_TYPE_WITH_INTERFACES(MyDevice, my_device,
+ *                                        MY_DEVICE, DEVICE,
+ *                                        { TYPE_USER_CREATABLE }, { NULL })
+ *   </programlisting>
+ * </example>
+ *
+ * If the type is not intended to be instantiated, then then
+ * the OBJECT_DEFINE_ABSTRACT_TYPE() macro can be used instead:
+ *
+ * <example>
+ *   <title>Defining a simple type</title>
+ *   <programlisting>
+ *     OBJECT_DEFINE_ABSTRACT_TYPE(MyDevice, my_device, MY_DEVICE, DEVICE)
+ *   </programlisting>
+ * </example>
  */
 
 
@@ -440,6 +553,170 @@ struct Object
     Object *parent;
 };
 
+/**
+ * OBJECT_DECLARE_TYPE:
+ * @ModuleObjName: the object name with initial capitalization
+ * @module_obj_name: the object name in lowercase with underscore separators
+ * @MODULE_OBJ_NAME: the object name in uppercase with underscore separators
+ *
+ * This macro is typically used in a header file, and will:
+ *
+ *   - create the typedefs for the object and class structs
+ *   - register the type for use with g_autoptr
+ *   - provide three standard type cast functions
+ *
+ * The object struct and class struct need to be declared manually.
+ */
+#define OBJECT_DECLARE_TYPE(ModuleObjName, module_obj_name, MODULE_OBJ_NAME) \
+    typedef struct ModuleObjName ModuleObjName; \
+    typedef struct ModuleObjName##Class ModuleObjName##Class; \
+    \
+    G_DEFINE_AUTOPTR_CLEANUP_FUNC(ModuleObjName, object_unref) \
+    \
+    static inline G_GNUC_UNUSED ModuleObjName##Class * \
+    MODULE_OBJ_NAME##_GET_CLASS(void *obj) \
+    { return OBJECT_GET_CLASS(ModuleObjName##Class, obj, \
+                              TYPE_##MODULE_OBJ_NAME); } \
+    \
+    static inline G_GNUC_UNUSED ModuleObjName##Class * \
+    MODULE_OBJ_NAME##_CLASS(void *klass) \
+    { return OBJECT_CLASS_CHECK(ModuleObjName##Class, klass, \
+                                TYPE_##MODULE_OBJ_NAME); } \
+    \
+    static inline G_GNUC_UNUSED ModuleObjName * \
+    MODULE_OBJ_NAME(void *obj) \
+    { return OBJECT_CHECK(ModuleObjName, obj, \
+                          TYPE_##MODULE_OBJ_NAME); }
+
+/**
+ * OBJECT_DECLARE_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
+ * @ParentModuleObjName: the parent object name with initial caps
+ *
+ * This does the same as OBJECT_DECLARE_TYPE(), but also declares
+ * the class struct, thus only the object struct needs to be declare
+ * manually.
+ *
+ * This macro should be used unless the class struct needs to have
+ * virtual methods declared.
+ */
+#define OBJECT_DECLARE_SIMPLE_TYPE(ModuleObjName, module_obj_name, \
+                                   MODULE_OBJ_NAME, ParentModuleObjName) \
+    OBJECT_DECLARE_TYPE(ModuleObjName, module_obj_name, MODULE_OBJ_NAME) \
+    struct ModuleObjName##Class { ParentModuleObjName##Class parent_class; };
+
+
+/**
+ * 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, ...) \
+    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_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);
+
+/**
+ * OBJECT_DEFINE_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 specialization of OBJECT_DEFINE_TYPE_EXTENDED, which is suitable
+ * for the common case of a non-abstract type, without any interfaces.
+ */
+#define OBJECT_DEFINE_TYPE(ModuleObjName, module_obj_name, MODULE_OBJ_NAME, \
+                           PARENT_MODULE_OBJ_NAME) \
+    OBJECT_DEFINE_TYPE_EXTENDED(ModuleObjName, module_obj_name, \
+                                MODULE_OBJ_NAME, PARENT_MODULE_OBJ_NAME, \
+                                false, { NULL })
+
+/**
+ * OBJECT_DEFINE_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
+ * @...: list of initializers for "InterfaceInfo" to declare implemented interfaces
+ *
+ * This is a specialization of OBJECT_DEFINE_TYPE_EXTENDED, which is suitable
+ * for the common case of a non-abstract type, with one or more implemented
+ * interfaces.
+ *
+ * Note when passing the list of interfaces, be sure to include the final
+ * NULL entry, e.g.  { TYPE_USER_CREATABLE }, { NULL }
+ */
+#define OBJECT_DEFINE_TYPE_WITH_INTERFACES(ModuleObjName, module_obj_name, \
+                                           MODULE_OBJ_NAME, \
+                                           PARENT_MODULE_OBJ_NAME, ...) \
+    OBJECT_DEFINE_TYPE_EXTENDED(ModuleObjName, module_obj_name, \
+                                MODULE_OBJ_NAME, PARENT_MODULE_OBJ_NAME, \
+                                false, __VA_ARGS__)
+
+/**
+ * OBJECT_DEFINE_ABSTRACT_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 specialization of OBJECT_DEFINE_TYPE_EXTENDED, which is suitable
+ * for defining an abstract type, without any interfaces.
+ */
+#define OBJECT_DEFINE_ABSTRACT_TYPE(ModuleObjName, module_obj_name, \
+                                    MODULE_OBJ_NAME, PARENT_MODULE_OBJ_NAME) \
+    OBJECT_DEFINE_TYPE_EXTENDED(ModuleObjName, module_obj_name, \
+                                MODULE_OBJ_NAME, PARENT_MODULE_OBJ_NAME, \
+                                true, { NULL })
+
 /**
  * TypeInfo:
  * @name: The name of the type.
-- 
2.26.2



  parent reply	other threads:[~2020-08-25 19:49 UTC|newest]

Thread overview: 101+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-25 19:19 [PATCH v3 00/74] qom: Automated conversion of type checking boilerplate Eduardo Habkost
2020-08-25 19:19 ` [PATCH v3 01/74] e1000: Rename QOM class cast macros Eduardo Habkost
2020-08-25 19:19 ` [PATCH v3 02/74] megasas: " Eduardo Habkost
2020-08-25 19:19 ` [PATCH v3 03/74] vmw_pvscsi: " Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 04/74] pl110: Rename pl110_version enum values Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 05/74] allwinner-h3: Rename memmap enum constants Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 06/74] aspeed_soc: Rename memmap/irqmap " Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 07/74] opentitan: Rename memmap " Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 08/74] sifive_e: " Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 09/74] sifive_u: " Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 10/74] aspeed_timer: Fix ASPEED_TIMER macro definition Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 11/74] versatile: Fix typo in PCI_VPB_HOST definition Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 12/74] virtio-ccw: Fix definition of VIRTIO_CCW_BUS_GET_CLASS Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 13/74] hvf: Add missing include Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 14/74] hcd-dwc2: Rename USB_*CLASS macros for consistency Eduardo Habkost
2020-08-26  5:10   ` Gerd Hoffmann
2020-08-25 19:20 ` [PATCH v3 15/74] tulip: Move TulipState typedef to header Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 16/74] throttle-groups: Move ThrottleGroup " Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 17/74] pci: Move PCIBusClass typedef to pci.h Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 18/74] i8254: Move PITCommonState/PITCommonClass typedefs to i8254.h Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 19/74] hvf: Move HVFState typedef to hvf.h Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 20/74] mcf_fec: Move mcf_fec_state typedef to header Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 21/74] s390_flic: Move KVMS390FLICState " Eduardo Habkost
2020-08-27  8:08   ` Thomas Huth
2020-08-25 19:20 ` [PATCH v3 22/74] can_emu: Delete macros for non-existing typedef Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 23/74] nubus: Delete unused NUBUS_BRIDGE macro Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 24/74] platform-bus: Delete macros for non-existing typedef Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 25/74] armsse: Rename QOM macros to avoid conflicts Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 26/74] xen-legacy-backend: Add missing typedef XenLegacyDevice Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 27/74] spapr: Move typedef SpaprMachineState to spapr.h Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 28/74] s390x: Move typedef SCLPEventFacility to event-facility.h Eduardo Habkost
2020-08-27  8:07   ` Thomas Huth
2020-08-25 19:20 ` [PATCH v3 29/74] vhost-user-gpu: Move QOM macro to header Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 30/74] ahci: Move QOM macros " Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 31/74] i8257: Move QOM macro " Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 32/74] ahci: " Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 33/74] pckbd: " Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 34/74] vmbus: Move QOM macros to vmbus.h Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 35/74] virtio-serial-bus: Move QOM macros to header Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 36/74] piix: " Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 37/74] auxbus: " Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 38/74] rocker: " Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 39/74] pxa2xx: " Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 40/74] mptsas: " Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 41/74] kvm: Move QOM macros to kvm.h Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 42/74] vfio/pci: Move QOM macros to header Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 43/74] nubus: Rename class type checking macros Eduardo Habkost
2020-08-26 10:18   ` Laurent Vivier
2020-08-25 19:20 ` [PATCH v3 44/74] imx_ccm: Rename IMX_GET_CLASS macro Eduardo Habkost
2020-08-31 18:45   ` Peter Maydell
2020-08-25 19:20 ` [PATCH v3 45/74] mos6522: Rename QOM macros Eduardo Habkost
2020-08-31 18:46   ` Peter Maydell
2020-08-25 19:20 ` [PATCH v3 46/74] x86-iommu: Rename QOM type macros Eduardo Habkost
2020-08-31 19:02   ` Peter Xu
2020-08-25 19:20 ` [PATCH v3 47/74] rdma: Rename INTERFACE_RDMA_PROVIDER_CLASS macro Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 48/74] s390-virtio-ccw: Rename S390_MACHINE_CLASS macro Eduardo Habkost
2020-08-26  7:16   ` Cornelia Huck
2020-08-25 19:20 ` [PATCH v3 49/74] swim: Rename struct SWIM to Swim Eduardo Habkost
2020-08-26 10:19   ` Laurent Vivier
2020-08-25 19:20 ` [PATCH v3 50/74] migration: Rename class type checking macros Eduardo Habkost
2020-08-26  7:59   ` Juan Quintela
2020-08-25 19:20 ` [PATCH v3 51/74] arm: Fix typo in AARCH64_CPU_GET_CLASS definition Eduardo Habkost
2020-08-31 18:45   ` Peter Maydell
2020-08-25 19:20 ` [PATCH v3 52/74] rx: Rename QOM type check macros Eduardo Habkost
2020-08-31 18:48   ` Peter Maydell
2020-08-25 19:20 ` [PATCH v3 53/74] rx: Move typedef RXCPU to cpu-qom.h Eduardo Habkost
2020-08-31 18:48   ` Peter Maydell
2020-08-25 19:20 ` [PATCH v3 54/74] qom: make object_ref/unref use a void * instead of Object * Eduardo Habkost
2020-08-25 19:20 ` Eduardo Habkost [this message]
2020-08-25 19:20 ` [PATCH v3 56/74] qom: Allow class type name to be specified in OBJECT_DECLARE* Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 57/74] qom: DECLARE_*_CHECKERS macros Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 58/74] qom: Make type checker functions accept const pointers Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 59/74] qom: TYPE_INFO macro Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 60/74] codeconverter: script for automating QOM code cleanups Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 61/74] [automated] Delete duplicate QOM typedefs Eduardo Habkost
2020-08-25 19:20 ` [PATCH v3 62/74] [automated] Use TYPE_INFO macro Eduardo Habkost
2020-08-26  8:02   ` Juan Quintela
2020-08-25 19:20 ` [PATCH v3 63/74] [automated] Use TYPE_INFO macro (pass 2) Eduardo Habkost
2020-08-25 19:21 ` [PATCH v3 64/74] [automated] Move QOM typedefs and add missing includes Eduardo Habkost
2020-08-26  8:05   ` Juan Quintela
2020-08-25 19:21 ` [PATCH v3 65/74] [automated] Move QOM typedefs and add missing includes (pass 2) Eduardo Habkost
2020-08-26  8:03   ` Juan Quintela
2020-08-25 19:21 ` [PATCH v3 66/74] [automated] Use DECLARE_*CHECKER* macros Eduardo Habkost
2020-08-26  8:08   ` Juan Quintela
2020-08-25 19:21 ` [PATCH v3 67/74] [automated] Use DECLARE_*CHECKER* macros (pass 2) Eduardo Habkost
2020-08-26  8:06   ` Juan Quintela
2020-08-25 19:21 ` [PATCH v3 68/74] [semi-automated] Use DECLARE_*CHECKER* when possible (--force mode) Eduardo Habkost
2020-08-25 19:21 ` [PATCH v3 69/74] [automated] Use OBJECT_DECLARE_TYPE where possible Eduardo Habkost
2020-08-25 19:21 ` [PATCH v3 70/74] [automated] Use OBJECT_DECLARE_TYPE where possible (pass 2) Eduardo Habkost
2020-08-25 19:21 ` [PATCH v3 71/74] [automated] Use OBJECT_DECLARE_SIMPLE_TYPE when possible Eduardo Habkost
2020-08-25 19:21 ` [PATCH v3 72/74] [automated] Remove redundant instance_size/class_size fields Eduardo Habkost
2020-08-26 15:54   ` Eduardo Habkost
2020-08-25 19:21 ` [PATCH v3 73/74] crypto: use QOM macros for declaration/definition of secret types Eduardo Habkost
2020-08-25 19:21 ` [PATCH v3 74/74] crypto: use QOM macros for declaration/definition of TLS creds types Eduardo Habkost
2020-08-26 10:22 ` [PATCH v3 00/74] qom: Automated conversion of type checking boilerplate Roman Bolshakov
2020-08-26 11:18   ` Eduardo Habkost
2020-08-26 17:06     ` Roman Bolshakov
2020-08-27 18:18 ` Eduardo Habkost
2020-08-31 17:23 ` Eduardo Habkost
2020-08-31 18:52   ` Peter Maydell
2020-08-31 19:07     ` Eduardo Habkost

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200825192110.3528606-56-ehabkost@redhat.com \
    --to=ehabkost@redhat.com \
    --cc=berrange@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).