All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: Eduardo Habkost <ehabkost@redhat.com>
Subject: [PULL 74/92] docs: Move object.h overview doc comment to qom.rst
Date: Thu, 24 Sep 2020 05:22:56 -0400	[thread overview]
Message-ID: <20200924092314.1722645-75-pbonzini@redhat.com> (raw)
In-Reply-To: <20200924092314.1722645-1-pbonzini@redhat.com>

Move the whole contents of the overview doc comment from object.h
to qom.rst.

This makes the documentation source easier to read and edit, and
also solves the backslash escaping issue at the typecasting macro
examples.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Message-Id: <20200910221526.10041-10-ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 docs/devel/qom.rst   | 373 ++++++++++++++++++++++++++++++++++++++++++
 include/qom/object.h | 377 -------------------------------------------
 2 files changed, 373 insertions(+), 377 deletions(-)

diff --git a/docs/devel/qom.rst b/docs/devel/qom.rst
index dc5be79a4a..0b943b2a1a 100644
--- a/docs/devel/qom.rst
+++ b/docs/devel/qom.rst
@@ -2,4 +2,377 @@
 The QEMU Object Model (QOM)
 ===========================
 
+.. highlight:: c
+
+The QEMU Object Model provides a framework for registering user creatable
+types and instantiating objects from those types.  QOM provides the following
+features:
+
+ - System for dynamically registering types
+ - Support for single-inheritance of types
+ - Multiple inheritance of stateless interfaces
+
+.. code-block:: c
+   :caption: Creating a minimal type
+
+   #include "qdev.h"
+
+   #define TYPE_MY_DEVICE "my-device"
+
+   // No new virtual functions: we can reuse the typedef for the
+   // superclass.
+   typedef DeviceClass MyDeviceClass;
+   typedef struct MyDevice
+   {
+       DeviceState parent;
+
+       int reg0, reg1, reg2;
+   } MyDevice;
+
+   static const TypeInfo my_device_info = {
+       .name = TYPE_MY_DEVICE,
+       .parent = TYPE_DEVICE,
+       .instance_size = sizeof(MyDevice),
+   };
+
+   static void my_device_register_types(void)
+   {
+       type_register_static(&my_device_info);
+   }
+
+   type_init(my_device_register_types)
+
+In the above example, we create a simple type that is described by #TypeInfo.
+#TypeInfo describes information about the type including what it inherits
+from, the instance and class size, and constructor/destructor hooks.
+
+Alternatively several static types could be registered using helper macro
+DEFINE_TYPES()
+
+.. code-block:: c
+
+   static const TypeInfo device_types_info[] = {
+       {
+           .name = TYPE_MY_DEVICE_A,
+           .parent = TYPE_DEVICE,
+           .instance_size = sizeof(MyDeviceA),
+       },
+       {
+           .name = TYPE_MY_DEVICE_B,
+           .parent = TYPE_DEVICE,
+           .instance_size = sizeof(MyDeviceB),
+       },
+   };
+
+   DEFINE_TYPES(device_types_info)
+
+Every type has an #ObjectClass associated with it.  #ObjectClass derivatives
+are instantiated dynamically but there is only ever one instance for any
+given type.  The #ObjectClass typically holds a table of function pointers
+for the virtual methods implemented by this type.
+
+Using object_new(), a new #Object derivative will be instantiated.  You can
+cast an #Object to a subclass (or base-class) type using
+object_dynamic_cast().  You typically want to define macro wrappers around
+OBJECT_CHECK() and OBJECT_CLASS_CHECK() to make it easier to convert to a
+specific type:
+
+.. code-block:: c
+   :caption: Typecasting macros
+
+   #define MY_DEVICE_GET_CLASS(obj) \
+      OBJECT_GET_CLASS(MyDeviceClass, obj, TYPE_MY_DEVICE)
+   #define MY_DEVICE_CLASS(klass) \
+      OBJECT_CLASS_CHECK(MyDeviceClass, klass, TYPE_MY_DEVICE)
+   #define MY_DEVICE(obj) \
+      OBJECT_CHECK(MyDevice, obj, TYPE_MY_DEVICE)
+
+Class Initialization
+====================
+
+Before an object is initialized, the class for the object must be
+initialized.  There is only one class object for all instance objects
+that is created lazily.
+
+Classes are initialized by first initializing any parent classes (if
+necessary).  After the parent class object has initialized, it will be
+copied into the current class object and any additional storage in the
+class object is zero filled.
+
+The effect of this is that classes automatically inherit any virtual
+function pointers that the parent class has already initialized.  All
+other fields will be zero filled.
+
+Once all of the parent classes have been initialized, #TypeInfo::class_init
+is called to let the class being instantiated provide default initialize for
+its virtual functions.  Here is how the above example might be modified
+to introduce an overridden virtual function:
+
+.. code-block:: c
+   :caption: Overriding a virtual function
+
+   #include "qdev.h"
+
+   void my_device_class_init(ObjectClass *klass, void *class_data)
+   {
+       DeviceClass *dc = DEVICE_CLASS(klass);
+       dc->reset = my_device_reset;
+   }
+
+   static const TypeInfo my_device_info = {
+       .name = TYPE_MY_DEVICE,
+       .parent = TYPE_DEVICE,
+       .instance_size = sizeof(MyDevice),
+       .class_init = my_device_class_init,
+   };
+
+Introducing new virtual methods requires a class to define its own
+struct and to add a .class_size member to the #TypeInfo.  Each method
+will also have a wrapper function to call it easily:
+
+.. code-block:: c
+   :caption: Defining an abstract class
+
+   #include "qdev.h"
+
+   typedef struct MyDeviceClass
+   {
+       DeviceClass parent;
+
+       void (*frobnicate) (MyDevice *obj);
+   } MyDeviceClass;
+
+   static const TypeInfo my_device_info = {
+       .name = TYPE_MY_DEVICE,
+       .parent = TYPE_DEVICE,
+       .instance_size = sizeof(MyDevice),
+       .abstract = true, // or set a default in my_device_class_init
+       .class_size = sizeof(MyDeviceClass),
+   };
+
+   void my_device_frobnicate(MyDevice *obj)
+   {
+       MyDeviceClass *klass = MY_DEVICE_GET_CLASS(obj);
+
+       klass->frobnicate(obj);
+   }
+
+Interfaces
+==========
+
+Interfaces allow a limited form of multiple inheritance.  Instances are
+similar to normal types except for the fact that are only defined by
+their classes and never carry any state.  As a consequence, a pointer to
+an interface instance should always be of incomplete type in order to be
+sure it cannot be dereferenced.  That is, you should define the
+'typedef struct SomethingIf SomethingIf' so that you can pass around
+``SomethingIf *si`` arguments, but not define a ``struct SomethingIf { ... }``.
+The only things you can validly do with a ``SomethingIf *`` are to pass it as
+an argument to a method on its corresponding SomethingIfClass, or to
+dynamically cast it to an object that implements the interface.
+
+Methods
+=======
+
+A <emphasis>method</emphasis> is a function within the namespace scope of
+a class. It usually operates on the object instance by passing it as a
+strongly-typed first argument.
+If it does not operate on an object instance, it is dubbed
+<emphasis>class method</emphasis>.
+
+Methods cannot be overloaded. That is, the #ObjectClass and method name
+uniquely identity the function to be called; the signature does not vary
+except for trailing varargs.
+
+Methods are always <emphasis>virtual</emphasis>. Overriding a method in
+#TypeInfo.class_init of a subclass leads to any user of the class obtained
+via OBJECT_GET_CLASS() accessing the overridden function.
+The original function is not automatically invoked. It is the responsibility
+of the overriding class to determine whether and when to invoke the method
+being overridden.
+
+To invoke the method being overridden, the preferred solution is to store
+the original value in the overriding class before overriding the method.
+This corresponds to ``{super,base}.method(...)`` in Java and C#
+respectively; this frees the overriding class from hardcoding its parent
+class, which someone might choose to change at some point.
+
+.. code-block:: c
+   :caption: Overriding a virtual method
+
+   typedef struct MyState MyState;
+
+   typedef void (*MyDoSomething)(MyState *obj);
+
+   typedef struct MyClass {
+       ObjectClass parent_class;
+
+       MyDoSomething do_something;
+   } MyClass;
+
+   static void my_do_something(MyState *obj)
+   {
+       // do something
+   }
+
+   static void my_class_init(ObjectClass *oc, void *data)
+   {
+       MyClass *mc = MY_CLASS(oc);
+
+       mc->do_something = my_do_something;
+   }
+
+   static const TypeInfo my_type_info = {
+       .name = TYPE_MY,
+       .parent = TYPE_OBJECT,
+       .instance_size = sizeof(MyState),
+       .class_size = sizeof(MyClass),
+       .class_init = my_class_init,
+   };
+
+   typedef struct DerivedClass {
+       MyClass parent_class;
+
+       MyDoSomething parent_do_something;
+   } DerivedClass;
+
+   static void derived_do_something(MyState *obj)
+   {
+       DerivedClass *dc = DERIVED_GET_CLASS(obj);
+
+       // do something here
+       dc->parent_do_something(obj);
+       // do something else here
+   }
+
+   static void derived_class_init(ObjectClass *oc, void *data)
+   {
+       MyClass *mc = MY_CLASS(oc);
+       DerivedClass *dc = DERIVED_CLASS(oc);
+
+       dc->parent_do_something = mc->do_something;
+       mc->do_something = derived_do_something;
+   }
+
+   static const TypeInfo derived_type_info = {
+       .name = TYPE_DERIVED,
+       .parent = TYPE_MY,
+       .class_size = sizeof(DerivedClass),
+       .class_init = derived_class_init,
+   };
+
+Alternatively, object_class_by_name() can be used to obtain the class and
+its non-overridden methods for a specific type. This would correspond to
+``MyClass::method(...)`` in C++.
+
+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:
+
+.. code-block:: c
+   :caption: Declaring a simple type
+
+    OBJECT_DECLARE_SIMPLE_TYPE(MyDevice, my_device, MY_DEVICE, DEVICE)
+
+This is equivalent to the following:
+
+.. code-block:: c
+   :caption: Expansion from declaring a simple type
+
+    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;
+    };
+
+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:
+
+.. code-block:: c
+   :caption: Defining a simple type
+
+    OBJECT_DEFINE_TYPE(MyDevice, my_device, MY_DEVICE, DEVICE)
+
+This is equivalent to the following:
+
+.. code-block:: c
+   :caption: Expansion from defining a simple type
+
+    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);
+
+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.
+
+.. code-block:: c
+   :caption: Defining a simple type implementing interfaces
+
+    OBJECT_DEFINE_TYPE_WITH_INTERFACES(MyDevice, my_device,
+                                       MY_DEVICE, DEVICE,
+                                       { TYPE_USER_CREATABLE }, { NULL })
+
+If the type is not intended to be instantiated, then then
+the OBJECT_DEFINE_ABSTRACT_TYPE() macro can be used instead:
+
+.. code-block:: c
+   :caption: Defining a simple abstract type
+
+    OBJECT_DEFINE_ABSTRACT_TYPE(MyDevice, my_device, MY_DEVICE, DEVICE)
+
+
+
+API Reference
+-------------
+
 .. kernel-doc:: include/qom/object.h
