Documentation/QOMConventions: Difference between revisions

From QEMU
No edit summary
m (keep the class example in one piece)
Line 46: Line 46:
     MyParentClass parent_class;
     MyParentClass parent_class;
     /*< public >*/
     /*< public >*/
 
     [any fields you need]
     [any fields you need]
  } FooClass;
  } FooClass;

Revision as of 16:03, 15 February 2013

QOM Coding Conventions

  • DO use TYPE_FOO constants defined in a header
  • DO use verbose macro names
  • DO use names-separated-by-dashes
  • DON'T duplicate literal string type names
#define TYPE_EXAMPLE "example"
.name = TYPE_EXAMPLE,
object_new(TYPE_EXAMPLE)
qdev_create(NULL, TYPE_EXAMPLE)
  • DO place parent field first
  • DON'T use “busdev” or similar qdev conventions
typedef struct MyState {
    /*< private >*/
    Object parent_obj; /* or PCIDevice parent_obj etc. */
    /*< public >*/

    uint32_t some_register_value;
} MyState;
  • DO use cast macros (based on struct layout)
  • DON'T rely on DO_UPCAST() (field names)
  • DO use per-type variable declarations
  • Avoid using cast macros other than OBJECT() inline
void do_something_with(MyDeviceState *s) {
    PCIDevice *pci = PCI_DEVICE(s);

    pci->field = foo; /* not s->pci.field or PCI(s)->field */

When to create class types and macros

CAUTION: section still under discussion

If your class (a) will be subclassed or (b) has member fields it needs to put in its class struct then you should write all of:

  • a FOO_CLASS macro
  • a FOO_GET_CLASS macro
  • a FooClass structure definition containing at least the parent class field:
typedef struct {
    /*< private >*/
    MyParentClass parent_class;
    /*< public >*/

    [any fields you need]
} FooClass;
  • and your TypeInfo for this class should set the .class_size field to sizeof(FooClass).

These ensure that nothing in future should need changing if new fields are added to your class struct, and that any subclasses have the correct typenames available so they won't need to change either even if your implementation changes.

If your class meets neither of the above requirements (ie it is a simple leaf class) then:

  • don't provide FOO_CLASS or FOO_GET_CLASS
  • don't provide a FooClass structure
  • leave the TypeInfo's .class_size field unset.

If a change means a class which didn't provide these macros/types now needs to provide them, then your change should add all of them (ie move the class from the latter category to the former).