diff --git a/qemu/include/qapi/qmp/qbool.h b/qemu/include/qapi/qmp/qbool.h index 0f00aa39..f339f546 100644 --- a/qemu/include/qapi/qmp/qbool.h +++ b/qemu/include/qapi/qmp/qbool.h @@ -18,7 +18,7 @@ #include "qapi/qmp/qobject.h" struct QBool { - QObject_HEAD; + struct QObjectBase_ base; bool value; }; diff --git a/qemu/include/qapi/qmp/qdict.h b/qemu/include/qapi/qmp/qdict.h index 6a5ee9a6..e08affd3 100644 --- a/qemu/include/qapi/qmp/qdict.h +++ b/qemu/include/qapi/qmp/qdict.h @@ -26,7 +26,7 @@ typedef struct QDictEntry { } QDictEntry; struct QDict { - QObject_HEAD; + struct QObjectBase_ base; size_t size; QLIST_HEAD(,QDictEntry) table[QDICT_BUCKET_MAX]; }; diff --git a/qemu/include/qapi/qmp/qlist.h b/qemu/include/qapi/qmp/qlist.h index c1d2ea2b..8d2c32ca 100644 --- a/qemu/include/qapi/qmp/qlist.h +++ b/qemu/include/qapi/qmp/qlist.h @@ -22,7 +22,7 @@ typedef struct QListEntry { } QListEntry; struct QList { - QObject_HEAD; + struct QObjectBase_ base; QTAILQ_HEAD(,QListEntry) head; }; diff --git a/qemu/include/qapi/qmp/qnull.h b/qemu/include/qapi/qmp/qnull.h index c992ee2a..e8ea2c31 100644 --- a/qemu/include/qapi/qmp/qnull.h +++ b/qemu/include/qapi/qmp/qnull.h @@ -16,7 +16,7 @@ #include "qapi/qmp/qobject.h" struct QNull { - QObject base; + struct QObjectBase_ base; }; extern QNull qnull_; diff --git a/qemu/include/qapi/qmp/qnum.h b/qemu/include/qapi/qmp/qnum.h index 3e47475b..45bf02a0 100644 --- a/qemu/include/qapi/qmp/qnum.h +++ b/qemu/include/qapi/qmp/qnum.h @@ -45,7 +45,7 @@ typedef enum { * convert under the hood. */ struct QNum { - QObject base; + struct QObjectBase_ base; QNumKind kind; union { int64_t i64; diff --git a/qemu/include/qapi/qmp/qobject.h b/qemu/include/qapi/qmp/qobject.h index 609b0245..a713c016 100644 --- a/qemu/include/qapi/qmp/qobject.h +++ b/qemu/include/qapi/qmp/qobject.h @@ -34,17 +34,21 @@ #include "qapi/qapi-builtin-types.h" -struct QObject { +/* Not for use outside include/qapi/qmp/ */ +struct QObjectBase_ { QType type; size_t refcnt; }; -/* Objects definitions must include this */ -#define QObject_HEAD \ - QObject base +/* this struct must have no other members than base */ +struct QObject { + struct QObjectBase_ base; +}; -/* Get the 'base' part of an object */ -#define QOBJECT(obj) (&(obj)->base) +#define QOBJECT(obj) ({ \ + typeof(obj) _obj = (obj); \ + _obj ? container_of(&(_obj)->base, QObject, base) : NULL; \ +}) /* High-level interface for qobject_incref() */ #define QINCREF(obj) \ @@ -72,8 +76,8 @@ QEMU_BUILD_BUG_MSG(QTYPE__MAX != 7, static inline void qobject_init(QObject *obj, QType type) { assert(QTYPE_NONE < type && type < QTYPE__MAX); - obj->refcnt = 1; - obj->type = type; + obj->base.refcnt = 1; + obj->base.type = type; } /** @@ -81,8 +85,9 @@ static inline void qobject_init(QObject *obj, QType type) */ static inline void qobject_incref(QObject *obj) { - if (obj) - obj->refcnt++; + if (obj) { + obj->base.refcnt++; + } } /** @@ -105,8 +110,8 @@ void qobject_destroy(QObject *obj); */ static inline void qobject_decref(QObject *obj) { - assert(!obj || obj->refcnt); - if (obj && --obj->refcnt == 0) { + assert(!obj || obj->base.refcnt); + if (obj && --obj->base.refcnt == 0) { qobject_destroy(obj); } } @@ -116,8 +121,8 @@ static inline void qobject_decref(QObject *obj) */ static inline QType qobject_type(const QObject *obj) { - assert(QTYPE_NONE < obj->type && obj->type < QTYPE__MAX); - return obj->type; + assert(QTYPE_NONE < obj->base.type && obj->base.type < QTYPE__MAX); + return obj->base.type; } /** diff --git a/qemu/include/qapi/qmp/qstring.h b/qemu/include/qapi/qmp/qstring.h index 9e476617..0a563f87 100644 --- a/qemu/include/qapi/qmp/qstring.h +++ b/qemu/include/qapi/qmp/qstring.h @@ -17,7 +17,7 @@ #include "qapi/qmp/qobject.h" struct QString { - QObject_HEAD; + struct QObjectBase_ base; char *string; size_t length; size_t capacity; diff --git a/qemu/qobject/qobject.c b/qemu/qobject/qobject.c index ce13affd..f73e222e 100644 --- a/qemu/qobject/qobject.c +++ b/qemu/qobject/qobject.c @@ -36,9 +36,9 @@ static void (*qdestroy[QTYPE__MAX])(QObject *) = { void qobject_destroy(QObject *obj) { - assert(!obj->refcnt); - assert(QTYPE_QNULL < obj->type && obj->type < QTYPE__MAX); - qdestroy[obj->type](obj); + assert(!obj->base.refcnt); + assert(QTYPE_QNULL < obj->base.type && obj->base.type < QTYPE__MAX); + qdestroy[obj->base.type](obj); } static bool (*qis_equal[QTYPE__MAX])(const QObject *, const QObject *) = { @@ -60,12 +60,11 @@ bool qobject_is_equal(const QObject *x, const QObject *y) return true; } - if (!x || !y || x->type != y->type) { + if (!x || !y || x->base.type != y->base.type) { return false; } - assert(QTYPE_NONE < x->type && x->type < QTYPE__MAX); + assert(QTYPE_NONE < x->base.type && x->base.type < QTYPE__MAX); - return qis_equal[x->type](x, y); + return qis_equal[x->base.type](x, y); } -