Documentation/QOMConventions: Difference between revisions
m (keep the class example in one piece) |
No edit summary |
||
(4 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
== [[Features/QOM|QOM]] Coding Conventions == | == [[Features/QOM|QOM]] Coding Conventions == | ||
* DO use | * DO use <code>TYPE_''FOO''</code> constants, defined in a header if used in other parts of code | ||
* DO use verbose macro names | * DO use verbose cast macro names | ||
** bad: <code>PHB(obj)</code> | |||
** bad: <code>PCI_HOST(obj)</code> | |||
** good: <code>PCI_HOST_BRIDGE(obj)</code> | |||
** excessive: <code>PERIPHERAL_COMPONENT_INTERCONNECT_HOST_BRIDGE(obj)</code> | |||
* DO use names-separated-by-dashes | * DO use names-separated-by-dashes | ||
* DON'T duplicate literal string type names | * DON'T duplicate literal string type names | ||
Line 14: | Line 18: | ||
* DO place parent field first | * DO place parent field first | ||
* DON'T use | * '''DON'T''' use <code>busdev</code> or similar qdev conventions | ||
typedef struct MyState { | typedef struct MyState { | ||
Line 24: | Line 28: | ||
} MyState; | } MyState; | ||
* DO use cast macros (based on struct layout) | * DO use QOM cast macros (based on struct layout) | ||
* DON'T rely on DO_UPCAST() (field names) | * '''DON'T''' rely on qdev's <code>DO_UPCAST()</code> macro (field names) | ||
* DO use per-type variable declarations | * DO use per-type variable declarations | ||
* Avoid using cast macros other than OBJECT() inline | * Avoid using cast macros other than <code>OBJECT()</code> inline | ||
void do_something_with(MyDeviceState *s) { | void do_something_with(MyDeviceState *s) { | ||
PCIDevice *pci = PCI_DEVICE(s); | PCIDevice *pci = PCI_DEVICE(s); | ||
pci->field = foo; /* not s->pci.field or | pci->field = foo; /* not s->pci.field or PCI_DEVICE(s)->field */ | ||
qdev_foo(DEVICE(s)); /* okay if cast is not repeated */ | |||
=== When to create class types and macros === | === When to create class types and macros === | ||
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: | 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: | ||
Line 59: | Line 62: | ||
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). | 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). | ||
[[Category:Developer documentation]] |
Latest revision as of 10:10, 12 October 2016
QOM Coding Conventions
- DO use
TYPE_FOO
constants, defined in a header if used in other parts of code - DO use verbose cast macro names
- bad:
PHB(obj)
- bad:
PCI_HOST(obj)
- good:
PCI_HOST_BRIDGE(obj)
- excessive:
PERIPHERAL_COMPONENT_INTERCONNECT_HOST_BRIDGE(obj)
- bad:
- 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 QOM cast macros (based on struct layout)
- DON'T rely on qdev's
DO_UPCAST()
macro (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_DEVICE(s)->field */ qdev_foo(DEVICE(s)); /* okay if cast is not repeated */
When to create class types and macros
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 tosizeof(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
orFOO_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).