From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MWrnX-0000m4-41 for qemu-devel@nongnu.org; Fri, 31 Jul 2009 09:05:23 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MWrnR-0000j9-78 for qemu-devel@nongnu.org; Fri, 31 Jul 2009 09:05:21 -0400 Received: from [199.232.76.173] (port=50623 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MWrnP-0000iL-4T for qemu-devel@nongnu.org; Fri, 31 Jul 2009 09:05:15 -0400 Received: from mx2.redhat.com ([66.187.237.31]:52767) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MWrnO-0004Q4-2K for qemu-devel@nongnu.org; Fri, 31 Jul 2009 09:05:14 -0400 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n6VD5BU2010052 for ; Fri, 31 Jul 2009 09:05:11 -0400 From: Gerd Hoffmann Date: Fri, 31 Jul 2009 15:04:58 +0200 Message-Id: <1249045499-10973-2-git-send-email-kraxel@redhat.com> In-Reply-To: <1249045499-10973-1-git-send-email-kraxel@redhat.com> References: <1249045499-10973-1-git-send-email-kraxel@redhat.com> Subject: [Qemu-devel] [RfC PATCH 1/2] qdev/prop: macros for creating typechecked properties. List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Gerd Hoffmann There are DEFINE_PROP_$TYPE("name", struct, field, default) macros for each property type. These macros link the qdev_prop_$name struct to the type used by that property. typeof(struct->field) is verifyed to be the correct one for the given property. This uses gcc extentions, but as it is a check only it could easily be turned off for non-gcc compilers if needed. The error message given by the compiler isn't that great, I didn't manage to make the compiler print something more helpful than "error: initializer element is not constant". Ideally I'd like to somehow generate a message containing the variable referenced by the macro reference in the failure case, so we could use the variable name to transport the message ... Signed-off-by: Gerd Hoffmann --- hw/qdev-addr.h | 3 +++ hw/qdev.h | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 0 deletions(-) diff --git a/hw/qdev-addr.h b/hw/qdev-addr.h index f02bd7a..9568c27 100644 --- a/hw/qdev-addr.h +++ b/hw/qdev-addr.h @@ -1,2 +1,5 @@ +#define DEFINE_PROP_TADDR(_n, _s, _f) \ + DEFINE_PROP(_n, _s, _f, qdev_prop_taddr, target_phys_addr_t) + extern PropertyInfo qdev_prop_taddr; void qdev_prop_set_taddr(DeviceState *dev, const char *name, target_phys_addr_t value); diff --git a/hw/qdev.h b/hw/qdev.h index b342afb..4fe534e 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -156,6 +156,46 @@ extern PropertyInfo qdev_prop_ptr; extern PropertyInfo qdev_prop_macaddr; extern PropertyInfo qdev_prop_pci_devfn; +extern int qdev_property_type_check_failed; /* undefined */ +#define typeof_field(type, field) typeof(((type *)0)->field) +#define type_check(t1,t2) __builtin_choose_expr( \ + __builtin_types_compatible_p(t1,t2),0,qdev_property_type_check_failed) + +#define DEFINE_PROP(_name, _state, _field, _prop, _type) { \ + .name = (_name), \ + .info = &(_prop), \ + .offset = offsetof(_state, _field) \ + + type_check(_type,typeof_field(_state, _field)), \ + } +#define DEFINE_PROP_DEFAULT(_name, _state, _field, _defval, _prop, _type) { \ + .name = (_name), \ + .info = &(_prop), \ + .offset = offsetof(_state, _field) \ + + type_check(_type,typeof_field(_state, _field)), \ + .defval = (_type[]) { _defval }, \ + } + +#define DEFINE_PROP_UINT16(_n, _s, _f, _d) \ + DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint16, uint16_t) +#define DEFINE_PROP_UINT32(_n, _s, _f, _d) \ + DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint32, uint32_t) +#define DEFINE_PROP_UINT64(_n, _s, _f, _d) \ + DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t) +#define DEFINE_PROP_HEX32(_n, _s, _f, _d) \ + DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex32, uint32_t) +#define DEFINE_PROP_HEX64(_n, _s, _f, _d) \ + DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex64, uint64_t) +#define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d) \ + DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_pci_devfn, uint32_t) + +#define DEFINE_PROP_PTR(_n, _s, _f) \ + DEFINE_PROP(_n, _s, _f, qdev_prop_ptr, void*) +#define DEFINE_PROP_MACADDR(_n, _s, _f) \ + DEFINE_PROP(_n, _s, _f, qdev_prop_macaddr, uint8_t[6]) + +#define DEFINE_PROP_END_OF_LIST() \ + {} + /* Set properties between creation and init. */ void *qdev_get_prop_ptr(DeviceState *dev, Property *prop); int qdev_prop_parse(DeviceState *dev, const char *name, const char *value); -- 1.6.2.5