Message ID | 20201023101222.250147-4-kwolf@redhat.com |
---|---|
State | New |
Headers | show |
Series | qemu-storage-daemon: QAPIfy --chardev | expand |
Hi On Fri, Oct 23, 2020 at 2:14 PM Kevin Wolf <kwolf@redhat.com> wrote: > Variants of simple unions are always contained in a wrapper object > called 'data' that serves no real use. When mapping a QAPI object to the > command line, this becomes very visible to users because they have to > add one or more useless 'data.' to many option names. > > As a first step towards avoiding this painful CLI experience, this gets > rid of the 'data' indirection internally: The QAPI parser doesn't use a > wrapper object as the variant type any more, so the indirection is > removed from the generated C types. As a result, the C type looks the > same for flat and simple unions now. A large part of this patch is > mechanical conversion of C code to remove the 'data' indirection. > > Conceptually, the important change is that variants can now have flat > and wrapped representations. For a transitioning period, we'll allow > variants to support both representations in a later patch. Eventually, > the plan is to deprecate and remove wrapped representations entirely, > unifying simple and flat unions. > > The externally visible interfaces stay unchanged: Visitors still expect > the 'data' wrappers, and introspection still shows it. > > Signed-off-by: Kevin Wolf <kwolf@redhat.com> > breaks the build for me: ../chardev/spice.c: In function ‘qemu_chr_open_spice_vmc’: ../chardev/spice.c:261:56: error: ‘ChardevSpiceChannel’ has no member named ‘data’ 261 | ChardevSpiceChannel *spicevmc = backend->u.spicevmc.data; | ^ ../chardev/spice.c: In function ‘qemu_chr_open_spice_port’: ../chardev/spice.c:297:55: error: ‘ChardevSpicePort’ has no member named ‘data’ 297 | ChardevSpicePort *spiceport = backend->u.spiceport.data; | ^ ../chardev/spice.c: In function ‘qemu_chr_parse_spice_vmc’: ../chardev/spice.c:331:35: error: ‘ChardevSpiceChannel’ has no member named ‘data’ 331 | spicevmc = backend->u.spicevmc.data = g_new0(ChardevSpiceChannel, 1); | ^ ../chardev/spice.c: In function ‘qemu_chr_parse_spice_port’: ../chardev/spice.c:347:37: error: ‘ChardevSpicePort’ has no member named ‘data’ 347 | spiceport = backend->u.spiceport.data = g_new0(ChardevSpicePort, 1); | ^ ../ui/spice-app.c: In function ‘chr_spice_backend_new’: ../ui/spice-app.c:63:20: error: ‘ChardevSpicePort’ has no member named ‘data’ 63 | be->u.spiceport.data = g_new0(ChardevSpicePort, 1); | ^ ../ui/spice-app.c: In function ‘vc_chr_open’: ../ui/spice-app.c:86:20: error: ‘ChardevSpicePort’ has no member named ‘data’ 86 | be->u.spiceport.data->fqdn = fqdn ? | ^ ../ui/spice-app.c: In function ‘spice_app_display_init’: ../ui/spice-app.c:185:20: error: ‘ChardevSpicePort’ has no member named ‘data’ 185 | be->u.spiceport.data->fqdn = g_strdup("org.qemu.monitor.qmp.0"); | ^ > --- > docs/devel/qapi-code-gen.txt | 32 ++++++++---- > backends/tpm/tpm_emulator.c | 3 +- > backends/tpm/tpm_passthrough.c | 4 +- > block/crypto.c | 3 +- > block/qcow2.c | 9 ++-- > block/vmdk.c | 14 ++---- > blockdev.c | 36 ++++++------- > chardev/char-file.c | 5 +- > chardev/char-mux.c | 5 +- > chardev/char-parallel.c | 5 +- > chardev/char-pipe.c | 7 ++- > chardev/char-ringbuf.c | 5 +- > chardev/char-serial.c | 5 +- > chardev/char-socket.c | 13 ++--- > chardev/char-stdio.c | 5 +- > chardev/char-udp.c | 11 ++-- > chardev/char.c | 10 ++-- > chardev/msmouse.c | 4 +- > chardev/wctablet.c | 4 +- > hw/core/numa.c | 6 +-- > hw/display/xenfb.c | 8 +-- > hw/input/hid.c | 8 +-- > hw/input/ps2.c | 6 +-- > hw/input/virtio-input-hid.c | 8 +-- > hw/mem/pc-dimm.c | 18 +++---- > hw/virtio/virtio-mem-pci.c | 3 +- > hw/virtio/virtio-pmem-pci.c | 3 +- > monitor/hmp-cmds.c | 14 +++--- > qemu-keymap.c | 2 +- > replay/replay-input.c | 46 +++++++---------- > tests/test-char.c | 12 ++--- > tests/test-clone-visitor.c | 14 +++--- > tests/test-qmp-cmds.c | 2 +- > tests/test-qobject-input-visitor.c | 24 ++++----- > tests/test-qobject-output-visitor.c | 24 ++++----- > ui/console.c | 5 +- > ui/input-keymap.c | 12 ++--- > ui/input-legacy.c | 12 ++--- > ui/input.c | 43 ++++++++-------- > util/qemu-sockets.c | 8 +-- > scripts/qapi/introspect.py | 7 ++- > scripts/qapi/schema.py | 48 ++++++++++++++---- > scripts/qapi/visit.py | 28 +++++++++++ > tests/qapi-schema/doc-good.out | 8 +-- > tests/qapi-schema/qapi-schema-test.out | 70 +++++++------------------- > 45 files changed, 308 insertions(+), 311 deletions(-) > > diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt > index c6438c6aa9..9722c1a204 100644 > --- a/docs/devel/qapi-code-gen.txt > +++ b/docs/devel/qapi-code-gen.txt > @@ -310,7 +310,20 @@ The BRANCH's STRING name is the branch name. > The BRANCH's value defines the branch's properties, in particular its > type. The form TYPE-REF is shorthand for { 'type': TYPE-REF }. > > -A simple union type defines a mapping from automatic discriminator > +Each branch can have flat or wrapped representation in the Client JSON > +Protocol. > + > +Wrapped representation of a branch means that it is represented by a > +'data' member that is of the specified data type corresponding to the > +discriminator value. > + > +Flat representation means that the union forms a single object that > +contains both common members (from the base type) and the selected > +branch's members, without any additional nesting. The two sets of > +member names must be disjoint. > + > +A simple union type automatically contains the 'type' member as a > +discriminator and defines a mapping from automatic discriminator > values to data types like in this example: > > { 'struct': 'BlockdevOptionsFile', 'data': { 'filename': 'str' } } > @@ -321,10 +334,8 @@ values to data types like in this example: > 'data': { 'file': 'BlockdevOptionsFile', > 'qcow2': 'BlockdevOptionsQcow2' } } > > -In the Client JSON Protocol, a simple union is represented by an > -object that contains the 'type' member as a discriminator, and a > -'data' member that is of the specified data type corresponding to the > -discriminator value, as in these examples: > +In the Client JSON Protocol, all simple union branches have wrapped > +representation, as in these examples: > > { "type": "file", "data": { "filename": "/some/place/my-image" } } > { "type": "qcow2", "data": { "backing": "/some/place/my-image", > @@ -344,13 +355,12 @@ object, it defines common members just like a struct > type's 'data' > member defines struct type members. If it is a STRING, it names a > struct type whose members are the common members. > > -All flat union branches must be of struct type. > +Member 'discriminator' must name a non-optional enum-typed member of > +the base struct and defines the option that should server as the > +discrimiator. > > -In the Client JSON Protocol, a flat union is represented by an object > -with the common members (from the base type) and the selected branch's > -members. The two sets of member names must be disjoint. Member > -'discriminator' must name a non-optional enum-typed member of the base > -struct. > +All flat union branches must be of struct type. They have always flat > +representation. > > The following example enhances the above simple union example by > adding an optional common member 'read-only', renaming the > diff --git a/backends/tpm/tpm_emulator.c b/backends/tpm/tpm_emulator.c > index 201cd38503..7d2dc2b19d 100644 > --- a/backends/tpm/tpm_emulator.c > +++ b/backends/tpm/tpm_emulator.c > @@ -629,7 +629,8 @@ static TpmTypeOptions > *tpm_emulator_get_tpm_options(TPMBackend *tb) > TpmTypeOptions *options = g_new0(TpmTypeOptions, 1); > > options->type = TPM_TYPE_OPTIONS_KIND_EMULATOR; > - options->u.emulator.data = QAPI_CLONE(TPMEmulatorOptions, > tpm_emu->options); > + QAPI_CLONE_MEMBERS(TPMEmulatorOptions, &options->u.emulator, > + tpm_emu->options); > > return options; > } > diff --git a/backends/tpm/tpm_passthrough.c > b/backends/tpm/tpm_passthrough.c > index 8f6f4998a5..7fa7c84f5a 100644 > --- a/backends/tpm/tpm_passthrough.c > +++ b/backends/tpm/tpm_passthrough.c > @@ -322,8 +322,8 @@ static TpmTypeOptions > *tpm_passthrough_get_tpm_options(TPMBackend *tb) > TpmTypeOptions *options = g_new0(TpmTypeOptions, 1); > > options->type = TPM_TYPE_OPTIONS_KIND_PASSTHROUGH; > - options->u.passthrough.data = QAPI_CLONE(TPMPassthroughOptions, > - > TPM_PASSTHROUGH(tb)->options); > + QAPI_CLONE_MEMBERS(TPMPassthroughOptions, &options->u.passthrough, > + TPM_PASSTHROUGH(tb)->options); > > return options; > } > diff --git a/block/crypto.c b/block/crypto.c > index 0807557763..0e7838d70a 100644 > --- a/block/crypto.c > +++ b/block/crypto.c > @@ -775,8 +775,7 @@ block_crypto_get_specific_info_luks(BlockDriverState > *bs, Error **errp) > > spec_info = g_new(ImageInfoSpecific, 1); > spec_info->type = IMAGE_INFO_SPECIFIC_KIND_LUKS; > - spec_info->u.luks.data = g_new(QCryptoBlockInfoLUKS, 1); > - *spec_info->u.luks.data = info->u.luks; > + spec_info->u.luks = info->u.luks; > > /* Blank out pointers we've just stolen to avoid double free */ > memset(&info->u.luks, 0, sizeof(info->u.luks)); > diff --git a/block/qcow2.c b/block/qcow2.c > index b05512718c..104fd8ad06 100644 > --- a/block/qcow2.c > +++ b/block/qcow2.c > @@ -5052,10 +5052,9 @@ static ImageInfoSpecific > *qcow2_get_specific_info(BlockDriverState *bs, > spec_info = g_new(ImageInfoSpecific, 1); > *spec_info = (ImageInfoSpecific){ > .type = IMAGE_INFO_SPECIFIC_KIND_QCOW2, > - .u.qcow2.data = g_new0(ImageInfoSpecificQCow2, 1), > }; > if (s->qcow_version == 2) { > - *spec_info->u.qcow2.data = (ImageInfoSpecificQCow2){ > + spec_info->u.qcow2 = (ImageInfoSpecificQCow2){ > .compat = g_strdup("0.10"), > .refcount_bits = s->refcount_bits, > }; > @@ -5068,7 +5067,7 @@ static ImageInfoSpecific > *qcow2_get_specific_info(BlockDriverState *bs, > qapi_free_QCryptoBlockInfo(encrypt_info); > return NULL; > } > - *spec_info->u.qcow2.data = (ImageInfoSpecificQCow2){ > + spec_info->u.qcow2 = (ImageInfoSpecificQCow2){ > .compat = g_strdup("1.1"), > .lazy_refcounts = s->compatible_features & > QCOW2_COMPAT_LAZY_REFCOUNTS, > @@ -5112,8 +5111,8 @@ static ImageInfoSpecific > *qcow2_get_specific_info(BlockDriverState *bs, > memset(&encrypt_info->u, 0, sizeof(encrypt_info->u)); > qapi_free_QCryptoBlockInfo(encrypt_info); > > - spec_info->u.qcow2.data->has_encrypt = true; > - spec_info->u.qcow2.data->encrypt = qencrypt; > + spec_info->u.qcow2.has_encrypt = true; > + spec_info->u.qcow2.encrypt = qencrypt; > } > > return spec_info; > diff --git a/block/vmdk.c b/block/vmdk.c > index a00dc00eb4..fc4ddcc351 100644 > --- a/block/vmdk.c > +++ b/block/vmdk.c > @@ -2932,18 +2932,14 @@ static ImageInfoSpecific > *vmdk_get_specific_info(BlockDriverState *bs, > > *spec_info = (ImageInfoSpecific){ > .type = IMAGE_INFO_SPECIFIC_KIND_VMDK, > - .u = { > - .vmdk.data = g_new0(ImageInfoSpecificVmdk, 1), > + .u.vmdk = (ImageInfoSpecificVmdk) { > + .create_type = g_strdup(s->create_type), > + .cid = s->cid, > + .parent_cid = s->parent_cid, > }, > }; > > - *spec_info->u.vmdk.data = (ImageInfoSpecificVmdk) { > - .create_type = g_strdup(s->create_type), > - .cid = s->cid, > - .parent_cid = s->parent_cid, > - }; > - > - next = &spec_info->u.vmdk.data->extents; > + next = &spec_info->u.vmdk.extents; > for (i = 0; i < s->num_extents; i++) { > *next = g_new0(ImageInfoList, 1); > (*next)->value = vmdk_get_extent_info(&s->extents[i]); > diff --git a/blockdev.c b/blockdev.c > index fe6fb5dc1d..2602298a26 100644 > --- a/blockdev.c > +++ b/blockdev.c > @@ -1090,7 +1090,7 @@ void qmp_blockdev_snapshot_sync(bool has_device, > const char *device, > }; > TransactionAction action = { > .type = TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC, > - .u.blockdev_snapshot_sync.data = &snapshot, > + .u.blockdev_snapshot_sync = snapshot, > }; > blockdev_do_action(&action, errp); > } > @@ -1104,7 +1104,7 @@ void qmp_blockdev_snapshot(const char *node, const > char *overlay, > }; > TransactionAction action = { > .type = TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT, > - .u.blockdev_snapshot.data = &snapshot_data, > + .u.blockdev_snapshot = snapshot_data, > }; > blockdev_do_action(&action, errp); > } > @@ -1119,7 +1119,7 @@ void qmp_blockdev_snapshot_internal_sync(const char > *device, > }; > TransactionAction action = { > .type = TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC, > - .u.blockdev_snapshot_internal_sync.data = &snapshot, > + .u.blockdev_snapshot_internal_sync = snapshot, > }; > blockdev_do_action(&action, errp); > } > @@ -1289,7 +1289,7 @@ static void internal_snapshot_prepare(BlkActionState > *common, > > g_assert(common->action->type == > TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC); > - internal = common->action->u.blockdev_snapshot_internal_sync.data; > + internal = &common->action->u.blockdev_snapshot_internal_sync; > state = DO_UPCAST(InternalSnapshotState, common, common); > > /* 1. parse input */ > @@ -1453,7 +1453,7 @@ static void external_snapshot_prepare(BlkActionState > *common, > switch (action->type) { > case TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT: > { > - BlockdevSnapshot *s = action->u.blockdev_snapshot.data; > + BlockdevSnapshot *s = &action->u.blockdev_snapshot; > device = s->node; > node_name = s->node; > new_image_file = NULL; > @@ -1462,7 +1462,7 @@ static void external_snapshot_prepare(BlkActionState > *common, > break; > case TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC: > { > - BlockdevSnapshotSync *s = > action->u.blockdev_snapshot_sync.data; > + BlockdevSnapshotSync *s = &action->u.blockdev_snapshot_sync; > device = s->has_device ? s->device : NULL; > node_name = s->has_node_name ? s->node_name : NULL; > new_image_file = s->snapshot_file; > @@ -1507,7 +1507,7 @@ static void external_snapshot_prepare(BlkActionState > *common, > } > > if (action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC) { > - BlockdevSnapshotSync *s = action->u.blockdev_snapshot_sync.data; > + BlockdevSnapshotSync *s = &action->u.blockdev_snapshot_sync; > const char *format = s->has_format ? s->format : "qcow2"; > enum NewImageMode mode; > const char *snapshot_node_name = > @@ -1712,7 +1712,7 @@ static void drive_backup_prepare(BlkActionState > *common, Error **errp) > int ret; > > assert(common->action->type == TRANSACTION_ACTION_KIND_DRIVE_BACKUP); > - backup = common->action->u.drive_backup.data; > + backup = &common->action->u.drive_backup; > > if (!backup->has_mode) { > backup->mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS; > @@ -1907,7 +1907,7 @@ static void blockdev_backup_prepare(BlkActionState > *common, Error **errp) > int ret; > > assert(common->action->type == > TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP); > - backup = common->action->u.blockdev_backup.data; > + backup = &common->action->u.blockdev_backup; > > bs = bdrv_lookup_bs(backup->device, backup->device, errp); > if (!bs) { > @@ -2012,7 +2012,7 @@ static void > block_dirty_bitmap_add_prepare(BlkActionState *common, > return; > } > > - action = common->action->u.block_dirty_bitmap_add.data; > + action = &common->action->u.block_dirty_bitmap_add; > /* AIO context taken and released within qmp_block_dirty_bitmap_add */ > qmp_block_dirty_bitmap_add(action->node, action->name, > action->has_granularity, > action->granularity, > @@ -2033,7 +2033,7 @@ static void > block_dirty_bitmap_add_abort(BlkActionState *common) > BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState, > common, common); > > - action = common->action->u.block_dirty_bitmap_add.data; > + action = &common->action->u.block_dirty_bitmap_add; > /* Should not be able to fail: IF the bitmap was added via .prepare(), > * then the node reference and bitmap name must have been valid. > */ > @@ -2053,7 +2053,7 @@ static void > block_dirty_bitmap_clear_prepare(BlkActionState *common, > return; > } > > - action = common->action->u.block_dirty_bitmap_clear.data; > + action = &common->action->u.block_dirty_bitmap_clear; > state->bitmap = block_dirty_bitmap_lookup(action->node, > action->name, > &state->bs, > @@ -2098,7 +2098,7 @@ static void > block_dirty_bitmap_enable_prepare(BlkActionState *common, > return; > } > > - action = common->action->u.block_dirty_bitmap_enable.data; > + action = &common->action->u.block_dirty_bitmap_enable; > state->bitmap = block_dirty_bitmap_lookup(action->node, > action->name, > NULL, > @@ -2136,7 +2136,7 @@ static void > block_dirty_bitmap_disable_prepare(BlkActionState *common, > return; > } > > - action = common->action->u.block_dirty_bitmap_disable.data; > + action = &common->action->u.block_dirty_bitmap_disable; > state->bitmap = block_dirty_bitmap_lookup(action->node, > action->name, > NULL, > @@ -2174,7 +2174,7 @@ static void > block_dirty_bitmap_merge_prepare(BlkActionState *common, > return; > } > > - action = common->action->u.block_dirty_bitmap_merge.data; > + action = &common->action->u.block_dirty_bitmap_merge; > > state->bitmap = block_dirty_bitmap_merge(action->node, action->target, > action->bitmaps, > &state->backup, > @@ -2192,7 +2192,7 @@ static void > block_dirty_bitmap_remove_prepare(BlkActionState *common, > return; > } > > - action = common->action->u.block_dirty_bitmap_remove.data; > + action = &common->action->u.block_dirty_bitmap_remove; > > state->bitmap = block_dirty_bitmap_remove(action->node, action->name, > false, &state->bs, errp); > @@ -2895,7 +2895,7 @@ void qmp_drive_backup(DriveBackup *backup, Error > **errp) > { > TransactionAction action = { > .type = TRANSACTION_ACTION_KIND_DRIVE_BACKUP, > - .u.drive_backup.data = backup, > + .u.drive_backup = *backup, > }; > blockdev_do_action(&action, errp); > } > @@ -2918,7 +2918,7 @@ void qmp_blockdev_backup(BlockdevBackup *backup, > Error **errp) > { > TransactionAction action = { > .type = TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP, > - .u.blockdev_backup.data = backup, > + .u.blockdev_backup = *backup, > }; > blockdev_do_action(&action, errp); > } > diff --git a/chardev/char-file.c b/chardev/char-file.c > index 2fd80707e5..3f0f0b6045 100644 > --- a/chardev/char-file.c > +++ b/chardev/char-file.c > @@ -39,7 +39,7 @@ static void qmp_chardev_open_file(Chardev *chr, > bool *be_opened, > Error **errp) > { > - ChardevFile *file = backend->u.file.data; > + ChardevFile *file = &backend->u.file; > #ifdef _WIN32 > HANDLE out; > DWORD accessmode; > @@ -100,14 +100,13 @@ static void qemu_chr_parse_file_out(QemuOpts *opts, > ChardevBackend *backend, > Error **errp) > { > const char *path = qemu_opt_get(opts, "path"); > - ChardevFile *file; > + ChardevFile *file = &backend->u.file; > > backend->type = CHARDEV_BACKEND_KIND_FILE; > if (path == NULL) { > error_setg(errp, "chardev: file: no filename given"); > return; > } > - file = backend->u.file.data = g_new0(ChardevFile, 1); > qemu_chr_parse_common(opts, qapi_ChardevFile_base(file)); > file->out = g_strdup(path); > > diff --git a/chardev/char-mux.c b/chardev/char-mux.c > index 6f980bb836..bfb4bc6b8b 100644 > --- a/chardev/char-mux.c > +++ b/chardev/char-mux.c > @@ -314,7 +314,7 @@ static void qemu_chr_open_mux(Chardev *chr, > bool *be_opened, > Error **errp) > { > - ChardevMux *mux = backend->u.mux.data; > + ChardevMux *mux = &backend->u.mux; > Chardev *drv; > MuxChardev *d = MUX_CHARDEV(chr); > > @@ -336,14 +336,13 @@ static void qemu_chr_parse_mux(QemuOpts *opts, > ChardevBackend *backend, > Error **errp) > { > const char *chardev = qemu_opt_get(opts, "chardev"); > - ChardevMux *mux; > + ChardevMux *mux = &backend->u.mux; > > if (chardev == NULL) { > error_setg(errp, "chardev: mux: no chardev given"); > return; > } > backend->type = CHARDEV_BACKEND_KIND_MUX; > - mux = backend->u.mux.data = g_new0(ChardevMux, 1); > qemu_chr_parse_common(opts, qapi_ChardevMux_base(mux)); > mux->chardev = g_strdup(chardev); > } > diff --git a/chardev/char-parallel.c b/chardev/char-parallel.c > index 05e7efbd6c..a17157a3be 100644 > --- a/chardev/char-parallel.c > +++ b/chardev/char-parallel.c > @@ -244,7 +244,7 @@ static void qmp_chardev_open_parallel(Chardev *chr, > bool *be_opened, > Error **errp) > { > - ChardevHostdev *parallel = backend->u.parallel.data; > + ChardevHostdev *parallel = &backend->u.parallel; > int fd; > > fd = qmp_chardev_open_file_source(parallel->device, O_RDWR, errp); > @@ -258,14 +258,13 @@ static void qemu_chr_parse_parallel(QemuOpts *opts, > ChardevBackend *backend, > Error **errp) > { > const char *device = qemu_opt_get(opts, "path"); > - ChardevHostdev *parallel; > + ChardevHostdev *parallel = &backend->u.parallel; > > if (device == NULL) { > error_setg(errp, "chardev: parallel: no device path given"); > return; > } > backend->type = CHARDEV_BACKEND_KIND_PARALLEL; > - parallel = backend->u.parallel.data = g_new0(ChardevHostdev, 1); > qemu_chr_parse_common(opts, qapi_ChardevHostdev_base(parallel)); > parallel->device = g_strdup(device); > } > diff --git a/chardev/char-pipe.c b/chardev/char-pipe.c > index 7eca5d9a56..eb19d9a526 100644 > --- a/chardev/char-pipe.c > +++ b/chardev/char-pipe.c > @@ -109,7 +109,7 @@ static void qemu_chr_open_pipe(Chardev *chr, > bool *be_opened, > Error **errp) > { > - ChardevHostdev *opts = backend->u.pipe.data; > + ChardevHostdev *opts = &backend->u.pipe; > const char *filename = opts->device; > > if (win_chr_pipe_init(chr, filename, errp) < 0) { > @@ -124,7 +124,7 @@ static void qemu_chr_open_pipe(Chardev *chr, > bool *be_opened, > Error **errp) > { > - ChardevHostdev *opts = backend->u.pipe.data; > + ChardevHostdev *opts = &backend->u.pipe; > int fd_in, fd_out; > char *filename_in; > char *filename_out; > @@ -158,14 +158,13 @@ static void qemu_chr_parse_pipe(QemuOpts *opts, > ChardevBackend *backend, > Error **errp) > { > const char *device = qemu_opt_get(opts, "path"); > - ChardevHostdev *dev; > + ChardevHostdev *dev = &backend->u.pipe; > > if (device == NULL) { > error_setg(errp, "chardev: pipe: no device path given"); > return; > } > backend->type = CHARDEV_BACKEND_KIND_PIPE; > - dev = backend->u.pipe.data = g_new0(ChardevHostdev, 1); > qemu_chr_parse_common(opts, qapi_ChardevHostdev_base(dev)); > dev->device = g_strdup(device); > } > diff --git a/chardev/char-ringbuf.c b/chardev/char-ringbuf.c > index d40d21d3cf..0ef2a17f90 100644 > --- a/chardev/char-ringbuf.c > +++ b/chardev/char-ringbuf.c > @@ -97,7 +97,7 @@ static void qemu_chr_open_ringbuf(Chardev *chr, > bool *be_opened, > Error **errp) > { > - ChardevRingbuf *opts = backend->u.ringbuf.data; > + ChardevRingbuf *opts = &backend->u.ringbuf; > RingBufChardev *d = RINGBUF_CHARDEV(chr); > > d->size = opts->has_size ? opts->size : 65536; > @@ -210,10 +210,9 @@ static void qemu_chr_parse_ringbuf(QemuOpts *opts, > ChardevBackend *backend, > Error **errp) > { > int val; > - ChardevRingbuf *ringbuf; > + ChardevRingbuf *ringbuf = &backend->u.ringbuf; > > backend->type = CHARDEV_BACKEND_KIND_RINGBUF; > - ringbuf = backend->u.ringbuf.data = g_new0(ChardevRingbuf, 1); > qemu_chr_parse_common(opts, qapi_ChardevRingbuf_base(ringbuf)); > > val = qemu_opt_get_size(opts, "size", 0); > diff --git a/chardev/char-serial.c b/chardev/char-serial.c > index 7c3d84ae24..baec955ecf 100644 > --- a/chardev/char-serial.c > +++ b/chardev/char-serial.c > @@ -263,7 +263,7 @@ static void qmp_chardev_open_serial(Chardev *chr, > bool *be_opened, > Error **errp) > { > - ChardevHostdev *serial = backend->u.serial.data; > + ChardevHostdev *serial = &backend->u.serial; > int fd; > > fd = qmp_chardev_open_file_source(serial->device, O_RDWR | O_NONBLOCK, > @@ -283,14 +283,13 @@ static void qemu_chr_parse_serial(QemuOpts *opts, > ChardevBackend *backend, > Error **errp) > { > const char *device = qemu_opt_get(opts, "path"); > - ChardevHostdev *serial; > + ChardevHostdev *serial = &backend->u.serial; > > if (device == NULL) { > error_setg(errp, "chardev: serial/tty: no device path given"); > return; > } > backend->type = CHARDEV_BACKEND_KIND_SERIAL; > - serial = backend->u.serial.data = g_new0(ChardevHostdev, 1); > qemu_chr_parse_common(opts, qapi_ChardevHostdev_base(serial)); > serial->device = g_strdup(device); > } > diff --git a/chardev/char-socket.c b/chardev/char-socket.c > index 95e45812d5..5332439d34 100644 > --- a/chardev/char-socket.c > +++ b/chardev/char-socket.c > @@ -1301,7 +1301,7 @@ static void qmp_chardev_open_socket(Chardev *chr, > Error **errp) > { > SocketChardev *s = SOCKET_CHARDEV(chr); > - ChardevSocket *sock = backend->u.socket.data; > + ChardevSocket *sock = &backend->u.socket; > bool do_nodelay = sock->has_nodelay ? sock->nodelay : false; > bool is_listen = sock->has_server ? sock->server : true; > bool is_telnet = sock->has_telnet ? sock->telnet : false; > @@ -1403,7 +1403,7 @@ static void qemu_chr_parse_socket(QemuOpts *opts, > ChardevBackend *backend, > } > > backend->type = CHARDEV_BACKEND_KIND_SOCKET; > - sock = backend->u.socket.data = g_new0(ChardevSocket, 1); > + sock = &backend->u.socket; > qemu_chr_parse_common(opts, qapi_ChardevSocket_base(sock)); > > sock->has_nodelay = qemu_opt_get(opts, "delay"); > @@ -1435,16 +1435,14 @@ static void qemu_chr_parse_socket(QemuOpts *opts, > ChardevBackend *backend, > > addr = g_new0(SocketAddressLegacy, 1); > if (path) { > - UnixSocketAddress *q_unix; > + UnixSocketAddress *q_unix = &addr->u.q_unix; > addr->type = SOCKET_ADDRESS_LEGACY_KIND_UNIX; > - q_unix = addr->u.q_unix.data = g_new0(UnixSocketAddress, 1); > q_unix->path = g_strdup(path); > q_unix->tight = tight; > q_unix->abstract = abstract; > } else if (host) { > addr->type = SOCKET_ADDRESS_LEGACY_KIND_INET; > - addr->u.inet.data = g_new(InetSocketAddress, 1); > - *addr->u.inet.data = (InetSocketAddress) { > + addr->u.inet = (InetSocketAddress) { > .host = g_strdup(host), > .port = g_strdup(port), > .has_to = qemu_opt_get(opts, "to"), > @@ -1456,8 +1454,7 @@ static void qemu_chr_parse_socket(QemuOpts *opts, > ChardevBackend *backend, > }; > } else if (fd) { > addr->type = SOCKET_ADDRESS_LEGACY_KIND_FD; > - addr->u.fd.data = g_new(String, 1); > - addr->u.fd.data->str = g_strdup(fd); > + addr->u.fd.str = g_strdup(fd); > } else { > g_assert_not_reached(); > } > diff --git a/chardev/char-stdio.c b/chardev/char-stdio.c > index 403da308c9..81ee655a21 100644 > --- a/chardev/char-stdio.c > +++ b/chardev/char-stdio.c > @@ -87,7 +87,7 @@ static void qemu_chr_open_stdio(Chardev *chr, > bool *be_opened, > Error **errp) > { > - ChardevStdio *opts = backend->u.stdio.data; > + ChardevStdio *opts = &backend->u.stdio; > struct sigaction act; > > if (is_daemonized()) { > @@ -120,10 +120,9 @@ static void qemu_chr_open_stdio(Chardev *chr, > static void qemu_chr_parse_stdio(QemuOpts *opts, ChardevBackend *backend, > Error **errp) > { > - ChardevStdio *stdio; > + ChardevStdio *stdio = &backend->u.stdio; > > backend->type = CHARDEV_BACKEND_KIND_STDIO; > - stdio = backend->u.stdio.data = g_new0(ChardevStdio, 1); > qemu_chr_parse_common(opts, qapi_ChardevStdio_base(stdio)); > stdio->has_signal = true; > stdio->signal = qemu_opt_get_bool(opts, "signal", true); > diff --git a/chardev/char-udp.c b/chardev/char-udp.c > index 16b5dbce58..3b1bdddbbd 100644 > --- a/chardev/char-udp.c > +++ b/chardev/char-udp.c > @@ -140,7 +140,7 @@ static void qemu_chr_parse_udp(QemuOpts *opts, > ChardevBackend *backend, > const char *localport = qemu_opt_get(opts, "localport"); > bool has_local = false; > SocketAddressLegacy *addr; > - ChardevUdp *udp; > + ChardevUdp *udp = &backend->u.udp; > > backend->type = CHARDEV_BACKEND_KIND_UDP; > if (host == NULL || strlen(host) == 0) { > @@ -161,13 +161,11 @@ static void qemu_chr_parse_udp(QemuOpts *opts, > ChardevBackend *backend, > has_local = true; > } > > - udp = backend->u.udp.data = g_new0(ChardevUdp, 1); > qemu_chr_parse_common(opts, qapi_ChardevUdp_base(udp)); > > addr = g_new0(SocketAddressLegacy, 1); > addr->type = SOCKET_ADDRESS_LEGACY_KIND_INET; > - addr->u.inet.data = g_new(InetSocketAddress, 1); > - *addr->u.inet.data = (InetSocketAddress) { > + addr->u.inet = (InetSocketAddress) { > .host = g_strdup(host), > .port = g_strdup(port), > .has_ipv4 = qemu_opt_get(opts, "ipv4"), > @@ -181,8 +179,7 @@ static void qemu_chr_parse_udp(QemuOpts *opts, > ChardevBackend *backend, > udp->has_local = true; > addr = g_new0(SocketAddressLegacy, 1); > addr->type = SOCKET_ADDRESS_LEGACY_KIND_INET; > - addr->u.inet.data = g_new(InetSocketAddress, 1); > - *addr->u.inet.data = (InetSocketAddress) { > + addr->u.inet = (InetSocketAddress) { > .host = g_strdup(localaddr), > .port = g_strdup(localport), > }; > @@ -195,7 +192,7 @@ static void qmp_chardev_open_udp(Chardev *chr, > bool *be_opened, > Error **errp) > { > - ChardevUdp *udp = backend->u.udp.data; > + ChardevUdp *udp = &backend->u.udp; > SocketAddress *local_addr = socket_address_flatten(udp->local); > SocketAddress *remote_addr = socket_address_flatten(udp->remote); > QIOChannelSocket *sioc = qio_channel_socket_new(); > diff --git a/chardev/char.c b/chardev/char.c > index 028612c333..5192964694 100644 > --- a/chardev/char.c > +++ b/chardev/char.c > @@ -238,7 +238,7 @@ static void qemu_char_open(Chardev *chr, > ChardevBackend *backend, > { > ChardevClass *cc = CHARDEV_GET_CLASS(chr); > /* Any ChardevCommon member would work */ > - ChardevCommon *common = backend ? backend->u.null.data : NULL; > + ChardevCommon *common = backend ? &backend->u.null : NULL; > > if (common && common->has_logfile) { > int flags = O_WRONLY | O_CREAT; > @@ -625,9 +625,8 @@ ChardevBackend *qemu_chr_parse_opts(QemuOpts *opts, > Error **errp) > return NULL; > } > } else { > - ChardevCommon *ccom = g_new0(ChardevCommon, 1); > - qemu_chr_parse_common(opts, ccom); > - backend->u.null.data = ccom; /* Any ChardevCommon member would > work */ > + /* Any ChardevCommon member would work */ > + qemu_chr_parse_common(opts, &backend->u.null); > } > > return backend; > @@ -690,8 +689,7 @@ Chardev *qemu_chr_new_from_opts(QemuOpts *opts, > GMainContext *context, > qapi_free_ChardevBackend(backend); > backend = g_new0(ChardevBackend, 1); > backend->type = CHARDEV_BACKEND_KIND_MUX; > - backend->u.mux.data = g_new0(ChardevMux, 1); > - backend->u.mux.data->chardev = g_strdup(bid); > + backend->u.mux.chardev = g_strdup(bid); > mux = qemu_chardev_new(id, TYPE_CHARDEV_MUX, backend, context, > errp); > if (mux == NULL) { > object_unparent(OBJECT(chr)); > diff --git a/chardev/msmouse.c b/chardev/msmouse.c > index eb9231dcdb..98b0ef8cd7 100644 > --- a/chardev/msmouse.c > +++ b/chardev/msmouse.c > @@ -111,12 +111,12 @@ static void msmouse_input_event(DeviceState *dev, > QemuConsole *src, > > switch (evt->type) { > case INPUT_EVENT_KIND_REL: > - move = evt->u.rel.data; > + move = &evt->u.rel; > mouse->axis[move->axis] += move->value; > break; > > case INPUT_EVENT_KIND_BTN: > - btn = evt->u.btn.data; > + btn = &evt->u.btn; > mouse->btns[btn->button] = btn->down; > mouse->btnc[btn->button] = true; > break; > diff --git a/chardev/wctablet.c b/chardev/wctablet.c > index 95e005f5a5..8479f59183 100644 > --- a/chardev/wctablet.c > +++ b/chardev/wctablet.c > @@ -154,12 +154,12 @@ static void wctablet_input_event(DeviceState *dev, > QemuConsole *src, > > switch (evt->type) { > case INPUT_EVENT_KIND_ABS: > - move = evt->u.abs.data; > + move = &evt->u.abs; > tablet->axis[move->axis] = move->value; > break; > > case INPUT_EVENT_KIND_BTN: > - btn = evt->u.btn.data; > + btn = &evt->u.btn; > tablet->btns[btn->button] = btn->down; > break; > > diff --git a/hw/core/numa.c b/hw/core/numa.c > index 7c4dd4e68e..24fe0e11d8 100644 > --- a/hw/core/numa.c > +++ b/hw/core/numa.c > @@ -765,19 +765,19 @@ static void numa_stat_memory_devices(NumaNodeMem > node_mem[]) > case MEMORY_DEVICE_INFO_KIND_DIMM: > case MEMORY_DEVICE_INFO_KIND_NVDIMM: > pcdimm_info = value->type == MEMORY_DEVICE_INFO_KIND_DIMM > ? > - value->u.dimm.data : value->u.nvdimm.data; > + &value->u.dimm : &value->u.nvdimm; > node_mem[pcdimm_info->node].node_mem += pcdimm_info->size; > node_mem[pcdimm_info->node].node_plugged_mem += > pcdimm_info->size; > break; > case MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM: > - vpi = value->u.virtio_pmem.data; > + vpi = &value->u.virtio_pmem; > /* TODO: once we support numa, assign to right node */ > node_mem[0].node_mem += vpi->size; > node_mem[0].node_plugged_mem += vpi->size; > break; > case MEMORY_DEVICE_INFO_KIND_VIRTIO_MEM: > - vmi = value->u.virtio_mem.data; > + vmi = &value->u.virtio_mem; > node_mem[vmi->node].node_mem += vmi->size; > node_mem[vmi->node].node_plugged_mem += vmi->size; > break; > diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c > index 838260b6ad..6aa6010774 100644 > --- a/hw/display/xenfb.c > +++ b/hw/display/xenfb.c > @@ -201,7 +201,7 @@ static void xenfb_key_event(DeviceState *dev, > QemuConsole *src, > InputEvent *evt) > { > struct XenInput *xenfb = (struct XenInput *)dev; > - InputKeyEvent *key = evt->u.key.data; > + InputKeyEvent *key = &evt->u.key; > int qcode = qemu_input_key_value_to_qcode(key->key); > int lnx; > > @@ -236,7 +236,7 @@ static void xenfb_mouse_event(DeviceState *dev, > QemuConsole *src, > > switch (evt->type) { > case INPUT_EVENT_KIND_BTN: > - btn = evt->u.btn.data; > + btn = &evt->u.btn; > switch (btn->button) { > case INPUT_BUTTON_LEFT: > xenfb_send_key(xenfb, btn->down, BTN_LEFT); > @@ -263,7 +263,7 @@ static void xenfb_mouse_event(DeviceState *dev, > QemuConsole *src, > break; > > case INPUT_EVENT_KIND_ABS: > - move = evt->u.abs.data; > + move = &evt->u.abs; > if (xenfb->raw_pointer_wanted) { > xenfb->axis[move->axis] = move->value; > } else { > @@ -289,7 +289,7 @@ static void xenfb_mouse_event(DeviceState *dev, > QemuConsole *src, > break; > > case INPUT_EVENT_KIND_REL: > - move = evt->u.rel.data; > + move = &evt->u.rel; > xenfb->axis[move->axis] += move->value; > break; > > diff --git a/hw/input/hid.c b/hw/input/hid.c > index 89239b5634..2472c5a902 100644 > --- a/hw/input/hid.c > +++ b/hw/input/hid.c > @@ -126,7 +126,7 @@ static void hid_pointer_event(DeviceState *dev, > QemuConsole *src, > > switch (evt->type) { > case INPUT_EVENT_KIND_REL: > - move = evt->u.rel.data; > + move = &evt->u.rel; > if (move->axis == INPUT_AXIS_X) { > e->xdx += move->value; > } else if (move->axis == INPUT_AXIS_Y) { > @@ -135,7 +135,7 @@ static void hid_pointer_event(DeviceState *dev, > QemuConsole *src, > break; > > case INPUT_EVENT_KIND_ABS: > - move = evt->u.abs.data; > + move = &evt->u.abs; > if (move->axis == INPUT_AXIS_X) { > e->xdx = move->value; > } else if (move->axis == INPUT_AXIS_Y) { > @@ -144,7 +144,7 @@ static void hid_pointer_event(DeviceState *dev, > QemuConsole *src, > break; > > case INPUT_EVENT_KIND_BTN: > - btn = evt->u.btn.data; > + btn = &evt->u.btn; > if (btn->down) { > e->buttons_state |= bmap[btn->button]; > if (btn->button == INPUT_BUTTON_WHEEL_UP) { > @@ -230,7 +230,7 @@ static void hid_keyboard_event(DeviceState *dev, > QemuConsole *src, > HIDState *hs = (HIDState *)dev; > int scancodes[3], i, count; > int slot; > - InputKeyEvent *key = evt->u.key.data; > + InputKeyEvent *key = &evt->u.key; > > count = qemu_input_key_value_to_scancode(key->key, > key->down, > diff --git a/hw/input/ps2.c b/hw/input/ps2.c > index f8746d2f52..1176ccc88c 100644 > --- a/hw/input/ps2.c > +++ b/hw/input/ps2.c > @@ -284,7 +284,7 @@ static void ps2_keyboard_event(DeviceState *dev, > QemuConsole *src, > InputEvent *evt) > { > PS2KbdState *s = (PS2KbdState *)dev; > - InputKeyEvent *key = evt->u.key.data; > + InputKeyEvent *key = &evt->u.key; > int qcode; > uint16_t keycode = 0; > int mod; > @@ -727,7 +727,7 @@ static void ps2_mouse_event(DeviceState *dev, > QemuConsole *src, > > switch (evt->type) { > case INPUT_EVENT_KIND_REL: > - move = evt->u.rel.data; > + move = &evt->u.rel; > if (move->axis == INPUT_AXIS_X) { > s->mouse_dx += move->value; > } else if (move->axis == INPUT_AXIS_Y) { > @@ -736,7 +736,7 @@ static void ps2_mouse_event(DeviceState *dev, > QemuConsole *src, > break; > > case INPUT_EVENT_KIND_BTN: > - btn = evt->u.btn.data; > + btn = &evt->u.btn; > if (btn->down) { > s->mouse_buttons |= bmap[btn->button]; > if (btn->button == INPUT_BUTTON_WHEEL_UP) { > diff --git a/hw/input/virtio-input-hid.c b/hw/input/virtio-input-hid.c > index a7a244a95d..1c7b07cf42 100644 > --- a/hw/input/virtio-input-hid.c > +++ b/hw/input/virtio-input-hid.c > @@ -83,7 +83,7 @@ static void virtio_input_handle_event(DeviceState *dev, > QemuConsole *src, > > switch (evt->type) { > case INPUT_EVENT_KIND_KEY: > - key = evt->u.key.data; > + key = &evt->u.key; > qcode = qemu_input_key_value_to_qcode(key->key); > if (qcode < qemu_input_map_qcode_to_linux_len && > qemu_input_map_qcode_to_linux[qcode]) { > @@ -99,7 +99,7 @@ static void virtio_input_handle_event(DeviceState *dev, > QemuConsole *src, > } > break; > case INPUT_EVENT_KIND_BTN: > - btn = evt->u.btn.data; > + btn = &evt->u.btn; > if (vhid->wheel_axis && > (btn->button == INPUT_BUTTON_WHEEL_UP || > btn->button == INPUT_BUTTON_WHEEL_DOWN) && > @@ -123,14 +123,14 @@ static void virtio_input_handle_event(DeviceState > *dev, QemuConsole *src, > } > break; > case INPUT_EVENT_KIND_REL: > - move = evt->u.rel.data; > + move = &evt->u.rel; > event.type = cpu_to_le16(EV_REL); > event.code = cpu_to_le16(axismap_rel[move->axis]); > event.value = cpu_to_le32(move->value); > virtio_input_send(vinput, &event); > break; > case INPUT_EVENT_KIND_ABS: > - move = evt->u.abs.data; > + move = &evt->u.abs; > event.type = cpu_to_le16(EV_ABS); > event.code = cpu_to_le16(axismap_abs[move->axis]); > event.value = cpu_to_le32(move->value); > diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c > index c30351070b..3d6f836621 100644 > --- a/hw/mem/pc-dimm.c > +++ b/hw/mem/pc-dimm.c > @@ -236,11 +236,19 @@ static MemoryRegion > *pc_dimm_md_get_memory_region(MemoryDeviceState *md, > static void pc_dimm_md_fill_device_info(const MemoryDeviceState *md, > MemoryDeviceInfo *info) > { > - PCDIMMDeviceInfo *di = g_new0(PCDIMMDeviceInfo, 1); > + PCDIMMDeviceInfo *di; > const DeviceClass *dc = DEVICE_GET_CLASS(md); > const PCDIMMDevice *dimm = PC_DIMM(md); > const DeviceState *dev = DEVICE(md); > > + if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) { > + di = &info->u.nvdimm; > + info->type = MEMORY_DEVICE_INFO_KIND_NVDIMM; > + } else { > + di = &info->u.dimm; > + info->type = MEMORY_DEVICE_INFO_KIND_DIMM; > + } > + > if (dev->id) { > di->has_id = true; > di->id = g_strdup(dev->id); > @@ -253,14 +261,6 @@ static void pc_dimm_md_fill_device_info(const > MemoryDeviceState *md, > di->size = object_property_get_uint(OBJECT(dimm), PC_DIMM_SIZE_PROP, > NULL); > di->memdev = object_get_canonical_path(OBJECT(dimm->hostmem)); > - > - if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) { > - info->u.nvdimm.data = di; > - info->type = MEMORY_DEVICE_INFO_KIND_NVDIMM; > - } else { > - info->u.dimm.data = di; > - info->type = MEMORY_DEVICE_INFO_KIND_DIMM; > - } > } > > static void pc_dimm_class_init(ObjectClass *oc, void *data) > diff --git a/hw/virtio/virtio-mem-pci.c b/hw/virtio/virtio-mem-pci.c > index 913f4a3326..f93572fc27 100644 > --- a/hw/virtio/virtio-mem-pci.c > +++ b/hw/virtio/virtio-mem-pci.c > @@ -58,7 +58,7 @@ static uint64_t virtio_mem_pci_get_plugged_size(const > MemoryDeviceState *md, > static void virtio_mem_pci_fill_device_info(const MemoryDeviceState *md, > MemoryDeviceInfo *info) > { > - VirtioMEMDeviceInfo *vi = g_new0(VirtioMEMDeviceInfo, 1); > + VirtioMEMDeviceInfo *vi = &info->u.virtio_mem; > VirtIOMEMPCI *pci_mem = VIRTIO_MEM_PCI(md); > VirtIOMEM *vmem = VIRTIO_MEM(&pci_mem->vdev); > VirtIOMEMClass *vpc = VIRTIO_MEM_GET_CLASS(vmem); > @@ -72,7 +72,6 @@ static void virtio_mem_pci_fill_device_info(const > MemoryDeviceState *md, > /* let the real device handle everything else */ > vpc->fill_device_info(vmem, vi); > > - info->u.virtio_mem.data = vi; > info->type = MEMORY_DEVICE_INFO_KIND_VIRTIO_MEM; > } > > diff --git a/hw/virtio/virtio-pmem-pci.c b/hw/virtio/virtio-pmem-pci.c > index 2b2a0b1eae..adf17f873b 100644 > --- a/hw/virtio/virtio-pmem-pci.c > +++ b/hw/virtio/virtio-pmem-pci.c > @@ -63,7 +63,7 @@ static uint64_t virtio_pmem_pci_get_plugged_size(const > MemoryDeviceState *md, > static void virtio_pmem_pci_fill_device_info(const MemoryDeviceState *md, > MemoryDeviceInfo *info) > { > - VirtioPMEMDeviceInfo *vi = g_new0(VirtioPMEMDeviceInfo, 1); > + VirtioPMEMDeviceInfo *vi = &info->u.virtio_pmem; > VirtIOPMEMPCI *pci_pmem = VIRTIO_PMEM_PCI(md); > VirtIOPMEM *pmem = VIRTIO_PMEM(&pci_pmem->vdev); > VirtIOPMEMClass *vpc = VIRTIO_PMEM_GET_CLASS(pmem); > @@ -77,7 +77,6 @@ static void virtio_pmem_pci_fill_device_info(const > MemoryDeviceState *md, > /* let the real device handle everything else */ > vpc->fill_device_info(pmem, vi); > > - info->u.virtio_pmem.data = vi; > info->type = MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM; > } > > diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c > index 9789f4277f..0324caa114 100644 > --- a/monitor/hmp-cmds.c > +++ b/monitor/hmp-cmds.c > @@ -918,7 +918,7 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict) > > switch (ti->options->type) { > case TPM_TYPE_OPTIONS_KIND_PASSTHROUGH: > - tpo = ti->options->u.passthrough.data; > + tpo = &ti->options->u.passthrough; > monitor_printf(mon, "%s%s%s%s", > tpo->has_path ? ",path=" : "", > tpo->has_path ? tpo->path : "", > @@ -926,7 +926,7 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict) > tpo->has_cancel_path ? tpo->cancel_path : ""); > break; > case TPM_TYPE_OPTIONS_KIND_EMULATOR: > - teo = ti->options->u.emulator.data; > + teo = &ti->options->u.emulator; > monitor_printf(mon, ",chardev=%s", teo->chardev); > break; > case TPM_TYPE_OPTIONS_KIND__MAX: > @@ -1728,14 +1728,14 @@ void hmp_sendkey(Monitor *mon, const QDict *qdict) > goto err_out; > } > keylist->value->type = KEY_VALUE_KIND_NUMBER; > - keylist->value->u.number.data = value; > + keylist->value->u.number = value; > } else { > int idx = index_from_key(keys, keyname_len); > if (idx == Q_KEY_CODE__MAX) { > goto err_out; > } > keylist->value->type = KEY_VALUE_KIND_QCODE; > - keylist->value->u.qcode.data = idx; > + keylist->value->u.qcode = idx; > } > > if (!*separator) { > @@ -1860,7 +1860,7 @@ void hmp_info_memory_devices(Monitor *mon, const > QDict *qdict) > case MEMORY_DEVICE_INFO_KIND_DIMM: > case MEMORY_DEVICE_INFO_KIND_NVDIMM: > di = value->type == MEMORY_DEVICE_INFO_KIND_DIMM ? > - value->u.dimm.data : value->u.nvdimm.data; > + &value->u.dimm : &value->u.nvdimm; > monitor_printf(mon, "Memory device [%s]: \"%s\"\n", > MemoryDeviceInfoKind_str(value->type), > di->id ? di->id : ""); > @@ -1875,7 +1875,7 @@ void hmp_info_memory_devices(Monitor *mon, const > QDict *qdict) > di->hotpluggable ? "true" : "false"); > break; > case MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM: > - vpi = value->u.virtio_pmem.data; > + vpi = &value->u.virtio_pmem; > monitor_printf(mon, "Memory device [%s]: \"%s\"\n", > MemoryDeviceInfoKind_str(value->type), > vpi->id ? vpi->id : ""); > @@ -1884,7 +1884,7 @@ void hmp_info_memory_devices(Monitor *mon, const > QDict *qdict) > monitor_printf(mon, " memdev: %s\n", vpi->memdev); > break; > case MEMORY_DEVICE_INFO_KIND_VIRTIO_MEM: > - vmi = value->u.virtio_mem.data; > + vmi = &value->u.virtio_mem; > monitor_printf(mon, "Memory device [%s]: \"%s\"\n", > MemoryDeviceInfoKind_str(value->type), > vmi->id ? vmi->id : ""); > diff --git a/qemu-keymap.c b/qemu-keymap.c > index 536e8f2385..52637c449c 100644 > --- a/qemu-keymap.c > +++ b/qemu-keymap.c > @@ -38,7 +38,7 @@ static uint32_t qcode_to_number(uint32_t qcode) > uint32_t number; > > keyvalue.type = KEY_VALUE_KIND_QCODE; > - keyvalue.u.qcode.data = qcode; > + keyvalue.u.qcode = qcode; > number = qemu_input_key_value_to_number(&keyvalue); > assert(number != 0); > return number; > diff --git a/replay/replay-input.c b/replay/replay-input.c > index 1147e3d34e..c1eb1b79e1 100644 > --- a/replay/replay-input.c > +++ b/replay/replay-input.c > @@ -26,16 +26,16 @@ void replay_save_input_event(InputEvent *evt) > > switch (evt->type) { > case INPUT_EVENT_KIND_KEY: > - key = evt->u.key.data; > + key = &evt->u.key; > replay_put_dword(key->key->type); > > switch (key->key->type) { > case KEY_VALUE_KIND_NUMBER: > - replay_put_qword(key->key->u.number.data); > + replay_put_qword(key->key->u.number); > replay_put_byte(key->down); > break; > case KEY_VALUE_KIND_QCODE: > - replay_put_dword(key->key->u.qcode.data); > + replay_put_dword(key->key->u.qcode); > replay_put_byte(key->down); > break; > case KEY_VALUE_KIND__MAX: > @@ -44,17 +44,17 @@ void replay_save_input_event(InputEvent *evt) > } > break; > case INPUT_EVENT_KIND_BTN: > - btn = evt->u.btn.data; > + btn = &evt->u.btn; > replay_put_dword(btn->button); > replay_put_byte(btn->down); > break; > case INPUT_EVENT_KIND_REL: > - move = evt->u.rel.data; > + move = &evt->u.rel; > replay_put_dword(move->axis); > replay_put_qword(move->value); > break; > case INPUT_EVENT_KIND_ABS: > - move = evt->u.abs.data; > + move = &evt->u.abs; > replay_put_dword(move->axis); > replay_put_qword(move->value); > break; > @@ -68,26 +68,21 @@ InputEvent *replay_read_input_event(void) > { > InputEvent evt; > KeyValue keyValue; > - InputKeyEvent key; > - key.key = &keyValue; > - InputBtnEvent btn; > - InputMoveEvent rel; > - InputMoveEvent abs; > + evt.u.key.key = &keyValue; > > evt.type = replay_get_dword(); > switch (evt.type) { > case INPUT_EVENT_KIND_KEY: > - evt.u.key.data = &key; > - evt.u.key.data->key->type = replay_get_dword(); > + evt.u.key.key->type = replay_get_dword(); > > - switch (evt.u.key.data->key->type) { > + switch (evt.u.key.key->type) { > case KEY_VALUE_KIND_NUMBER: > - evt.u.key.data->key->u.number.data = replay_get_qword(); > - evt.u.key.data->down = replay_get_byte(); > + evt.u.key.key->u.number = replay_get_qword(); > + evt.u.key.down = replay_get_byte(); > break; > case KEY_VALUE_KIND_QCODE: > - evt.u.key.data->key->u.qcode.data = > (QKeyCode)replay_get_dword(); > - evt.u.key.data->down = replay_get_byte(); > + evt.u.key.key->u.qcode = (QKeyCode)replay_get_dword(); > + evt.u.key.down = replay_get_byte(); > break; > case KEY_VALUE_KIND__MAX: > /* keep gcc happy */ > @@ -95,19 +90,16 @@ InputEvent *replay_read_input_event(void) > } > break; > case INPUT_EVENT_KIND_BTN: > - evt.u.btn.data = &btn; > - evt.u.btn.data->button = (InputButton)replay_get_dword(); > - evt.u.btn.data->down = replay_get_byte(); > + evt.u.btn.button = (InputButton)replay_get_dword(); > + evt.u.btn.down = replay_get_byte(); > break; > case INPUT_EVENT_KIND_REL: > - evt.u.rel.data = &rel; > - evt.u.rel.data->axis = (InputAxis)replay_get_dword(); > - evt.u.rel.data->value = replay_get_qword(); > + evt.u.rel.axis = (InputAxis)replay_get_dword(); > + evt.u.rel.value = replay_get_qword(); > break; > case INPUT_EVENT_KIND_ABS: > - evt.u.abs.data = &abs; > - evt.u.abs.data->axis = (InputAxis)replay_get_dword(); > - evt.u.abs.data->value = replay_get_qword(); > + evt.u.abs.axis = (InputAxis)replay_get_dword(); > + evt.u.abs.value = replay_get_qword(); > break; > case INPUT_EVENT_KIND__MAX: > /* keep gcc happy */ > diff --git a/tests/test-char.c b/tests/test-char.c > index 9196e566e9..0e7a033a90 100644 > --- a/tests/test-char.c > +++ b/tests/test-char.c > @@ -1220,7 +1220,7 @@ static void char_file_fifo_test(void) > .has_in = true, > .out = out }; > ChardevBackend backend = { .type = CHARDEV_BACKEND_KIND_FILE, > - .u.file.data = &file }; > + .u.file = file }; > FeHandler fe = { 0, }; > int fd, ret; > > @@ -1273,19 +1273,17 @@ static void char_file_test_internal(Chardev > *ext_chr, const char *filepath) > char *out; > Chardev *chr; > char *contents = NULL; > - ChardevFile file = {}; > - ChardevBackend backend = { .type = CHARDEV_BACKEND_KIND_FILE, > - .u.file.data = &file }; > + ChardevBackend backend = { .type = CHARDEV_BACKEND_KIND_FILE }; > gsize length; > int ret; > > if (ext_chr) { > chr = ext_chr; > out = g_strdup(filepath); > - file.out = out; > + backend.u.file.out = out; > } else { > out = g_build_filename(tmp_path, "out", NULL); > - file.out = out; > + backend.u.file.out = out; > chr = qemu_chardev_new(NULL, TYPE_CHARDEV_FILE, &backend, > NULL, &error_abort); > } > @@ -1384,7 +1382,7 @@ static void char_hotswap_test(void) > char *filename = g_build_filename(tmp_path, "file", NULL); > ChardevFile file = { .out = filename }; > ChardevBackend backend = { .type = CHARDEV_BACKEND_KIND_FILE, > - .u.file.data = &file }; > + .u.file = file }; > ChardevReturn *ret; > > int port; > diff --git a/tests/test-clone-visitor.c b/tests/test-clone-visitor.c > index 5e1e8b2f5e..0a62704bed 100644 > --- a/tests/test-clone-visitor.c > +++ b/tests/test-clone-visitor.c > @@ -110,7 +110,7 @@ static void test_clone_complex1(void) > dst = QAPI_CLONE(UserDefListUnion, src); > g_assert(dst); > g_assert_cmpint(dst->type, ==, src->type); > - g_assert(!dst->u.string.data); > + g_assert(!dst->u.string); > > qapi_free_UserDefListUnion(src); > qapi_free_UserDefListUnion(dst); > @@ -155,30 +155,30 @@ static void test_clone_complex3(void) > tmp = src->array = g_new0(__org_qemu_x_Union1List, 1); > tmp->value = g_new0(__org_qemu_x_Union1, 1); > tmp->value->type = ORG_QEMU_X_UNION1_KIND___ORG_QEMU_X_BRANCH; > - tmp->value->u.__org_qemu_x_branch.data = g_strdup("one"); > + tmp->value->u.__org_qemu_x_branch = g_strdup("one"); > tmp = tmp->next = g_new0(__org_qemu_x_Union1List, 1); > tmp->value = g_new0(__org_qemu_x_Union1, 1); > tmp->value->type = ORG_QEMU_X_UNION1_KIND___ORG_QEMU_X_BRANCH; > - tmp->value->u.__org_qemu_x_branch.data = g_strdup("two"); > + tmp->value->u.__org_qemu_x_branch = g_strdup("two"); > tmp = tmp->next = g_new0(__org_qemu_x_Union1List, 1); > tmp->value = g_new0(__org_qemu_x_Union1, 1); > tmp->value->type = ORG_QEMU_X_UNION1_KIND___ORG_QEMU_X_BRANCH; > - tmp->value->u.__org_qemu_x_branch.data = g_strdup("three"); > + tmp->value->u.__org_qemu_x_branch = g_strdup("three"); > > dst = QAPI_CLONE(__org_qemu_x_Struct2, src); > g_assert(dst); > tmp = dst->array; > g_assert(tmp); > g_assert(tmp->value); > - g_assert_cmpstr(tmp->value->u.__org_qemu_x_branch.data, ==, "one"); > + g_assert_cmpstr(tmp->value->u.__org_qemu_x_branch, ==, "one"); > tmp = tmp->next; > g_assert(tmp); > g_assert(tmp->value); > - g_assert_cmpstr(tmp->value->u.__org_qemu_x_branch.data, ==, "two"); > + g_assert_cmpstr(tmp->value->u.__org_qemu_x_branch, ==, "two"); > tmp = tmp->next; > g_assert(tmp); > g_assert(tmp->value); > - g_assert_cmpstr(tmp->value->u.__org_qemu_x_branch.data, ==, "three"); > + g_assert_cmpstr(tmp->value->u.__org_qemu_x_branch, ==, "three"); > tmp = tmp->next; > g_assert(!tmp); > > diff --git a/tests/test-qmp-cmds.c b/tests/test-qmp-cmds.c > index d3413bfef0..3d699fbb66 100644 > --- a/tests/test-qmp-cmds.c > +++ b/tests/test-qmp-cmds.c > @@ -136,7 +136,7 @@ __org_qemu_x_Union1 > *qmp___org_qemu_x_command(__org_qemu_x_EnumList *a, > __org_qemu_x_Union1 *ret = g_new0(__org_qemu_x_Union1, 1); > > ret->type = ORG_QEMU_X_UNION1_KIND___ORG_QEMU_X_BRANCH; > - ret->u.__org_qemu_x_branch.data = strdup("blah1"); > + ret->u.__org_qemu_x_branch = strdup("blah1"); > > /* Also test that 'wchar-t' was munged to 'q_wchar_t' */ > if (b && b->value && !b->value->has_q_wchar_t) { > diff --git a/tests/test-qobject-input-visitor.c > b/tests/test-qobject-input-visitor.c > index e41b91a2a6..b976ab9763 100644 > --- a/tests/test-qobject-input-visitor.c > +++ b/tests/test-qobject-input-visitor.c > @@ -710,7 +710,7 @@ static void > test_list_union_integer_helper(TestInputVisitorData *data, > switch (kind) { > case USER_DEF_LIST_UNION_KIND_INTEGER: { > intList *elem = NULL; > - for (i = 0, elem = cvalue->u.integer.data; > + for (i = 0, elem = cvalue->u.integer; > elem; elem = elem->next, i++) { > g_assert_cmpint(elem->value, ==, i); > } > @@ -718,56 +718,56 @@ static void > test_list_union_integer_helper(TestInputVisitorData *data, > } > case USER_DEF_LIST_UNION_KIND_S8: { > int8List *elem = NULL; > - for (i = 0, elem = cvalue->u.s8.data; elem; elem = elem->next, > i++) { > + for (i = 0, elem = cvalue->u.s8; elem; elem = elem->next, i++) { > g_assert_cmpint(elem->value, ==, i); > } > break; > } > case USER_DEF_LIST_UNION_KIND_S16: { > int16List *elem = NULL; > - for (i = 0, elem = cvalue->u.s16.data; elem; elem = elem->next, > i++) { > + for (i = 0, elem = cvalue->u.s16; elem; elem = elem->next, i++) { > g_assert_cmpint(elem->value, ==, i); > } > break; > } > case USER_DEF_LIST_UNION_KIND_S32: { > int32List *elem = NULL; > - for (i = 0, elem = cvalue->u.s32.data; elem; elem = elem->next, > i++) { > + for (i = 0, elem = cvalue->u.s32; elem; elem = elem->next, i++) { > g_assert_cmpint(elem->value, ==, i); > } > break; > } > case USER_DEF_LIST_UNION_KIND_S64: { > int64List *elem = NULL; > - for (i = 0, elem = cvalue->u.s64.data; elem; elem = elem->next, > i++) { > + for (i = 0, elem = cvalue->u.s64; elem; elem = elem->next, i++) { > g_assert_cmpint(elem->value, ==, i); > } > break; > } > case USER_DEF_LIST_UNION_KIND_U8: { > uint8List *elem = NULL; > - for (i = 0, elem = cvalue->u.u8.data; elem; elem = elem->next, > i++) { > + for (i = 0, elem = cvalue->u.u8; elem; elem = elem->next, i++) { > g_assert_cmpint(elem->value, ==, i); > } > break; > } > case USER_DEF_LIST_UNION_KIND_U16: { > uint16List *elem = NULL; > - for (i = 0, elem = cvalue->u.u16.data; elem; elem = elem->next, > i++) { > + for (i = 0, elem = cvalue->u.u16; elem; elem = elem->next, i++) { > g_assert_cmpint(elem->value, ==, i); > } > break; > } > case USER_DEF_LIST_UNION_KIND_U32: { > uint32List *elem = NULL; > - for (i = 0, elem = cvalue->u.u32.data; elem; elem = elem->next, > i++) { > + for (i = 0, elem = cvalue->u.u32; elem; elem = elem->next, i++) { > g_assert_cmpint(elem->value, ==, i); > } > break; > } > case USER_DEF_LIST_UNION_KIND_U64: { > uint64List *elem = NULL; > - for (i = 0, elem = cvalue->u.u64.data; elem; elem = elem->next, > i++) { > + for (i = 0, elem = cvalue->u.u64; elem; elem = elem->next, i++) { > g_assert_cmpint(elem->value, ==, i); > } > break; > @@ -868,7 +868,7 @@ static void > test_visitor_in_list_union_bool(TestInputVisitorData *data, > g_assert(cvalue != NULL); > g_assert_cmpint(cvalue->type, ==, USER_DEF_LIST_UNION_KIND_BOOLEAN); > > - for (i = 0, elem = cvalue->u.boolean.data; elem; elem = elem->next, > i++) { > + for (i = 0, elem = cvalue->u.boolean; elem; elem = elem->next, i++) { > g_assert_cmpint(elem->value, ==, (i % 3 == 0) ? 1 : 0); > } > > @@ -900,7 +900,7 @@ static void > test_visitor_in_list_union_string(TestInputVisitorData *data, > g_assert(cvalue != NULL); > g_assert_cmpint(cvalue->type, ==, USER_DEF_LIST_UNION_KIND_STRING); > > - for (i = 0, elem = cvalue->u.string.data; elem; elem = elem->next, > i++) { > + for (i = 0, elem = cvalue->u.string; elem; elem = elem->next, i++) { > gchar str[8]; > sprintf(str, "%d", i); > g_assert_cmpstr(elem->value, ==, str); > @@ -936,7 +936,7 @@ static void > test_visitor_in_list_union_number(TestInputVisitorData *data, > g_assert(cvalue != NULL); > g_assert_cmpint(cvalue->type, ==, USER_DEF_LIST_UNION_KIND_NUMBER); > > - for (i = 0, elem = cvalue->u.number.data; elem; elem = elem->next, > i++) { > + for (i = 0, elem = cvalue->u.number; elem; elem = elem->next, i++) { > GString *double_expected = g_string_new(""); > GString *double_actual = g_string_new(""); > > diff --git a/tests/test-qobject-output-visitor.c > b/tests/test-qobject-output-visitor.c > index 1c856d9bd2..202f848062 100644 > --- a/tests/test-qobject-output-visitor.c > +++ b/tests/test-qobject-output-visitor.c > @@ -444,7 +444,7 @@ static void init_list_union(UserDefListUnion *cvalue) > int i; > switch (cvalue->type) { > case USER_DEF_LIST_UNION_KIND_INTEGER: { > - intList **list = &cvalue->u.integer.data; > + intList **list = &cvalue->u.integer; > for (i = 0; i < 32; i++) { > *list = g_new0(intList, 1); > (*list)->value = i; > @@ -454,7 +454,7 @@ static void init_list_union(UserDefListUnion *cvalue) > break; > } > case USER_DEF_LIST_UNION_KIND_S8: { > - int8List **list = &cvalue->u.s8.data; > + int8List **list = &cvalue->u.s8; > for (i = 0; i < 32; i++) { > *list = g_new0(int8List, 1); > (*list)->value = i; > @@ -464,7 +464,7 @@ static void init_list_union(UserDefListUnion *cvalue) > break; > } > case USER_DEF_LIST_UNION_KIND_S16: { > - int16List **list = &cvalue->u.s16.data; > + int16List **list = &cvalue->u.s16; > for (i = 0; i < 32; i++) { > *list = g_new0(int16List, 1); > (*list)->value = i; > @@ -474,7 +474,7 @@ static void init_list_union(UserDefListUnion *cvalue) > break; > } > case USER_DEF_LIST_UNION_KIND_S32: { > - int32List **list = &cvalue->u.s32.data; > + int32List **list = &cvalue->u.s32; > for (i = 0; i < 32; i++) { > *list = g_new0(int32List, 1); > (*list)->value = i; > @@ -484,7 +484,7 @@ static void init_list_union(UserDefListUnion *cvalue) > break; > } > case USER_DEF_LIST_UNION_KIND_S64: { > - int64List **list = &cvalue->u.s64.data; > + int64List **list = &cvalue->u.s64; > for (i = 0; i < 32; i++) { > *list = g_new0(int64List, 1); > (*list)->value = i; > @@ -494,7 +494,7 @@ static void init_list_union(UserDefListUnion *cvalue) > break; > } > case USER_DEF_LIST_UNION_KIND_U8: { > - uint8List **list = &cvalue->u.u8.data; > + uint8List **list = &cvalue->u.u8; > for (i = 0; i < 32; i++) { > *list = g_new0(uint8List, 1); > (*list)->value = i; > @@ -504,7 +504,7 @@ static void init_list_union(UserDefListUnion *cvalue) > break; > } > case USER_DEF_LIST_UNION_KIND_U16: { > - uint16List **list = &cvalue->u.u16.data; > + uint16List **list = &cvalue->u.u16; > for (i = 0; i < 32; i++) { > *list = g_new0(uint16List, 1); > (*list)->value = i; > @@ -514,7 +514,7 @@ static void init_list_union(UserDefListUnion *cvalue) > break; > } > case USER_DEF_LIST_UNION_KIND_U32: { > - uint32List **list = &cvalue->u.u32.data; > + uint32List **list = &cvalue->u.u32; > for (i = 0; i < 32; i++) { > *list = g_new0(uint32List, 1); > (*list)->value = i; > @@ -524,7 +524,7 @@ static void init_list_union(UserDefListUnion *cvalue) > break; > } > case USER_DEF_LIST_UNION_KIND_U64: { > - uint64List **list = &cvalue->u.u64.data; > + uint64List **list = &cvalue->u.u64; > for (i = 0; i < 32; i++) { > *list = g_new0(uint64List, 1); > (*list)->value = i; > @@ -534,7 +534,7 @@ static void init_list_union(UserDefListUnion *cvalue) > break; > } > case USER_DEF_LIST_UNION_KIND_BOOLEAN: { > - boolList **list = &cvalue->u.boolean.data; > + boolList **list = &cvalue->u.boolean; > for (i = 0; i < 32; i++) { > *list = g_new0(boolList, 1); > (*list)->value = QEMU_IS_ALIGNED(i, 3); > @@ -544,7 +544,7 @@ static void init_list_union(UserDefListUnion *cvalue) > break; > } > case USER_DEF_LIST_UNION_KIND_STRING: { > - strList **list = &cvalue->u.string.data; > + strList **list = &cvalue->u.string; > for (i = 0; i < 32; i++) { > *list = g_new0(strList, 1); > (*list)->value = g_strdup_printf("%d", i); > @@ -554,7 +554,7 @@ static void init_list_union(UserDefListUnion *cvalue) > break; > } > case USER_DEF_LIST_UNION_KIND_NUMBER: { > - numberList **list = &cvalue->u.number.data; > + numberList **list = &cvalue->u.number; > for (i = 0; i < 32; i++) { > *list = g_new0(numberList, 1); > (*list)->value = (double)i / 3; > diff --git a/ui/console.c b/ui/console.c > index 820e408170..2f93723ed6 100644 > --- a/ui/console.c > +++ b/ui/console.c > @@ -2212,7 +2212,7 @@ static void vc_chr_open(Chardev *chr, > bool *be_opened, > Error **errp) > { > - ChardevVC *vc = backend->u.vc.data; > + ChardevVC *vc = &backend->u.vc; > VCChardev *drv = VC_CHARDEV(chr); > QemuConsole *s; > unsigned width = 0; > @@ -2362,10 +2362,9 @@ void qemu_display_help(void) > void qemu_chr_parse_vc(QemuOpts *opts, ChardevBackend *backend, Error > **errp) > { > int val; > - ChardevVC *vc; > + ChardevVC *vc = &backend->u.vc; > > backend->type = CHARDEV_BACKEND_KIND_VC; > - vc = backend->u.vc.data = g_new0(ChardevVC, 1); > qemu_chr_parse_common(opts, qapi_ChardevVC_base(vc)); > > val = qemu_opt_get_number(opts, "width", 0); > diff --git a/ui/input-keymap.c b/ui/input-keymap.c > index 1b756a6970..0232e25124 100644 > --- a/ui/input-keymap.c > +++ b/ui/input-keymap.c > @@ -33,13 +33,13 @@ int qemu_input_linux_to_qcode(unsigned int lnx) > int qemu_input_key_value_to_number(const KeyValue *value) > { > if (value->type == KEY_VALUE_KIND_QCODE) { > - if (value->u.qcode.data >= qemu_input_map_qcode_to_qnum_len) { > + if (value->u.qcode >= qemu_input_map_qcode_to_qnum_len) { > return 0; > } > - return qemu_input_map_qcode_to_qnum[value->u.qcode.data]; > + return qemu_input_map_qcode_to_qnum[value->u.qcode]; > } else { > assert(value->type == KEY_VALUE_KIND_NUMBER); > - return value->u.number.data; > + return value->u.number; > } > } > > @@ -54,10 +54,10 @@ int qemu_input_key_number_to_qcode(unsigned int nr) > int qemu_input_key_value_to_qcode(const KeyValue *value) > { > if (value->type == KEY_VALUE_KIND_QCODE) { > - return value->u.qcode.data; > + return value->u.qcode; > } else { > assert(value->type == KEY_VALUE_KIND_NUMBER); > - return qemu_input_key_number_to_qcode(value->u.number.data); > + return qemu_input_key_number_to_qcode(value->u.number); > } > } > > @@ -68,7 +68,7 @@ int qemu_input_key_value_to_scancode(const KeyValue > *value, bool down, > int count = 0; > > if (value->type == KEY_VALUE_KIND_QCODE && > - value->u.qcode.data == Q_KEY_CODE_PAUSE) { > + value->u.qcode == Q_KEY_CODE_PAUSE) { > /* specific case */ > int v = down ? 0 : 0x80; > codes[count++] = 0xe1; > diff --git a/ui/input-legacy.c b/ui/input-legacy.c > index 9fc78a639b..5a32b010d4 100644 > --- a/ui/input-legacy.c > +++ b/ui/input-legacy.c > @@ -75,9 +75,9 @@ static KeyValue *copy_key_value(KeyValue *src) > KeyValue *dst = g_new(KeyValue, 1); > memcpy(dst, src, sizeof(*src)); > if (dst->type == KEY_VALUE_KIND_NUMBER) { > - QKeyCode code = > qemu_input_key_number_to_qcode(dst->u.number.data); > + QKeyCode code = qemu_input_key_number_to_qcode(dst->u.number); > dst->type = KEY_VALUE_KIND_QCODE; > - dst->u.qcode.data = code; > + dst->u.qcode = code; > } > return dst; > } > @@ -113,7 +113,7 @@ static void legacy_kbd_event(DeviceState *dev, > QemuConsole *src, > { > QEMUPutKbdEntry *entry = (QEMUPutKbdEntry *)dev; > int scancodes[3], i, count; > - InputKeyEvent *key = evt->u.key.data; > + InputKeyEvent *key = &evt->u.key; > > if (!entry || !entry->put_kbd) { > return; > @@ -159,7 +159,7 @@ static void legacy_mouse_event(DeviceState *dev, > QemuConsole *src, > > switch (evt->type) { > case INPUT_EVENT_KIND_BTN: > - btn = evt->u.btn.data; > + btn = &evt->u.btn; > if (btn->down) { > s->buttons |= bmap[btn->button]; > } else { > @@ -181,11 +181,11 @@ static void legacy_mouse_event(DeviceState *dev, > QemuConsole *src, > } > break; > case INPUT_EVENT_KIND_ABS: > - move = evt->u.abs.data; > + move = &evt->u.abs; > s->axis[move->axis] = move->value; > break; > case INPUT_EVENT_KIND_REL: > - move = evt->u.rel.data; > + move = &evt->u.rel; > s->axis[move->axis] += move->value; > break; > default: > diff --git a/ui/input.c b/ui/input.c > index 4791b089c7..a4078780ee 100644 > --- a/ui/input.c > +++ b/ui/input.c > @@ -164,10 +164,10 @@ void qmp_input_send_event(bool has_device, const > char *device, > InputEvent *evt = e->value; > > if (evt->type == INPUT_EVENT_KIND_KEY && > - evt->u.key.data->key->type == KEY_VALUE_KIND_NUMBER) { > - KeyValue *key = evt->u.key.data->key; > - QKeyCode code = > qemu_input_key_number_to_qcode(key->u.number.data); > - qemu_input_event_send_key_qcode(con, code, > evt->u.key.data->down); > + evt->u.key.key->type == KEY_VALUE_KIND_NUMBER) { > + KeyValue *key = evt->u.key.key; > + QKeyCode code = qemu_input_key_number_to_qcode(key->u.number); > + qemu_input_event_send_key_qcode(con, code, evt->u.key.down); > } else { > qemu_input_event_send(con, evt); > } > @@ -183,7 +183,7 @@ static int qemu_input_transform_invert_abs_value(int > value) > > static void qemu_input_transform_abs_rotate(InputEvent *evt) > { > - InputMoveEvent *move = evt->u.abs.data; > + InputMoveEvent *move = &evt->u.abs; > switch (graphic_rotate) { > case 90: > if (move->axis == INPUT_AXIS_X) { > @@ -220,16 +220,16 @@ static void qemu_input_event_trace(QemuConsole *src, > InputEvent *evt) > } > switch (evt->type) { > case INPUT_EVENT_KIND_KEY: > - key = evt->u.key.data; > + key = &evt->u.key; > switch (key->key->type) { > case KEY_VALUE_KIND_NUMBER: > - qcode = > qemu_input_key_number_to_qcode(key->key->u.number.data); > + qcode = qemu_input_key_number_to_qcode(key->key->u.number); > name = QKeyCode_str(qcode); > - trace_input_event_key_number(idx, key->key->u.number.data, > + trace_input_event_key_number(idx, key->key->u.number, > name, key->down); > break; > case KEY_VALUE_KIND_QCODE: > - name = QKeyCode_str(key->key->u.qcode.data); > + name = QKeyCode_str(key->key->u.qcode); > trace_input_event_key_qcode(idx, name, key->down); > break; > case KEY_VALUE_KIND__MAX: > @@ -238,17 +238,17 @@ static void qemu_input_event_trace(QemuConsole *src, > InputEvent *evt) > } > break; > case INPUT_EVENT_KIND_BTN: > - btn = evt->u.btn.data; > + btn = &evt->u.btn; > name = InputButton_str(btn->button); > trace_input_event_btn(idx, name, btn->down); > break; > case INPUT_EVENT_KIND_REL: > - move = evt->u.rel.data; > + move = &evt->u.rel; > name = InputAxis_str(move->axis); > trace_input_event_rel(idx, name, move->value); > break; > case INPUT_EVENT_KIND_ABS: > - move = evt->u.abs.data; > + move = &evt->u.abs; > name = InputAxis_str(move->axis); > trace_input_event_abs(idx, name, move->value); > break; > @@ -355,7 +355,7 @@ void qemu_input_event_send(QemuConsole *src, > InputEvent *evt) > /* Expect all parts of QEMU to send events with QCodes exclusively. > * Key numbers are only supported as end-user input via QMP */ > assert(!(evt->type == INPUT_EVENT_KIND_KEY && > - evt->u.key.data->key->type == KEY_VALUE_KIND_NUMBER)); > + evt->u.key.key->type == KEY_VALUE_KIND_NUMBER)); > > > /* > @@ -367,8 +367,8 @@ void qemu_input_event_send(QemuConsole *src, > InputEvent *evt) > * neeed to deal with this mistake > */ > if (evt->type == INPUT_EVENT_KIND_KEY && > - evt->u.key.data->key->u.qcode.data == Q_KEY_CODE_SYSRQ) { > - evt->u.key.data->key->u.qcode.data = Q_KEY_CODE_PRINT; > + evt->u.key.key->u.qcode == Q_KEY_CODE_SYSRQ) { > + evt->u.key.key->u.qcode = Q_KEY_CODE_PRINT; > } > > if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) { > @@ -407,10 +407,9 @@ void qemu_input_event_sync(void) > static InputEvent *qemu_input_event_new_key(KeyValue *key, bool down) > { > InputEvent *evt = g_new0(InputEvent, 1); > - evt->u.key.data = g_new0(InputKeyEvent, 1); > evt->type = INPUT_EVENT_KIND_KEY; > - evt->u.key.data->key = key; > - evt->u.key.data->down = down; > + evt->u.key.key = key; > + evt->u.key.down = down; > return evt; > } > > @@ -440,7 +439,7 @@ void qemu_input_event_send_key_qcode(QemuConsole *src, > QKeyCode q, bool down) > { > KeyValue *key = g_new0(KeyValue, 1); > key->type = KEY_VALUE_KIND_QCODE; > - key->u.qcode.data = q; > + key->u.qcode = q; > qemu_input_event_send_key(src, key, down); > } > > @@ -469,7 +468,7 @@ void qemu_input_queue_btn(QemuConsole *src, > InputButton btn, bool down) > }; > InputEvent evt = { > .type = INPUT_EVENT_KIND_BTN, > - .u.btn.data = &bevt, > + .u.btn = bevt, > }; > > qemu_input_event_send(src, &evt); > @@ -520,7 +519,7 @@ void qemu_input_queue_rel(QemuConsole *src, InputAxis > axis, int value) > }; > InputEvent evt = { > .type = INPUT_EVENT_KIND_REL, > - .u.rel.data = &move, > + .u.rel = move, > }; > > qemu_input_event_send(src, &evt); > @@ -537,7 +536,7 @@ void qemu_input_queue_abs(QemuConsole *src, InputAxis > axis, int value, > }; > InputEvent evt = { > .type = INPUT_EVENT_KIND_ABS, > - .u.abs.data = &move, > + .u.abs = move, > }; > > qemu_input_event_send(src, &evt); > diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c > index 05e5c73f9d..59e317cbb8 100644 > --- a/util/qemu-sockets.c > +++ b/util/qemu-sockets.c > @@ -1365,21 +1365,21 @@ SocketAddress > *socket_address_flatten(SocketAddressLegacy *addr_legacy) > case SOCKET_ADDRESS_LEGACY_KIND_INET: > addr->type = SOCKET_ADDRESS_TYPE_INET; > QAPI_CLONE_MEMBERS(InetSocketAddress, &addr->u.inet, > - addr_legacy->u.inet.data); > + &addr_legacy->u.inet); > break; > case SOCKET_ADDRESS_LEGACY_KIND_UNIX: > addr->type = SOCKET_ADDRESS_TYPE_UNIX; > QAPI_CLONE_MEMBERS(UnixSocketAddress, &addr->u.q_unix, > - addr_legacy->u.q_unix.data); > + &addr_legacy->u.q_unix); > break; > case SOCKET_ADDRESS_LEGACY_KIND_VSOCK: > addr->type = SOCKET_ADDRESS_TYPE_VSOCK; > QAPI_CLONE_MEMBERS(VsockSocketAddress, &addr->u.vsock, > - addr_legacy->u.vsock.data); > + &addr_legacy->u.vsock); > break; > case SOCKET_ADDRESS_LEGACY_KIND_FD: > addr->type = SOCKET_ADDRESS_TYPE_FD; > - QAPI_CLONE_MEMBERS(String, &addr->u.fd, addr_legacy->u.fd.data); > + QAPI_CLONE_MEMBERS(String, &addr->u.fd, &addr_legacy->u.fd); > break; > default: > abort(); > diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py > index fafec94e02..1c4e3407a3 100644 > --- a/scripts/qapi/introspect.py > +++ b/scripts/qapi/introspect.py > @@ -188,7 +188,12 @@ const QLitObject %(c_name)s = %(c_string)s; > 'variants': [self._gen_variant(v) for v in variants]} > > def _gen_variant(self, variant): > - obj = {'case': variant.name, 'type': > self._use_type(variant.type)} > + if variant.wrapped: > + obj = {'case': variant.name, > + 'type': self._use_type(variant.wrapper_type)} > + else: > + obj = {'case': variant.name, > + 'type': self._use_type(variant.type)} > return _make_tree(obj, variant.ifcond, None) > > def visit_builtin_type(self, name, info, json_type): > diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py > index 720449feee..17525b4216 100644 > --- a/scripts/qapi/schema.py > +++ b/scripts/qapi/schema.py > @@ -216,6 +216,11 @@ class QAPISchemaBuiltinType(QAPISchemaType): > self._json_type_name = json_type > self._c_type_name = c_type > > + def check(self, schema): > + # Don't check twice, it would fail an assertion > + if not self._checked: > + super().check(schema) > + > def c_name(self): > return self.name > > @@ -593,18 +598,21 @@ class QAPISchemaVariants: > "branch '%s' is not a value of %s" > % (v.name, self.tag_member.type.describe())) > if (not isinstance(v.type, QAPISchemaObjectType) > - or v.type.variants): > + or v.type.variants) and v.flat: > raise QAPISemError( > self.info, > "%s cannot use %s" > % (v.describe(self.info), v.type.describe())) > - v.type.check(schema) > + if isinstance(v.type, QAPISchemaObjectType): > + v.type.check(schema) > > def check_clash(self, info, seen): > for v in self.variants: > # Reset seen map for each variant, since qapi names from one > - # branch do not affect another branch > - v.type.check_clash(info, dict(seen)) > + # branch do not affect another branch. Variants that are > + # never flat don't even conflict with the base. > + if isinstance(v.type, QAPISchemaObjectType): > + v.type.check_clash(info, dict(seen) if v.flat else {}) > > > class QAPISchemaMember: > @@ -705,9 +713,22 @@ class QAPISchemaObjectTypeMember(QAPISchemaMember): > class QAPISchemaVariant(QAPISchemaObjectTypeMember): > role = 'branch' > > - def __init__(self, name, info, typ, ifcond=None): > + def __init__(self, name, info, typ, ifcond=None, flat=True, > + wrapper_type=None): > super().__init__(name, info, typ, False, ifcond) > > + self.flat = flat > + self.wrapped = bool(wrapper_type) > + self.wrapper_type = wrapper_type > + > + # For now, unions are either flat or wrapped, never both > + assert self.flat or self.wrapped > + assert not (self.flat and self.wrapped) > + > + def check(self, schema): > + super().check(schema) > + if self.wrapped: > + self.wrapper_type.check(schema) > > class QAPISchemaCommand(QAPISchemaEntity): > meta = 'command' > @@ -1017,14 +1038,19 @@ class QAPISchema: > def _make_variant(self, case, typ, ifcond, info): > return QAPISchemaVariant(case, info, typ, ifcond) > > - def _make_simple_variant(self, case, typ, ifcond, info): > + def _make_simple_variant(self, union_name, case, typ, ifcond, info): > if isinstance(typ, list): > assert len(typ) == 1 > typ = self._make_array_type(typ[0], info) > - typ = self._make_implicit_object_type( > - typ, info, self.lookup_type(typ), > - 'wrapper', [self._make_member('data', typ, None, None, info)]) > - return QAPISchemaVariant(case, info, typ, ifcond) > + > + # The wrapper type is only used for introspection compatibility. > + # Don't add it to the entity list of the schema. > + wrapper_name = 'q_obj_%s-%s-wrapper' % (union_name, case) > + wrapper_member = self._make_member('data', typ, None, None, info) > + wrapper_type = QAPISchemaObjectType(wrapper_name, info, None, > ifcond, > + None, None, [wrapper_member], > None) > + return QAPISchemaVariant(case, info, typ, ifcond, flat=False, > + wrapper_type=wrapper_type) > > def _def_union_type(self, expr, info, doc): > name = expr['union'] > @@ -1044,7 +1070,7 @@ class QAPISchema: > for (key, value) in data.items()] > members = [] > else: > - variants = [self._make_simple_variant(key, value['type'], > + variants = [self._make_simple_variant(name, key, > value['type'], > value.get('if'), info) > for (key, value) in data.items()] > enum = [{'name': v.name, 'if': v.ifcond} for v in variants] > diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py > index 339f152152..f72567cbcc 100644 > --- a/scripts/qapi/visit.py > +++ b/scripts/qapi/visit.py > @@ -118,6 +118,34 @@ bool visit_type_%(c_name)s_members(Visitor *v, > %(c_name)s *obj, Error **errp) > break; > ''', > case=case_str) > + elif not isinstance(var.type, QAPISchemaObjectType): > + assert not var.flat > + ret += mcgen(''' > + case %(case)s: > + return visit_type_%(c_type)s(v, "data", &obj->u.%(c_name)s, errp); > +''', > + case=case_str, > + c_type=var.type.c_name(), c_name=c_name( > var.name)) > + elif var.wrapped: > + ret += mcgen(''' > + case %(case)s: > + { > + bool ok; > + > + if (!visit_start_struct(v, "data", NULL, 0, errp)) { > + return false; > + } > + ok = visit_type_%(c_type)s_members(v, &obj->u.%(c_name)s, errp); > + if (ok) { > + ok = visit_check_struct(v, errp); > + } > + visit_end_struct(v, NULL); > + return ok; > + } > +''', > + case=case_str, > + c_type=var.type.c_name(), c_name=c_name( > var.name)) > + > else: > ret += mcgen(''' > case %(case)s: > diff --git a/tests/qapi-schema/doc-good.out > b/tests/qapi-schema/doc-good.out > index 419284dae2..bcbcbd2fce 100644 > --- a/tests/qapi-schema/doc-good.out > +++ b/tests/qapi-schema/doc-good.out > @@ -31,10 +31,6 @@ object Object > case two: Variant2 > if ['IFTWO'] > feature union-feat1 > -object q_obj_Variant1-wrapper > - member data: Variant1 optional=False > -object q_obj_Variant2-wrapper > - member data: Variant2 optional=False > enum SugaredUnionKind > member one > member two > @@ -42,8 +38,8 @@ enum SugaredUnionKind > object SugaredUnion > member type: SugaredUnionKind optional=False > tag type > - case one: q_obj_Variant1-wrapper > - case two: q_obj_Variant2-wrapper > + case one: Variant1 > + case two: Variant2 > if ['IFTWO'] > feature union-feat2 > alternate Alternate > diff --git a/tests/qapi-schema/qapi-schema-test.out > b/tests/qapi-schema/qapi-schema-test.out > index 8868ca0dca..a4e4051c61 100644 > --- a/tests/qapi-schema/qapi-schema-test.out > +++ b/tests/qapi-schema/qapi-schema-test.out > @@ -125,36 +125,6 @@ alternate AltStrObj > tag type > case s: str > case o: TestStruct > -object q_obj_intList-wrapper > - member data: intList optional=False > -object q_obj_int8List-wrapper > - member data: int8List optional=False > -object q_obj_int16List-wrapper > - member data: int16List optional=False > -object q_obj_int32List-wrapper > - member data: int32List optional=False > -object q_obj_int64List-wrapper > - member data: int64List optional=False > -object q_obj_uint8List-wrapper > - member data: uint8List optional=False > -object q_obj_uint16List-wrapper > - member data: uint16List optional=False > -object q_obj_uint32List-wrapper > - member data: uint32List optional=False > -object q_obj_uint64List-wrapper > - member data: uint64List optional=False > -object q_obj_numberList-wrapper > - member data: numberList optional=False > -object q_obj_boolList-wrapper > - member data: boolList optional=False > -object q_obj_strList-wrapper > - member data: strList optional=False > -object q_obj_sizeList-wrapper > - member data: sizeList optional=False > -object q_obj_anyList-wrapper > - member data: anyList optional=False > -object q_obj_StatusList-wrapper > - member data: StatusList optional=False > enum UserDefListUnionKind > member integer > member s8 > @@ -174,21 +144,21 @@ enum UserDefListUnionKind > object UserDefListUnion > member type: UserDefListUnionKind optional=False > tag type > - case integer: q_obj_intList-wrapper > - case s8: q_obj_int8List-wrapper > - case s16: q_obj_int16List-wrapper > - case s32: q_obj_int32List-wrapper > - case s64: q_obj_int64List-wrapper > - case u8: q_obj_uint8List-wrapper > - case u16: q_obj_uint16List-wrapper > - case u32: q_obj_uint32List-wrapper > - case u64: q_obj_uint64List-wrapper > - case number: q_obj_numberList-wrapper > - case boolean: q_obj_boolList-wrapper > - case string: q_obj_strList-wrapper > - case sizes: q_obj_sizeList-wrapper > - case any: q_obj_anyList-wrapper > - case user: q_obj_StatusList-wrapper > + case integer: intList > + case s8: int8List > + case s16: int16List > + case s32: int32List > + case s64: int64List > + case u8: uint8List > + case u16: uint16List > + case u32: uint32List > + case u64: uint64List > + case number: numberList > + case boolean: boolList > + case string: strList > + case sizes: sizeList > + case any: anyList > + case user: StatusList > include include/sub-module.json > command user_def_cmd None -> None > gen=True success_response=True boxed=False oob=False preconfig=False > @@ -263,14 +233,12 @@ object __org.qemu_x-Struct > base __org.qemu_x-Base > member __org.qemu_x-member2: str optional=False > member wchar-t: int optional=True > -object q_obj_str-wrapper > - member data: str optional=False > enum __org.qemu_x-Union1Kind > member __org.qemu_x-branch > object __org.qemu_x-Union1 > member type: __org.qemu_x-Union1Kind optional=False > tag type > - case __org.qemu_x-branch: q_obj_str-wrapper > + case __org.qemu_x-branch: str > alternate __org.qemu_x-Alt1 > tag type > case __org.qemu_x-branch: str > @@ -305,8 +273,6 @@ enum TestIfEnum > member bar > if ['defined(TEST_IF_ENUM_BAR)'] > if ['defined(TEST_IF_ENUM)'] > -object q_obj_TestStruct-wrapper > - member data: TestStruct optional=False > enum TestIfUnionKind > member foo > member union_bar > @@ -315,8 +281,8 @@ enum TestIfUnionKind > object TestIfUnion > member type: TestIfUnionKind optional=False > tag type > - case foo: q_obj_TestStruct-wrapper > - case union_bar: q_obj_str-wrapper > + case foo: TestStruct > + case union_bar: str > if ['defined(TEST_IF_UNION_BAR)'] > if ['defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)'] > object q_obj_TestIfUnionCmd-arg > -- > 2.28.0 > > > -- Marc-André Lureau <div dir="ltr"><div dir="ltr">Hi<br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Oct 23, 2020 at 2:14 PM Kevin Wolf <<a href="mailto:kwolf@redhat.com">kwolf@redhat.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Variants of simple unions are always contained in a wrapper object<br> called 'data' that serves no real use. When mapping a QAPI object to the<br> command line, this becomes very visible to users because they have to<br> add one or more useless 'data.' to many option names.<br> <br> As a first step towards avoiding this painful CLI experience, this gets<br> rid of the 'data' indirection internally: The QAPI parser doesn't use a<br> wrapper object as the variant type any more, so the indirection is<br> removed from the generated C types. As a result, the C type looks the<br> same for flat and simple unions now. A large part of this patch is<br> mechanical conversion of C code to remove the 'data' indirection.<br> <br> Conceptually, the important change is that variants can now have flat<br> and wrapped representations. For a transitioning period, we'll allow<br> variants to support both representations in a later patch. Eventually,<br> the plan is to deprecate and remove wrapped representations entirely,<br> unifying simple and flat unions.<br> <br> The externally visible interfaces stay unchanged: Visitors still expect<br> the 'data' wrappers, and introspection still shows it.<br> <br> Signed-off-by: Kevin Wolf <<a href="mailto:kwolf@redhat.com" target="_blank">kwolf@redhat.com</a>><br></blockquote><div><br></div><div>breaks the build for me:<br></div><div><br></div><div>../chardev/spice.c: In function ‘qemu_chr_open_spice_vmc’:<br>../chardev/spice.c:261:56: error: ‘ChardevSpiceChannel’ has no member named ‘data’<br> 261 | ChardevSpiceChannel *spicevmc = backend->u.spicevmc.data;<br> | ^<br>../chardev/spice.c: In function ‘qemu_chr_open_spice_port’:<br>../chardev/spice.c:297:55: error: ‘ChardevSpicePort’ has no member named ‘data’<br> 297 | ChardevSpicePort *spiceport = backend->u.spiceport.data;<br> | ^<br>../chardev/spice.c: In function ‘qemu_chr_parse_spice_vmc’:<br>../chardev/spice.c:331:35: error: ‘ChardevSpiceChannel’ has no member named ‘data’<br> 331 | spicevmc = backend->u.spicevmc.data = g_new0(ChardevSpiceChannel, 1);<br> | ^<br>../chardev/spice.c: In function ‘qemu_chr_parse_spice_port’:<br>../chardev/spice.c:347:37: error: ‘ChardevSpicePort’ has no member named ‘data’<br> 347 | spiceport = backend->u.spiceport.data = g_new0(ChardevSpicePort, 1);<br> | ^<br>../ui/spice-app.c: In function ‘chr_spice_backend_new’:<br>../ui/spice-app.c:63:20: error: ‘ChardevSpicePort’ has no member named ‘data’<br> 63 | be->u.spiceport.data = g_new0(ChardevSpicePort, 1);<br> | ^<br>../ui/spice-app.c: In function ‘vc_chr_open’:<br>../ui/spice-app.c:86:20: error: ‘ChardevSpicePort’ has no member named ‘data’<br> 86 | be->u.spiceport.data->fqdn = fqdn ?<br> | ^<br>../ui/spice-app.c: In function ‘spice_app_display_init’:<br>../ui/spice-app.c:185:20: error: ‘ChardevSpicePort’ has no member named ‘data’<br> 185 | be->u.spiceport.data->fqdn = g_strdup("org.qemu.monitor.qmp.0");<br> | ^<br> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> ---<br> docs/devel/qapi-code-gen.txt | 32 ++++++++----<br> backends/tpm/tpm_emulator.c | 3 +-<br> backends/tpm/tpm_passthrough.c | 4 +-<br> block/crypto.c | 3 +-<br> block/qcow2.c | 9 ++--<br> block/vmdk.c | 14 ++----<br> blockdev.c | 36 ++++++-------<br> chardev/char-file.c | 5 +-<br> chardev/char-mux.c | 5 +-<br> chardev/char-parallel.c | 5 +-<br> chardev/char-pipe.c | 7 ++-<br> chardev/char-ringbuf.c | 5 +-<br> chardev/char-serial.c | 5 +-<br> chardev/char-socket.c | 13 ++---<br> chardev/char-stdio.c | 5 +-<br> chardev/char-udp.c | 11 ++--<br> chardev/char.c | 10 ++--<br> chardev/msmouse.c | 4 +-<br> chardev/wctablet.c | 4 +-<br> hw/core/numa.c | 6 +--<br> hw/display/xenfb.c | 8 +--<br> hw/input/hid.c | 8 +--<br> hw/input/ps2.c | 6 +--<br> hw/input/virtio-input-hid.c | 8 +--<br> hw/mem/pc-dimm.c | 18 +++----<br> hw/virtio/virtio-mem-pci.c | 3 +-<br> hw/virtio/virtio-pmem-pci.c | 3 +-<br> monitor/hmp-cmds.c | 14 +++---<br> qemu-keymap.c | 2 +-<br> replay/replay-input.c | 46 +++++++----------<br> tests/test-char.c | 12 ++---<br> tests/test-clone-visitor.c | 14 +++---<br> tests/test-qmp-cmds.c | 2 +-<br> tests/test-qobject-input-visitor.c | 24 ++++-----<br> tests/test-qobject-output-visitor.c | 24 ++++-----<br> ui/console.c | 5 +-<br> ui/input-keymap.c | 12 ++---<br> ui/input-legacy.c | 12 ++---<br> ui/input.c | 43 ++++++++--------<br> util/qemu-sockets.c | 8 +--<br> scripts/qapi/introspect.py | 7 ++-<br> scripts/qapi/schema.py | 48 ++++++++++++++----<br> scripts/qapi/visit.py | 28 +++++++++++<br> tests/qapi-schema/doc-good.out | 8 +--<br> tests/qapi-schema/qapi-schema-test.out | 70 +++++++-------------------<br> 45 files changed, 308 insertions(+), 311 deletions(-)<br> <br> diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt<br> index c6438c6aa9..9722c1a204 100644<br> --- a/docs/devel/qapi-code-gen.txt<br> +++ b/docs/devel/qapi-code-gen.txt<br> @@ -310,7 +310,20 @@ The BRANCH's STRING name is the branch name.<br> The BRANCH's value defines the branch's properties, in particular its<br> type. The form TYPE-REF is shorthand for { 'type': TYPE-REF }.<br> <br> -A simple union type defines a mapping from automatic discriminator<br> +Each branch can have flat or wrapped representation in the Client JSON<br> +Protocol.<br> +<br> +Wrapped representation of a branch means that it is represented by a<br> +'data' member that is of the specified data type corresponding to the<br> +discriminator value.<br> +<br> +Flat representation means that the union forms a single object that<br> +contains both common members (from the base type) and the selected<br> +branch's members, without any additional nesting. The two sets of<br> +member names must be disjoint.<br> +<br> +A simple union type automatically contains the 'type' member as a<br> +discriminator and defines a mapping from automatic discriminator<br> values to data types like in this example:<br> <br> { 'struct': 'BlockdevOptionsFile', 'data': { 'filename': 'str' } }<br> @@ -321,10 +334,8 @@ values to data types like in this example:<br> 'data': { 'file': 'BlockdevOptionsFile',<br> 'qcow2': 'BlockdevOptionsQcow2' } }<br> <br> -In the Client JSON Protocol, a simple union is represented by an<br> -object that contains the 'type' member as a discriminator, and a<br> -'data' member that is of the specified data type corresponding to the<br> -discriminator value, as in these examples:<br> +In the Client JSON Protocol, all simple union branches have wrapped<br> +representation, as in these examples:<br> <br> { "type": "file", "data": { "filename": "/some/place/my-image" } }<br> { "type": "qcow2", "data": { "backing": "/some/place/my-image",<br> @@ -344,13 +355,12 @@ object, it defines common members just like a struct type's 'data'<br> member defines struct type members. If it is a STRING, it names a<br> struct type whose members are the common members.<br> <br> -All flat union branches must be of struct type.<br> +Member 'discriminator' must name a non-optional enum-typed member of<br> +the base struct and defines the option that should server as the<br> +discrimiator.<br> <br> -In the Client JSON Protocol, a flat union is represented by an object<br> -with the common members (from the base type) and the selected branch's<br> -members. The two sets of member names must be disjoint. Member<br> -'discriminator' must name a non-optional enum-typed member of the base<br> -struct.<br> +All flat union branches must be of struct type. They have always flat<br> +representation.<br> <br> The following example enhances the above simple union example by<br> adding an optional common member 'read-only', renaming the<br> diff --git a/backends/tpm/tpm_emulator.c b/backends/tpm/tpm_emulator.c<br> index 201cd38503..7d2dc2b19d 100644<br> --- a/backends/tpm/tpm_emulator.c<br> +++ b/backends/tpm/tpm_emulator.c<br> @@ -629,7 +629,8 @@ static TpmTypeOptions *tpm_emulator_get_tpm_options(TPMBackend *tb)<br> TpmTypeOptions *options = g_new0(TpmTypeOptions, 1);<br> <br> options->type = TPM_TYPE_OPTIONS_KIND_EMULATOR;<br> - options->u.emulator.data = QAPI_CLONE(TPMEmulatorOptions, tpm_emu->options);<br> + QAPI_CLONE_MEMBERS(TPMEmulatorOptions, &options->u.emulator,<br> + tpm_emu->options);<br> <br> return options;<br> }<br> diff --git a/backends/tpm/tpm_passthrough.c b/backends/tpm/tpm_passthrough.c<br> index 8f6f4998a5..7fa7c84f5a 100644<br> --- a/backends/tpm/tpm_passthrough.c<br> +++ b/backends/tpm/tpm_passthrough.c<br> @@ -322,8 +322,8 @@ static TpmTypeOptions *tpm_passthrough_get_tpm_options(TPMBackend *tb)<br> TpmTypeOptions *options = g_new0(TpmTypeOptions, 1);<br> <br> options->type = TPM_TYPE_OPTIONS_KIND_PASSTHROUGH;<br> - options->u.passthrough.data = QAPI_CLONE(TPMPassthroughOptions,<br> - TPM_PASSTHROUGH(tb)->options);<br> + QAPI_CLONE_MEMBERS(TPMPassthroughOptions, &options->u.passthrough,<br> + TPM_PASSTHROUGH(tb)->options);<br> <br> return options;<br> }<br> diff --git a/block/crypto.c b/block/crypto.c<br> index 0807557763..0e7838d70a 100644<br> --- a/block/crypto.c<br> +++ b/block/crypto.c<br> @@ -775,8 +775,7 @@ block_crypto_get_specific_info_luks(BlockDriverState *bs, Error **errp)<br> <br> spec_info = g_new(ImageInfoSpecific, 1);<br> spec_info->type = IMAGE_INFO_SPECIFIC_KIND_LUKS;<br> - spec_info->u.luks.data = g_new(QCryptoBlockInfoLUKS, 1);<br> - *spec_info->u.luks.data = info->u.luks;<br> + spec_info->u.luks = info->u.luks;<br> <br> /* Blank out pointers we've just stolen to avoid double free */<br> memset(&info->u.luks, 0, sizeof(info->u.luks));<br> diff --git a/block/qcow2.c b/block/qcow2.c<br> index b05512718c..104fd8ad06 100644<br> --- a/block/qcow2.c<br> +++ b/block/qcow2.c<br> @@ -5052,10 +5052,9 @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs,<br> spec_info = g_new(ImageInfoSpecific, 1);<br> *spec_info = (ImageInfoSpecific){<br> .type = IMAGE_INFO_SPECIFIC_KIND_QCOW2,<br> - .u.qcow2.data = g_new0(ImageInfoSpecificQCow2, 1),<br> };<br> if (s->qcow_version == 2) {<br> - *spec_info->u.qcow2.data = (ImageInfoSpecificQCow2){<br> + spec_info->u.qcow2 = (ImageInfoSpecificQCow2){<br> .compat = g_strdup("0.10"),<br> .refcount_bits = s->refcount_bits,<br> };<br> @@ -5068,7 +5067,7 @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs,<br> qapi_free_QCryptoBlockInfo(encrypt_info);<br> return NULL;<br> }<br> - *spec_info->u.qcow2.data = (ImageInfoSpecificQCow2){<br> + spec_info->u.qcow2 = (ImageInfoSpecificQCow2){<br> .compat = g_strdup("1.1"),<br> .lazy_refcounts = s->compatible_features &<br> QCOW2_COMPAT_LAZY_REFCOUNTS,<br> @@ -5112,8 +5111,8 @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs,<br> memset(&encrypt_info->u, 0, sizeof(encrypt_info->u));<br> qapi_free_QCryptoBlockInfo(encrypt_info);<br> <br> - spec_info->u.qcow2.data->has_encrypt = true;<br> - spec_info->u.qcow2.data->encrypt = qencrypt;<br> + spec_info->u.qcow2.has_encrypt = true;<br> + spec_info->u.qcow2.encrypt = qencrypt;<br> }<br> <br> return spec_info;<br> diff --git a/block/vmdk.c b/block/vmdk.c<br> index a00dc00eb4..fc4ddcc351 100644<br> --- a/block/vmdk.c<br> +++ b/block/vmdk.c<br> @@ -2932,18 +2932,14 @@ static ImageInfoSpecific *vmdk_get_specific_info(BlockDriverState *bs,<br> <br> *spec_info = (ImageInfoSpecific){<br> .type = IMAGE_INFO_SPECIFIC_KIND_VMDK,<br> - .u = {<br> - .vmdk.data = g_new0(ImageInfoSpecificVmdk, 1),<br> + .u.vmdk = (ImageInfoSpecificVmdk) {<br> + .create_type = g_strdup(s->create_type),<br> + .cid = s->cid,<br> + .parent_cid = s->parent_cid,<br> },<br> };<br> <br> - *spec_info->u.vmdk.data = (ImageInfoSpecificVmdk) {<br> - .create_type = g_strdup(s->create_type),<br> - .cid = s->cid,<br> - .parent_cid = s->parent_cid,<br> - };<br> -<br> - next = &spec_info->u.vmdk.data->extents;<br> + next = &spec_info->u.vmdk.extents;<br> for (i = 0; i < s->num_extents; i++) {<br> *next = g_new0(ImageInfoList, 1);<br> (*next)->value = vmdk_get_extent_info(&s->extents[i]);<br> diff --git a/blockdev.c b/blockdev.c<br> index fe6fb5dc1d..2602298a26 100644<br> --- a/blockdev.c<br> +++ b/blockdev.c<br> @@ -1090,7 +1090,7 @@ void qmp_blockdev_snapshot_sync(bool has_device, const char *device,<br> };<br> TransactionAction action = {<br> .type = TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC,<br> - .u.blockdev_snapshot_sync.data = &snapshot,<br> + .u.blockdev_snapshot_sync = snapshot,<br> };<br> blockdev_do_action(&action, errp);<br> }<br> @@ -1104,7 +1104,7 @@ void qmp_blockdev_snapshot(const char *node, const char *overlay,<br> };<br> TransactionAction action = {<br> .type = TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT,<br> - .u.blockdev_snapshot.data = &snapshot_data,<br> + .u.blockdev_snapshot = snapshot_data,<br> };<br> blockdev_do_action(&action, errp);<br> }<br> @@ -1119,7 +1119,7 @@ void qmp_blockdev_snapshot_internal_sync(const char *device,<br> };<br> TransactionAction action = {<br> .type = TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC,<br> - .u.blockdev_snapshot_internal_sync.data = &snapshot,<br> + .u.blockdev_snapshot_internal_sync = snapshot,<br> };<br> blockdev_do_action(&action, errp);<br> }<br> @@ -1289,7 +1289,7 @@ static void internal_snapshot_prepare(BlkActionState *common,<br> <br> g_assert(common->action->type ==<br> TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC);<br> - internal = common->action->u.blockdev_snapshot_internal_sync.data;<br> + internal = &common->action->u.blockdev_snapshot_internal_sync;<br> state = DO_UPCAST(InternalSnapshotState, common, common);<br> <br> /* 1. parse input */<br> @@ -1453,7 +1453,7 @@ static void external_snapshot_prepare(BlkActionState *common,<br> switch (action->type) {<br> case TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT:<br> {<br> - BlockdevSnapshot *s = action->u.blockdev_snapshot.data;<br> + BlockdevSnapshot *s = &action->u.blockdev_snapshot;<br> device = s->node;<br> node_name = s->node;<br> new_image_file = NULL;<br> @@ -1462,7 +1462,7 @@ static void external_snapshot_prepare(BlkActionState *common,<br> break;<br> case TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC:<br> {<br> - BlockdevSnapshotSync *s = action->u.blockdev_snapshot_sync.data;<br> + BlockdevSnapshotSync *s = &action->u.blockdev_snapshot_sync;<br> device = s->has_device ? s->device : NULL;<br> node_name = s->has_node_name ? s->node_name : NULL;<br> new_image_file = s->snapshot_file;<br> @@ -1507,7 +1507,7 @@ static void external_snapshot_prepare(BlkActionState *common,<br> }<br> <br> if (action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC) {<br> - BlockdevSnapshotSync *s = action->u.blockdev_snapshot_sync.data;<br> + BlockdevSnapshotSync *s = &action->u.blockdev_snapshot_sync;<br> const char *format = s->has_format ? s->format : "qcow2";<br> enum NewImageMode mode;<br> const char *snapshot_node_name =<br> @@ -1712,7 +1712,7 @@ static void drive_backup_prepare(BlkActionState *common, Error **errp)<br> int ret;<br> <br> assert(common->action->type == TRANSACTION_ACTION_KIND_DRIVE_BACKUP);<br> - backup = common->action->u.drive_backup.data;<br> + backup = &common->action->u.drive_backup;<br> <br> if (!backup->has_mode) {<br> backup->mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;<br> @@ -1907,7 +1907,7 @@ static void blockdev_backup_prepare(BlkActionState *common, Error **errp)<br> int ret;<br> <br> assert(common->action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP);<br> - backup = common->action->u.blockdev_backup.data;<br> + backup = &common->action->u.blockdev_backup;<br> <br> bs = bdrv_lookup_bs(backup->device, backup->device, errp);<br> if (!bs) {<br> @@ -2012,7 +2012,7 @@ static void block_dirty_bitmap_add_prepare(BlkActionState *common,<br> return;<br> }<br> <br> - action = common->action->u.block_dirty_bitmap_add.data;<br> + action = &common->action->u.block_dirty_bitmap_add;<br> /* AIO context taken and released within qmp_block_dirty_bitmap_add */<br> qmp_block_dirty_bitmap_add(action->node, action->name,<br> action->has_granularity, action->granularity,<br> @@ -2033,7 +2033,7 @@ static void block_dirty_bitmap_add_abort(BlkActionState *common)<br> BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState,<br> common, common);<br> <br> - action = common->action->u.block_dirty_bitmap_add.data;<br> + action = &common->action->u.block_dirty_bitmap_add;<br> /* Should not be able to fail: IF the bitmap was added via .prepare(),<br> * then the node reference and bitmap name must have been valid.<br> */<br> @@ -2053,7 +2053,7 @@ static void block_dirty_bitmap_clear_prepare(BlkActionState *common,<br> return;<br> }<br> <br> - action = common->action->u.block_dirty_bitmap_clear.data;<br> + action = &common->action->u.block_dirty_bitmap_clear;<br> state->bitmap = block_dirty_bitmap_lookup(action->node,<br> action->name,<br> &state->bs,<br> @@ -2098,7 +2098,7 @@ static void block_dirty_bitmap_enable_prepare(BlkActionState *common,<br> return;<br> }<br> <br> - action = common->action->u.block_dirty_bitmap_enable.data;<br> + action = &common->action->u.block_dirty_bitmap_enable;<br> state->bitmap = block_dirty_bitmap_lookup(action->node,<br> action->name,<br> NULL,<br> @@ -2136,7 +2136,7 @@ static void block_dirty_bitmap_disable_prepare(BlkActionState *common,<br> return;<br> }<br> <br> - action = common->action->u.block_dirty_bitmap_disable.data;<br> + action = &common->action->u.block_dirty_bitmap_disable;<br> state->bitmap = block_dirty_bitmap_lookup(action->node,<br> action->name,<br> NULL,<br> @@ -2174,7 +2174,7 @@ static void block_dirty_bitmap_merge_prepare(BlkActionState *common,<br> return;<br> }<br> <br> - action = common->action->u.block_dirty_bitmap_merge.data;<br> + action = &common->action->u.block_dirty_bitmap_merge;<br> <br> state->bitmap = block_dirty_bitmap_merge(action->node, action->target,<br> action->bitmaps, &state->backup,<br> @@ -2192,7 +2192,7 @@ static void block_dirty_bitmap_remove_prepare(BlkActionState *common,<br> return;<br> }<br> <br> - action = common->action->u.block_dirty_bitmap_remove.data;<br> + action = &common->action->u.block_dirty_bitmap_remove;<br> <br> state->bitmap = block_dirty_bitmap_remove(action->node, action->name,<br> false, &state->bs, errp);<br> @@ -2895,7 +2895,7 @@ void qmp_drive_backup(DriveBackup *backup, Error **errp)<br> {<br> TransactionAction action = {<br> .type = TRANSACTION_ACTION_KIND_DRIVE_BACKUP,<br> - .u.drive_backup.data = backup,<br> + .u.drive_backup = *backup,<br> };<br> blockdev_do_action(&action, errp);<br> }<br> @@ -2918,7 +2918,7 @@ void qmp_blockdev_backup(BlockdevBackup *backup, Error **errp)<br> {<br> TransactionAction action = {<br> .type = TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP,<br> - .u.blockdev_backup.data = backup,<br> + .u.blockdev_backup = *backup,<br> };<br> blockdev_do_action(&action, errp);<br> }<br> diff --git a/chardev/char-file.c b/chardev/char-file.c<br> index 2fd80707e5..3f0f0b6045 100644<br> --- a/chardev/char-file.c<br> +++ b/chardev/char-file.c<br> @@ -39,7 +39,7 @@ static void qmp_chardev_open_file(Chardev *chr,<br> bool *be_opened,<br> Error **errp)<br> {<br> - ChardevFile *file = backend->u.file.data;<br> + ChardevFile *file = &backend->u.file;<br> #ifdef _WIN32<br> HANDLE out;<br> DWORD accessmode;<br> @@ -100,14 +100,13 @@ static void qemu_chr_parse_file_out(QemuOpts *opts, ChardevBackend *backend,<br> Error **errp)<br> {<br> const char *path = qemu_opt_get(opts, "path");<br> - ChardevFile *file;<br> + ChardevFile *file = &backend->u.file;<br> <br> backend->type = CHARDEV_BACKEND_KIND_FILE;<br> if (path == NULL) {<br> error_setg(errp, "chardev: file: no filename given");<br> return;<br> }<br> - file = backend->u.file.data = g_new0(ChardevFile, 1);<br> qemu_chr_parse_common(opts, qapi_ChardevFile_base(file));<br> file->out = g_strdup(path);<br> <br> diff --git a/chardev/char-mux.c b/chardev/char-mux.c<br> index 6f980bb836..bfb4bc6b8b 100644<br> --- a/chardev/char-mux.c<br> +++ b/chardev/char-mux.c<br> @@ -314,7 +314,7 @@ static void qemu_chr_open_mux(Chardev *chr,<br> bool *be_opened,<br> Error **errp)<br> {<br> - ChardevMux *mux = backend->u.mux.data;<br> + ChardevMux *mux = &backend->u.mux;<br> Chardev *drv;<br> MuxChardev *d = MUX_CHARDEV(chr);<br> <br> @@ -336,14 +336,13 @@ static void qemu_chr_parse_mux(QemuOpts *opts, ChardevBackend *backend,<br> Error **errp)<br> {<br> const char *chardev = qemu_opt_get(opts, "chardev");<br> - ChardevMux *mux;<br> + ChardevMux *mux = &backend->u.mux;<br> <br> if (chardev == NULL) {<br> error_setg(errp, "chardev: mux: no chardev given");<br> return;<br> }<br> backend->type = CHARDEV_BACKEND_KIND_MUX;<br> - mux = backend->u.mux.data = g_new0(ChardevMux, 1);<br> qemu_chr_parse_common(opts, qapi_ChardevMux_base(mux));<br> mux->chardev = g_strdup(chardev);<br> }<br> diff --git a/chardev/char-parallel.c b/chardev/char-parallel.c<br> index 05e7efbd6c..a17157a3be 100644<br> --- a/chardev/char-parallel.c<br> +++ b/chardev/char-parallel.c<br> @@ -244,7 +244,7 @@ static void qmp_chardev_open_parallel(Chardev *chr,<br> bool *be_opened,<br> Error **errp)<br> {<br> - ChardevHostdev *parallel = backend->u.parallel.data;<br> + ChardevHostdev *parallel = &backend->u.parallel;<br> int fd;<br> <br> fd = qmp_chardev_open_file_source(parallel->device, O_RDWR, errp);<br> @@ -258,14 +258,13 @@ static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend,<br> Error **errp)<br> {<br> const char *device = qemu_opt_get(opts, "path");<br> - ChardevHostdev *parallel;<br> + ChardevHostdev *parallel = &backend->u.parallel;<br> <br> if (device == NULL) {<br> error_setg(errp, "chardev: parallel: no device path given");<br> return;<br> }<br> backend->type = CHARDEV_BACKEND_KIND_PARALLEL;<br> - parallel = backend->u.parallel.data = g_new0(ChardevHostdev, 1);<br> qemu_chr_parse_common(opts, qapi_ChardevHostdev_base(parallel));<br> parallel->device = g_strdup(device);<br> }<br> diff --git a/chardev/char-pipe.c b/chardev/char-pipe.c<br> index 7eca5d9a56..eb19d9a526 100644<br> --- a/chardev/char-pipe.c<br> +++ b/chardev/char-pipe.c<br> @@ -109,7 +109,7 @@ static void qemu_chr_open_pipe(Chardev *chr,<br> bool *be_opened,<br> Error **errp)<br> {<br> - ChardevHostdev *opts = backend->u.pipe.data;<br> + ChardevHostdev *opts = &backend->u.pipe;<br> const char *filename = opts->device;<br> <br> if (win_chr_pipe_init(chr, filename, errp) < 0) {<br> @@ -124,7 +124,7 @@ static void qemu_chr_open_pipe(Chardev *chr,<br> bool *be_opened,<br> Error **errp)<br> {<br> - ChardevHostdev *opts = backend->u.pipe.data;<br> + ChardevHostdev *opts = &backend->u.pipe;<br> int fd_in, fd_out;<br> char *filename_in;<br> char *filename_out;<br> @@ -158,14 +158,13 @@ static void qemu_chr_parse_pipe(QemuOpts *opts, ChardevBackend *backend,<br> Error **errp)<br> {<br> const char *device = qemu_opt_get(opts, "path");<br> - ChardevHostdev *dev;<br> + ChardevHostdev *dev = &backend->u.pipe;<br> <br> if (device == NULL) {<br> error_setg(errp, "chardev: pipe: no device path given");<br> return;<br> }<br> backend->type = CHARDEV_BACKEND_KIND_PIPE;<br> - dev = backend->u.pipe.data = g_new0(ChardevHostdev, 1);<br> qemu_chr_parse_common(opts, qapi_ChardevHostdev_base(dev));<br> dev->device = g_strdup(device);<br> }<br> diff --git a/chardev/char-ringbuf.c b/chardev/char-ringbuf.c<br> index d40d21d3cf..0ef2a17f90 100644<br> --- a/chardev/char-ringbuf.c<br> +++ b/chardev/char-ringbuf.c<br> @@ -97,7 +97,7 @@ static void qemu_chr_open_ringbuf(Chardev *chr,<br> bool *be_opened,<br> Error **errp)<br> {<br> - ChardevRingbuf *opts = backend->u.ringbuf.data;<br> + ChardevRingbuf *opts = &backend->u.ringbuf;<br> RingBufChardev *d = RINGBUF_CHARDEV(chr);<br> <br> d->size = opts->has_size ? opts->size : 65536;<br> @@ -210,10 +210,9 @@ static void qemu_chr_parse_ringbuf(QemuOpts *opts, ChardevBackend *backend,<br> Error **errp)<br> {<br> int val;<br> - ChardevRingbuf *ringbuf;<br> + ChardevRingbuf *ringbuf = &backend->u.ringbuf;<br> <br> backend->type = CHARDEV_BACKEND_KIND_RINGBUF;<br> - ringbuf = backend->u.ringbuf.data = g_new0(ChardevRingbuf, 1);<br> qemu_chr_parse_common(opts, qapi_ChardevRingbuf_base(ringbuf));<br> <br> val = qemu_opt_get_size(opts, "size", 0);<br> diff --git a/chardev/char-serial.c b/chardev/char-serial.c<br> index 7c3d84ae24..baec955ecf 100644<br> --- a/chardev/char-serial.c<br> +++ b/chardev/char-serial.c<br> @@ -263,7 +263,7 @@ static void qmp_chardev_open_serial(Chardev *chr,<br> bool *be_opened,<br> Error **errp)<br> {<br> - ChardevHostdev *serial = backend->u.serial.data;<br> + ChardevHostdev *serial = &backend->u.serial;<br> int fd;<br> <br> fd = qmp_chardev_open_file_source(serial->device, O_RDWR | O_NONBLOCK,<br> @@ -283,14 +283,13 @@ static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend,<br> Error **errp)<br> {<br> const char *device = qemu_opt_get(opts, "path");<br> - ChardevHostdev *serial;<br> + ChardevHostdev *serial = &backend->u.serial;<br> <br> if (device == NULL) {<br> error_setg(errp, "chardev: serial/tty: no device path given");<br> return;<br> }<br> backend->type = CHARDEV_BACKEND_KIND_SERIAL;<br> - serial = backend->u.serial.data = g_new0(ChardevHostdev, 1);<br> qemu_chr_parse_common(opts, qapi_ChardevHostdev_base(serial));<br> serial->device = g_strdup(device);<br> }<br> diff --git a/chardev/char-socket.c b/chardev/char-socket.c<br> index 95e45812d5..5332439d34 100644<br> --- a/chardev/char-socket.c<br> +++ b/chardev/char-socket.c<br> @@ -1301,7 +1301,7 @@ static void qmp_chardev_open_socket(Chardev *chr,<br> Error **errp)<br> {<br> SocketChardev *s = SOCKET_CHARDEV(chr);<br> - ChardevSocket *sock = backend->u.socket.data;<br> + ChardevSocket *sock = &backend->u.socket;<br> bool do_nodelay = sock->has_nodelay ? sock->nodelay : false;<br> bool is_listen = sock->has_server ? sock->server : true;<br> bool is_telnet = sock->has_telnet ? sock->telnet : false;<br> @@ -1403,7 +1403,7 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,<br> }<br> <br> backend->type = CHARDEV_BACKEND_KIND_SOCKET;<br> - sock = backend->u.socket.data = g_new0(ChardevSocket, 1);<br> + sock = &backend->u.socket;<br> qemu_chr_parse_common(opts, qapi_ChardevSocket_base(sock));<br> <br> sock->has_nodelay = qemu_opt_get(opts, "delay");<br> @@ -1435,16 +1435,14 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,<br> <br> addr = g_new0(SocketAddressLegacy, 1);<br> if (path) {<br> - UnixSocketAddress *q_unix;<br> + UnixSocketAddress *q_unix = &addr->u.q_unix;<br> addr->type = SOCKET_ADDRESS_LEGACY_KIND_UNIX;<br> - q_unix = addr->u.q_unix.data = g_new0(UnixSocketAddress, 1);<br> q_unix->path = g_strdup(path);<br> q_unix->tight = tight;<br> q_unix->abstract = abstract;<br> } else if (host) {<br> addr->type = SOCKET_ADDRESS_LEGACY_KIND_INET;<br> - addr->u.inet.data = g_new(InetSocketAddress, 1);<br> - *addr->u.inet.data = (InetSocketAddress) {<br> + addr->u.inet = (InetSocketAddress) {<br> .host = g_strdup(host),<br> .port = g_strdup(port),<br> .has_to = qemu_opt_get(opts, "to"),<br> @@ -1456,8 +1454,7 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,<br> };<br> } else if (fd) {<br> addr->type = SOCKET_ADDRESS_LEGACY_KIND_FD;<br> - addr->u.fd.data = g_new(String, 1);<br> - addr->u.fd.data->str = g_strdup(fd);<br> + addr->u.fd.str = g_strdup(fd);<br> } else {<br> g_assert_not_reached();<br> }<br> diff --git a/chardev/char-stdio.c b/chardev/char-stdio.c<br> index 403da308c9..81ee655a21 100644<br> --- a/chardev/char-stdio.c<br> +++ b/chardev/char-stdio.c<br> @@ -87,7 +87,7 @@ static void qemu_chr_open_stdio(Chardev *chr,<br> bool *be_opened,<br> Error **errp)<br> {<br> - ChardevStdio *opts = backend->u.stdio.data;<br> + ChardevStdio *opts = &backend->u.stdio;<br> struct sigaction act;<br> <br> if (is_daemonized()) {<br> @@ -120,10 +120,9 @@ static void qemu_chr_open_stdio(Chardev *chr,<br> static void qemu_chr_parse_stdio(QemuOpts *opts, ChardevBackend *backend,<br> Error **errp)<br> {<br> - ChardevStdio *stdio;<br> + ChardevStdio *stdio = &backend->u.stdio;<br> <br> backend->type = CHARDEV_BACKEND_KIND_STDIO;<br> - stdio = backend->u.stdio.data = g_new0(ChardevStdio, 1);<br> qemu_chr_parse_common(opts, qapi_ChardevStdio_base(stdio));<br> stdio->has_signal = true;<br> stdio->signal = qemu_opt_get_bool(opts, "signal", true);<br> diff --git a/chardev/char-udp.c b/chardev/char-udp.c<br> index 16b5dbce58..3b1bdddbbd 100644<br> --- a/chardev/char-udp.c<br> +++ b/chardev/char-udp.c<br> @@ -140,7 +140,7 @@ static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend,<br> const char *localport = qemu_opt_get(opts, "localport");<br> bool has_local = false;<br> SocketAddressLegacy *addr;<br> - ChardevUdp *udp;<br> + ChardevUdp *udp = &backend->u.udp;<br> <br> backend->type = CHARDEV_BACKEND_KIND_UDP;<br> if (host == NULL || strlen(host) == 0) {<br> @@ -161,13 +161,11 @@ static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend,<br> has_local = true;<br> }<br> <br> - udp = backend->u.udp.data = g_new0(ChardevUdp, 1);<br> qemu_chr_parse_common(opts, qapi_ChardevUdp_base(udp));<br> <br> addr = g_new0(SocketAddressLegacy, 1);<br> addr->type = SOCKET_ADDRESS_LEGACY_KIND_INET;<br> - addr->u.inet.data = g_new(InetSocketAddress, 1);<br> - *addr->u.inet.data = (InetSocketAddress) {<br> + addr->u.inet = (InetSocketAddress) {<br> .host = g_strdup(host),<br> .port = g_strdup(port),<br> .has_ipv4 = qemu_opt_get(opts, "ipv4"),<br> @@ -181,8 +179,7 @@ static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend,<br> udp->has_local = true;<br> addr = g_new0(SocketAddressLegacy, 1);<br> addr->type = SOCKET_ADDRESS_LEGACY_KIND_INET;<br> - addr->u.inet.data = g_new(InetSocketAddress, 1);<br> - *addr->u.inet.data = (InetSocketAddress) {<br> + addr->u.inet = (InetSocketAddress) {<br> .host = g_strdup(localaddr),<br> .port = g_strdup(localport),<br> };<br> @@ -195,7 +192,7 @@ static void qmp_chardev_open_udp(Chardev *chr,<br> bool *be_opened,<br> Error **errp)<br> {<br> - ChardevUdp *udp = backend->u.udp.data;<br> + ChardevUdp *udp = &backend->u.udp;<br> SocketAddress *local_addr = socket_address_flatten(udp->local);<br> SocketAddress *remote_addr = socket_address_flatten(udp->remote);<br> QIOChannelSocket *sioc = qio_channel_socket_new();<br> diff --git a/chardev/char.c b/chardev/char.c<br> index 028612c333..5192964694 100644<br> --- a/chardev/char.c<br> +++ b/chardev/char.c<br> @@ -238,7 +238,7 @@ static void qemu_char_open(Chardev *chr, ChardevBackend *backend,<br> {<br> ChardevClass *cc = CHARDEV_GET_CLASS(chr);<br> /* Any ChardevCommon member would work */<br> - ChardevCommon *common = backend ? backend->u.null.data : NULL;<br> + ChardevCommon *common = backend ? &backend->u.null : NULL;<br> <br> if (common && common->has_logfile) {<br> int flags = O_WRONLY | O_CREAT;<br> @@ -625,9 +625,8 @@ ChardevBackend *qemu_chr_parse_opts(QemuOpts *opts, Error **errp)<br> return NULL;<br> }<br> } else {<br> - ChardevCommon *ccom = g_new0(ChardevCommon, 1);<br> - qemu_chr_parse_common(opts, ccom);<br> - backend->u.null.data = ccom; /* Any ChardevCommon member would work */<br> + /* Any ChardevCommon member would work */<br> + qemu_chr_parse_common(opts, &backend->u.null);<br> }<br> <br> return backend;<br> @@ -690,8 +689,7 @@ Chardev *qemu_chr_new_from_opts(QemuOpts *opts, GMainContext *context,<br> qapi_free_ChardevBackend(backend);<br> backend = g_new0(ChardevBackend, 1);<br> backend->type = CHARDEV_BACKEND_KIND_MUX;<br> - backend->u.mux.data = g_new0(ChardevMux, 1);<br> - backend->u.mux.data->chardev = g_strdup(bid);<br> + backend->u.mux.chardev = g_strdup(bid);<br> mux = qemu_chardev_new(id, TYPE_CHARDEV_MUX, backend, context, errp);<br> if (mux == NULL) {<br> object_unparent(OBJECT(chr));<br> diff --git a/chardev/msmouse.c b/chardev/msmouse.c<br> index eb9231dcdb..98b0ef8cd7 100644<br> --- a/chardev/msmouse.c<br> +++ b/chardev/msmouse.c<br> @@ -111,12 +111,12 @@ static void msmouse_input_event(DeviceState *dev, QemuConsole *src,<br> <br> switch (evt->type) {<br> case INPUT_EVENT_KIND_REL:<br> - move = evt->u.rel.data;<br> + move = &evt->u.rel;<br> mouse->axis[move->axis] += move->value;<br> break;<br> <br> case INPUT_EVENT_KIND_BTN:<br> - btn = evt->u.btn.data;<br> + btn = &evt->u.btn;<br> mouse->btns[btn->button] = btn->down;<br> mouse->btnc[btn->button] = true;<br> break;<br> diff --git a/chardev/wctablet.c b/chardev/wctablet.c<br> index 95e005f5a5..8479f59183 100644<br> --- a/chardev/wctablet.c<br> +++ b/chardev/wctablet.c<br> @@ -154,12 +154,12 @@ static void wctablet_input_event(DeviceState *dev, QemuConsole *src,<br> <br> switch (evt->type) {<br> case INPUT_EVENT_KIND_ABS:<br> - move = evt->u.abs.data;<br> + move = &evt->u.abs;<br> tablet->axis[move->axis] = move->value;<br> break;<br> <br> case INPUT_EVENT_KIND_BTN:<br> - btn = evt->u.btn.data;<br> + btn = &evt->u.btn;<br> tablet->btns[btn->button] = btn->down;<br> break;<br> <br> diff --git a/hw/core/numa.c b/hw/core/numa.c<br> index 7c4dd4e68e..24fe0e11d8 100644<br> --- a/hw/core/numa.c<br> +++ b/hw/core/numa.c<br> @@ -765,19 +765,19 @@ static void numa_stat_memory_devices(NumaNodeMem node_mem[])<br> case MEMORY_DEVICE_INFO_KIND_DIMM:<br> case MEMORY_DEVICE_INFO_KIND_NVDIMM:<br> pcdimm_info = value->type == MEMORY_DEVICE_INFO_KIND_DIMM ?<br> - value->u.dimm.data : value->u.nvdimm.data;<br> + &value->u.dimm : &value->u.nvdimm;<br> node_mem[pcdimm_info->node].node_mem += pcdimm_info->size;<br> node_mem[pcdimm_info->node].node_plugged_mem +=<br> pcdimm_info->size;<br> break;<br> case MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM:<br> - vpi = value->u.virtio_pmem.data;<br> + vpi = &value->u.virtio_pmem;<br> /* TODO: once we support numa, assign to right node */<br> node_mem[0].node_mem += vpi->size;<br> node_mem[0].node_plugged_mem += vpi->size;<br> break;<br> case MEMORY_DEVICE_INFO_KIND_VIRTIO_MEM:<br> - vmi = value->u.virtio_mem.data;<br> + vmi = &value->u.virtio_mem;<br> node_mem[vmi->node].node_mem += vmi->size;<br> node_mem[vmi->node].node_plugged_mem += vmi->size;<br> break;<br> diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c<br> index 838260b6ad..6aa6010774 100644<br> --- a/hw/display/xenfb.c<br> +++ b/hw/display/xenfb.c<br> @@ -201,7 +201,7 @@ static void xenfb_key_event(DeviceState *dev, QemuConsole *src,<br> InputEvent *evt)<br> {<br> struct XenInput *xenfb = (struct XenInput *)dev;<br> - InputKeyEvent *key = evt->u.key.data;<br> + InputKeyEvent *key = &evt->u.key;<br> int qcode = qemu_input_key_value_to_qcode(key->key);<br> int lnx;<br> <br> @@ -236,7 +236,7 @@ static void xenfb_mouse_event(DeviceState *dev, QemuConsole *src,<br> <br> switch (evt->type) {<br> case INPUT_EVENT_KIND_BTN:<br> - btn = evt->u.btn.data;<br> + btn = &evt->u.btn;<br> switch (btn->button) {<br> case INPUT_BUTTON_LEFT:<br> xenfb_send_key(xenfb, btn->down, BTN_LEFT);<br> @@ -263,7 +263,7 @@ static void xenfb_mouse_event(DeviceState *dev, QemuConsole *src,<br> break;<br> <br> case INPUT_EVENT_KIND_ABS:<br> - move = evt->u.abs.data;<br> + move = &evt->u.abs;<br> if (xenfb->raw_pointer_wanted) {<br> xenfb->axis[move->axis] = move->value;<br> } else {<br> @@ -289,7 +289,7 @@ static void xenfb_mouse_event(DeviceState *dev, QemuConsole *src,<br> break;<br> <br> case INPUT_EVENT_KIND_REL:<br> - move = evt->u.rel.data;<br> + move = &evt->u.rel;<br> xenfb->axis[move->axis] += move->value;<br> break;<br> <br> diff --git a/hw/input/hid.c b/hw/input/hid.c<br> index 89239b5634..2472c5a902 100644<br> --- a/hw/input/hid.c<br> +++ b/hw/input/hid.c<br> @@ -126,7 +126,7 @@ static void hid_pointer_event(DeviceState *dev, QemuConsole *src,<br> <br> switch (evt->type) {<br> case INPUT_EVENT_KIND_REL:<br> - move = evt->u.rel.data;<br> + move = &evt->u.rel;<br> if (move->axis == INPUT_AXIS_X) {<br> e->xdx += move->value;<br> } else if (move->axis == INPUT_AXIS_Y) {<br> @@ -135,7 +135,7 @@ static void hid_pointer_event(DeviceState *dev, QemuConsole *src,<br> break;<br> <br> case INPUT_EVENT_KIND_ABS:<br> - move = evt->u.abs.data;<br> + move = &evt->u.abs;<br> if (move->axis == INPUT_AXIS_X) {<br> e->xdx = move->value;<br> } else if (move->axis == INPUT_AXIS_Y) {<br> @@ -144,7 +144,7 @@ static void hid_pointer_event(DeviceState *dev, QemuConsole *src,<br> break;<br> <br> case INPUT_EVENT_KIND_BTN:<br> - btn = evt->u.btn.data;<br> + btn = &evt->u.btn;<br> if (btn->down) {<br> e->buttons_state |= bmap[btn->button];<br> if (btn->button == INPUT_BUTTON_WHEEL_UP) {<br> @@ -230,7 +230,7 @@ static void hid_keyboard_event(DeviceState *dev, QemuConsole *src,<br> HIDState *hs = (HIDState *)dev;<br> int scancodes[3], i, count;<br> int slot;<br> - InputKeyEvent *key = evt->u.key.data;<br> + InputKeyEvent *key = &evt->u.key;<br> <br> count = qemu_input_key_value_to_scancode(key->key,<br> key->down,<br> diff --git a/hw/input/ps2.c b/hw/input/ps2.c<br> index f8746d2f52..1176ccc88c 100644<br> --- a/hw/input/ps2.c<br> +++ b/hw/input/ps2.c<br> @@ -284,7 +284,7 @@ static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,<br> InputEvent *evt)<br> {<br> PS2KbdState *s = (PS2KbdState *)dev;<br> - InputKeyEvent *key = evt->u.key.data;<br> + InputKeyEvent *key = &evt->u.key;<br> int qcode;<br> uint16_t keycode = 0;<br> int mod;<br> @@ -727,7 +727,7 @@ static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,<br> <br> switch (evt->type) {<br> case INPUT_EVENT_KIND_REL:<br> - move = evt->u.rel.data;<br> + move = &evt->u.rel;<br> if (move->axis == INPUT_AXIS_X) {<br> s->mouse_dx += move->value;<br> } else if (move->axis == INPUT_AXIS_Y) {<br> @@ -736,7 +736,7 @@ static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,<br> break;<br> <br> case INPUT_EVENT_KIND_BTN:<br> - btn = evt->u.btn.data;<br> + btn = &evt->u.btn;<br> if (btn->down) {<br> s->mouse_buttons |= bmap[btn->button];<br> if (btn->button == INPUT_BUTTON_WHEEL_UP) {<br> diff --git a/hw/input/virtio-input-hid.c b/hw/input/virtio-input-hid.c<br> index a7a244a95d..1c7b07cf42 100644<br> --- a/hw/input/virtio-input-hid.c<br> +++ b/hw/input/virtio-input-hid.c<br> @@ -83,7 +83,7 @@ static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src,<br> <br> switch (evt->type) {<br> case INPUT_EVENT_KIND_KEY:<br> - key = evt->u.key.data;<br> + key = &evt->u.key;<br> qcode = qemu_input_key_value_to_qcode(key->key);<br> if (qcode < qemu_input_map_qcode_to_linux_len &&<br> qemu_input_map_qcode_to_linux[qcode]) {<br> @@ -99,7 +99,7 @@ static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src,<br> }<br> break;<br> case INPUT_EVENT_KIND_BTN:<br> - btn = evt->u.btn.data;<br> + btn = &evt->u.btn;<br> if (vhid->wheel_axis &&<br> (btn->button == INPUT_BUTTON_WHEEL_UP ||<br> btn->button == INPUT_BUTTON_WHEEL_DOWN) &&<br> @@ -123,14 +123,14 @@ static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src,<br> }<br> break;<br> case INPUT_EVENT_KIND_REL:<br> - move = evt->u.rel.data;<br> + move = &evt->u.rel;<br> event.type = cpu_to_le16(EV_REL);<br> event.code = cpu_to_le16(axismap_rel[move->axis]);<br> event.value = cpu_to_le32(move->value);<br> virtio_input_send(vinput, &event);<br> break;<br> case INPUT_EVENT_KIND_ABS:<br> - move = evt->u.abs.data;<br> + move = &evt->u.abs;<br> event.type = cpu_to_le16(EV_ABS);<br> event.code = cpu_to_le16(axismap_abs[move->axis]);<br> event.value = cpu_to_le32(move->value);<br> diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c<br> index c30351070b..3d6f836621 100644<br> --- a/hw/mem/pc-dimm.c<br> +++ b/hw/mem/pc-dimm.c<br> @@ -236,11 +236,19 @@ static MemoryRegion *pc_dimm_md_get_memory_region(MemoryDeviceState *md,<br> static void pc_dimm_md_fill_device_info(const MemoryDeviceState *md,<br> MemoryDeviceInfo *info)<br> {<br> - PCDIMMDeviceInfo *di = g_new0(PCDIMMDeviceInfo, 1);<br> + PCDIMMDeviceInfo *di;<br> const DeviceClass *dc = DEVICE_GET_CLASS(md);<br> const PCDIMMDevice *dimm = PC_DIMM(md);<br> const DeviceState *dev = DEVICE(md);<br> <br> + if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {<br> + di = &info->u.nvdimm;<br> + info->type = MEMORY_DEVICE_INFO_KIND_NVDIMM;<br> + } else {<br> + di = &info->u.dimm;<br> + info->type = MEMORY_DEVICE_INFO_KIND_DIMM;<br> + }<br> +<br> if (dev->id) {<br> di->has_id = true;<br> di->id = g_strdup(dev->id);<br> @@ -253,14 +261,6 @@ static void pc_dimm_md_fill_device_info(const MemoryDeviceState *md,<br> di->size = object_property_get_uint(OBJECT(dimm), PC_DIMM_SIZE_PROP,<br> NULL);<br> di->memdev = object_get_canonical_path(OBJECT(dimm->hostmem));<br> -<br> - if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {<br> - info->u.nvdimm.data = di;<br> - info->type = MEMORY_DEVICE_INFO_KIND_NVDIMM;<br> - } else {<br> - info->u.dimm.data = di;<br> - info->type = MEMORY_DEVICE_INFO_KIND_DIMM;<br> - }<br> }<br> <br> static void pc_dimm_class_init(ObjectClass *oc, void *data)<br> diff --git a/hw/virtio/virtio-mem-pci.c b/hw/virtio/virtio-mem-pci.c<br> index 913f4a3326..f93572fc27 100644<br> --- a/hw/virtio/virtio-mem-pci.c<br> +++ b/hw/virtio/virtio-mem-pci.c<br> @@ -58,7 +58,7 @@ static uint64_t virtio_mem_pci_get_plugged_size(const MemoryDeviceState *md,<br> static void virtio_mem_pci_fill_device_info(const MemoryDeviceState *md,<br> MemoryDeviceInfo *info)<br> {<br> - VirtioMEMDeviceInfo *vi = g_new0(VirtioMEMDeviceInfo, 1);<br> + VirtioMEMDeviceInfo *vi = &info->u.virtio_mem;<br> VirtIOMEMPCI *pci_mem = VIRTIO_MEM_PCI(md);<br> VirtIOMEM *vmem = VIRTIO_MEM(&pci_mem->vdev);<br> VirtIOMEMClass *vpc = VIRTIO_MEM_GET_CLASS(vmem);<br> @@ -72,7 +72,6 @@ static void virtio_mem_pci_fill_device_info(const MemoryDeviceState *md,<br> /* let the real device handle everything else */<br> vpc->fill_device_info(vmem, vi);<br> <br> - info->u.virtio_mem.data = vi;<br> info->type = MEMORY_DEVICE_INFO_KIND_VIRTIO_MEM;<br> }<br> <br> diff --git a/hw/virtio/virtio-pmem-pci.c b/hw/virtio/virtio-pmem-pci.c<br> index 2b2a0b1eae..adf17f873b 100644<br> --- a/hw/virtio/virtio-pmem-pci.c<br> +++ b/hw/virtio/virtio-pmem-pci.c<br> @@ -63,7 +63,7 @@ static uint64_t virtio_pmem_pci_get_plugged_size(const MemoryDeviceState *md,<br> static void virtio_pmem_pci_fill_device_info(const MemoryDeviceState *md,<br> MemoryDeviceInfo *info)<br> {<br> - VirtioPMEMDeviceInfo *vi = g_new0(VirtioPMEMDeviceInfo, 1);<br> + VirtioPMEMDeviceInfo *vi = &info->u.virtio_pmem;<br> VirtIOPMEMPCI *pci_pmem = VIRTIO_PMEM_PCI(md);<br> VirtIOPMEM *pmem = VIRTIO_PMEM(&pci_pmem->vdev);<br> VirtIOPMEMClass *vpc = VIRTIO_PMEM_GET_CLASS(pmem);<br> @@ -77,7 +77,6 @@ static void virtio_pmem_pci_fill_device_info(const MemoryDeviceState *md,<br> /* let the real device handle everything else */<br> vpc->fill_device_info(pmem, vi);<br> <br> - info->u.virtio_pmem.data = vi;<br> info->type = MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM;<br> }<br> <br> diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c<br> index 9789f4277f..0324caa114 100644<br> --- a/monitor/hmp-cmds.c<br> +++ b/monitor/hmp-cmds.c<br> @@ -918,7 +918,7 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict)<br> <br> switch (ti->options->type) {<br> case TPM_TYPE_OPTIONS_KIND_PASSTHROUGH:<br> - tpo = ti->options->u.passthrough.data;<br> + tpo = &ti->options->u.passthrough;<br> monitor_printf(mon, "%s%s%s%s",<br> tpo->has_path ? ",path=" : "",<br> tpo->has_path ? tpo->path : "",<br> @@ -926,7 +926,7 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict)<br> tpo->has_cancel_path ? tpo->cancel_path : "");<br> break;<br> case TPM_TYPE_OPTIONS_KIND_EMULATOR:<br> - teo = ti->options->u.emulator.data;<br> + teo = &ti->options->u.emulator;<br> monitor_printf(mon, ",chardev=%s", teo->chardev);<br> break;<br> case TPM_TYPE_OPTIONS_KIND__MAX:<br> @@ -1728,14 +1728,14 @@ void hmp_sendkey(Monitor *mon, const QDict *qdict)<br> goto err_out;<br> }<br> keylist->value->type = KEY_VALUE_KIND_NUMBER;<br> - keylist->value->u.number.data = value;<br> + keylist->value->u.number = value;<br> } else {<br> int idx = index_from_key(keys, keyname_len);<br> if (idx == Q_KEY_CODE__MAX) {<br> goto err_out;<br> }<br> keylist->value->type = KEY_VALUE_KIND_QCODE;<br> - keylist->value->u.qcode.data = idx;<br> + keylist->value->u.qcode = idx;<br> }<br> <br> if (!*separator) {<br> @@ -1860,7 +1860,7 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)<br> case MEMORY_DEVICE_INFO_KIND_DIMM:<br> case MEMORY_DEVICE_INFO_KIND_NVDIMM:<br> di = value->type == MEMORY_DEVICE_INFO_KIND_DIMM ?<br> - value->u.dimm.data : value->u.nvdimm.data;<br> + &value->u.dimm : &value->u.nvdimm;<br> monitor_printf(mon, "Memory device [%s]: \"%s\"\n",<br> MemoryDeviceInfoKind_str(value->type),<br> di->id ? di->id : "");<br> @@ -1875,7 +1875,7 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)<br> di->hotpluggable ? "true" : "false");<br> break;<br> case MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM:<br> - vpi = value->u.virtio_pmem.data;<br> + vpi = &value->u.virtio_pmem;<br> monitor_printf(mon, "Memory device [%s]: \"%s\"\n",<br> MemoryDeviceInfoKind_str(value->type),<br> vpi->id ? vpi->id : "");<br> @@ -1884,7 +1884,7 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)<br> monitor_printf(mon, " memdev: %s\n", vpi->memdev);<br> break;<br> case MEMORY_DEVICE_INFO_KIND_VIRTIO_MEM:<br> - vmi = value->u.virtio_mem.data;<br> + vmi = &value->u.virtio_mem;<br> monitor_printf(mon, "Memory device [%s]: \"%s\"\n",<br> MemoryDeviceInfoKind_str(value->type),<br> vmi->id ? vmi->id : "");<br> diff --git a/qemu-keymap.c b/qemu-keymap.c<br> index 536e8f2385..52637c449c 100644<br> --- a/qemu-keymap.c<br> +++ b/qemu-keymap.c<br> @@ -38,7 +38,7 @@ static uint32_t qcode_to_number(uint32_t qcode)<br> uint32_t number;<br> <br> keyvalue.type = KEY_VALUE_KIND_QCODE;<br> - keyvalue.u.qcode.data = qcode;<br> + keyvalue.u.qcode = qcode;<br> number = qemu_input_key_value_to_number(&keyvalue);<br> assert(number != 0);<br> return number;<br> diff --git a/replay/replay-input.c b/replay/replay-input.c<br> index 1147e3d34e..c1eb1b79e1 100644<br> --- a/replay/replay-input.c<br> +++ b/replay/replay-input.c<br> @@ -26,16 +26,16 @@ void replay_save_input_event(InputEvent *evt)<br> <br> switch (evt->type) {<br> case INPUT_EVENT_KIND_KEY:<br> - key = evt->u.key.data;<br> + key = &evt->u.key;<br> replay_put_dword(key->key->type);<br> <br> switch (key->key->type) {<br> case KEY_VALUE_KIND_NUMBER:<br> - replay_put_qword(key->key->u.number.data);<br> + replay_put_qword(key->key->u.number);<br> replay_put_byte(key->down);<br> break;<br> case KEY_VALUE_KIND_QCODE:<br> - replay_put_dword(key->key->u.qcode.data);<br> + replay_put_dword(key->key->u.qcode);<br> replay_put_byte(key->down);<br> break;<br> case KEY_VALUE_KIND__MAX:<br> @@ -44,17 +44,17 @@ void replay_save_input_event(InputEvent *evt)<br> }<br> break;<br> case INPUT_EVENT_KIND_BTN:<br> - btn = evt->u.btn.data;<br> + btn = &evt->u.btn;<br> replay_put_dword(btn->button);<br> replay_put_byte(btn->down);<br> break;<br> case INPUT_EVENT_KIND_REL:<br> - move = evt->u.rel.data;<br> + move = &evt->u.rel;<br> replay_put_dword(move->axis);<br> replay_put_qword(move->value);<br> break;<br> case INPUT_EVENT_KIND_ABS:<br> - move = evt->u.abs.data;<br> + move = &evt->u.abs;<br> replay_put_dword(move->axis);<br> replay_put_qword(move->value);<br> break;<br> @@ -68,26 +68,21 @@ InputEvent *replay_read_input_event(void)<br> {<br> InputEvent evt;<br> KeyValue keyValue;<br> - InputKeyEvent key;<br> - key.key = &keyValue;<br> - InputBtnEvent btn;<br> - InputMoveEvent rel;<br> - InputMoveEvent abs;<br> + evt.u.key.key = &keyValue;<br> <br> evt.type = replay_get_dword();<br> switch (evt.type) {<br> case INPUT_EVENT_KIND_KEY:<br> - evt.u.key.data = &key;<br> - evt.u.key.data->key->type = replay_get_dword();<br> + evt.u.key.key->type = replay_get_dword();<br> <br> - switch (evt.u.key.data->key->type) {<br> + switch (evt.u.key.key->type) {<br> case KEY_VALUE_KIND_NUMBER:<br> - evt.u.key.data->key->u.number.data = replay_get_qword();<br> - evt.u.key.data->down = replay_get_byte();<br> + evt.u.key.key->u.number = replay_get_qword();<br> + evt.u.key.down = replay_get_byte();<br> break;<br> case KEY_VALUE_KIND_QCODE:<br> - evt.u.key.data->key->u.qcode.data = (QKeyCode)replay_get_dword();<br> - evt.u.key.data->down = replay_get_byte();<br> + evt.u.key.key->u.qcode = (QKeyCode)replay_get_dword();<br> + evt.u.key.down = replay_get_byte();<br> break;<br> case KEY_VALUE_KIND__MAX:<br> /* keep gcc happy */<br> @@ -95,19 +90,16 @@ InputEvent *replay_read_input_event(void)<br> }<br> break;<br> case INPUT_EVENT_KIND_BTN:<br> - evt.u.btn.data = &btn;<br> - evt.u.btn.data->button = (InputButton)replay_get_dword();<br> - evt.u.btn.data->down = replay_get_byte();<br> + evt.u.btn.button = (InputButton)replay_get_dword();<br> + evt.u.btn.down = replay_get_byte();<br> break;<br> case INPUT_EVENT_KIND_REL:<br> - evt.u.rel.data = &rel;<br> - evt.u.rel.data->axis = (InputAxis)replay_get_dword();<br> - evt.u.rel.data->value = replay_get_qword();<br> + evt.u.rel.axis = (InputAxis)replay_get_dword();<br> + evt.u.rel.value = replay_get_qword();<br> break;<br> case INPUT_EVENT_KIND_ABS:<br> - evt.u.abs.data = &abs;<br> - evt.u.abs.data->axis = (InputAxis)replay_get_dword();<br> - evt.u.abs.data->value = replay_get_qword();<br> + evt.u.abs.axis = (InputAxis)replay_get_dword();<br> + evt.u.abs.value = replay_get_qword();<br> break;<br> case INPUT_EVENT_KIND__MAX:<br> /* keep gcc happy */<br> diff --git a/tests/test-char.c b/tests/test-char.c<br> index 9196e566e9..0e7a033a90 100644<br> --- a/tests/test-char.c<br> +++ b/tests/test-char.c<br> @@ -1220,7 +1220,7 @@ static void char_file_fifo_test(void)<br> .has_in = true,<br> .out = out };<br> ChardevBackend backend = { .type = CHARDEV_BACKEND_KIND_FILE,<br> - .u.file.data = &file };<br> + .u.file = file };<br> FeHandler fe = { 0, };<br> int fd, ret;<br> <br> @@ -1273,19 +1273,17 @@ static void char_file_test_internal(Chardev *ext_chr, const char *filepath)<br> char *out;<br> Chardev *chr;<br> char *contents = NULL;<br> - ChardevFile file = {};<br> - ChardevBackend backend = { .type = CHARDEV_BACKEND_KIND_FILE,<br> - .u.file.data = &file };<br> + ChardevBackend backend = { .type = CHARDEV_BACKEND_KIND_FILE };<br> gsize length;<br> int ret;<br> <br> if (ext_chr) {<br> chr = ext_chr;<br> out = g_strdup(filepath);<br> - file.out = out;<br> + backend.u.file.out = out;<br> } else {<br> out = g_build_filename(tmp_path, "out", NULL);<br> - file.out = out;<br> + backend.u.file.out = out;<br> chr = qemu_chardev_new(NULL, TYPE_CHARDEV_FILE, &backend,<br> NULL, &error_abort);<br> }<br> @@ -1384,7 +1382,7 @@ static void char_hotswap_test(void)<br> char *filename = g_build_filename(tmp_path, "file", NULL);<br> ChardevFile file = { .out = filename };<br> ChardevBackend backend = { .type = CHARDEV_BACKEND_KIND_FILE,<br> - .u.file.data = &file };<br> + .u.file = file };<br> ChardevReturn *ret;<br> <br> int port;<br> diff --git a/tests/test-clone-visitor.c b/tests/test-clone-visitor.c<br> index 5e1e8b2f5e..0a62704bed 100644<br> --- a/tests/test-clone-visitor.c<br> +++ b/tests/test-clone-visitor.c<br> @@ -110,7 +110,7 @@ static void test_clone_complex1(void)<br> dst = QAPI_CLONE(UserDefListUnion, src);<br> g_assert(dst);<br> g_assert_cmpint(dst->type, ==, src->type);<br> - g_assert(!dst->u.string.data);<br> + g_assert(!dst->u.string);<br> <br> qapi_free_UserDefListUnion(src);<br> qapi_free_UserDefListUnion(dst);<br> @@ -155,30 +155,30 @@ static void test_clone_complex3(void)<br> tmp = src->array = g_new0(__org_qemu_x_Union1List, 1);<br> tmp->value = g_new0(__org_qemu_x_Union1, 1);<br> tmp->value->type = ORG_QEMU_X_UNION1_KIND___ORG_QEMU_X_BRANCH;<br> - tmp->value->u.__org_qemu_x_branch.data = g_strdup("one");<br> + tmp->value->u.__org_qemu_x_branch = g_strdup("one");<br> tmp = tmp->next = g_new0(__org_qemu_x_Union1List, 1);<br> tmp->value = g_new0(__org_qemu_x_Union1, 1);<br> tmp->value->type = ORG_QEMU_X_UNION1_KIND___ORG_QEMU_X_BRANCH;<br> - tmp->value->u.__org_qemu_x_branch.data = g_strdup("two");<br> + tmp->value->u.__org_qemu_x_branch = g_strdup("two");<br> tmp = tmp->next = g_new0(__org_qemu_x_Union1List, 1);<br> tmp->value = g_new0(__org_qemu_x_Union1, 1);<br> tmp->value->type = ORG_QEMU_X_UNION1_KIND___ORG_QEMU_X_BRANCH;<br> - tmp->value->u.__org_qemu_x_branch.data = g_strdup("three");<br> + tmp->value->u.__org_qemu_x_branch = g_strdup("three");<br> <br> dst = QAPI_CLONE(__org_qemu_x_Struct2, src);<br> g_assert(dst);<br> tmp = dst->array;<br> g_assert(tmp);<br> g_assert(tmp->value);<br> - g_assert_cmpstr(tmp->value->u.__org_qemu_x_branch.data, ==, "one");<br> + g_assert_cmpstr(tmp->value->u.__org_qemu_x_branch, ==, "one");<br> tmp = tmp->next;<br> g_assert(tmp);<br> g_assert(tmp->value);<br> - g_assert_cmpstr(tmp->value->u.__org_qemu_x_branch.data, ==, "two");<br> + g_assert_cmpstr(tmp->value->u.__org_qemu_x_branch, ==, "two");<br> tmp = tmp->next;<br> g_assert(tmp);<br> g_assert(tmp->value);<br> - g_assert_cmpstr(tmp->value->u.__org_qemu_x_branch.data, ==, "three");<br> + g_assert_cmpstr(tmp->value->u.__org_qemu_x_branch, ==, "three");<br> tmp = tmp->next;<br> g_assert(!tmp);<br> <br> diff --git a/tests/test-qmp-cmds.c b/tests/test-qmp-cmds.c<br> index d3413bfef0..3d699fbb66 100644<br> --- a/tests/test-qmp-cmds.c<br> +++ b/tests/test-qmp-cmds.c<br> @@ -136,7 +136,7 @@ __org_qemu_x_Union1 *qmp___org_qemu_x_command(__org_qemu_x_EnumList *a,<br> __org_qemu_x_Union1 *ret = g_new0(__org_qemu_x_Union1, 1);<br> <br> ret->type = ORG_QEMU_X_UNION1_KIND___ORG_QEMU_X_BRANCH;<br> - ret->u.__org_qemu_x_branch.data = strdup("blah1");<br> + ret->u.__org_qemu_x_branch = strdup("blah1");<br> <br> /* Also test that 'wchar-t' was munged to 'q_wchar_t' */<br> if (b && b->value && !b->value->has_q_wchar_t) {<br> diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c<br> index e41b91a2a6..b976ab9763 100644<br> --- a/tests/test-qobject-input-visitor.c<br> +++ b/tests/test-qobject-input-visitor.c<br> @@ -710,7 +710,7 @@ static void test_list_union_integer_helper(TestInputVisitorData *data,<br> switch (kind) {<br> case USER_DEF_LIST_UNION_KIND_INTEGER: {<br> intList *elem = NULL;<br> - for (i = 0, elem = cvalue->u.integer.data;<br> + for (i = 0, elem = cvalue->u.integer;<br> elem; elem = elem->next, i++) {<br> g_assert_cmpint(elem->value, ==, i);<br> }<br> @@ -718,56 +718,56 @@ static void test_list_union_integer_helper(TestInputVisitorData *data,<br> }<br> case USER_DEF_LIST_UNION_KIND_S8: {<br> int8List *elem = NULL;<br> - for (i = 0, elem = cvalue->u.s8.data; elem; elem = elem->next, i++) {<br> + for (i = 0, elem = cvalue->u.s8; elem; elem = elem->next, i++) {<br> g_assert_cmpint(elem->value, ==, i);<br> }<br> break;<br> }<br> case USER_DEF_LIST_UNION_KIND_S16: {<br> int16List *elem = NULL;<br> - for (i = 0, elem = cvalue->u.s16.data; elem; elem = elem->next, i++) {<br> + for (i = 0, elem = cvalue->u.s16; elem; elem = elem->next, i++) {<br> g_assert_cmpint(elem->value, ==, i);<br> }<br> break;<br> }<br> case USER_DEF_LIST_UNION_KIND_S32: {<br> int32List *elem = NULL;<br> - for (i = 0, elem = cvalue->u.s32.data; elem; elem = elem->next, i++) {<br> + for (i = 0, elem = cvalue->u.s32; elem; elem = elem->next, i++) {<br> g_assert_cmpint(elem->value, ==, i);<br> }<br> break;<br> }<br> case USER_DEF_LIST_UNION_KIND_S64: {<br> int64List *elem = NULL;<br> - for (i = 0, elem = cvalue->u.s64.data; elem; elem = elem->next, i++) {<br> + for (i = 0, elem = cvalue->u.s64; elem; elem = elem->next, i++) {<br> g_assert_cmpint(elem->value, ==, i);<br> }<br> break;<br> }<br> case USER_DEF_LIST_UNION_KIND_U8: {<br> uint8List *elem = NULL;<br> - for (i = 0, elem = cvalue->u.u8.data; elem; elem = elem->next, i++) {<br> + for (i = 0, elem = cvalue->u.u8; elem; elem = elem->next, i++) {<br> g_assert_cmpint(elem->value, ==, i);<br> }<br> break;<br> }<br> case USER_DEF_LIST_UNION_KIND_U16: {<br> uint16List *elem = NULL;<br> - for (i = 0, elem = cvalue->u.u16.data; elem; elem = elem->next, i++) {<br> + for (i = 0, elem = cvalue->u.u16; elem; elem = elem->next, i++) {<br> g_assert_cmpint(elem->value, ==, i);<br> }<br> break;<br> }<br> case USER_DEF_LIST_UNION_KIND_U32: {<br> uint32List *elem = NULL;<br> - for (i = 0, elem = cvalue->u.u32.data; elem; elem = elem->next, i++) {<br> + for (i = 0, elem = cvalue->u.u32; elem; elem = elem->next, i++) {<br> g_assert_cmpint(elem->value, ==, i);<br> }<br> break;<br> }<br> case USER_DEF_LIST_UNION_KIND_U64: {<br> uint64List *elem = NULL;<br> - for (i = 0, elem = cvalue->u.u64.data; elem; elem = elem->next, i++) {<br> + for (i = 0, elem = cvalue->u.u64; elem; elem = elem->next, i++) {<br> g_assert_cmpint(elem->value, ==, i);<br> }<br> break;<br> @@ -868,7 +868,7 @@ static void test_visitor_in_list_union_bool(TestInputVisitorData *data,<br> g_assert(cvalue != NULL);<br> g_assert_cmpint(cvalue->type, ==, USER_DEF_LIST_UNION_KIND_BOOLEAN);<br> <br> - for (i = 0, elem = cvalue->u.boolean.data; elem; elem = elem->next, i++) {<br> + for (i = 0, elem = cvalue->u.boolean; elem; elem = elem->next, i++) {<br> g_assert_cmpint(elem->value, ==, (i % 3 == 0) ? 1 : 0);<br> }<br> <br> @@ -900,7 +900,7 @@ static void test_visitor_in_list_union_string(TestInputVisitorData *data,<br> g_assert(cvalue != NULL);<br> g_assert_cmpint(cvalue->type, ==, USER_DEF_LIST_UNION_KIND_STRING);<br> <br> - for (i = 0, elem = cvalue->u.string.data; elem; elem = elem->next, i++) {<br> + for (i = 0, elem = cvalue->u.string; elem; elem = elem->next, i++) {<br> gchar str[8];<br> sprintf(str, "%d", i);<br> g_assert_cmpstr(elem->value, ==, str);<br> @@ -936,7 +936,7 @@ static void test_visitor_in_list_union_number(TestInputVisitorData *data,<br> g_assert(cvalue != NULL);<br> g_assert_cmpint(cvalue->type, ==, USER_DEF_LIST_UNION_KIND_NUMBER);<br> <br> - for (i = 0, elem = cvalue->u.number.data; elem; elem = elem->next, i++) {<br> + for (i = 0, elem = cvalue->u.number; elem; elem = elem->next, i++) {<br> GString *double_expected = g_string_new("");<br> GString *double_actual = g_string_new("");<br> <br> diff --git a/tests/test-qobject-output-visitor.c b/tests/test-qobject-output-visitor.c<br> index 1c856d9bd2..202f848062 100644<br> --- a/tests/test-qobject-output-visitor.c<br> +++ b/tests/test-qobject-output-visitor.c<br> @@ -444,7 +444,7 @@ static void init_list_union(UserDefListUnion *cvalue)<br> int i;<br> switch (cvalue->type) {<br> case USER_DEF_LIST_UNION_KIND_INTEGER: {<br> - intList **list = &cvalue->u.integer.data;<br> + intList **list = &cvalue->u.integer;<br> for (i = 0; i < 32; i++) {<br> *list = g_new0(intList, 1);<br> (*list)->value = i;<br> @@ -454,7 +454,7 @@ static void init_list_union(UserDefListUnion *cvalue)<br> break;<br> }<br> case USER_DEF_LIST_UNION_KIND_S8: {<br> - int8List **list = &cvalue->u.s8.data;<br> + int8List **list = &cvalue->u.s8;<br> for (i = 0; i < 32; i++) {<br> *list = g_new0(int8List, 1);<br> (*list)->value = i;<br> @@ -464,7 +464,7 @@ static void init_list_union(UserDefListUnion *cvalue)<br> break;<br> }<br> case USER_DEF_LIST_UNION_KIND_S16: {<br> - int16List **list = &cvalue->u.s16.data;<br> + int16List **list = &cvalue->u.s16;<br> for (i = 0; i < 32; i++) {<br> *list = g_new0(int16List, 1);<br> (*list)->value = i;<br> @@ -474,7 +474,7 @@ static void init_list_union(UserDefListUnion *cvalue)<br> break;<br> }<br> case USER_DEF_LIST_UNION_KIND_S32: {<br> - int32List **list = &cvalue->u.s32.data;<br> + int32List **list = &cvalue->u.s32;<br> for (i = 0; i < 32; i++) {<br> *list = g_new0(int32List, 1);<br> (*list)->value = i;<br> @@ -484,7 +484,7 @@ static void init_list_union(UserDefListUnion *cvalue)<br> break;<br> }<br> case USER_DEF_LIST_UNION_KIND_S64: {<br> - int64List **list = &cvalue->u.s64.data;<br> + int64List **list = &cvalue->u.s64;<br> for (i = 0; i < 32; i++) {<br> *list = g_new0(int64List, 1);<br> (*list)->value = i;<br> @@ -494,7 +494,7 @@ static void init_list_union(UserDefListUnion *cvalue)<br> break;<br> }<br> case USER_DEF_LIST_UNION_KIND_U8: {<br> - uint8List **list = &cvalue->u.u8.data;<br> + uint8List **list = &cvalue->u.u8;<br> for (i = 0; i < 32; i++) {<br> *list = g_new0(uint8List, 1);<br> (*list)->value = i;<br> @@ -504,7 +504,7 @@ static void init_list_union(UserDefListUnion *cvalue)<br> break;<br> }<br> case USER_DEF_LIST_UNION_KIND_U16: {<br> - uint16List **list = &cvalue->u.u16.data;<br> + uint16List **list = &cvalue->u.u16;<br> for (i = 0; i < 32; i++) {<br> *list = g_new0(uint16List, 1);<br> (*list)->value = i;<br> @@ -514,7 +514,7 @@ static void init_list_union(UserDefListUnion *cvalue)<br> break;<br> }<br> case USER_DEF_LIST_UNION_KIND_U32: {<br> - uint32List **list = &cvalue->u.u32.data;<br> + uint32List **list = &cvalue->u.u32;<br> for (i = 0; i < 32; i++) {<br> *list = g_new0(uint32List, 1);<br> (*list)->value = i;<br> @@ -524,7 +524,7 @@ static void init_list_union(UserDefListUnion *cvalue)<br> break;<br> }<br> case USER_DEF_LIST_UNION_KIND_U64: {<br> - uint64List **list = &cvalue->u.u64.data;<br> + uint64List **list = &cvalue->u.u64;<br> for (i = 0; i < 32; i++) {<br> *list = g_new0(uint64List, 1);<br> (*list)->value = i;<br> @@ -534,7 +534,7 @@ static void init_list_union(UserDefListUnion *cvalue)<br> break;<br> }<br> case USER_DEF_LIST_UNION_KIND_BOOLEAN: {<br> - boolList **list = &cvalue->u.boolean.data;<br> + boolList **list = &cvalue->u.boolean;<br> for (i = 0; i < 32; i++) {<br> *list = g_new0(boolList, 1);<br> (*list)->value = QEMU_IS_ALIGNED(i, 3);<br> @@ -544,7 +544,7 @@ static void init_list_union(UserDefListUnion *cvalue)<br> break;<br> }<br> case USER_DEF_LIST_UNION_KIND_STRING: {<br> - strList **list = &cvalue->u.string.data;<br> + strList **list = &cvalue->u.string;<br> for (i = 0; i < 32; i++) {<br> *list = g_new0(strList, 1);<br> (*list)->value = g_strdup_printf("%d", i);<br> @@ -554,7 +554,7 @@ static void init_list_union(UserDefListUnion *cvalue)<br> break;<br> }<br> case USER_DEF_LIST_UNION_KIND_NUMBER: {<br> - numberList **list = &cvalue->u.number.data;<br> + numberList **list = &cvalue->u.number;<br> for (i = 0; i < 32; i++) {<br> *list = g_new0(numberList, 1);<br> (*list)->value = (double)i / 3;<br> diff --git a/ui/console.c b/ui/console.c<br> index 820e408170..2f93723ed6 100644<br> --- a/ui/console.c<br> +++ b/ui/console.c<br> @@ -2212,7 +2212,7 @@ static void vc_chr_open(Chardev *chr,<br> bool *be_opened,<br> Error **errp)<br> {<br> - ChardevVC *vc = backend->u.vc.data;<br> + ChardevVC *vc = &backend-><a href="http://u.vc" rel="noreferrer" target="_blank">u.vc</a>;<br> VCChardev *drv = VC_CHARDEV(chr);<br> QemuConsole *s;<br> unsigned width = 0;<br> @@ -2362,10 +2362,9 @@ void qemu_display_help(void)<br> void qemu_chr_parse_vc(QemuOpts *opts, ChardevBackend *backend, Error **errp)<br> {<br> int val;<br> - ChardevVC *vc;<br> + ChardevVC *vc = &backend-><a href="http://u.vc" rel="noreferrer" target="_blank">u.vc</a>;<br> <br> backend->type = CHARDEV_BACKEND_KIND_VC;<br> - vc = backend->u.vc.data = g_new0(ChardevVC, 1);<br> qemu_chr_parse_common(opts, qapi_ChardevVC_base(vc));<br> <br> val = qemu_opt_get_number(opts, "width", 0);<br> diff --git a/ui/input-keymap.c b/ui/input-keymap.c<br> index 1b756a6970..0232e25124 100644<br> --- a/ui/input-keymap.c<br> +++ b/ui/input-keymap.c<br> @@ -33,13 +33,13 @@ int qemu_input_linux_to_qcode(unsigned int lnx)<br> int qemu_input_key_value_to_number(const KeyValue *value)<br> {<br> if (value->type == KEY_VALUE_KIND_QCODE) {<br> - if (value->u.qcode.data >= qemu_input_map_qcode_to_qnum_len) {<br> + if (value->u.qcode >= qemu_input_map_qcode_to_qnum_len) {<br> return 0;<br> }<br> - return qemu_input_map_qcode_to_qnum[value->u.qcode.data];<br> + return qemu_input_map_qcode_to_qnum[value->u.qcode];<br> } else {<br> assert(value->type == KEY_VALUE_KIND_NUMBER);<br> - return value->u.number.data;<br> + return value->u.number;<br> }<br> }<br> <br> @@ -54,10 +54,10 @@ int qemu_input_key_number_to_qcode(unsigned int nr)<br> int qemu_input_key_value_to_qcode(const KeyValue *value)<br> {<br> if (value->type == KEY_VALUE_KIND_QCODE) {<br> - return value->u.qcode.data;<br> + return value->u.qcode;<br> } else {<br> assert(value->type == KEY_VALUE_KIND_NUMBER);<br> - return qemu_input_key_number_to_qcode(value->u.number.data);<br> + return qemu_input_key_number_to_qcode(value->u.number);<br> }<br> }<br> <br> @@ -68,7 +68,7 @@ int qemu_input_key_value_to_scancode(const KeyValue *value, bool down,<br> int count = 0;<br> <br> if (value->type == KEY_VALUE_KIND_QCODE &&<br> - value->u.qcode.data == Q_KEY_CODE_PAUSE) {<br> + value->u.qcode == Q_KEY_CODE_PAUSE) {<br> /* specific case */<br> int v = down ? 0 : 0x80;<br> codes[count++] = 0xe1;<br> diff --git a/ui/input-legacy.c b/ui/input-legacy.c<br> index 9fc78a639b..5a32b010d4 100644<br> --- a/ui/input-legacy.c<br> +++ b/ui/input-legacy.c<br> @@ -75,9 +75,9 @@ static KeyValue *copy_key_value(KeyValue *src)<br> KeyValue *dst = g_new(KeyValue, 1);<br> memcpy(dst, src, sizeof(*src));<br> if (dst->type == KEY_VALUE_KIND_NUMBER) {<br> - QKeyCode code = qemu_input_key_number_to_qcode(dst->u.number.data);<br> + QKeyCode code = qemu_input_key_number_to_qcode(dst->u.number);<br> dst->type = KEY_VALUE_KIND_QCODE;<br> - dst->u.qcode.data = code;<br> + dst->u.qcode = code;<br> }<br> return dst;<br> }<br> @@ -113,7 +113,7 @@ static void legacy_kbd_event(DeviceState *dev, QemuConsole *src,<br> {<br> QEMUPutKbdEntry *entry = (QEMUPutKbdEntry *)dev;<br> int scancodes[3], i, count;<br> - InputKeyEvent *key = evt->u.key.data;<br> + InputKeyEvent *key = &evt->u.key;<br> <br> if (!entry || !entry->put_kbd) {<br> return;<br> @@ -159,7 +159,7 @@ static void legacy_mouse_event(DeviceState *dev, QemuConsole *src,<br> <br> switch (evt->type) {<br> case INPUT_EVENT_KIND_BTN:<br> - btn = evt->u.btn.data;<br> + btn = &evt->u.btn;<br> if (btn->down) {<br> s->buttons |= bmap[btn->button];<br> } else {<br> @@ -181,11 +181,11 @@ static void legacy_mouse_event(DeviceState *dev, QemuConsole *src,<br> }<br> break;<br> case INPUT_EVENT_KIND_ABS:<br> - move = evt->u.abs.data;<br> + move = &evt->u.abs;<br> s->axis[move->axis] = move->value;<br> break;<br> case INPUT_EVENT_KIND_REL:<br> - move = evt->u.rel.data;<br> + move = &evt->u.rel;<br> s->axis[move->axis] += move->value;<br> break;<br> default:<br> diff --git a/ui/input.c b/ui/input.c<br> index 4791b089c7..a4078780ee 100644<br> --- a/ui/input.c<br> +++ b/ui/input.c<br> @@ -164,10 +164,10 @@ void qmp_input_send_event(bool has_device, const char *device,<br> InputEvent *evt = e->value;<br> <br> if (evt->type == INPUT_EVENT_KIND_KEY &&<br> - evt->u.key.data->key->type == KEY_VALUE_KIND_NUMBER) {<br> - KeyValue *key = evt->u.key.data->key;<br> - QKeyCode code = qemu_input_key_number_to_qcode(key->u.number.data);<br> - qemu_input_event_send_key_qcode(con, code, evt->u.key.data->down);<br> + evt->u.key.key->type == KEY_VALUE_KIND_NUMBER) {<br> + KeyValue *key = evt->u.key.key;<br> + QKeyCode code = qemu_input_key_number_to_qcode(key->u.number);<br> + qemu_input_event_send_key_qcode(con, code, evt->u.key.down);<br> } else {<br> qemu_input_event_send(con, evt);<br> }<br> @@ -183,7 +183,7 @@ static int qemu_input_transform_invert_abs_value(int value)<br> <br> static void qemu_input_transform_abs_rotate(InputEvent *evt)<br> {<br> - InputMoveEvent *move = evt->u.abs.data;<br> + InputMoveEvent *move = &evt->u.abs;<br> switch (graphic_rotate) {<br> case 90:<br> if (move->axis == INPUT_AXIS_X) {<br> @@ -220,16 +220,16 @@ static void qemu_input_event_trace(QemuConsole *src, InputEvent *evt)<br> }<br> switch (evt->type) {<br> case INPUT_EVENT_KIND_KEY:<br> - key = evt->u.key.data;<br> + key = &evt->u.key;<br> switch (key->key->type) {<br> case KEY_VALUE_KIND_NUMBER:<br> - qcode = qemu_input_key_number_to_qcode(key->key->u.number.data);<br> + qcode = qemu_input_key_number_to_qcode(key->key->u.number);<br> name = QKeyCode_str(qcode);<br> - trace_input_event_key_number(idx, key->key->u.number.data,<br> + trace_input_event_key_number(idx, key->key->u.number,<br> name, key->down);<br> break;<br> case KEY_VALUE_KIND_QCODE:<br> - name = QKeyCode_str(key->key->u.qcode.data);<br> + name = QKeyCode_str(key->key->u.qcode);<br> trace_input_event_key_qcode(idx, name, key->down);<br> break;<br> case KEY_VALUE_KIND__MAX:<br> @@ -238,17 +238,17 @@ static void qemu_input_event_trace(QemuConsole *src, InputEvent *evt)<br> }<br> break;<br> case INPUT_EVENT_KIND_BTN:<br> - btn = evt->u.btn.data;<br> + btn = &evt->u.btn;<br> name = InputButton_str(btn->button);<br> trace_input_event_btn(idx, name, btn->down);<br> break;<br> case INPUT_EVENT_KIND_REL:<br> - move = evt->u.rel.data;<br> + move = &evt->u.rel;<br> name = InputAxis_str(move->axis);<br> trace_input_event_rel(idx, name, move->value);<br> break;<br> case INPUT_EVENT_KIND_ABS:<br> - move = evt->u.abs.data;<br> + move = &evt->u.abs;<br> name = InputAxis_str(move->axis);<br> trace_input_event_abs(idx, name, move->value);<br> break;<br> @@ -355,7 +355,7 @@ void qemu_input_event_send(QemuConsole *src, InputEvent *evt)<br> /* Expect all parts of QEMU to send events with QCodes exclusively.<br> * Key numbers are only supported as end-user input via QMP */<br> assert(!(evt->type == INPUT_EVENT_KIND_KEY &&<br> - evt->u.key.data->key->type == KEY_VALUE_KIND_NUMBER));<br> + evt->u.key.key->type == KEY_VALUE_KIND_NUMBER));<br> <br> <br> /*<br> @@ -367,8 +367,8 @@ void qemu_input_event_send(QemuConsole *src, InputEvent *evt)<br> * neeed to deal with this mistake<br> */<br> if (evt->type == INPUT_EVENT_KIND_KEY &&<br> - evt->u.key.data->key->u.qcode.data == Q_KEY_CODE_SYSRQ) {<br> - evt->u.key.data->key->u.qcode.data = Q_KEY_CODE_PRINT;<br> + evt->u.key.key->u.qcode == Q_KEY_CODE_SYSRQ) {<br> + evt->u.key.key->u.qcode = Q_KEY_CODE_PRINT;<br> }<br> <br> if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {<br> @@ -407,10 +407,9 @@ void qemu_input_event_sync(void)<br> static InputEvent *qemu_input_event_new_key(KeyValue *key, bool down)<br> {<br> InputEvent *evt = g_new0(InputEvent, 1);<br> - evt->u.key.data = g_new0(InputKeyEvent, 1);<br> evt->type = INPUT_EVENT_KIND_KEY;<br> - evt->u.key.data->key = key;<br> - evt->u.key.data->down = down;<br> + evt->u.key.key = key;<br> + evt->u.key.down = down;<br> return evt;<br> }<br> <br> @@ -440,7 +439,7 @@ void qemu_input_event_send_key_qcode(QemuConsole *src, QKeyCode q, bool down)<br> {<br> KeyValue *key = g_new0(KeyValue, 1);<br> key->type = KEY_VALUE_KIND_QCODE;<br> - key->u.qcode.data = q;<br> + key->u.qcode = q;<br> qemu_input_event_send_key(src, key, down);<br> }<br> <br> @@ -469,7 +468,7 @@ void qemu_input_queue_btn(QemuConsole *src, InputButton btn, bool down)<br> };<br> InputEvent evt = {<br> .type = INPUT_EVENT_KIND_BTN,<br> - .u.btn.data = &bevt,<br> + .u.btn = bevt,<br> };<br> <br> qemu_input_event_send(src, &evt);<br> @@ -520,7 +519,7 @@ void qemu_input_queue_rel(QemuConsole *src, InputAxis axis, int value)<br> };<br> InputEvent evt = {<br> .type = INPUT_EVENT_KIND_REL,<br> - .u.rel.data = &move,<br> + .u.rel = move,<br> };<br> <br> qemu_input_event_send(src, &evt);<br> @@ -537,7 +536,7 @@ void qemu_input_queue_abs(QemuConsole *src, InputAxis axis, int value,<br> };<br> InputEvent evt = {<br> .type = INPUT_EVENT_KIND_ABS,<br> - .u.abs.data = &move,<br> + .u.abs = move,<br> };<br> <br> qemu_input_event_send(src, &evt);<br> diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c<br> index 05e5c73f9d..59e317cbb8 100644<br> --- a/util/qemu-sockets.c<br> +++ b/util/qemu-sockets.c<br> @@ -1365,21 +1365,21 @@ SocketAddress *socket_address_flatten(SocketAddressLegacy *addr_legacy)<br> case SOCKET_ADDRESS_LEGACY_KIND_INET:<br> addr->type = SOCKET_ADDRESS_TYPE_INET;<br> QAPI_CLONE_MEMBERS(InetSocketAddress, &addr->u.inet,<br> - addr_legacy->u.inet.data);<br> + &addr_legacy->u.inet);<br> break;<br> case SOCKET_ADDRESS_LEGACY_KIND_UNIX:<br> addr->type = SOCKET_ADDRESS_TYPE_UNIX;<br> QAPI_CLONE_MEMBERS(UnixSocketAddress, &addr->u.q_unix,<br> - addr_legacy->u.q_unix.data);<br> + &addr_legacy->u.q_unix);<br> break;<br> case SOCKET_ADDRESS_LEGACY_KIND_VSOCK:<br> addr->type = SOCKET_ADDRESS_TYPE_VSOCK;<br> QAPI_CLONE_MEMBERS(VsockSocketAddress, &addr->u.vsock,<br> - addr_legacy->u.vsock.data);<br> + &addr_legacy->u.vsock);<br> break;<br> case SOCKET_ADDRESS_LEGACY_KIND_FD:<br> addr->type = SOCKET_ADDRESS_TYPE_FD;<br> - QAPI_CLONE_MEMBERS(String, &addr->u.fd, addr_legacy->u.fd.data);<br> + QAPI_CLONE_MEMBERS(String, &addr->u.fd, &addr_legacy->u.fd);<br> break;<br> default:<br> abort();<br> diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py<br> index fafec94e02..1c4e3407a3 100644<br> --- a/scripts/qapi/introspect.py<br> +++ b/scripts/qapi/introspect.py<br> @@ -188,7 +188,12 @@ const QLitObject %(c_name)s = %(c_string)s;<br> 'variants': [self._gen_variant(v) for v in variants]}<br> <br> def _gen_variant(self, variant):<br> - obj = {'case': <a href="http://variant.name" rel="noreferrer" target="_blank">variant.name</a>, 'type': self._use_type(variant.type)}<br> + if variant.wrapped:<br> + obj = {'case': <a href="http://variant.name" rel="noreferrer" target="_blank">variant.name</a>,<br> + 'type': self._use_type(variant.wrapper_type)}<br> + else:<br> + obj = {'case': <a href="http://variant.name" rel="noreferrer" target="_blank">variant.name</a>,<br> + 'type': self._use_type(variant.type)}<br> return _make_tree(obj, variant.ifcond, None)<br> <br> def visit_builtin_type(self, name, info, json_type):<br> diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py<br> index 720449feee..17525b4216 100644<br> --- a/scripts/qapi/schema.py<br> +++ b/scripts/qapi/schema.py<br> @@ -216,6 +216,11 @@ class QAPISchemaBuiltinType(QAPISchemaType):<br> self._json_type_name = json_type<br> self._c_type_name = c_type<br> <br> + def check(self, schema):<br> + # Don't check twice, it would fail an assertion<br> + if not self._checked:<br> + super().check(schema)<br> +<br> def c_name(self):<br> return <a href="http://self.name" rel="noreferrer" target="_blank">self.name</a><br> <br> @@ -593,18 +598,21 @@ class QAPISchemaVariants:<br> "branch '%s' is not a value of %s"<br> % (<a href="http://v.name" rel="noreferrer" target="_blank">v.name</a>, self.tag_member.type.describe()))<br> if (not isinstance(v.type, QAPISchemaObjectType)<br> - or v.type.variants):<br> + or v.type.variants) and v.flat:<br> raise QAPISemError(<br> <a href="http://self.info" rel="noreferrer" target="_blank">self.info</a>,<br> "%s cannot use %s"<br> % (v.describe(<a href="http://self.info" rel="noreferrer" target="_blank">self.info</a>), v.type.describe()))<br> - v.type.check(schema)<br> + if isinstance(v.type, QAPISchemaObjectType):<br> + v.type.check(schema)<br> <br> def check_clash(self, info, seen):<br> for v in self.variants:<br> # Reset seen map for each variant, since qapi names from one<br> - # branch do not affect another branch<br> - v.type.check_clash(info, dict(seen))<br> + # branch do not affect another branch. Variants that are<br> + # never flat don't even conflict with the base.<br> + if isinstance(v.type, QAPISchemaObjectType):<br> + v.type.check_clash(info, dict(seen) if v.flat else {})<br> <br> <br> class QAPISchemaMember:<br> @@ -705,9 +713,22 @@ class QAPISchemaObjectTypeMember(QAPISchemaMember):<br> class QAPISchemaVariant(QAPISchemaObjectTypeMember):<br> role = 'branch'<br> <br> - def __init__(self, name, info, typ, ifcond=None):<br> + def __init__(self, name, info, typ, ifcond=None, flat=True,<br> + wrapper_type=None):<br> super().__init__(name, info, typ, False, ifcond)<br> <br> + self.flat = flat<br> + self.wrapped = bool(wrapper_type)<br> + self.wrapper_type = wrapper_type<br> +<br> + # For now, unions are either flat or wrapped, never both<br> + assert self.flat or self.wrapped<br> + assert not (self.flat and self.wrapped)<br> +<br> + def check(self, schema):<br> + super().check(schema)<br> + if self.wrapped:<br> + self.wrapper_type.check(schema)<br> <br> class QAPISchemaCommand(QAPISchemaEntity):<br> meta = 'command'<br> @@ -1017,14 +1038,19 @@ class QAPISchema:<br> def _make_variant(self, case, typ, ifcond, info):<br> return QAPISchemaVariant(case, info, typ, ifcond)<br> <br> - def _make_simple_variant(self, case, typ, ifcond, info):<br> + def _make_simple_variant(self, union_name, case, typ, ifcond, info):<br> if isinstance(typ, list):<br> assert len(typ) == 1<br> typ = self._make_array_type(typ[0], info)<br> - typ = self._make_implicit_object_type(<br> - typ, info, self.lookup_type(typ),<br> - 'wrapper', [self._make_member('data', typ, None, None, info)])<br> - return QAPISchemaVariant(case, info, typ, ifcond)<br> +<br> + # The wrapper type is only used for introspection compatibility.<br> + # Don't add it to the entity list of the schema.<br> + wrapper_name = 'q_obj_%s-%s-wrapper' % (union_name, case)<br> + wrapper_member = self._make_member('data', typ, None, None, info)<br> + wrapper_type = QAPISchemaObjectType(wrapper_name, info, None, ifcond,<br> + None, None, [wrapper_member], None)<br> + return QAPISchemaVariant(case, info, typ, ifcond, flat=False,<br> + wrapper_type=wrapper_type)<br> <br> def _def_union_type(self, expr, info, doc):<br> name = expr['union']<br> @@ -1044,7 +1070,7 @@ class QAPISchema:<br> for (key, value) in data.items()]<br> members = []<br> else:<br> - variants = [self._make_simple_variant(key, value['type'],<br> + variants = [self._make_simple_variant(name, key, value['type'],<br> value.get('if'), info)<br> for (key, value) in data.items()]<br> enum = [{'name': <a href="http://v.name" rel="noreferrer" target="_blank">v.name</a>, 'if': v.ifcond} for v in variants]<br> diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py<br> index 339f152152..f72567cbcc 100644<br> --- a/scripts/qapi/visit.py<br> +++ b/scripts/qapi/visit.py<br> @@ -118,6 +118,34 @@ bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)<br> break;<br> ''',<br> case=case_str)<br> + elif not isinstance(var.type, QAPISchemaObjectType):<br> + assert not var.flat<br> + ret += mcgen('''<br> + case %(case)s:<br> + return visit_type_%(c_type)s(v, "data", &obj->u.%(c_name)s, errp);<br> +''',<br> + case=case_str,<br> + c_type=var.type.c_name(), c_name=c_name(<a href="http://var.name" rel="noreferrer" target="_blank">var.name</a>))<br> + elif var.wrapped:<br> + ret += mcgen('''<br> + case %(case)s:<br> + {<br> + bool ok;<br> +<br> + if (!visit_start_struct(v, "data", NULL, 0, errp)) {<br> + return false;<br> + }<br> + ok = visit_type_%(c_type)s_members(v, &obj->u.%(c_name)s, errp);<br> + if (ok) {<br> + ok = visit_check_struct(v, errp);<br> + }<br> + visit_end_struct(v, NULL);<br> + return ok;<br> + }<br> +''',<br> + case=case_str,<br> + c_type=var.type.c_name(), c_name=c_name(<a href="http://var.name" rel="noreferrer" target="_blank">var.name</a>))<br> +<br> else:<br> ret += mcgen('''<br> case %(case)s:<br> diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out<br> index 419284dae2..bcbcbd2fce 100644<br> --- a/tests/qapi-schema/doc-good.out<br> +++ b/tests/qapi-schema/doc-good.out<br> @@ -31,10 +31,6 @@ object Object<br> case two: Variant2<br> if ['IFTWO']<br> feature union-feat1<br> -object q_obj_Variant1-wrapper<br> - member data: Variant1 optional=False<br> -object q_obj_Variant2-wrapper<br> - member data: Variant2 optional=False<br> enum SugaredUnionKind<br> member one<br> member two<br> @@ -42,8 +38,8 @@ enum SugaredUnionKind<br> object SugaredUnion<br> member type: SugaredUnionKind optional=False<br> tag type<br> - case one: q_obj_Variant1-wrapper<br> - case two: q_obj_Variant2-wrapper<br> + case one: Variant1<br> + case two: Variant2<br> if ['IFTWO']<br> feature union-feat2<br> alternate Alternate<br> diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out<br> index 8868ca0dca..a4e4051c61 100644<br> --- a/tests/qapi-schema/qapi-schema-test.out<br> +++ b/tests/qapi-schema/qapi-schema-test.out<br> @@ -125,36 +125,6 @@ alternate AltStrObj<br> tag type<br> case s: str<br> case o: TestStruct<br> -object q_obj_intList-wrapper<br> - member data: intList optional=False<br> -object q_obj_int8List-wrapper<br> - member data: int8List optional=False<br> -object q_obj_int16List-wrapper<br> - member data: int16List optional=False<br> -object q_obj_int32List-wrapper<br> - member data: int32List optional=False<br> -object q_obj_int64List-wrapper<br> - member data: int64List optional=False<br> -object q_obj_uint8List-wrapper<br> - member data: uint8List optional=False<br> -object q_obj_uint16List-wrapper<br> - member data: uint16List optional=False<br> -object q_obj_uint32List-wrapper<br> - member data: uint32List optional=False<br> -object q_obj_uint64List-wrapper<br> - member data: uint64List optional=False<br> -object q_obj_numberList-wrapper<br> - member data: numberList optional=False<br> -object q_obj_boolList-wrapper<br> - member data: boolList optional=False<br> -object q_obj_strList-wrapper<br> - member data: strList optional=False<br> -object q_obj_sizeList-wrapper<br> - member data: sizeList optional=False<br> -object q_obj_anyList-wrapper<br> - member data: anyList optional=False<br> -object q_obj_StatusList-wrapper<br> - member data: StatusList optional=False<br> enum UserDefListUnionKind<br> member integer<br> member s8<br> @@ -174,21 +144,21 @@ enum UserDefListUnionKind<br> object UserDefListUnion<br> member type: UserDefListUnionKind optional=False<br> tag type<br> - case integer: q_obj_intList-wrapper<br> - case s8: q_obj_int8List-wrapper<br> - case s16: q_obj_int16List-wrapper<br> - case s32: q_obj_int32List-wrapper<br> - case s64: q_obj_int64List-wrapper<br> - case u8: q_obj_uint8List-wrapper<br> - case u16: q_obj_uint16List-wrapper<br> - case u32: q_obj_uint32List-wrapper<br> - case u64: q_obj_uint64List-wrapper<br> - case number: q_obj_numberList-wrapper<br> - case boolean: q_obj_boolList-wrapper<br> - case string: q_obj_strList-wrapper<br> - case sizes: q_obj_sizeList-wrapper<br> - case any: q_obj_anyList-wrapper<br> - case user: q_obj_StatusList-wrapper<br> + case integer: intList<br> + case s8: int8List<br> + case s16: int16List<br> + case s32: int32List<br> + case s64: int64List<br> + case u8: uint8List<br> + case u16: uint16List<br> + case u32: uint32List<br> + case u64: uint64List<br> + case number: numberList<br> + case boolean: boolList<br> + case string: strList<br> + case sizes: sizeList<br> + case any: anyList<br> + case user: StatusList<br> include include/sub-module.json<br> command user_def_cmd None -> None<br> gen=True success_response=True boxed=False oob=False preconfig=False<br> @@ -263,14 +233,12 @@ object __org.qemu_x-Struct<br> base __org.qemu_x-Base<br> member __org.qemu_x-member2: str optional=False<br> member wchar-t: int optional=True<br> -object q_obj_str-wrapper<br> - member data: str optional=False<br> enum __org.qemu_x-Union1Kind<br> member __org.qemu_x-branch<br> object __org.qemu_x-Union1<br> member type: __org.qemu_x-Union1Kind optional=False<br> tag type<br> - case __org.qemu_x-branch: q_obj_str-wrapper<br> + case __org.qemu_x-branch: str<br> alternate __org.qemu_x-Alt1<br> tag type<br> case __org.qemu_x-branch: str<br> @@ -305,8 +273,6 @@ enum TestIfEnum<br> member bar<br> if ['defined(TEST_IF_ENUM_BAR)']<br> if ['defined(TEST_IF_ENUM)']<br> -object q_obj_TestStruct-wrapper<br> - member data: TestStruct optional=False<br> enum TestIfUnionKind<br> member foo<br> member union_bar<br> @@ -315,8 +281,8 @@ enum TestIfUnionKind<br> object TestIfUnion<br> member type: TestIfUnionKind optional=False<br> tag type<br> - case foo: q_obj_TestStruct-wrapper<br> - case union_bar: q_obj_str-wrapper<br> + case foo: TestStruct<br> + case union_bar: str<br> if ['defined(TEST_IF_UNION_BAR)']<br> if ['defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)']<br> object q_obj_TestIfUnionCmd-arg<br> -- <br> 2.28.0<br> <br> <br> </blockquote></div><br clear="all"><br>-- <br><div dir="ltr" class="gmail_signature">Marc-André Lureau<br></div></div>
diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt index c6438c6aa9..9722c1a204 100644 --- a/docs/devel/qapi-code-gen.txt +++ b/docs/devel/qapi-code-gen.txt @@ -310,7 +310,20 @@ The BRANCH's STRING name is the branch name. The BRANCH's value defines the branch's properties, in particular its type. The form TYPE-REF is shorthand for { 'type': TYPE-REF }. -A simple union type defines a mapping from automatic discriminator +Each branch can have flat or wrapped representation in the Client JSON +Protocol. + +Wrapped representation of a branch means that it is represented by a +'data' member that is of the specified data type corresponding to the +discriminator value. + +Flat representation means that the union forms a single object that +contains both common members (from the base type) and the selected +branch's members, without any additional nesting. The two sets of +member names must be disjoint. + +A simple union type automatically contains the 'type' member as a +discriminator and defines a mapping from automatic discriminator values to data types like in this example: { 'struct': 'BlockdevOptionsFile', 'data': { 'filename': 'str' } } @@ -321,10 +334,8 @@ values to data types like in this example: 'data': { 'file': 'BlockdevOptionsFile', 'qcow2': 'BlockdevOptionsQcow2' } } -In the Client JSON Protocol, a simple union is represented by an -object that contains the 'type' member as a discriminator, and a -'data' member that is of the specified data type corresponding to the -discriminator value, as in these examples: +In the Client JSON Protocol, all simple union branches have wrapped +representation, as in these examples: { "type": "file", "data": { "filename": "/some/place/my-image" } } { "type": "qcow2", "data": { "backing": "/some/place/my-image", @@ -344,13 +355,12 @@ object, it defines common members just like a struct type's 'data' member defines struct type members. If it is a STRING, it names a struct type whose members are the common members. -All flat union branches must be of struct type. +Member 'discriminator' must name a non-optional enum-typed member of +the base struct and defines the option that should server as the +discrimiator. -In the Client JSON Protocol, a flat union is represented by an object -with the common members (from the base type) and the selected branch's -members. The two sets of member names must be disjoint. Member -'discriminator' must name a non-optional enum-typed member of the base -struct. +All flat union branches must be of struct type. They have always flat +representation. The following example enhances the above simple union example by adding an optional common member 'read-only', renaming the diff --git a/backends/tpm/tpm_emulator.c b/backends/tpm/tpm_emulator.c index 201cd38503..7d2dc2b19d 100644 --- a/backends/tpm/tpm_emulator.c +++ b/backends/tpm/tpm_emulator.c @@ -629,7 +629,8 @@ static TpmTypeOptions *tpm_emulator_get_tpm_options(TPMBackend *tb) TpmTypeOptions *options = g_new0(TpmTypeOptions, 1); options->type = TPM_TYPE_OPTIONS_KIND_EMULATOR; - options->u.emulator.data = QAPI_CLONE(TPMEmulatorOptions, tpm_emu->options); + QAPI_CLONE_MEMBERS(TPMEmulatorOptions, &options->u.emulator, + tpm_emu->options); return options; } diff --git a/backends/tpm/tpm_passthrough.c b/backends/tpm/tpm_passthrough.c index 8f6f4998a5..7fa7c84f5a 100644 --- a/backends/tpm/tpm_passthrough.c +++ b/backends/tpm/tpm_passthrough.c @@ -322,8 +322,8 @@ static TpmTypeOptions *tpm_passthrough_get_tpm_options(TPMBackend *tb) TpmTypeOptions *options = g_new0(TpmTypeOptions, 1); options->type = TPM_TYPE_OPTIONS_KIND_PASSTHROUGH; - options->u.passthrough.data = QAPI_CLONE(TPMPassthroughOptions, - TPM_PASSTHROUGH(tb)->options); + QAPI_CLONE_MEMBERS(TPMPassthroughOptions, &options->u.passthrough, + TPM_PASSTHROUGH(tb)->options); return options; } diff --git a/block/crypto.c b/block/crypto.c index 0807557763..0e7838d70a 100644 --- a/block/crypto.c +++ b/block/crypto.c @@ -775,8 +775,7 @@ block_crypto_get_specific_info_luks(BlockDriverState *bs, Error **errp) spec_info = g_new(ImageInfoSpecific, 1); spec_info->type = IMAGE_INFO_SPECIFIC_KIND_LUKS; - spec_info->u.luks.data = g_new(QCryptoBlockInfoLUKS, 1); - *spec_info->u.luks.data = info->u.luks; + spec_info->u.luks = info->u.luks; /* Blank out pointers we've just stolen to avoid double free */ memset(&info->u.luks, 0, sizeof(info->u.luks)); diff --git a/block/qcow2.c b/block/qcow2.c index b05512718c..104fd8ad06 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -5052,10 +5052,9 @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs, spec_info = g_new(ImageInfoSpecific, 1); *spec_info = (ImageInfoSpecific){ .type = IMAGE_INFO_SPECIFIC_KIND_QCOW2, - .u.qcow2.data = g_new0(ImageInfoSpecificQCow2, 1), }; if (s->qcow_version == 2) { - *spec_info->u.qcow2.data = (ImageInfoSpecificQCow2){ + spec_info->u.qcow2 = (ImageInfoSpecificQCow2){ .compat = g_strdup("0.10"), .refcount_bits = s->refcount_bits, }; @@ -5068,7 +5067,7 @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs, qapi_free_QCryptoBlockInfo(encrypt_info); return NULL; } - *spec_info->u.qcow2.data = (ImageInfoSpecificQCow2){ + spec_info->u.qcow2 = (ImageInfoSpecificQCow2){ .compat = g_strdup("1.1"), .lazy_refcounts = s->compatible_features & QCOW2_COMPAT_LAZY_REFCOUNTS, @@ -5112,8 +5111,8 @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs, memset(&encrypt_info->u, 0, sizeof(encrypt_info->u)); qapi_free_QCryptoBlockInfo(encrypt_info); - spec_info->u.qcow2.data->has_encrypt = true; - spec_info->u.qcow2.data->encrypt = qencrypt; + spec_info->u.qcow2.has_encrypt = true; + spec_info->u.qcow2.encrypt = qencrypt; } return spec_info; diff --git a/block/vmdk.c b/block/vmdk.c index a00dc00eb4..fc4ddcc351 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -2932,18 +2932,14 @@ static ImageInfoSpecific *vmdk_get_specific_info(BlockDriverState *bs, *spec_info = (ImageInfoSpecific){ .type = IMAGE_INFO_SPECIFIC_KIND_VMDK, - .u = { - .vmdk.data = g_new0(ImageInfoSpecificVmdk, 1), + .u.vmdk = (ImageInfoSpecificVmdk) { + .create_type = g_strdup(s->create_type), + .cid = s->cid, + .parent_cid = s->parent_cid, }, }; - *spec_info->u.vmdk.data = (ImageInfoSpecificVmdk) { - .create_type = g_strdup(s->create_type), - .cid = s->cid, - .parent_cid = s->parent_cid, - }; - - next = &spec_info->u.vmdk.data->extents; + next = &spec_info->u.vmdk.extents; for (i = 0; i < s->num_extents; i++) { *next = g_new0(ImageInfoList, 1); (*next)->value = vmdk_get_extent_info(&s->extents[i]); diff --git a/blockdev.c b/blockdev.c index fe6fb5dc1d..2602298a26 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1090,7 +1090,7 @@ void qmp_blockdev_snapshot_sync(bool has_device, const char *device, }; TransactionAction action = { .type = TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC, - .u.blockdev_snapshot_sync.data = &snapshot, + .u.blockdev_snapshot_sync = snapshot, }; blockdev_do_action(&action, errp); } @@ -1104,7 +1104,7 @@ void qmp_blockdev_snapshot(const char *node, const char *overlay, }; TransactionAction action = { .type = TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT, - .u.blockdev_snapshot.data = &snapshot_data, + .u.blockdev_snapshot = snapshot_data, }; blockdev_do_action(&action, errp); } @@ -1119,7 +1119,7 @@ void qmp_blockdev_snapshot_internal_sync(const char *device, }; TransactionAction action = { .type = TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC, - .u.blockdev_snapshot_internal_sync.data = &snapshot, + .u.blockdev_snapshot_internal_sync = snapshot, }; blockdev_do_action(&action, errp); } @@ -1289,7 +1289,7 @@ static void internal_snapshot_prepare(BlkActionState *common, g_assert(common->action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC); - internal = common->action->u.blockdev_snapshot_internal_sync.data; + internal = &common->action->u.blockdev_snapshot_internal_sync; state = DO_UPCAST(InternalSnapshotState, common, common); /* 1. parse input */ @@ -1453,7 +1453,7 @@ static void external_snapshot_prepare(BlkActionState *common, switch (action->type) { case TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT: { - BlockdevSnapshot *s = action->u.blockdev_snapshot.data; + BlockdevSnapshot *s = &action->u.blockdev_snapshot; device = s->node; node_name = s->node; new_image_file = NULL; @@ -1462,7 +1462,7 @@ static void external_snapshot_prepare(BlkActionState *common, break; case TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC: { - BlockdevSnapshotSync *s = action->u.blockdev_snapshot_sync.data; + BlockdevSnapshotSync *s = &action->u.blockdev_snapshot_sync; device = s->has_device ? s->device : NULL; node_name = s->has_node_name ? s->node_name : NULL; new_image_file = s->snapshot_file; @@ -1507,7 +1507,7 @@ static void external_snapshot_prepare(BlkActionState *common, } if (action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC) { - BlockdevSnapshotSync *s = action->u.blockdev_snapshot_sync.data; + BlockdevSnapshotSync *s = &action->u.blockdev_snapshot_sync; const char *format = s->has_format ? s->format : "qcow2"; enum NewImageMode mode; const char *snapshot_node_name = @@ -1712,7 +1712,7 @@ static void drive_backup_prepare(BlkActionState *common, Error **errp) int ret; assert(common->action->type == TRANSACTION_ACTION_KIND_DRIVE_BACKUP); - backup = common->action->u.drive_backup.data; + backup = &common->action->u.drive_backup; if (!backup->has_mode) { backup->mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS; @@ -1907,7 +1907,7 @@ static void blockdev_backup_prepare(BlkActionState *common, Error **errp) int ret; assert(common->action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP); - backup = common->action->u.blockdev_backup.data; + backup = &common->action->u.blockdev_backup; bs = bdrv_lookup_bs(backup->device, backup->device, errp); if (!bs) { @@ -2012,7 +2012,7 @@ static void block_dirty_bitmap_add_prepare(BlkActionState *common, return; } - action = common->action->u.block_dirty_bitmap_add.data; + action = &common->action->u.block_dirty_bitmap_add; /* AIO context taken and released within qmp_block_dirty_bitmap_add */ qmp_block_dirty_bitmap_add(action->node, action->name, action->has_granularity, action->granularity, @@ -2033,7 +2033,7 @@ static void block_dirty_bitmap_add_abort(BlkActionState *common) BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState, common, common); - action = common->action->u.block_dirty_bitmap_add.data; + action = &common->action->u.block_dirty_bitmap_add; /* Should not be able to fail: IF the bitmap was added via .prepare(), * then the node reference and bitmap name must have been valid. */ @@ -2053,7 +2053,7 @@ static void block_dirty_bitmap_clear_prepare(BlkActionState *common, return; } - action = common->action->u.block_dirty_bitmap_clear.data; + action = &common->action->u.block_dirty_bitmap_clear; state->bitmap = block_dirty_bitmap_lookup(action->node, action->name, &state->bs, @@ -2098,7 +2098,7 @@ static void block_dirty_bitmap_enable_prepare(BlkActionState *common, return; } - action = common->action->u.block_dirty_bitmap_enable.data; + action = &common->action->u.block_dirty_bitmap_enable; state->bitmap = block_dirty_bitmap_lookup(action->node, action->name, NULL, @@ -2136,7 +2136,7 @@ static void block_dirty_bitmap_disable_prepare(BlkActionState *common, return; } - action = common->action->u.block_dirty_bitmap_disable.data; + action = &common->action->u.block_dirty_bitmap_disable; state->bitmap = block_dirty_bitmap_lookup(action->node, action->name, NULL, @@ -2174,7 +2174,7 @@ static void block_dirty_bitmap_merge_prepare(BlkActionState *common, return; } - action = common->action->u.block_dirty_bitmap_merge.data; + action = &common->action->u.block_dirty_bitmap_merge; state->bitmap = block_dirty_bitmap_merge(action->node, action->target, action->bitmaps, &state->backup, @@ -2192,7 +2192,7 @@ static void block_dirty_bitmap_remove_prepare(BlkActionState *common, return; } - action = common->action->u.block_dirty_bitmap_remove.data; + action = &common->action->u.block_dirty_bitmap_remove; state->bitmap = block_dirty_bitmap_remove(action->node, action->name, false, &state->bs, errp); @@ -2895,7 +2895,7 @@ void qmp_drive_backup(DriveBackup *backup, Error **errp) { TransactionAction action = { .type = TRANSACTION_ACTION_KIND_DRIVE_BACKUP, - .u.drive_backup.data = backup, + .u.drive_backup = *backup, }; blockdev_do_action(&action, errp); } @@ -2918,7 +2918,7 @@ void qmp_blockdev_backup(BlockdevBackup *backup, Error **errp) { TransactionAction action = { .type = TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP, - .u.blockdev_backup.data = backup, + .u.blockdev_backup = *backup, }; blockdev_do_action(&action, errp); } diff --git a/chardev/char-file.c b/chardev/char-file.c index 2fd80707e5..3f0f0b6045 100644 --- a/chardev/char-file.c +++ b/chardev/char-file.c @@ -39,7 +39,7 @@ static void qmp_chardev_open_file(Chardev *chr, bool *be_opened, Error **errp) { - ChardevFile *file = backend->u.file.data; + ChardevFile *file = &backend->u.file; #ifdef _WIN32 HANDLE out; DWORD accessmode; @@ -100,14 +100,13 @@ static void qemu_chr_parse_file_out(QemuOpts *opts, ChardevBackend *backend, Error **errp) { const char *path = qemu_opt_get(opts, "path"); - ChardevFile *file; + ChardevFile *file = &backend->u.file; backend->type = CHARDEV_BACKEND_KIND_FILE; if (path == NULL) { error_setg(errp, "chardev: file: no filename given"); return; } - file = backend->u.file.data = g_new0(ChardevFile, 1); qemu_chr_parse_common(opts, qapi_ChardevFile_base(file)); file->out = g_strdup(path); diff --git a/chardev/char-mux.c b/chardev/char-mux.c index 6f980bb836..bfb4bc6b8b 100644 --- a/chardev/char-mux.c +++ b/chardev/char-mux.c @@ -314,7 +314,7 @@ static void qemu_chr_open_mux(Chardev *chr, bool *be_opened, Error **errp) { - ChardevMux *mux = backend->u.mux.data; + ChardevMux *mux = &backend->u.mux; Chardev *drv; MuxChardev *d = MUX_CHARDEV(chr); @@ -336,14 +336,13 @@ static void qemu_chr_parse_mux(QemuOpts *opts, ChardevBackend *backend, Error **errp) { const char *chardev = qemu_opt_get(opts, "chardev"); - ChardevMux *mux; + ChardevMux *mux = &backend->u.mux; if (chardev == NULL) { error_setg(errp, "chardev: mux: no chardev given"); return; } backend->type = CHARDEV_BACKEND_KIND_MUX; - mux = backend->u.mux.data = g_new0(ChardevMux, 1); qemu_chr_parse_common(opts, qapi_ChardevMux_base(mux)); mux->chardev = g_strdup(chardev); } diff --git a/chardev/char-parallel.c b/chardev/char-parallel.c index 05e7efbd6c..a17157a3be 100644 --- a/chardev/char-parallel.c +++ b/chardev/char-parallel.c @@ -244,7 +244,7 @@ static void qmp_chardev_open_parallel(Chardev *chr, bool *be_opened, Error **errp) { - ChardevHostdev *parallel = backend->u.parallel.data; + ChardevHostdev *parallel = &backend->u.parallel; int fd; fd = qmp_chardev_open_file_source(parallel->device, O_RDWR, errp); @@ -258,14 +258,13 @@ static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend, Error **errp) { const char *device = qemu_opt_get(opts, "path"); - ChardevHostdev *parallel; + ChardevHostdev *parallel = &backend->u.parallel; if (device == NULL) { error_setg(errp, "chardev: parallel: no device path given"); return; } backend->type = CHARDEV_BACKEND_KIND_PARALLEL; - parallel = backend->u.parallel.data = g_new0(ChardevHostdev, 1); qemu_chr_parse_common(opts, qapi_ChardevHostdev_base(parallel)); parallel->device = g_strdup(device); } diff --git a/chardev/char-pipe.c b/chardev/char-pipe.c index 7eca5d9a56..eb19d9a526 100644 --- a/chardev/char-pipe.c +++ b/chardev/char-pipe.c @@ -109,7 +109,7 @@ static void qemu_chr_open_pipe(Chardev *chr, bool *be_opened, Error **errp) { - ChardevHostdev *opts = backend->u.pipe.data; + ChardevHostdev *opts = &backend->u.pipe; const char *filename = opts->device; if (win_chr_pipe_init(chr, filename, errp) < 0) { @@ -124,7 +124,7 @@ static void qemu_chr_open_pipe(Chardev *chr, bool *be_opened, Error **errp) { - ChardevHostdev *opts = backend->u.pipe.data; + ChardevHostdev *opts = &backend->u.pipe; int fd_in, fd_out; char *filename_in; char *filename_out; @@ -158,14 +158,13 @@ static void qemu_chr_parse_pipe(QemuOpts *opts, ChardevBackend *backend, Error **errp) { const char *device = qemu_opt_get(opts, "path"); - ChardevHostdev *dev; + ChardevHostdev *dev = &backend->u.pipe; if (device == NULL) { error_setg(errp, "chardev: pipe: no device path given"); return; } backend->type = CHARDEV_BACKEND_KIND_PIPE; - dev = backend->u.pipe.data = g_new0(ChardevHostdev, 1); qemu_chr_parse_common(opts, qapi_ChardevHostdev_base(dev)); dev->device = g_strdup(device); } diff --git a/chardev/char-ringbuf.c b/chardev/char-ringbuf.c index d40d21d3cf..0ef2a17f90 100644 --- a/chardev/char-ringbuf.c +++ b/chardev/char-ringbuf.c @@ -97,7 +97,7 @@ static void qemu_chr_open_ringbuf(Chardev *chr, bool *be_opened, Error **errp) { - ChardevRingbuf *opts = backend->u.ringbuf.data; + ChardevRingbuf *opts = &backend->u.ringbuf; RingBufChardev *d = RINGBUF_CHARDEV(chr); d->size = opts->has_size ? opts->size : 65536; @@ -210,10 +210,9 @@ static void qemu_chr_parse_ringbuf(QemuOpts *opts, ChardevBackend *backend, Error **errp) { int val; - ChardevRingbuf *ringbuf; + ChardevRingbuf *ringbuf = &backend->u.ringbuf; backend->type = CHARDEV_BACKEND_KIND_RINGBUF; - ringbuf = backend->u.ringbuf.data = g_new0(ChardevRingbuf, 1); qemu_chr_parse_common(opts, qapi_ChardevRingbuf_base(ringbuf)); val = qemu_opt_get_size(opts, "size", 0); diff --git a/chardev/char-serial.c b/chardev/char-serial.c index 7c3d84ae24..baec955ecf 100644 --- a/chardev/char-serial.c +++ b/chardev/char-serial.c @@ -263,7 +263,7 @@ static void qmp_chardev_open_serial(Chardev *chr, bool *be_opened, Error **errp) { - ChardevHostdev *serial = backend->u.serial.data; + ChardevHostdev *serial = &backend->u.serial; int fd; fd = qmp_chardev_open_file_source(serial->device, O_RDWR | O_NONBLOCK, @@ -283,14 +283,13 @@ static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend, Error **errp) { const char *device = qemu_opt_get(opts, "path"); - ChardevHostdev *serial; + ChardevHostdev *serial = &backend->u.serial; if (device == NULL) { error_setg(errp, "chardev: serial/tty: no device path given"); return; } backend->type = CHARDEV_BACKEND_KIND_SERIAL; - serial = backend->u.serial.data = g_new0(ChardevHostdev, 1); qemu_chr_parse_common(opts, qapi_ChardevHostdev_base(serial)); serial->device = g_strdup(device); } diff --git a/chardev/char-socket.c b/chardev/char-socket.c index 95e45812d5..5332439d34 100644 --- a/chardev/char-socket.c +++ b/chardev/char-socket.c @@ -1301,7 +1301,7 @@ static void qmp_chardev_open_socket(Chardev *chr, Error **errp) { SocketChardev *s = SOCKET_CHARDEV(chr); - ChardevSocket *sock = backend->u.socket.data; + ChardevSocket *sock = &backend->u.socket; bool do_nodelay = sock->has_nodelay ? sock->nodelay : false; bool is_listen = sock->has_server ? sock->server : true; bool is_telnet = sock->has_telnet ? sock->telnet : false; @@ -1403,7 +1403,7 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend, } backend->type = CHARDEV_BACKEND_KIND_SOCKET; - sock = backend->u.socket.data = g_new0(ChardevSocket, 1); + sock = &backend->u.socket; qemu_chr_parse_common(opts, qapi_ChardevSocket_base(sock)); sock->has_nodelay = qemu_opt_get(opts, "delay"); @@ -1435,16 +1435,14 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend, addr = g_new0(SocketAddressLegacy, 1); if (path) { - UnixSocketAddress *q_unix; + UnixSocketAddress *q_unix = &addr->u.q_unix; addr->type = SOCKET_ADDRESS_LEGACY_KIND_UNIX; - q_unix = addr->u.q_unix.data = g_new0(UnixSocketAddress, 1); q_unix->path = g_strdup(path); q_unix->tight = tight; q_unix->abstract = abstract; } else if (host) { addr->type = SOCKET_ADDRESS_LEGACY_KIND_INET; - addr->u.inet.data = g_new(InetSocketAddress, 1); - *addr->u.inet.data = (InetSocketAddress) { + addr->u.inet = (InetSocketAddress) { .host = g_strdup(host), .port = g_strdup(port), .has_to = qemu_opt_get(opts, "to"), @@ -1456,8 +1454,7 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend, }; } else if (fd) { addr->type = SOCKET_ADDRESS_LEGACY_KIND_FD; - addr->u.fd.data = g_new(String, 1); - addr->u.fd.data->str = g_strdup(fd); + addr->u.fd.str = g_strdup(fd); } else { g_assert_not_reached(); } diff --git a/chardev/char-stdio.c b/chardev/char-stdio.c index 403da308c9..81ee655a21 100644 --- a/chardev/char-stdio.c +++ b/chardev/char-stdio.c @@ -87,7 +87,7 @@ static void qemu_chr_open_stdio(Chardev *chr, bool *be_opened, Error **errp) { - ChardevStdio *opts = backend->u.stdio.data; + ChardevStdio *opts = &backend->u.stdio; struct sigaction act; if (is_daemonized()) { @@ -120,10 +120,9 @@ static void qemu_chr_open_stdio(Chardev *chr, static void qemu_chr_parse_stdio(QemuOpts *opts, ChardevBackend *backend, Error **errp) { - ChardevStdio *stdio; + ChardevStdio *stdio = &backend->u.stdio; backend->type = CHARDEV_BACKEND_KIND_STDIO; - stdio = backend->u.stdio.data = g_new0(ChardevStdio, 1); qemu_chr_parse_common(opts, qapi_ChardevStdio_base(stdio)); stdio->has_signal = true; stdio->signal = qemu_opt_get_bool(opts, "signal", true); diff --git a/chardev/char-udp.c b/chardev/char-udp.c index 16b5dbce58..3b1bdddbbd 100644 --- a/chardev/char-udp.c +++ b/chardev/char-udp.c @@ -140,7 +140,7 @@ static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend, const char *localport = qemu_opt_get(opts, "localport"); bool has_local = false; SocketAddressLegacy *addr; - ChardevUdp *udp; + ChardevUdp *udp = &backend->u.udp; backend->type = CHARDEV_BACKEND_KIND_UDP; if (host == NULL || strlen(host) == 0) { @@ -161,13 +161,11 @@ static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend, has_local = true; } - udp = backend->u.udp.data = g_new0(ChardevUdp, 1); qemu_chr_parse_common(opts, qapi_ChardevUdp_base(udp)); addr = g_new0(SocketAddressLegacy, 1); addr->type = SOCKET_ADDRESS_LEGACY_KIND_INET; - addr->u.inet.data = g_new(InetSocketAddress, 1); - *addr->u.inet.data = (InetSocketAddress) { + addr->u.inet = (InetSocketAddress) { .host = g_strdup(host), .port = g_strdup(port), .has_ipv4 = qemu_opt_get(opts, "ipv4"), @@ -181,8 +179,7 @@ static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend, udp->has_local = true; addr = g_new0(SocketAddressLegacy, 1); addr->type = SOCKET_ADDRESS_LEGACY_KIND_INET; - addr->u.inet.data = g_new(InetSocketAddress, 1); - *addr->u.inet.data = (InetSocketAddress) { + addr->u.inet = (InetSocketAddress) { .host = g_strdup(localaddr), .port = g_strdup(localport), }; @@ -195,7 +192,7 @@ static void qmp_chardev_open_udp(Chardev *chr, bool *be_opened, Error **errp) { - ChardevUdp *udp = backend->u.udp.data; + ChardevUdp *udp = &backend->u.udp; SocketAddress *local_addr = socket_address_flatten(udp->local); SocketAddress *remote_addr = socket_address_flatten(udp->remote); QIOChannelSocket *sioc = qio_channel_socket_new(); diff --git a/chardev/char.c b/chardev/char.c index 028612c333..5192964694 100644 --- a/chardev/char.c +++ b/chardev/char.c @@ -238,7 +238,7 @@ static void qemu_char_open(Chardev *chr, ChardevBackend *backend, { ChardevClass *cc = CHARDEV_GET_CLASS(chr); /* Any ChardevCommon member would work */ - ChardevCommon *common = backend ? backend->u.null.data : NULL; + ChardevCommon *common = backend ? &backend->u.null : NULL; if (common && common->has_logfile) { int flags = O_WRONLY | O_CREAT; @@ -625,9 +625,8 @@ ChardevBackend *qemu_chr_parse_opts(QemuOpts *opts, Error **errp) return NULL; } } else { - ChardevCommon *ccom = g_new0(ChardevCommon, 1); - qemu_chr_parse_common(opts, ccom); - backend->u.null.data = ccom; /* Any ChardevCommon member would work */ + /* Any ChardevCommon member would work */ + qemu_chr_parse_common(opts, &backend->u.null); } return backend; @@ -690,8 +689,7 @@ Chardev *qemu_chr_new_from_opts(QemuOpts *opts, GMainContext *context, qapi_free_ChardevBackend(backend); backend = g_new0(ChardevBackend, 1); backend->type = CHARDEV_BACKEND_KIND_MUX; - backend->u.mux.data = g_new0(ChardevMux, 1); - backend->u.mux.data->chardev = g_strdup(bid); + backend->u.mux.chardev = g_strdup(bid); mux = qemu_chardev_new(id, TYPE_CHARDEV_MUX, backend, context, errp); if (mux == NULL) { object_unparent(OBJECT(chr)); diff --git a/chardev/msmouse.c b/chardev/msmouse.c index eb9231dcdb..98b0ef8cd7 100644 --- a/chardev/msmouse.c +++ b/chardev/msmouse.c @@ -111,12 +111,12 @@ static void msmouse_input_event(DeviceState *dev, QemuConsole *src, switch (evt->type) { case INPUT_EVENT_KIND_REL: - move = evt->u.rel.data; + move = &evt->u.rel; mouse->axis[move->axis] += move->value; break; case INPUT_EVENT_KIND_BTN: - btn = evt->u.btn.data; + btn = &evt->u.btn; mouse->btns[btn->button] = btn->down; mouse->btnc[btn->button] = true; break; diff --git a/chardev/wctablet.c b/chardev/wctablet.c index 95e005f5a5..8479f59183 100644 --- a/chardev/wctablet.c +++ b/chardev/wctablet.c @@ -154,12 +154,12 @@ static void wctablet_input_event(DeviceState *dev, QemuConsole *src, switch (evt->type) { case INPUT_EVENT_KIND_ABS: - move = evt->u.abs.data; + move = &evt->u.abs; tablet->axis[move->axis] = move->value; break; case INPUT_EVENT_KIND_BTN: - btn = evt->u.btn.data; + btn = &evt->u.btn; tablet->btns[btn->button] = btn->down; break; diff --git a/hw/core/numa.c b/hw/core/numa.c index 7c4dd4e68e..24fe0e11d8 100644 --- a/hw/core/numa.c +++ b/hw/core/numa.c @@ -765,19 +765,19 @@ static void numa_stat_memory_devices(NumaNodeMem node_mem[]) case MEMORY_DEVICE_INFO_KIND_DIMM: case MEMORY_DEVICE_INFO_KIND_NVDIMM: pcdimm_info = value->type == MEMORY_DEVICE_INFO_KIND_DIMM ? - value->u.dimm.data : value->u.nvdimm.data; + &value->u.dimm : &value->u.nvdimm; node_mem[pcdimm_info->node].node_mem += pcdimm_info->size; node_mem[pcdimm_info->node].node_plugged_mem += pcdimm_info->size; break; case MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM: - vpi = value->u.virtio_pmem.data; + vpi = &value->u.virtio_pmem; /* TODO: once we support numa, assign to right node */ node_mem[0].node_mem += vpi->size; node_mem[0].node_plugged_mem += vpi->size; break; case MEMORY_DEVICE_INFO_KIND_VIRTIO_MEM: - vmi = value->u.virtio_mem.data; + vmi = &value->u.virtio_mem; node_mem[vmi->node].node_mem += vmi->size; node_mem[vmi->node].node_plugged_mem += vmi->size; break; diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c index 838260b6ad..6aa6010774 100644 --- a/hw/display/xenfb.c +++ b/hw/display/xenfb.c @@ -201,7 +201,7 @@ static void xenfb_key_event(DeviceState *dev, QemuConsole *src, InputEvent *evt) { struct XenInput *xenfb = (struct XenInput *)dev; - InputKeyEvent *key = evt->u.key.data; + InputKeyEvent *key = &evt->u.key; int qcode = qemu_input_key_value_to_qcode(key->key); int lnx; @@ -236,7 +236,7 @@ static void xenfb_mouse_event(DeviceState *dev, QemuConsole *src, switch (evt->type) { case INPUT_EVENT_KIND_BTN: - btn = evt->u.btn.data; + btn = &evt->u.btn; switch (btn->button) { case INPUT_BUTTON_LEFT: xenfb_send_key(xenfb, btn->down, BTN_LEFT); @@ -263,7 +263,7 @@ static void xenfb_mouse_event(DeviceState *dev, QemuConsole *src, break; case INPUT_EVENT_KIND_ABS: - move = evt->u.abs.data; + move = &evt->u.abs; if (xenfb->raw_pointer_wanted) { xenfb->axis[move->axis] = move->value; } else { @@ -289,7 +289,7 @@ static void xenfb_mouse_event(DeviceState *dev, QemuConsole *src, break; case INPUT_EVENT_KIND_REL: - move = evt->u.rel.data; + move = &evt->u.rel; xenfb->axis[move->axis] += move->value; break; diff --git a/hw/input/hid.c b/hw/input/hid.c index 89239b5634..2472c5a902 100644 --- a/hw/input/hid.c +++ b/hw/input/hid.c @@ -126,7 +126,7 @@ static void hid_pointer_event(DeviceState *dev, QemuConsole *src, switch (evt->type) { case INPUT_EVENT_KIND_REL: - move = evt->u.rel.data; + move = &evt->u.rel; if (move->axis == INPUT_AXIS_X) { e->xdx += move->value; } else if (move->axis == INPUT_AXIS_Y) { @@ -135,7 +135,7 @@ static void hid_pointer_event(DeviceState *dev, QemuConsole *src, break; case INPUT_EVENT_KIND_ABS: - move = evt->u.abs.data; + move = &evt->u.abs; if (move->axis == INPUT_AXIS_X) { e->xdx = move->value; } else if (move->axis == INPUT_AXIS_Y) { @@ -144,7 +144,7 @@ static void hid_pointer_event(DeviceState *dev, QemuConsole *src, break; case INPUT_EVENT_KIND_BTN: - btn = evt->u.btn.data; + btn = &evt->u.btn; if (btn->down) { e->buttons_state |= bmap[btn->button]; if (btn->button == INPUT_BUTTON_WHEEL_UP) { @@ -230,7 +230,7 @@ static void hid_keyboard_event(DeviceState *dev, QemuConsole *src, HIDState *hs = (HIDState *)dev; int scancodes[3], i, count; int slot; - InputKeyEvent *key = evt->u.key.data; + InputKeyEvent *key = &evt->u.key; count = qemu_input_key_value_to_scancode(key->key, key->down, diff --git a/hw/input/ps2.c b/hw/input/ps2.c index f8746d2f52..1176ccc88c 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -284,7 +284,7 @@ static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src, InputEvent *evt) { PS2KbdState *s = (PS2KbdState *)dev; - InputKeyEvent *key = evt->u.key.data; + InputKeyEvent *key = &evt->u.key; int qcode; uint16_t keycode = 0; int mod; @@ -727,7 +727,7 @@ static void ps2_mouse_event(DeviceState *dev, QemuConsole *src, switch (evt->type) { case INPUT_EVENT_KIND_REL: - move = evt->u.rel.data; + move = &evt->u.rel; if (move->axis == INPUT_AXIS_X) { s->mouse_dx += move->value; } else if (move->axis == INPUT_AXIS_Y) { @@ -736,7 +736,7 @@ static void ps2_mouse_event(DeviceState *dev, QemuConsole *src, break; case INPUT_EVENT_KIND_BTN: - btn = evt->u.btn.data; + btn = &evt->u.btn; if (btn->down) { s->mouse_buttons |= bmap[btn->button]; if (btn->button == INPUT_BUTTON_WHEEL_UP) { diff --git a/hw/input/virtio-input-hid.c b/hw/input/virtio-input-hid.c index a7a244a95d..1c7b07cf42 100644 --- a/hw/input/virtio-input-hid.c +++ b/hw/input/virtio-input-hid.c @@ -83,7 +83,7 @@ static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src, switch (evt->type) { case INPUT_EVENT_KIND_KEY: - key = evt->u.key.data; + key = &evt->u.key; qcode = qemu_input_key_value_to_qcode(key->key); if (qcode < qemu_input_map_qcode_to_linux_len && qemu_input_map_qcode_to_linux[qcode]) { @@ -99,7 +99,7 @@ static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src, } break; case INPUT_EVENT_KIND_BTN: - btn = evt->u.btn.data; + btn = &evt->u.btn; if (vhid->wheel_axis && (btn->button == INPUT_BUTTON_WHEEL_UP || btn->button == INPUT_BUTTON_WHEEL_DOWN) && @@ -123,14 +123,14 @@ static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src, } break; case INPUT_EVENT_KIND_REL: - move = evt->u.rel.data; + move = &evt->u.rel; event.type = cpu_to_le16(EV_REL); event.code = cpu_to_le16(axismap_rel[move->axis]); event.value = cpu_to_le32(move->value); virtio_input_send(vinput, &event); break; case INPUT_EVENT_KIND_ABS: - move = evt->u.abs.data; + move = &evt->u.abs; event.type = cpu_to_le16(EV_ABS); event.code = cpu_to_le16(axismap_abs[move->axis]); event.value = cpu_to_le32(move->value); diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c index c30351070b..3d6f836621 100644 --- a/hw/mem/pc-dimm.c +++ b/hw/mem/pc-dimm.c @@ -236,11 +236,19 @@ static MemoryRegion *pc_dimm_md_get_memory_region(MemoryDeviceState *md, static void pc_dimm_md_fill_device_info(const MemoryDeviceState *md, MemoryDeviceInfo *info) { - PCDIMMDeviceInfo *di = g_new0(PCDIMMDeviceInfo, 1); + PCDIMMDeviceInfo *di; const DeviceClass *dc = DEVICE_GET_CLASS(md); const PCDIMMDevice *dimm = PC_DIMM(md); const DeviceState *dev = DEVICE(md); + if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) { + di = &info->u.nvdimm; + info->type = MEMORY_DEVICE_INFO_KIND_NVDIMM; + } else { + di = &info->u.dimm; + info->type = MEMORY_DEVICE_INFO_KIND_DIMM; + } + if (dev->id) { di->has_id = true; di->id = g_strdup(dev->id); @@ -253,14 +261,6 @@ static void pc_dimm_md_fill_device_info(const MemoryDeviceState *md, di->size = object_property_get_uint(OBJECT(dimm), PC_DIMM_SIZE_PROP, NULL); di->memdev = object_get_canonical_path(OBJECT(dimm->hostmem)); - - if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) { - info->u.nvdimm.data = di; - info->type = MEMORY_DEVICE_INFO_KIND_NVDIMM; - } else { - info->u.dimm.data = di; - info->type = MEMORY_DEVICE_INFO_KIND_DIMM; - } } static void pc_dimm_class_init(ObjectClass *oc, void *data) diff --git a/hw/virtio/virtio-mem-pci.c b/hw/virtio/virtio-mem-pci.c index 913f4a3326..f93572fc27 100644 --- a/hw/virtio/virtio-mem-pci.c +++ b/hw/virtio/virtio-mem-pci.c @@ -58,7 +58,7 @@ static uint64_t virtio_mem_pci_get_plugged_size(const MemoryDeviceState *md, static void virtio_mem_pci_fill_device_info(const MemoryDeviceState *md, MemoryDeviceInfo *info) { - VirtioMEMDeviceInfo *vi = g_new0(VirtioMEMDeviceInfo, 1); + VirtioMEMDeviceInfo *vi = &info->u.virtio_mem; VirtIOMEMPCI *pci_mem = VIRTIO_MEM_PCI(md); VirtIOMEM *vmem = VIRTIO_MEM(&pci_mem->vdev); VirtIOMEMClass *vpc = VIRTIO_MEM_GET_CLASS(vmem); @@ -72,7 +72,6 @@ static void virtio_mem_pci_fill_device_info(const MemoryDeviceState *md, /* let the real device handle everything else */ vpc->fill_device_info(vmem, vi); - info->u.virtio_mem.data = vi; info->type = MEMORY_DEVICE_INFO_KIND_VIRTIO_MEM; } diff --git a/hw/virtio/virtio-pmem-pci.c b/hw/virtio/virtio-pmem-pci.c index 2b2a0b1eae..adf17f873b 100644 --- a/hw/virtio/virtio-pmem-pci.c +++ b/hw/virtio/virtio-pmem-pci.c @@ -63,7 +63,7 @@ static uint64_t virtio_pmem_pci_get_plugged_size(const MemoryDeviceState *md, static void virtio_pmem_pci_fill_device_info(const MemoryDeviceState *md, MemoryDeviceInfo *info) { - VirtioPMEMDeviceInfo *vi = g_new0(VirtioPMEMDeviceInfo, 1); + VirtioPMEMDeviceInfo *vi = &info->u.virtio_pmem; VirtIOPMEMPCI *pci_pmem = VIRTIO_PMEM_PCI(md); VirtIOPMEM *pmem = VIRTIO_PMEM(&pci_pmem->vdev); VirtIOPMEMClass *vpc = VIRTIO_PMEM_GET_CLASS(pmem); @@ -77,7 +77,6 @@ static void virtio_pmem_pci_fill_device_info(const MemoryDeviceState *md, /* let the real device handle everything else */ vpc->fill_device_info(pmem, vi); - info->u.virtio_pmem.data = vi; info->type = MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM; } diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index 9789f4277f..0324caa114 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -918,7 +918,7 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict) switch (ti->options->type) { case TPM_TYPE_OPTIONS_KIND_PASSTHROUGH: - tpo = ti->options->u.passthrough.data; + tpo = &ti->options->u.passthrough; monitor_printf(mon, "%s%s%s%s", tpo->has_path ? ",path=" : "", tpo->has_path ? tpo->path : "", @@ -926,7 +926,7 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict) tpo->has_cancel_path ? tpo->cancel_path : ""); break; case TPM_TYPE_OPTIONS_KIND_EMULATOR: - teo = ti->options->u.emulator.data; + teo = &ti->options->u.emulator; monitor_printf(mon, ",chardev=%s", teo->chardev); break; case TPM_TYPE_OPTIONS_KIND__MAX: @@ -1728,14 +1728,14 @@ void hmp_sendkey(Monitor *mon, const QDict *qdict) goto err_out; } keylist->value->type = KEY_VALUE_KIND_NUMBER; - keylist->value->u.number.data = value; + keylist->value->u.number = value; } else { int idx = index_from_key(keys, keyname_len); if (idx == Q_KEY_CODE__MAX) { goto err_out; } keylist->value->type = KEY_VALUE_KIND_QCODE; - keylist->value->u.qcode.data = idx; + keylist->value->u.qcode = idx; } if (!*separator) { @@ -1860,7 +1860,7 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict) case MEMORY_DEVICE_INFO_KIND_DIMM: case MEMORY_DEVICE_INFO_KIND_NVDIMM: di = value->type == MEMORY_DEVICE_INFO_KIND_DIMM ? - value->u.dimm.data : value->u.nvdimm.data; + &value->u.dimm : &value->u.nvdimm; monitor_printf(mon, "Memory device [%s]: \"%s\"\n", MemoryDeviceInfoKind_str(value->type), di->id ? di->id : ""); @@ -1875,7 +1875,7 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict) di->hotpluggable ? "true" : "false"); break; case MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM: - vpi = value->u.virtio_pmem.data; + vpi = &value->u.virtio_pmem; monitor_printf(mon, "Memory device [%s]: \"%s\"\n", MemoryDeviceInfoKind_str(value->type), vpi->id ? vpi->id : ""); @@ -1884,7 +1884,7 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict) monitor_printf(mon, " memdev: %s\n", vpi->memdev); break; case MEMORY_DEVICE_INFO_KIND_VIRTIO_MEM: - vmi = value->u.virtio_mem.data; + vmi = &value->u.virtio_mem; monitor_printf(mon, "Memory device [%s]: \"%s\"\n", MemoryDeviceInfoKind_str(value->type), vmi->id ? vmi->id : ""); diff --git a/qemu-keymap.c b/qemu-keymap.c index 536e8f2385..52637c449c 100644 --- a/qemu-keymap.c +++ b/qemu-keymap.c @@ -38,7 +38,7 @@ static uint32_t qcode_to_number(uint32_t qcode) uint32_t number; keyvalue.type = KEY_VALUE_KIND_QCODE; - keyvalue.u.qcode.data = qcode; + keyvalue.u.qcode = qcode; number = qemu_input_key_value_to_number(&keyvalue); assert(number != 0); return number; diff --git a/replay/replay-input.c b/replay/replay-input.c index 1147e3d34e..c1eb1b79e1 100644 --- a/replay/replay-input.c +++ b/replay/replay-input.c @@ -26,16 +26,16 @@ void replay_save_input_event(InputEvent *evt) switch (evt->type) { case INPUT_EVENT_KIND_KEY: - key = evt->u.key.data; + key = &evt->u.key; replay_put_dword(key->key->type); switch (key->key->type) { case KEY_VALUE_KIND_NUMBER: - replay_put_qword(key->key->u.number.data); + replay_put_qword(key->key->u.number); replay_put_byte(key->down); break; case KEY_VALUE_KIND_QCODE: - replay_put_dword(key->key->u.qcode.data); + replay_put_dword(key->key->u.qcode); replay_put_byte(key->down); break; case KEY_VALUE_KIND__MAX: @@ -44,17 +44,17 @@ void replay_save_input_event(InputEvent *evt) } break; case INPUT_EVENT_KIND_BTN: - btn = evt->u.btn.data; + btn = &evt->u.btn; replay_put_dword(btn->button); replay_put_byte(btn->down); break; case INPUT_EVENT_KIND_REL: - move = evt->u.rel.data; + move = &evt->u.rel; replay_put_dword(move->axis); replay_put_qword(move->value); break; case INPUT_EVENT_KIND_ABS: - move = evt->u.abs.data; + move = &evt->u.abs; replay_put_dword(move->axis); replay_put_qword(move->value); break; @@ -68,26 +68,21 @@ InputEvent *replay_read_input_event(void) { InputEvent evt; KeyValue keyValue; - InputKeyEvent key; - key.key = &keyValue; - InputBtnEvent btn; - InputMoveEvent rel; - InputMoveEvent abs; + evt.u.key.key = &keyValue; evt.type = replay_get_dword(); switch (evt.type) { case INPUT_EVENT_KIND_KEY: - evt.u.key.data = &key; - evt.u.key.data->key->type = replay_get_dword(); + evt.u.key.key->type = replay_get_dword(); - switch (evt.u.key.data->key->type) { + switch (evt.u.key.key->type) { case KEY_VALUE_KIND_NUMBER: - evt.u.key.data->key->u.number.data = replay_get_qword(); - evt.u.key.data->down = replay_get_byte(); + evt.u.key.key->u.number = replay_get_qword(); + evt.u.key.down = replay_get_byte(); break; case KEY_VALUE_KIND_QCODE: - evt.u.key.data->key->u.qcode.data = (QKeyCode)replay_get_dword(); - evt.u.key.data->down = replay_get_byte(); + evt.u.key.key->u.qcode = (QKeyCode)replay_get_dword(); + evt.u.key.down = replay_get_byte(); break; case KEY_VALUE_KIND__MAX: /* keep gcc happy */ @@ -95,19 +90,16 @@ InputEvent *replay_read_input_event(void) } break; case INPUT_EVENT_KIND_BTN: - evt.u.btn.data = &btn; - evt.u.btn.data->button = (InputButton)replay_get_dword(); - evt.u.btn.data->down = replay_get_byte(); + evt.u.btn.button = (InputButton)replay_get_dword(); + evt.u.btn.down = replay_get_byte(); break; case INPUT_EVENT_KIND_REL: - evt.u.rel.data = &rel; - evt.u.rel.data->axis = (InputAxis)replay_get_dword(); - evt.u.rel.data->value = replay_get_qword(); + evt.u.rel.axis = (InputAxis)replay_get_dword(); + evt.u.rel.value = replay_get_qword(); break; case INPUT_EVENT_KIND_ABS: - evt.u.abs.data = &abs; - evt.u.abs.data->axis = (InputAxis)replay_get_dword(); - evt.u.abs.data->value = replay_get_qword(); + evt.u.abs.axis = (InputAxis)replay_get_dword(); + evt.u.abs.value = replay_get_qword(); break; case INPUT_EVENT_KIND__MAX: /* keep gcc happy */ diff --git a/tests/test-char.c b/tests/test-char.c index 9196e566e9..0e7a033a90 100644 --- a/tests/test-char.c +++ b/tests/test-char.c @@ -1220,7 +1220,7 @@ static void char_file_fifo_test(void) .has_in = true, .out = out }; ChardevBackend backend = { .type = CHARDEV_BACKEND_KIND_FILE, - .u.file.data = &file }; + .u.file = file }; FeHandler fe = { 0, }; int fd, ret; @@ -1273,19 +1273,17 @@ static void char_file_test_internal(Chardev *ext_chr, const char *filepath) char *out; Chardev *chr; char *contents = NULL; - ChardevFile file = {}; - ChardevBackend backend = { .type = CHARDEV_BACKEND_KIND_FILE, - .u.file.data = &file }; + ChardevBackend backend = { .type = CHARDEV_BACKEND_KIND_FILE }; gsize length; int ret; if (ext_chr) { chr = ext_chr; out = g_strdup(filepath); - file.out = out; + backend.u.file.out = out; } else { out = g_build_filename(tmp_path, "out", NULL); - file.out = out; + backend.u.file.out = out; chr = qemu_chardev_new(NULL, TYPE_CHARDEV_FILE, &backend, NULL, &error_abort); } @@ -1384,7 +1382,7 @@ static void char_hotswap_test(void) char *filename = g_build_filename(tmp_path, "file", NULL); ChardevFile file = { .out = filename }; ChardevBackend backend = { .type = CHARDEV_BACKEND_KIND_FILE, - .u.file.data = &file }; + .u.file = file }; ChardevReturn *ret; int port; diff --git a/tests/test-clone-visitor.c b/tests/test-clone-visitor.c index 5e1e8b2f5e..0a62704bed 100644 --- a/tests/test-clone-visitor.c +++ b/tests/test-clone-visitor.c @@ -110,7 +110,7 @@ static void test_clone_complex1(void) dst = QAPI_CLONE(UserDefListUnion, src); g_assert(dst); g_assert_cmpint(dst->type, ==, src->type); - g_assert(!dst->u.string.data); + g_assert(!dst->u.string); qapi_free_UserDefListUnion(src); qapi_free_UserDefListUnion(dst); @@ -155,30 +155,30 @@ static void test_clone_complex3(void) tmp = src->array = g_new0(__org_qemu_x_Union1List, 1); tmp->value = g_new0(__org_qemu_x_Union1, 1); tmp->value->type = ORG_QEMU_X_UNION1_KIND___ORG_QEMU_X_BRANCH; - tmp->value->u.__org_qemu_x_branch.data = g_strdup("one"); + tmp->value->u.__org_qemu_x_branch = g_strdup("one"); tmp = tmp->next = g_new0(__org_qemu_x_Union1List, 1); tmp->value = g_new0(__org_qemu_x_Union1, 1); tmp->value->type = ORG_QEMU_X_UNION1_KIND___ORG_QEMU_X_BRANCH; - tmp->value->u.__org_qemu_x_branch.data = g_strdup("two"); + tmp->value->u.__org_qemu_x_branch = g_strdup("two"); tmp = tmp->next = g_new0(__org_qemu_x_Union1List, 1); tmp->value = g_new0(__org_qemu_x_Union1, 1); tmp->value->type = ORG_QEMU_X_UNION1_KIND___ORG_QEMU_X_BRANCH; - tmp->value->u.__org_qemu_x_branch.data = g_strdup("three"); + tmp->value->u.__org_qemu_x_branch = g_strdup("three"); dst = QAPI_CLONE(__org_qemu_x_Struct2, src); g_assert(dst); tmp = dst->array; g_assert(tmp); g_assert(tmp->value); - g_assert_cmpstr(tmp->value->u.__org_qemu_x_branch.data, ==, "one"); + g_assert_cmpstr(tmp->value->u.__org_qemu_x_branch, ==, "one"); tmp = tmp->next; g_assert(tmp); g_assert(tmp->value); - g_assert_cmpstr(tmp->value->u.__org_qemu_x_branch.data, ==, "two"); + g_assert_cmpstr(tmp->value->u.__org_qemu_x_branch, ==, "two"); tmp = tmp->next; g_assert(tmp); g_assert(tmp->value); - g_assert_cmpstr(tmp->value->u.__org_qemu_x_branch.data, ==, "three"); + g_assert_cmpstr(tmp->value->u.__org_qemu_x_branch, ==, "three"); tmp = tmp->next; g_assert(!tmp); diff --git a/tests/test-qmp-cmds.c b/tests/test-qmp-cmds.c index d3413bfef0..3d699fbb66 100644 --- a/tests/test-qmp-cmds.c +++ b/tests/test-qmp-cmds.c @@ -136,7 +136,7 @@ __org_qemu_x_Union1 *qmp___org_qemu_x_command(__org_qemu_x_EnumList *a, __org_qemu_x_Union1 *ret = g_new0(__org_qemu_x_Union1, 1); ret->type = ORG_QEMU_X_UNION1_KIND___ORG_QEMU_X_BRANCH; - ret->u.__org_qemu_x_branch.data = strdup("blah1"); + ret->u.__org_qemu_x_branch = strdup("blah1"); /* Also test that 'wchar-t' was munged to 'q_wchar_t' */ if (b && b->value && !b->value->has_q_wchar_t) { diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c index e41b91a2a6..b976ab9763 100644 --- a/tests/test-qobject-input-visitor.c +++ b/tests/test-qobject-input-visitor.c @@ -710,7 +710,7 @@ static void test_list_union_integer_helper(TestInputVisitorData *data, switch (kind) { case USER_DEF_LIST_UNION_KIND_INTEGER: { intList *elem = NULL; - for (i = 0, elem = cvalue->u.integer.data; + for (i = 0, elem = cvalue->u.integer; elem; elem = elem->next, i++) { g_assert_cmpint(elem->value, ==, i); } @@ -718,56 +718,56 @@ static void test_list_union_integer_helper(TestInputVisitorData *data, } case USER_DEF_LIST_UNION_KIND_S8: { int8List *elem = NULL; - for (i = 0, elem = cvalue->u.s8.data; elem; elem = elem->next, i++) { + for (i = 0, elem = cvalue->u.s8; elem; elem = elem->next, i++) { g_assert_cmpint(elem->value, ==, i); } break; } case USER_DEF_LIST_UNION_KIND_S16: { int16List *elem = NULL; - for (i = 0, elem = cvalue->u.s16.data; elem; elem = elem->next, i++) { + for (i = 0, elem = cvalue->u.s16; elem; elem = elem->next, i++) { g_assert_cmpint(elem->value, ==, i); } break; } case USER_DEF_LIST_UNION_KIND_S32: { int32List *elem = NULL; - for (i = 0, elem = cvalue->u.s32.data; elem; elem = elem->next, i++) { + for (i = 0, elem = cvalue->u.s32; elem; elem = elem->next, i++) { g_assert_cmpint(elem->value, ==, i); } break; } case USER_DEF_LIST_UNION_KIND_S64: { int64List *elem = NULL; - for (i = 0, elem = cvalue->u.s64.data; elem; elem = elem->next, i++) { + for (i = 0, elem = cvalue->u.s64; elem; elem = elem->next, i++) { g_assert_cmpint(elem->value, ==, i); } break; } case USER_DEF_LIST_UNION_KIND_U8: { uint8List *elem = NULL; - for (i = 0, elem = cvalue->u.u8.data; elem; elem = elem->next, i++) { + for (i = 0, elem = cvalue->u.u8; elem; elem = elem->next, i++) { g_assert_cmpint(elem->value, ==, i); } break; } case USER_DEF_LIST_UNION_KIND_U16: { uint16List *elem = NULL; - for (i = 0, elem = cvalue->u.u16.data; elem; elem = elem->next, i++) { + for (i = 0, elem = cvalue->u.u16; elem; elem = elem->next, i++) { g_assert_cmpint(elem->value, ==, i); } break; } case USER_DEF_LIST_UNION_KIND_U32: { uint32List *elem = NULL; - for (i = 0, elem = cvalue->u.u32.data; elem; elem = elem->next, i++) { + for (i = 0, elem = cvalue->u.u32; elem; elem = elem->next, i++) { g_assert_cmpint(elem->value, ==, i); } break; } case USER_DEF_LIST_UNION_KIND_U64: { uint64List *elem = NULL; - for (i = 0, elem = cvalue->u.u64.data; elem; elem = elem->next, i++) { + for (i = 0, elem = cvalue->u.u64; elem; elem = elem->next, i++) { g_assert_cmpint(elem->value, ==, i); } break; @@ -868,7 +868,7 @@ static void test_visitor_in_list_union_bool(TestInputVisitorData *data, g_assert(cvalue != NULL); g_assert_cmpint(cvalue->type, ==, USER_DEF_LIST_UNION_KIND_BOOLEAN); - for (i = 0, elem = cvalue->u.boolean.data; elem; elem = elem->next, i++) { + for (i = 0, elem = cvalue->u.boolean; elem; elem = elem->next, i++) { g_assert_cmpint(elem->value, ==, (i % 3 == 0) ? 1 : 0); } @@ -900,7 +900,7 @@ static void test_visitor_in_list_union_string(TestInputVisitorData *data, g_assert(cvalue != NULL); g_assert_cmpint(cvalue->type, ==, USER_DEF_LIST_UNION_KIND_STRING); - for (i = 0, elem = cvalue->u.string.data; elem; elem = elem->next, i++) { + for (i = 0, elem = cvalue->u.string; elem; elem = elem->next, i++) { gchar str[8]; sprintf(str, "%d", i); g_assert_cmpstr(elem->value, ==, str); @@ -936,7 +936,7 @@ static void test_visitor_in_list_union_number(TestInputVisitorData *data, g_assert(cvalue != NULL); g_assert_cmpint(cvalue->type, ==, USER_DEF_LIST_UNION_KIND_NUMBER); - for (i = 0, elem = cvalue->u.number.data; elem; elem = elem->next, i++) { + for (i = 0, elem = cvalue->u.number; elem; elem = elem->next, i++) { GString *double_expected = g_string_new(""); GString *double_actual = g_string_new(""); diff --git a/tests/test-qobject-output-visitor.c b/tests/test-qobject-output-visitor.c index 1c856d9bd2..202f848062 100644 --- a/tests/test-qobject-output-visitor.c +++ b/tests/test-qobject-output-visitor.c @@ -444,7 +444,7 @@ static void init_list_union(UserDefListUnion *cvalue) int i; switch (cvalue->type) { case USER_DEF_LIST_UNION_KIND_INTEGER: { - intList **list = &cvalue->u.integer.data; + intList **list = &cvalue->u.integer; for (i = 0; i < 32; i++) { *list = g_new0(intList, 1); (*list)->value = i; @@ -454,7 +454,7 @@ static void init_list_union(UserDefListUnion *cvalue) break; } case USER_DEF_LIST_UNION_KIND_S8: { - int8List **list = &cvalue->u.s8.data; + int8List **list = &cvalue->u.s8; for (i = 0; i < 32; i++) { *list = g_new0(int8List, 1); (*list)->value = i; @@ -464,7 +464,7 @@ static void init_list_union(UserDefListUnion *cvalue) break; } case USER_DEF_LIST_UNION_KIND_S16: { - int16List **list = &cvalue->u.s16.data; + int16List **list = &cvalue->u.s16; for (i = 0; i < 32; i++) { *list = g_new0(int16List, 1); (*list)->value = i; @@ -474,7 +474,7 @@ static void init_list_union(UserDefListUnion *cvalue) break; } case USER_DEF_LIST_UNION_KIND_S32: { - int32List **list = &cvalue->u.s32.data; + int32List **list = &cvalue->u.s32; for (i = 0; i < 32; i++) { *list = g_new0(int32List, 1); (*list)->value = i; @@ -484,7 +484,7 @@ static void init_list_union(UserDefListUnion *cvalue) break; } case USER_DEF_LIST_UNION_KIND_S64: { - int64List **list = &cvalue->u.s64.data; + int64List **list = &cvalue->u.s64; for (i = 0; i < 32; i++) { *list = g_new0(int64List, 1); (*list)->value = i; @@ -494,7 +494,7 @@ static void init_list_union(UserDefListUnion *cvalue) break; } case USER_DEF_LIST_UNION_KIND_U8: { - uint8List **list = &cvalue->u.u8.data; + uint8List **list = &cvalue->u.u8; for (i = 0; i < 32; i++) { *list = g_new0(uint8List, 1); (*list)->value = i; @@ -504,7 +504,7 @@ static void init_list_union(UserDefListUnion *cvalue) break; } case USER_DEF_LIST_UNION_KIND_U16: { - uint16List **list = &cvalue->u.u16.data; + uint16List **list = &cvalue->u.u16; for (i = 0; i < 32; i++) { *list = g_new0(uint16List, 1); (*list)->value = i; @@ -514,7 +514,7 @@ static void init_list_union(UserDefListUnion *cvalue) break; } case USER_DEF_LIST_UNION_KIND_U32: { - uint32List **list = &cvalue->u.u32.data; + uint32List **list = &cvalue->u.u32; for (i = 0; i < 32; i++) { *list = g_new0(uint32List, 1); (*list)->value = i; @@ -524,7 +524,7 @@ static void init_list_union(UserDefListUnion *cvalue) break; } case USER_DEF_LIST_UNION_KIND_U64: { - uint64List **list = &cvalue->u.u64.data; + uint64List **list = &cvalue->u.u64; for (i = 0; i < 32; i++) { *list = g_new0(uint64List, 1); (*list)->value = i; @@ -534,7 +534,7 @@ static void init_list_union(UserDefListUnion *cvalue) break; } case USER_DEF_LIST_UNION_KIND_BOOLEAN: { - boolList **list = &cvalue->u.boolean.data; + boolList **list = &cvalue->u.boolean; for (i = 0; i < 32; i++) { *list = g_new0(boolList, 1); (*list)->value = QEMU_IS_ALIGNED(i, 3); @@ -544,7 +544,7 @@ static void init_list_union(UserDefListUnion *cvalue) break; } case USER_DEF_LIST_UNION_KIND_STRING: { - strList **list = &cvalue->u.string.data; + strList **list = &cvalue->u.string; for (i = 0; i < 32; i++) { *list = g_new0(strList, 1); (*list)->value = g_strdup_printf("%d", i); @@ -554,7 +554,7 @@ static void init_list_union(UserDefListUnion *cvalue) break; } case USER_DEF_LIST_UNION_KIND_NUMBER: { - numberList **list = &cvalue->u.number.data; + numberList **list = &cvalue->u.number; for (i = 0; i < 32; i++) { *list = g_new0(numberList, 1); (*list)->value = (double)i / 3; diff --git a/ui/console.c b/ui/console.c index 820e408170..2f93723ed6 100644 --- a/ui/console.c +++ b/ui/console.c @@ -2212,7 +2212,7 @@ static void vc_chr_open(Chardev *chr, bool *be_opened, Error **errp) { - ChardevVC *vc = backend->u.vc.data; + ChardevVC *vc = &backend->u.vc; VCChardev *drv = VC_CHARDEV(chr); QemuConsole *s; unsigned width = 0; @@ -2362,10 +2362,9 @@ void qemu_display_help(void) void qemu_chr_parse_vc(QemuOpts *opts, ChardevBackend *backend, Error **errp) { int val; - ChardevVC *vc; + ChardevVC *vc = &backend->u.vc; backend->type = CHARDEV_BACKEND_KIND_VC; - vc = backend->u.vc.data = g_new0(ChardevVC, 1); qemu_chr_parse_common(opts, qapi_ChardevVC_base(vc)); val = qemu_opt_get_number(opts, "width", 0); diff --git a/ui/input-keymap.c b/ui/input-keymap.c index 1b756a6970..0232e25124 100644 --- a/ui/input-keymap.c +++ b/ui/input-keymap.c @@ -33,13 +33,13 @@ int qemu_input_linux_to_qcode(unsigned int lnx) int qemu_input_key_value_to_number(const KeyValue *value) { if (value->type == KEY_VALUE_KIND_QCODE) { - if (value->u.qcode.data >= qemu_input_map_qcode_to_qnum_len) { + if (value->u.qcode >= qemu_input_map_qcode_to_qnum_len) { return 0; } - return qemu_input_map_qcode_to_qnum[value->u.qcode.data]; + return qemu_input_map_qcode_to_qnum[value->u.qcode]; } else { assert(value->type == KEY_VALUE_KIND_NUMBER); - return value->u.number.data; + return value->u.number; } } @@ -54,10 +54,10 @@ int qemu_input_key_number_to_qcode(unsigned int nr) int qemu_input_key_value_to_qcode(const KeyValue *value) { if (value->type == KEY_VALUE_KIND_QCODE) { - return value->u.qcode.data; + return value->u.qcode; } else { assert(value->type == KEY_VALUE_KIND_NUMBER); - return qemu_input_key_number_to_qcode(value->u.number.data); + return qemu_input_key_number_to_qcode(value->u.number); } } @@ -68,7 +68,7 @@ int qemu_input_key_value_to_scancode(const KeyValue *value, bool down, int count = 0; if (value->type == KEY_VALUE_KIND_QCODE && - value->u.qcode.data == Q_KEY_CODE_PAUSE) { + value->u.qcode == Q_KEY_CODE_PAUSE) { /* specific case */ int v = down ? 0 : 0x80; codes[count++] = 0xe1; diff --git a/ui/input-legacy.c b/ui/input-legacy.c index 9fc78a639b..5a32b010d4 100644 --- a/ui/input-legacy.c +++ b/ui/input-legacy.c @@ -75,9 +75,9 @@ static KeyValue *copy_key_value(KeyValue *src) KeyValue *dst = g_new(KeyValue, 1); memcpy(dst, src, sizeof(*src)); if (dst->type == KEY_VALUE_KIND_NUMBER) { - QKeyCode code = qemu_input_key_number_to_qcode(dst->u.number.data); + QKeyCode code = qemu_input_key_number_to_qcode(dst->u.number); dst->type = KEY_VALUE_KIND_QCODE; - dst->u.qcode.data = code; + dst->u.qcode = code; } return dst; } @@ -113,7 +113,7 @@ static void legacy_kbd_event(DeviceState *dev, QemuConsole *src, { QEMUPutKbdEntry *entry = (QEMUPutKbdEntry *)dev; int scancodes[3], i, count; - InputKeyEvent *key = evt->u.key.data; + InputKeyEvent *key = &evt->u.key; if (!entry || !entry->put_kbd) { return; @@ -159,7 +159,7 @@ static void legacy_mouse_event(DeviceState *dev, QemuConsole *src, switch (evt->type) { case INPUT_EVENT_KIND_BTN: - btn = evt->u.btn.data; + btn = &evt->u.btn; if (btn->down) { s->buttons |= bmap[btn->button]; } else { @@ -181,11 +181,11 @@ static void legacy_mouse_event(DeviceState *dev, QemuConsole *src, } break; case INPUT_EVENT_KIND_ABS: - move = evt->u.abs.data; + move = &evt->u.abs; s->axis[move->axis] = move->value; break; case INPUT_EVENT_KIND_REL: - move = evt->u.rel.data; + move = &evt->u.rel; s->axis[move->axis] += move->value; break; default: diff --git a/ui/input.c b/ui/input.c index 4791b089c7..a4078780ee 100644 --- a/ui/input.c +++ b/ui/input.c @@ -164,10 +164,10 @@ void qmp_input_send_event(bool has_device, const char *device, InputEvent *evt = e->value; if (evt->type == INPUT_EVENT_KIND_KEY && - evt->u.key.data->key->type == KEY_VALUE_KIND_NUMBER) { - KeyValue *key = evt->u.key.data->key; - QKeyCode code = qemu_input_key_number_to_qcode(key->u.number.data); - qemu_input_event_send_key_qcode(con, code, evt->u.key.data->down); + evt->u.key.key->type == KEY_VALUE_KIND_NUMBER) { + KeyValue *key = evt->u.key.key; + QKeyCode code = qemu_input_key_number_to_qcode(key->u.number); + qemu_input_event_send_key_qcode(con, code, evt->u.key.down); } else { qemu_input_event_send(con, evt); } @@ -183,7 +183,7 @@ static int qemu_input_transform_invert_abs_value(int value) static void qemu_input_transform_abs_rotate(InputEvent *evt) { - InputMoveEvent *move = evt->u.abs.data; + InputMoveEvent *move = &evt->u.abs; switch (graphic_rotate) { case 90: if (move->axis == INPUT_AXIS_X) { @@ -220,16 +220,16 @@ static void qemu_input_event_trace(QemuConsole *src, InputEvent *evt) } switch (evt->type) { case INPUT_EVENT_KIND_KEY: - key = evt->u.key.data; + key = &evt->u.key; switch (key->key->type) { case KEY_VALUE_KIND_NUMBER: - qcode = qemu_input_key_number_to_qcode(key->key->u.number.data); + qcode = qemu_input_key_number_to_qcode(key->key->u.number); name = QKeyCode_str(qcode); - trace_input_event_key_number(idx, key->key->u.number.data, + trace_input_event_key_number(idx, key->key->u.number, name, key->down); break; case KEY_VALUE_KIND_QCODE: - name = QKeyCode_str(key->key->u.qcode.data); + name = QKeyCode_str(key->key->u.qcode); trace_input_event_key_qcode(idx, name, key->down); break; case KEY_VALUE_KIND__MAX: @@ -238,17 +238,17 @@ static void qemu_input_event_trace(QemuConsole *src, InputEvent *evt) } break; case INPUT_EVENT_KIND_BTN: - btn = evt->u.btn.data; + btn = &evt->u.btn; name = InputButton_str(btn->button); trace_input_event_btn(idx, name, btn->down); break; case INPUT_EVENT_KIND_REL: - move = evt->u.rel.data; + move = &evt->u.rel; name = InputAxis_str(move->axis); trace_input_event_rel(idx, name, move->value); break; case INPUT_EVENT_KIND_ABS: - move = evt->u.abs.data; + move = &evt->u.abs; name = InputAxis_str(move->axis); trace_input_event_abs(idx, name, move->value); break; @@ -355,7 +355,7 @@ void qemu_input_event_send(QemuConsole *src, InputEvent *evt) /* Expect all parts of QEMU to send events with QCodes exclusively. * Key numbers are only supported as end-user input via QMP */ assert(!(evt->type == INPUT_EVENT_KIND_KEY && - evt->u.key.data->key->type == KEY_VALUE_KIND_NUMBER)); + evt->u.key.key->type == KEY_VALUE_KIND_NUMBER)); /* @@ -367,8 +367,8 @@ void qemu_input_event_send(QemuConsole *src, InputEvent *evt) * neeed to deal with this mistake */ if (evt->type == INPUT_EVENT_KIND_KEY && - evt->u.key.data->key->u.qcode.data == Q_KEY_CODE_SYSRQ) { - evt->u.key.data->key->u.qcode.data = Q_KEY_CODE_PRINT; + evt->u.key.key->u.qcode == Q_KEY_CODE_SYSRQ) { + evt->u.key.key->u.qcode = Q_KEY_CODE_PRINT; } if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) { @@ -407,10 +407,9 @@ void qemu_input_event_sync(void) static InputEvent *qemu_input_event_new_key(KeyValue *key, bool down) { InputEvent *evt = g_new0(InputEvent, 1); - evt->u.key.data = g_new0(InputKeyEvent, 1); evt->type = INPUT_EVENT_KIND_KEY; - evt->u.key.data->key = key; - evt->u.key.data->down = down; + evt->u.key.key = key; + evt->u.key.down = down; return evt; } @@ -440,7 +439,7 @@ void qemu_input_event_send_key_qcode(QemuConsole *src, QKeyCode q, bool down) { KeyValue *key = g_new0(KeyValue, 1); key->type = KEY_VALUE_KIND_QCODE; - key->u.qcode.data = q; + key->u.qcode = q; qemu_input_event_send_key(src, key, down); } @@ -469,7 +468,7 @@ void qemu_input_queue_btn(QemuConsole *src, InputButton btn, bool down) }; InputEvent evt = { .type = INPUT_EVENT_KIND_BTN, - .u.btn.data = &bevt, + .u.btn = bevt, }; qemu_input_event_send(src, &evt); @@ -520,7 +519,7 @@ void qemu_input_queue_rel(QemuConsole *src, InputAxis axis, int value) }; InputEvent evt = { .type = INPUT_EVENT_KIND_REL, - .u.rel.data = &move, + .u.rel = move, }; qemu_input_event_send(src, &evt); @@ -537,7 +536,7 @@ void qemu_input_queue_abs(QemuConsole *src, InputAxis axis, int value, }; InputEvent evt = { .type = INPUT_EVENT_KIND_ABS, - .u.abs.data = &move, + .u.abs = move, }; qemu_input_event_send(src, &evt); diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c index 05e5c73f9d..59e317cbb8 100644 --- a/util/qemu-sockets.c +++ b/util/qemu-sockets.c @@ -1365,21 +1365,21 @@ SocketAddress *socket_address_flatten(SocketAddressLegacy *addr_legacy) case SOCKET_ADDRESS_LEGACY_KIND_INET: addr->type = SOCKET_ADDRESS_TYPE_INET; QAPI_CLONE_MEMBERS(InetSocketAddress, &addr->u.inet, - addr_legacy->u.inet.data); + &addr_legacy->u.inet); break; case SOCKET_ADDRESS_LEGACY_KIND_UNIX: addr->type = SOCKET_ADDRESS_TYPE_UNIX; QAPI_CLONE_MEMBERS(UnixSocketAddress, &addr->u.q_unix, - addr_legacy->u.q_unix.data); + &addr_legacy->u.q_unix); break; case SOCKET_ADDRESS_LEGACY_KIND_VSOCK: addr->type = SOCKET_ADDRESS_TYPE_VSOCK; QAPI_CLONE_MEMBERS(VsockSocketAddress, &addr->u.vsock, - addr_legacy->u.vsock.data); + &addr_legacy->u.vsock); break; case SOCKET_ADDRESS_LEGACY_KIND_FD: addr->type = SOCKET_ADDRESS_TYPE_FD; - QAPI_CLONE_MEMBERS(String, &addr->u.fd, addr_legacy->u.fd.data); + QAPI_CLONE_MEMBERS(String, &addr->u.fd, &addr_legacy->u.fd); break; default: abort(); diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py index fafec94e02..1c4e3407a3 100644 --- a/scripts/qapi/introspect.py +++ b/scripts/qapi/introspect.py @@ -188,7 +188,12 @@ const QLitObject %(c_name)s = %(c_string)s; 'variants': [self._gen_variant(v) for v in variants]} def _gen_variant(self, variant): - obj = {'case': variant.name, 'type': self._use_type(variant.type)} + if variant.wrapped: + obj = {'case': variant.name, + 'type': self._use_type(variant.wrapper_type)} + else: + obj = {'case': variant.name, + 'type': self._use_type(variant.type)} return _make_tree(obj, variant.ifcond, None) def visit_builtin_type(self, name, info, json_type): diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index 720449feee..17525b4216 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -216,6 +216,11 @@ class QAPISchemaBuiltinType(QAPISchemaType): self._json_type_name = json_type self._c_type_name = c_type + def check(self, schema): + # Don't check twice, it would fail an assertion + if not self._checked: + super().check(schema) + def c_name(self): return self.name @@ -593,18 +598,21 @@ class QAPISchemaVariants: "branch '%s' is not a value of %s" % (v.name, self.tag_member.type.describe())) if (not isinstance(v.type, QAPISchemaObjectType) - or v.type.variants): + or v.type.variants) and v.flat: raise QAPISemError( self.info, "%s cannot use %s" % (v.describe(self.info), v.type.describe())) - v.type.check(schema) + if isinstance(v.type, QAPISchemaObjectType): + v.type.check(schema) def check_clash(self, info, seen): for v in self.variants: # Reset seen map for each variant, since qapi names from one - # branch do not affect another branch - v.type.check_clash(info, dict(seen)) + # branch do not affect another branch. Variants that are + # never flat don't even conflict with the base. + if isinstance(v.type, QAPISchemaObjectType): + v.type.check_clash(info, dict(seen) if v.flat else {}) class QAPISchemaMember: @@ -705,9 +713,22 @@ class QAPISchemaObjectTypeMember(QAPISchemaMember): class QAPISchemaVariant(QAPISchemaObjectTypeMember): role = 'branch' - def __init__(self, name, info, typ, ifcond=None): + def __init__(self, name, info, typ, ifcond=None, flat=True, + wrapper_type=None): super().__init__(name, info, typ, False, ifcond) + self.flat = flat + self.wrapped = bool(wrapper_type) + self.wrapper_type = wrapper_type + + # For now, unions are either flat or wrapped, never both + assert self.flat or self.wrapped + assert not (self.flat and self.wrapped) + + def check(self, schema): + super().check(schema) + if self.wrapped: + self.wrapper_type.check(schema) class QAPISchemaCommand(QAPISchemaEntity): meta = 'command' @@ -1017,14 +1038,19 @@ class QAPISchema: def _make_variant(self, case, typ, ifcond, info): return QAPISchemaVariant(case, info, typ, ifcond) - def _make_simple_variant(self, case, typ, ifcond, info): + def _make_simple_variant(self, union_name, case, typ, ifcond, info): if isinstance(typ, list): assert len(typ) == 1 typ = self._make_array_type(typ[0], info) - typ = self._make_implicit_object_type( - typ, info, self.lookup_type(typ), - 'wrapper', [self._make_member('data', typ, None, None, info)]) - return QAPISchemaVariant(case, info, typ, ifcond) + + # The wrapper type is only used for introspection compatibility. + # Don't add it to the entity list of the schema. + wrapper_name = 'q_obj_%s-%s-wrapper' % (union_name, case) + wrapper_member = self._make_member('data', typ, None, None, info) + wrapper_type = QAPISchemaObjectType(wrapper_name, info, None, ifcond, + None, None, [wrapper_member], None) + return QAPISchemaVariant(case, info, typ, ifcond, flat=False, + wrapper_type=wrapper_type) def _def_union_type(self, expr, info, doc): name = expr['union'] @@ -1044,7 +1070,7 @@ class QAPISchema: for (key, value) in data.items()] members = [] else: - variants = [self._make_simple_variant(key, value['type'], + variants = [self._make_simple_variant(name, key, value['type'], value.get('if'), info) for (key, value) in data.items()] enum = [{'name': v.name, 'if': v.ifcond} for v in variants] diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py index 339f152152..f72567cbcc 100644 --- a/scripts/qapi/visit.py +++ b/scripts/qapi/visit.py @@ -118,6 +118,34 @@ bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp) break; ''', case=case_str) + elif not isinstance(var.type, QAPISchemaObjectType): + assert not var.flat + ret += mcgen(''' + case %(case)s: + return visit_type_%(c_type)s(v, "data", &obj->u.%(c_name)s, errp); +''', + case=case_str, + c_type=var.type.c_name(), c_name=c_name(var.name)) + elif var.wrapped: + ret += mcgen(''' + case %(case)s: + { + bool ok; + + if (!visit_start_struct(v, "data", NULL, 0, errp)) { + return false; + } + ok = visit_type_%(c_type)s_members(v, &obj->u.%(c_name)s, errp); + if (ok) { + ok = visit_check_struct(v, errp); + } + visit_end_struct(v, NULL); + return ok; + } +''', + case=case_str, + c_type=var.type.c_name(), c_name=c_name(var.name)) + else: ret += mcgen(''' case %(case)s: diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out index 419284dae2..bcbcbd2fce 100644 --- a/tests/qapi-schema/doc-good.out +++ b/tests/qapi-schema/doc-good.out @@ -31,10 +31,6 @@ object Object case two: Variant2 if ['IFTWO'] feature union-feat1 -object q_obj_Variant1-wrapper - member data: Variant1 optional=False -object q_obj_Variant2-wrapper - member data: Variant2 optional=False enum SugaredUnionKind member one member two @@ -42,8 +38,8 @@ enum SugaredUnionKind object SugaredUnion member type: SugaredUnionKind optional=False tag type - case one: q_obj_Variant1-wrapper - case two: q_obj_Variant2-wrapper + case one: Variant1 + case two: Variant2 if ['IFTWO'] feature union-feat2 alternate Alternate diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index 8868ca0dca..a4e4051c61 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -125,36 +125,6 @@ alternate AltStrObj tag type case s: str case o: TestStruct -object q_obj_intList-wrapper - member data: intList optional=False -object q_obj_int8List-wrapper - member data: int8List optional=False -object q_obj_int16List-wrapper - member data: int16List optional=False -object q_obj_int32List-wrapper - member data: int32List optional=False -object q_obj_int64List-wrapper - member data: int64List optional=False -object q_obj_uint8List-wrapper - member data: uint8List optional=False -object q_obj_uint16List-wrapper - member data: uint16List optional=False -object q_obj_uint32List-wrapper - member data: uint32List optional=False -object q_obj_uint64List-wrapper - member data: uint64List optional=False -object q_obj_numberList-wrapper - member data: numberList optional=False -object q_obj_boolList-wrapper - member data: boolList optional=False -object q_obj_strList-wrapper - member data: strList optional=False -object q_obj_sizeList-wrapper - member data: sizeList optional=False -object q_obj_anyList-wrapper - member data: anyList optional=False -object q_obj_StatusList-wrapper - member data: StatusList optional=False enum UserDefListUnionKind member integer member s8 @@ -174,21 +144,21 @@ enum UserDefListUnionKind object UserDefListUnion member type: UserDefListUnionKind optional=False tag type - case integer: q_obj_intList-wrapper - case s8: q_obj_int8List-wrapper - case s16: q_obj_int16List-wrapper - case s32: q_obj_int32List-wrapper - case s64: q_obj_int64List-wrapper - case u8: q_obj_uint8List-wrapper - case u16: q_obj_uint16List-wrapper - case u32: q_obj_uint32List-wrapper - case u64: q_obj_uint64List-wrapper - case number: q_obj_numberList-wrapper - case boolean: q_obj_boolList-wrapper - case string: q_obj_strList-wrapper - case sizes: q_obj_sizeList-wrapper - case any: q_obj_anyList-wrapper - case user: q_obj_StatusList-wrapper + case integer: intList + case s8: int8List + case s16: int16List + case s32: int32List + case s64: int64List + case u8: uint8List + case u16: uint16List + case u32: uint32List + case u64: uint64List + case number: numberList + case boolean: boolList + case string: strList + case sizes: sizeList + case any: anyList + case user: StatusList include include/sub-module.json command user_def_cmd None -> None gen=True success_response=True boxed=False oob=False preconfig=False @@ -263,14 +233,12 @@ object __org.qemu_x-Struct base __org.qemu_x-Base member __org.qemu_x-member2: str optional=False member wchar-t: int optional=True -object q_obj_str-wrapper - member data: str optional=False enum __org.qemu_x-Union1Kind member __org.qemu_x-branch object __org.qemu_x-Union1 member type: __org.qemu_x-Union1Kind optional=False tag type - case __org.qemu_x-branch: q_obj_str-wrapper + case __org.qemu_x-branch: str alternate __org.qemu_x-Alt1 tag type case __org.qemu_x-branch: str @@ -305,8 +273,6 @@ enum TestIfEnum member bar if ['defined(TEST_IF_ENUM_BAR)'] if ['defined(TEST_IF_ENUM)'] -object q_obj_TestStruct-wrapper - member data: TestStruct optional=False enum TestIfUnionKind member foo member union_bar @@ -315,8 +281,8 @@ enum TestIfUnionKind object TestIfUnion member type: TestIfUnionKind optional=False tag type - case foo: q_obj_TestStruct-wrapper - case union_bar: q_obj_str-wrapper + case foo: TestStruct + case union_bar: str if ['defined(TEST_IF_UNION_BAR)'] if ['defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)'] object q_obj_TestIfUnionCmd-arg
Variants of simple unions are always contained in a wrapper object called 'data' that serves no real use. When mapping a QAPI object to the command line, this becomes very visible to users because they have to add one or more useless 'data.' to many option names. As a first step towards avoiding this painful CLI experience, this gets rid of the 'data' indirection internally: The QAPI parser doesn't use a wrapper object as the variant type any more, so the indirection is removed from the generated C types. As a result, the C type looks the same for flat and simple unions now. A large part of this patch is mechanical conversion of C code to remove the 'data' indirection. Conceptually, the important change is that variants can now have flat and wrapped representations. For a transitioning period, we'll allow variants to support both representations in a later patch. Eventually, the plan is to deprecate and remove wrapped representations entirely, unifying simple and flat unions. The externally visible interfaces stay unchanged: Visitors still expect the 'data' wrappers, and introspection still shows it. Signed-off-by: Kevin Wolf <kwolf@redhat.com> --- docs/devel/qapi-code-gen.txt | 32 ++++++++---- backends/tpm/tpm_emulator.c | 3 +- backends/tpm/tpm_passthrough.c | 4 +- block/crypto.c | 3 +- block/qcow2.c | 9 ++-- block/vmdk.c | 14 ++---- blockdev.c | 36 ++++++------- chardev/char-file.c | 5 +- chardev/char-mux.c | 5 +- chardev/char-parallel.c | 5 +- chardev/char-pipe.c | 7 ++- chardev/char-ringbuf.c | 5 +- chardev/char-serial.c | 5 +- chardev/char-socket.c | 13 ++--- chardev/char-stdio.c | 5 +- chardev/char-udp.c | 11 ++-- chardev/char.c | 10 ++-- chardev/msmouse.c | 4 +- chardev/wctablet.c | 4 +- hw/core/numa.c | 6 +-- hw/display/xenfb.c | 8 +-- hw/input/hid.c | 8 +-- hw/input/ps2.c | 6 +-- hw/input/virtio-input-hid.c | 8 +-- hw/mem/pc-dimm.c | 18 +++---- hw/virtio/virtio-mem-pci.c | 3 +- hw/virtio/virtio-pmem-pci.c | 3 +- monitor/hmp-cmds.c | 14 +++--- qemu-keymap.c | 2 +- replay/replay-input.c | 46 +++++++---------- tests/test-char.c | 12 ++--- tests/test-clone-visitor.c | 14 +++--- tests/test-qmp-cmds.c | 2 +- tests/test-qobject-input-visitor.c | 24 ++++----- tests/test-qobject-output-visitor.c | 24 ++++----- ui/console.c | 5 +- ui/input-keymap.c | 12 ++--- ui/input-legacy.c | 12 ++--- ui/input.c | 43 ++++++++-------- util/qemu-sockets.c | 8 +-- scripts/qapi/introspect.py | 7 ++- scripts/qapi/schema.py | 48 ++++++++++++++---- scripts/qapi/visit.py | 28 +++++++++++ tests/qapi-schema/doc-good.out | 8 +-- tests/qapi-schema/qapi-schema-test.out | 70 +++++++------------------- 45 files changed, 308 insertions(+), 311 deletions(-)