From patchwork Thu Jul 25 16:42:02 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 261796 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 318492C00C1 for ; Fri, 26 Jul 2013 02:54:51 +1000 (EST) Received: from localhost ([::1]:36135 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V2OoT-0000KH-BR for incoming@patchwork.ozlabs.org; Thu, 25 Jul 2013 12:54:49 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55658) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V2Ony-0000FN-6x for qemu-devel@nongnu.org; Thu, 25 Jul 2013 12:54:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1V2Onu-0006nJ-GP for qemu-devel@nongnu.org; Thu, 25 Jul 2013 12:54:18 -0400 Received: from 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.d.1.0.0.b.8.0.1.0.0.2.ip6.arpa ([2001:8b0:1d0::1]:58953 helo=mnementh.archaic.org.uk) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V2Onu-0006mY-8v for qemu-devel@nongnu.org; Thu, 25 Jul 2013 12:54:14 -0400 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1V2Oc8-0001iV-2Z; Thu, 25 Jul 2013 17:42:04 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Thu, 25 Jul 2013 17:42:02 +0100 Message-Id: <1374770523-6570-2-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1374770523-6570-1-git-send-email-peter.maydell@linaro.org> References: <1374770523-6570-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:8b0:1d0::1 Cc: Alexander Graf , Anthony Liguori , =?UTF-8?q?Andreas=20F=C3=A4rber?= , patches@linaro.org Subject: [Qemu-devel] [RFC 1/2] Provide infrastructure for marking private QOM struct fields X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Provide infrastructure for marking private QOM struct fields, so that a compiler warning is generated when a user of the QOM object attempts to access them directly. This is implemented using GCC's 'deprecated' attribute; preprocessor macros arrange that when compiling the class implementation, no attribute is applied to the fields; when compiling a user of the class the fields are marked deprecated. This allows us to have a single simple C struct defining the object, and for users of the QOM object to be able to embed instances of it into other structs, but still to have a guard against users accidentally touching parts of the structure they should not be accessing. Signed-off-by: Peter Maydell --- include/qemu/compiler.h | 10 ++++++++++ include/qom/object.h | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h index 155b358..d7cc153 100644 --- a/include/qemu/compiler.h +++ b/include/qemu/compiler.h @@ -52,4 +52,14 @@ #define GCC_FMT_ATTR(n, m) #endif +/* An attribute usable to mark structure fields as private to the + * implementation; since this is only a diagnostic to catch programming + * errors, it's OK if it expands to nothing on non-gcc compilers. + */ +#if defined __GNUC__ +# define QEMU_PRIVATE_ATTR __attribute__((deprecated("this field is private"))) +#else +# define QEMU_PRIVATE_ATTR +#endif + #endif /* COMPILER_H */ diff --git a/include/qom/object.h b/include/qom/object.h index 23fc048..7f02f80 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -284,6 +284,53 @@ typedef struct InterfaceInfo InterfaceInfo; * * The first example of such a QOM method was #CPUClass.reset, * another example is #DeviceClass.realize. + * + * = Marking fields as private to the class implementation = + * + * The expected code structure for QOM objects is that they should + * have a header file in include/ which defines the class and object + * structures and the typecasting macros. This header can then be + * included by both the source file which implements the QOM object + * and also by other source files which merely wish to use the object. + * Users of your object need the class and object structures so that + * they can embed instances of the object in their own structures; + * however they do not need to be able to access individual fields in + * these structures. To enforce this you should use the QEMU_PRIVATE_ATTR + * macro in a pattern like this: + * + * + * Marking fields as private + * + * #ifdef IMPLEMENTING_MY_DEVICE + * # define __private + * #else + * # define __private QEMU_PRIVATE_ATTR + * #endif + * + * typedef struct MyDevice + * { + * __private DeviceState parent; + * + * __private int reg0, reg1, reg2; + * } MyDevice; + * + * typedef struct MyDeviceClass + * { + * __private DeviceClass parent; + * + * void (*frobnicate) (MyDevice *obj); + * } MyDeviceClass; + * + * #undef __private + * + * + * + * The source files which provide the implementation of your + * class (or of subclasses to it) should then have + * "#define IMPLEMENTING_MY_DEVICE" before they include any + * headers. Since users of the class will not define this + * macro, they will get a compilation warning if they access + * any of the private fields by mistake. */