diff --git a/include/qom/object.h b/include/qom/object.h
index d839a2c39f..93b6418dbc 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -28,383 +28,6 @@ typedef struct InterfaceInfo InterfaceInfo;
 
 #define TYPE_OBJECT "object"
 
-/**
- * DOC:
- *
- * .. highlight:: c
- *
- * The QEMU Object Model provides a framework for registering user creatable
- * types and instantiating objects from those types.  QOM provides the following
- * features:
- *
- *  - System for dynamically registering types
- *  - Support for single-inheritance of types
- *  - Multiple inheritance of stateless interfaces
- *
- * .. code-block:: c
- *    :caption: Creating a minimal type
- *
- *    #include "qdev.h"
- *
- *    #define TYPE_MY_DEVICE "my-device"
- *
- *    // No new virtual functions: we can reuse the typedef for the
- *    // superclass.
- *    typedef DeviceClass MyDeviceClass;
- *    typedef struct MyDevice
- *    {
- *        DeviceState parent;
- *
- *        int reg0, reg1, reg2;
- *    } MyDevice;
- *
- *    static const TypeInfo my_device_info = {
- *        .name = TYPE_MY_DEVICE,
- *        .parent = TYPE_DEVICE,
- *        .instance_size = sizeof(MyDevice),
- *    };
- *
- *    static void my_device_register_types(void)
- *    {
- *        type_register_static(&my_device_info);
- *    }
- *
- *    type_init(my_device_register_types)
- *
- * In the above example, we create a simple type that is described by #TypeInfo.
- * #TypeInfo describes information about the type including what it inherits
- * from, the instance and class size, and constructor/destructor hooks.
- *
- * Alternatively several static types could be registered using helper macro
- * DEFINE_TYPES()
- *
- * .. code-block:: c
- *
- *    static const TypeInfo device_types_info[] = {
- *        {
- *            .name = TYPE_MY_DEVICE_A,
- *            .parent = TYPE_DEVICE,
- *            .instance_size = sizeof(MyDeviceA),
- *        },
- *        {
- *            .name = TYPE_MY_DEVICE_B,
- *            .parent = TYPE_DEVICE,
- *            .instance_size = sizeof(MyDeviceB),
- *        },
- *    };
- *
- *    DEFINE_TYPES(device_types_info)
- *
- * Every type has an #ObjectClass associated with it.  #ObjectClass derivatives
- * are instantiated dynamically but there is only ever one instance for any
- * given type.  The #ObjectClass typically holds a table of function pointers
- * for the virtual methods implemented by this type.
- *
- * Using object_new(), a new #Object derivative will be instantiated.  You can
- * cast an #Object to a subclass (or base-class) type using
- * object_dynamic_cast().  You typically want to define macro wrappers around
- * OBJECT_CHECK() and OBJECT_CLASS_CHECK() to make it easier to convert to a
- * specific type:
- *
- * .. kernel-doc messes up with the code block below because of the
- *    backslash at the end of lines.  This will be fixes if we move this
- *    content to qom.rst.
- *
- * .. code-block:: c
- *    :caption: Typecasting macros
- *
- *    #define MY_DEVICE_GET_CLASS(obj) \
- *       OBJECT_GET_CLASS(MyDeviceClass, obj, TYPE_MY_DEVICE)
- *    #define MY_DEVICE_CLASS(klass) \
- *       OBJECT_CLASS_CHECK(MyDeviceClass, klass, TYPE_MY_DEVICE)
- *    #define MY_DEVICE(obj) \
- *       OBJECT_CHECK(MyDevice, obj, TYPE_MY_DEVICE)
- *
- * Class Initialization
- * ====================
- *
- * Before an object is initialized, the class for the object must be
- * initialized.  There is only one class object for all instance objects
- * that is created lazily.
- *
- * Classes are initialized by first initializing any parent classes (if
- * necessary).  After the parent class object has initialized, it will be
- * copied into the current class object and any additional storage in the
- * class object is zero filled.
- *
- * The effect of this is that classes automatically inherit any virtual
- * function pointers that the parent class has already initialized.  All
- * other fields will be zero filled.
- *
- * Once all of the parent classes have been initialized, #TypeInfo::class_init
- * is called to let the class being instantiated provide default initialize for
- * its virtual functions.  Here is how the above example might be modified
- * to introduce an overridden virtual function:
- *
- * .. code-block:: c
- *    :caption: Overriding a virtual function
- *
- *    #include "qdev.h"
- *
- *    void my_device_class_init(ObjectClass *klass, void *class_data)
- *    {
- *        DeviceClass *dc = DEVICE_CLASS(klass);
- *        dc->reset = my_device_reset;
- *    }
- *
- *    static const TypeInfo my_device_info = {
- *        .name = TYPE_MY_DEVICE,
- *        .parent = TYPE_DEVICE,
- *        .instance_size = sizeof(MyDevice),
- *        .class_init = my_device_class_init,
- *    };
- *
- * Introducing new virtual methods requires a class to define its own
- * struct and to add a .class_size member to the #TypeInfo.  Each method
- * will also have a wrapper function to call it easily:
- *
- * .. code-block:: c
- *    :caption: Defining an abstract class
- *
- *    #include "qdev.h"
- *
- *    typedef struct MyDeviceClass
- *    {
- *        DeviceClass parent;
- *
- *        void (*frobnicate) (MyDevice *obj);
- *    } MyDeviceClass;
- *
- *    static const TypeInfo my_device_info = {
- *        .name = TYPE_MY_DEVICE,
- *        .parent = TYPE_DEVICE,
- *        .instance_size = sizeof(MyDevice),
- *        .abstract = true, // or set a default in my_device_class_init
- *        .class_size = sizeof(MyDeviceClass),
- *    };
- *
- *    void my_device_frobnicate(MyDevice *obj)
- *    {
- *        MyDeviceClass *klass = MY_DEVICE_GET_CLASS(obj);
- *
- *        klass->frobnicate(obj);
- *    }
- *
- * Interfaces
- * ==========
- *
- * Interfaces allow a limited form of multiple inheritance.  Instances are
- * similar to normal types except for the fact that are only defined by
- * their classes and never carry any state.  As a consequence, a pointer to
- * an interface instance should always be of incomplete type in order to be
- * sure it cannot be dereferenced.  That is, you should define the
- * 'typedef struct SomethingIf SomethingIf' so that you can pass around
- * ``SomethingIf *si`` arguments, but not define a ``struct SomethingIf { ... }``.
- * The only things you can validly do with a ``SomethingIf *`` are to pass it as
- * an argument to a method on its corresponding SomethingIfClass, or to
- * dynamically cast it to an object that implements the interface.
- *
- * Methods
- * =======
- *
- * A <emphasis>method</emphasis> is a function within the namespace scope of
- * a class. It usually operates on the object instance by passing it as a
- * strongly-typed first argument.
- * If it does not operate on an object instance, it is dubbed
- * <emphasis>class method</emphasis>.
- *
- * Methods cannot be overloaded. That is, the #ObjectClass and method name
- * uniquely identity the function to be called; the signature does not vary
- * except for trailing varargs.
- *
- * Methods are always <emphasis>virtual</emphasis>. Overriding a method in
- * #TypeInfo.class_init of a subclass leads to any user of the class obtained
- * via OBJECT_GET_CLASS() accessing the overridden function.
- * The original function is not automatically invoked. It is the responsibility
- * of the overriding class to determine whether and when to invoke the method
- * being overridden.
- *
- * To invoke the method being overridden, the preferred solution is to store
- * the original value in the overriding class before overriding the method.
- * This corresponds to ``{super,base}.method(...)`` in Java and C#
- * respectively; this frees the overriding class from hardcoding its parent
- * class, which someone might choose to change at some point.
- *
- * .. code-block:: c
- *    :caption: Overriding a virtual method
- *
- *    typedef struct MyState MyState;
- *
- *    typedef void (*MyDoSomething)(MyState *obj);
- *
- *    typedef struct MyClass {
- *        ObjectClass parent_class;
- *
- *        MyDoSomething do_something;
- *    } MyClass;
- *
- *    static void my_do_something(MyState *obj)
- *    {
- *        // do something
- *    }
- *
- *    static void my_class_init(ObjectClass *oc, void *data)
- *    {
- *        MyClass *mc = MY_CLASS(oc);
- *
- *        mc->do_something = my_do_something;
- *    }
- *
- *    static const TypeInfo my_type_info = {
- *        .name = TYPE_MY,
- *        .parent = TYPE_OBJECT,
- *        .instance_size = sizeof(MyState),
- *        .class_size = sizeof(MyClass),
- *        .class_init = my_class_init,
- *    };
- *
- *    typedef struct DerivedClass {
- *        MyClass parent_class;
- *
- *        MyDoSomething parent_do_something;
- *    } DerivedClass;
- *
- *    static void derived_do_something(MyState *obj)
- *    {
- *        DerivedClass *dc = DERIVED_GET_CLASS(obj);
- *
- *        // do something here
- *        dc->parent_do_something(obj);
- *        // do something else here
- *    }
- *
- *    static void derived_class_init(ObjectClass *oc, void *data)
- *    {
- *        MyClass *mc = MY_CLASS(oc);
- *        DerivedClass *dc = DERIVED_CLASS(oc);
- *
- *        dc->parent_do_something = mc->do_something;
- *        mc->do_something = derived_do_something;
- *    }
- *
- *    static const TypeInfo derived_type_info = {
- *        .name = TYPE_DERIVED,
- *        .parent = TYPE_MY,
- *        .class_size = sizeof(DerivedClass),
- *        .class_init = derived_class_init,
- *    };
- *
- * Alternatively, object_class_by_name() can be used to obtain the class and
- * its non-overridden methods for a specific type. This would correspond to
- * ``MyClass::method(...)`` in C++.
- *
- * 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:
- *
- * .. code-block:: c
- *    :caption: Declaring a simple type
- *
- *     OBJECT_DECLARE_SIMPLE_TYPE(MyDevice, my_device, MY_DEVICE, DEVICE)
- *
- * This is equivalent to the following:
- *
- * .. code-block:: c
- *    :caption: Expansion from declaring a simple type
- *
- *     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;
- *     };
- *
- * 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:
- *
- * .. code-block:: c
- *    :caption: Defining a simple type
- *
- *     OBJECT_DEFINE_TYPE(MyDevice, my_device, MY_DEVICE, DEVICE)
- *
- * This is equivalent to the following:
- *
- * .. code-block:: c
- *    :caption: Expansion from defining a simple type
- *
- *     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);
- *
- * 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.
- *
- * .. code-block:: c
- *    :caption: Defining a simple type implementing interfaces
- *
- *     OBJECT_DEFINE_TYPE_WITH_INTERFACES(MyDevice, my_device,
- *                                        MY_DEVICE, DEVICE,
- *                                        { TYPE_USER_CREATABLE }, { NULL })
- *
- * If the type is not intended to be instantiated, then then
- * the OBJECT_DEFINE_ABSTRACT_TYPE() macro can be used instead:
- *
- * .. code-block:: c
- *    :caption: Defining a simple abstract type
- *
- *     OBJECT_DEFINE_ABSTRACT_TYPE(MyDevice, my_device, MY_DEVICE, DEVICE)
- */
-
-
 typedef struct ObjectProperty ObjectProperty;
 
 /**
-- 
2.26.2




  parent reply	other threads:[~2020-09-24  9:57 UTC|newest]

Thread overview: 101+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-24  9:21 [PULL 00/92] Misc patches for 2020-09-24 Paolo Bonzini
2020-09-24  9:21 ` [PULL 01/92] tests: add missing genh dependency Paolo Bonzini
2020-09-24  9:21 ` [PULL 02/92] meson: clean up build_by_default Paolo Bonzini
2020-09-24  9:21 ` [PULL 03/92] ninjatool: rebuild multi-output targets if outputs are missing Paolo Bonzini
2020-09-24  9:21 ` [PULL 04/92] meson: fix MSI rule Paolo Bonzini
2020-09-24  9:21 ` [PULL 05/92] meson: error out if qemu_suffix starts with / Paolo Bonzini
2020-09-24  9:21 ` [PULL 06/92] WHPX: vmware cpuid leaf for tsc and apic frequency Paolo Bonzini
2020-09-24  9:21 ` [PULL 07/92] configure: Do not intent to build WHPX on 32-bit host Paolo Bonzini
2020-09-24  9:21 ` [PULL 08/92] MAINTAINERS: add Paolo Bonzini as RCU maintainer Paolo Bonzini
2020-09-24  9:21 ` [PULL 09/92] target/i386: support KVM_FEATURE_ASYNC_PF_INT Paolo Bonzini
2020-09-24  9:21 ` [PULL 10/92] memory: Convert IOMMUMemoryRegionClass doc comment to kernel-doc Paolo Bonzini
2020-09-24  9:21 ` [PULL 11/92] vhost-scsi: support inflight io track Paolo Bonzini
2020-09-24  9:21 ` [PULL 12/92] acpi: i386: Move VMBus DSDT entry to SB Paolo Bonzini
2020-09-24  9:21 ` [PULL 13/92] numa: drop support for '-numa node' (without memory specified) Paolo Bonzini
2020-09-24  9:21 ` [PULL 14/92] doc: Cleanup "'-mem-path' fallback to RAM" deprecation text Paolo Bonzini
2020-09-24  9:21 ` [PULL 15/92] numa: remove fixup numa_state->num_nodes to MAX_NODES Paolo Bonzini
2020-09-24  9:21 ` [PULL 16/92] hw/mips/mipssim: Use MMIO serial device on fake ISA I/O Paolo Bonzini
2020-09-24  9:21 ` [PULL 17/92] hw/char/serial: Remove TYPE_SERIAL_IO Paolo Bonzini
2020-09-24  9:22 ` [PULL 18/92] configure: rename QEMU_GA_MSI_ENABLED to CONFIG_QGA_MSI Paolo Bonzini
2020-09-24  9:22 ` [PULL 19/92] hw/char/serial: Assert serial_ioport_read/write offset fits 8 bytes Paolo Bonzini
2020-11-18 15:40   ` Peter Maydell
2020-11-18 17:08     ` Paolo Bonzini
2020-11-18 18:37       ` Philippe Mathieu-Daudé
2020-09-24  9:22 ` [PULL 20/92] hw/char/serial: Replace commented DPRINTF() by trace event Paolo Bonzini
2020-09-24  9:22 ` [PULL 21/92] hw/char/serial: Remove old DEBUG_SERIAL commented code Paolo Bonzini
2020-09-24  9:22 ` [PULL 22/92] hw/char/serial: Rename I/O read/write trace events Paolo Bonzini
2020-09-24  9:22 ` [PULL 23/92] hw/char/serial: Make 'wakeup' property boolean Paolo Bonzini
2020-09-24  9:22 ` [PULL 24/92] hw/char/serial-{isa, pci}: Alias QDEV properties from generic serial object Paolo Bonzini
2020-09-24  9:22 ` [PULL 25/92] scsi-generic: Fix HM-zoned device scan Paolo Bonzini
2020-09-24  9:22 ` [PULL 26/92] hw: megasas: return -1 when 'megasas_map_sgl' fails Paolo Bonzini
2020-09-24  9:22 ` [PULL 27/92] hw: megasas: consider 'iov_count=0' is an error in megasas_map_sgl Paolo Bonzini
2020-09-24  9:22 ` [PULL 28/92] i386/cpu: Clear FEAT_XSAVE_COMP_{LO, HI} when XSAVE is not available Paolo Bonzini
2020-09-24  9:22 ` [PULL 29/92] meson: move libudev test Paolo Bonzini
2020-09-24  9:22 ` [PULL 30/92] meson: move libmpathpersist test Paolo Bonzini
2020-09-24  9:22 ` [PULL 31/92] meson: extend libmpathpersist test for static linking Paolo Bonzini
2020-09-24  9:22 ` [PULL 32/92] configure: move malloc_trim/tcmalloc/jemalloc to meson Paolo Bonzini
2020-09-24  9:22 ` [PULL 33/92] configure: fix --meson=/path/to/meson Paolo Bonzini
2020-09-24  9:22 ` [PULL 34/92] configure: move cocoa option to Meson Paolo Bonzini
2020-09-24  9:22 ` [PULL 35/92] configure: do not limit Hypervisor.framework test to Darwin Paolo Bonzini
2020-09-24  9:22 ` [PULL 36/92] meson: qtest: set "depends" correctly Paolo Bonzini
2020-09-24  9:22 ` [PULL 37/92] mtest2make: add support for introspected test dependencies Paolo Bonzini
2020-09-24  9:22 ` [PULL 38/92] meson: report accelerator support Paolo Bonzini
2020-09-24  9:22 ` [PULL 39/92] oslib: do not call g_strdup from qemu_get_exec_dir Paolo Bonzini
2020-09-24  9:22 ` [PULL 40/92] fuzz: use qemu_get_exec_dir Paolo Bonzini
2020-09-24  9:22 ` [PULL 41/92] oslib-posix: default exec_dir to bindir Paolo Bonzini
2020-09-24  9:22 ` [PULL 42/92] cutils: introduce get_relocated_path Paolo Bonzini
2020-11-02 18:05   ` Peter Maydell
2020-11-02 18:09     ` Peter Maydell
2020-09-24  9:22 ` [PULL 43/92] oslib-posix: relocate path to /var Paolo Bonzini
2020-09-24  9:22 ` [PULL 44/92] module: relocate path to modules Paolo Bonzini
2020-09-24  9:22 ` [PULL 45/92] net: relocate paths to helpers and scripts Paolo Bonzini
2020-09-24  9:22 ` [PULL 46/92] vl: relocate paths to data directories Paolo Bonzini
2020-09-24  9:22 ` [PULL 47/92] vl: relocate path to configuration file Paolo Bonzini
2020-09-24  9:22 ` [PULL 48/92] qemu-bridge-helper: relocate path to default ACL Paolo Bonzini
2020-09-24  9:22 ` [PULL 49/92] qga: relocate path to default configuration and hook Paolo Bonzini
2020-09-24  9:22 ` [PULL 50/92] ui: relocate paths to icons and translations Paolo Bonzini
2020-09-24  9:22 ` [PULL 51/92] configure: use a platform-neutral prefix Paolo Bonzini
2020-09-24  9:22 ` [PULL 52/92] hw/i386/q35: Remove unreachable Xen code on Q35 machine Paolo Bonzini
2020-09-24  9:22 ` [PULL 53/92] exec: Remove MemoryRegion::global_locking field Paolo Bonzini
2020-09-24  9:22 ` [PULL 54/92] checkpatch: avoid error on cover letter files Paolo Bonzini
2020-09-24  9:22 ` [PULL 55/92] meson: fix installation of keymaps Paolo Bonzini
2020-09-24  9:22 ` [PULL 56/92] configure: fix performance regression due to PIC objects Paolo Bonzini
2020-09-24  9:22 ` [PULL 57/92] oss-fuzz: move linker arg to fix coverage-build Paolo Bonzini
2020-09-24  9:22 ` [PULL 58/92] tests/tcg: reinstate or replace desired parts of rules.mak Paolo Bonzini
2020-09-24  9:22 ` [PULL 59/92] configure: cleanup invocation of submodule Make Paolo Bonzini
2020-09-24  9:22 ` [PULL 60/92] configure: cleanup CFLAGS and LDFLAGS for submodules Paolo Bonzini
2020-09-24  9:22 ` [PULL 61/92] configure: do not clobber environment CFLAGS/CXXFLAGS/LDFLAGS Paolo Bonzini
2020-09-24  9:22 ` [PULL 62/92] configure: consistently pass CFLAGS/CXXFLAGS/LDFLAGS to meson Paolo Bonzini
2020-09-24  9:22 ` [PULL 63/92] smp: drop support for deprecated (invalid topologies) Paolo Bonzini
2020-09-24  9:22 ` [PULL 64/92] cphp: remove deprecated cpu-add command(s) Paolo Bonzini
2020-09-24  9:22 ` [PULL 65/92] char: fix logging when chardev write fails Paolo Bonzini
2020-09-24  9:22 ` [PULL 66/92] qom: Document all function parameters in doc comments Paolo Bonzini
2020-09-24  9:22 ` [PULL 67/92] qom: Use kernel-doc private/public tags in structs Paolo Bonzini
2020-09-24  9:22 ` [PULL 68/92] qom: Use ``code`` Sphinx syntax where appropriate Paolo Bonzini
2020-09-24  9:22 ` [PULL 69/92] qom: Add kernel-doc markup to introduction doc comment Paolo Bonzini
2020-09-24  9:22 ` [PULL 70/92] qom: Reformat section titles using Sphinx syntax Paolo Bonzini
2020-09-24  9:22 ` [PULL 71/92] qom: Indent existing code examples Paolo Bonzini
2020-09-24  9:22 ` [PULL 72/92] qom: Add code block markup to all code blocks Paolo Bonzini
2020-09-24  9:22 ` [PULL 73/92] docs: Create docs/devel/qom.rst Paolo Bonzini
2020-09-24  9:22 ` Paolo Bonzini [this message]
2020-09-24  9:22 ` [PULL 75/92] hw/i386/xen: Rename X86/PC specific function as xen_hvm_init_pc() Paolo Bonzini
2020-09-24  9:22 ` [PULL 76/92] sysemu/xen: Add missing 'exec/cpu-common.h' header for ram_addr_t type Paolo Bonzini
2020-09-24  9:22 ` [PULL 77/92] stubs: Split accelerator / hardware related stubs Paolo Bonzini
2020-09-24  9:23 ` [PULL 78/92] hw/xen: Split x86-specific declaration from generic hardware ones Paolo Bonzini
2020-09-24  9:23 ` [PULL 79/92] typedefs: Restrict PCMachineState to 'hw/i386/pc.h' Paolo Bonzini
2020-09-24  9:23 ` [PULL 80/92] checkpatch: Detect '%#' or '%0#' in printf-style format strings Paolo Bonzini
2020-09-24  9:23 ` [PULL 81/92] helper_syscall x86_64: clear exception_is_int Paolo Bonzini
2020-09-24  9:23 ` [PULL 82/92] target/i386: Fix VM migration when interrupt based APF is enabled Paolo Bonzini
2020-09-24  9:23 ` [PULL 83/92] target/i386: always create kvmclock device Paolo Bonzini
2020-09-24  9:23 ` [PULL 84/92] bios-tables-test: Remove kernel-irqchip=off option Paolo Bonzini
2020-09-24  9:23 ` [PULL 85/92] target/i386: kvm: do not use kvm_check_extension to find paravirtual capabilities Paolo Bonzini
2020-09-24  9:23 ` [PULL 86/92] net/can: Initial host SocketCan support for CAN FD Paolo Bonzini
2020-09-24  9:23 ` [PULL 87/92] hw/net/can: sja1000 ignore CAN FD frames Paolo Bonzini
2020-09-24  9:23 ` [PULL 88/92] net/can: Add can_dlc2len and can_len2dlc for CAN FD Paolo Bonzini
2020-09-24  9:23 ` [PULL 89/92] hw/net/can/ctucafd: Add CTU CAN FD core register definitions Paolo Bonzini
2020-09-24  9:23 ` [PULL 90/92] hw/net/can: CTU CAN FD IP open hardware core emulation Paolo Bonzini
2020-11-02 16:32   ` Peter Maydell
2020-09-24  9:23 ` [PULL 91/92] hw/net/can: Documentation for " Paolo Bonzini
2020-09-24  9:23 ` [PULL 92/92] hw/net/can: Correct Kconfig dependencies Paolo Bonzini
2020-09-24 11:16 ` [PULL 00/92] Misc patches for 2020-09-24 no-reply
2020-09-25 10:08 ` Peter Maydell

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=20200924092314.1722645-75-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=ehabkost@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.