From patchwork Fri Aug 28 16:45:48 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 511967 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)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id CE7B114018C for ; Sat, 29 Aug 2015 02:52:58 +1000 (AEST) Received: from localhost ([::1]:48970 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZVMtc-00033h-Uq for incoming@patchwork.ozlabs.org; Fri, 28 Aug 2015 12:52:56 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54240) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZVMn8-0008BW-5z for qemu-devel@nongnu.org; Fri, 28 Aug 2015 12:46:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZVMn6-0000Jj-Fh for qemu-devel@nongnu.org; Fri, 28 Aug 2015 12:46:14 -0400 Received: from mx1.redhat.com ([209.132.183.28]:55858) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZVMn6-0000Iy-2O for qemu-devel@nongnu.org; Fri, 28 Aug 2015 12:46:12 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id BCFC48EA29; Fri, 28 Aug 2015 16:46:11 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-73.ams2.redhat.com [10.36.116.73]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t7SGk9c8015687 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Fri, 28 Aug 2015 12:46:11 -0400 Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 8E8723001106; Fri, 28 Aug 2015 18:46:06 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Fri, 28 Aug 2015 18:45:48 +0200 Message-Id: <1440780366-7177-9-git-send-email-armbru@redhat.com> In-Reply-To: <1440780366-7177-1-git-send-email-armbru@redhat.com> References: <1440780366-7177-1-git-send-email-armbru@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: mdroth@linux.vnet.ibm.com Subject: [Qemu-devel] [PATCH v2 08/26] qapi: Generate a nicer struct for flat unions 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 The struct generated for a flat union is weird: the members of its base are at the end, except for the union tag, which is at the beginning. Example: qapi-schema-test.json has { 'struct': 'UserDefUnionBase', 'data': { 'string': 'str', 'enum1': 'EnumOne' } } { 'union': 'UserDefFlatUnion', 'base': 'UserDefUnionBase', 'discriminator': 'enum1', 'data': { 'value1' : 'UserDefA', 'value2' : 'UserDefB', 'value3' : 'UserDefB' } } We generate: struct UserDefFlatUnion { EnumOne enum1; union { void *data; UserDefA *value1; UserDefB *value2; UserDefB *value3; }; char *string; }; Change to put all base members at the beginning, unadulterated. Not only is this easier to understand, it also permits casting the flat union to its base, if that should become useful. We now generate: struct UserDefFlatUnion { /* Members inherited from UserDefUnionBase: */ char *string; EnumOne enum1; /* Own members: */ union { /* union tag is @enum1 */ void *data; UserDefA *value1; UserDefB *value2; UserDefB *value3; }; }; Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake --- scripts/qapi-types.py | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py index ac8dad3..82141cd 100644 --- a/scripts/qapi-types.py +++ b/scripts/qapi-types.py @@ -200,13 +200,30 @@ def generate_union(expr, meta): ret = mcgen(''' struct %(name)s { - %(discriminator_type_name)s %(discriminator)s; - union { +''', + name=name) + if base: + ret += mcgen(''' + /* Members inherited from %(c_name)s: */ +''', + c_name=c_name(base)) + base_fields = find_struct(base)['data'] + ret += generate_struct_fields(base_fields) + ret += mcgen(''' + /* Own members: */ +''') + else: + assert not discriminator + ret += mcgen(''' + %(discriminator_type_name)s kind; +''', + discriminator_type_name=c_name(discriminator_type_name)) + + ret += mcgen(''' + union { /* union tag is @%(c_name)s */ void *data; ''', - name=name, - discriminator=c_name(discriminator or 'kind'), - discriminator_type_name=c_name(discriminator_type_name)) + c_name=c_name(discriminator or 'kind')) for key in typeinfo: ret += mcgen(''' @@ -217,17 +234,6 @@ struct %(name)s ret += mcgen(''' }; -''') - - if base: - assert discriminator - base_fields = find_struct(base)['data'].copy() - del base_fields[discriminator] - ret += generate_struct_fields(base_fields) - else: - assert not discriminator - - ret += mcgen(''' }; ''') if meta == 'alternate':