[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v5 34/46] qapi: Unbox base members
From: |
Eric Blake |
Subject: |
[Qemu-devel] [PATCH v5 34/46] qapi: Unbox base members |
Date: |
Mon, 21 Sep 2015 15:57:50 -0600 |
Rather than storing a base class as a pointer to a box, just
store the fields of that base class in the same order, so that
a child struct can be safely cast to its parent. This gives
less malloc overhead, less pointer dereferencing, and even less
generated code.
Without boxing, the corner case of one empty struct having
another empty struct as its base type now requires inserting a
dummy member (previously, the pointer to the base would have
sufficed).
And now that we no longer consume a 'base' member in the generated
C struct, we can delete the former negative test struct-base-clash2
and replace it with a positive test in qapi-schema-test that
ensures we don't reintroduce the naming collision.
Compare to the earlier commit 1e6c1616a "qapi: Generate a nicer
struct for flat unions".
Signed-off-by: Eric Blake <address@hidden>
---
hmp.c | 6 +++---
scripts/qapi-types.py | 29 +++++++++++++++--------------
scripts/qapi-visit.py | 9 ++++++---
tests/Makefile | 1 -
tests/qapi-schema/qapi-schema-test.json | 3 +++
tests/qapi-schema/qapi-schema-test.out | 3 +++
tests/qapi-schema/struct-base-clash2.err | 0
tests/qapi-schema/struct-base-clash2.exit | 1 -
tests/qapi-schema/struct-base-clash2.json | 5 -----
tests/qapi-schema/struct-base-clash2.out | 5 -----
tests/test-qmp-commands.c | 15 +++++----------
tests/test-qmp-event.c | 8 ++------
tests/test-qmp-input-visitor.c | 4 ++--
tests/test-qmp-output-visitor.c | 12 ++++--------
tests/test-visitor-serialization.c | 14 ++++++--------
ui/spice-core.c | 23 +++++++++++++----------
ui/vnc.c | 20 +++++++++-----------
17 files changed, 71 insertions(+), 87 deletions(-)
delete mode 100644 tests/qapi-schema/struct-base-clash2.err
delete mode 100644 tests/qapi-schema/struct-base-clash2.exit
delete mode 100644 tests/qapi-schema/struct-base-clash2.json
delete mode 100644 tests/qapi-schema/struct-base-clash2.out
diff --git a/hmp.c b/hmp.c
index 849b292..ab8e700 100644
--- a/hmp.c
+++ b/hmp.c
@@ -558,8 +558,8 @@ void hmp_info_vnc(Monitor *mon, const QDict *qdict)
for (client = info->clients; client; client = client->next) {
monitor_printf(mon, "Client:\n");
monitor_printf(mon, " address: %s:%s\n",
- client->value->base->host,
- client->value->base->service);
+ client->value->host,
+ client->value->service);
monitor_printf(mon, " x509_dname: %s\n",
client->value->x509_dname ?
client->value->x509_dname : "none");
@@ -627,7 +627,7 @@ void hmp_info_spice(Monitor *mon, const QDict *qdict)
for (chan = info->channels; chan; chan = chan->next) {
monitor_printf(mon, "Channel:\n");
monitor_printf(mon, " address: %s:%s%s\n",
- chan->value->base->host, chan->value->base->port,
+ chan->value->host, chan->value->port,
chan->value->tls ? " [tls]" : "");
monitor_printf(mon, " session: %" PRId64 "\n",
chan->value->connection_id);
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 7eb7f35..5b9cb69 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -51,8 +51,19 @@ def gen_struct_field(name, typ, optional):
return ret
-def gen_struct_fields(members):
+def gen_struct_fields(members, base, nested=False):
ret = ''
+ if base:
+ if not nested:
+ ret += mcgen('''
+ /* Members inherited from %(c_name)s: */
+''',
+ c_name=base.c_name())
+ ret += gen_struct_fields(base.local_members, base.base, True)
+ if not nested:
+ ret += mcgen('''
+ /* Own members: */
+''')
for memb in members:
ret += gen_struct_field(memb.name, memb.type, memb.optional)
@@ -66,16 +77,13 @@ struct %(c_name)s {
''',
c_name=c_name(name))
- if base:
- ret += gen_struct_field('base', base, False)
-
- ret += gen_struct_fields(members)
+ ret += gen_struct_fields(members, base)
# Make sure that all structs have at least one field; this avoids
# potential issues with attempting to malloc space for zero-length
# structs in C, and also incompatibility with C++ (where an empty
# struct is size 1).
- if not base and not members:
+ if not (base and base.members) and not members:
ret += mcgen('''
char qapi_dummy_field_for_empty_struct;
''')
@@ -94,14 +102,7 @@ struct %(c_name)s {
''',
c_name=c_name(name))
if base:
- ret += mcgen('''
- /* Members inherited from %(c_name)s: */
-''',
- c_name=c_name(base.name))
- ret += gen_struct_fields(base.members)
- ret += mcgen('''
- /* Own members: */
-''')
+ ret += gen_struct_fields([], base)
tag_name = variants.tag_member.name
elif not variants.tag_member:
ret += mcgen('''
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 2b3b6a3..9968cc5 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -69,12 +69,15 @@ static void visit_type_implicit_%(c_type)s(Visitor *v,
%(c_type)s **obj, Error *
def gen_visit_struct_fields(name, base, members):
+ if name in struct_fields_seen:
+ return ''
struct_fields_seen.add(name)
ret = ''
if base:
- ret += gen_visit_implicit_struct(base)
+ ret += gen_visit_struct_fields(base.name, base.base,
+ base.local_members)
ret += mcgen('''
@@ -88,12 +91,12 @@ static void visit_type_%(c_name)s_fields(Visitor *v,
%(c_name)s **obj, Error **e
if base:
ret += mcgen('''
-visit_type_implicit_%(c_type)s(v, &(*obj)->%(c_name)s, &err);
+visit_type_%(c_type)s_fields(v, (%(c_type)s **)obj, &err);
if (err) {
goto out;
}
''',
- c_type=base.c_name(), c_name=c_name('base'))
+ c_type=base.c_name())
ret += gen_visit_fields(members, '(*obj)->', False, 'err')
diff --git a/tests/Makefile b/tests/Makefile
index 20b84b5..f351833 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -323,7 +323,6 @@ qapi-schema += returns-unknown.json
qapi-schema += returns-whitelist.json
qapi-schema += struct-base-clash-deep.json
qapi-schema += struct-base-clash.json
-qapi-schema += struct-base-clash2.json
qapi-schema += struct-data-invalid.json
qapi-schema += struct-member-invalid.json
qapi-schema += trailing-comma-list.json
diff --git a/tests/qapi-schema/qapi-schema-test.json
b/tests/qapi-schema/qapi-schema-test.json
index 7593ecb..b1292c5 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -31,6 +31,9 @@
'data': { 'string0': 'str',
'dict1': 'UserDefTwoDict' } }
+{ 'struct': 'UserDefThree',
+ 'base': 'UserDefOne', 'data': { 'base': 'str' } }
+
# for testing unions
# name collisions between branches should not clash
{ 'struct': 'UserDefA',
diff --git a/tests/qapi-schema/qapi-schema-test.out
b/tests/qapi-schema/qapi-schema-test.out
index 2036df5..d9e8595 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -139,6 +139,9 @@ object UserDefOptions
member u16: uint16List optional=True
member i64x: int optional=True
member u64x: uint64 optional=True
+object UserDefThree
+ base UserDefOne
+ member base: str optional=False
object UserDefTwo
member string0: str optional=False
member dict1: UserDefTwoDict optional=False
diff --git a/tests/qapi-schema/struct-base-clash2.err
b/tests/qapi-schema/struct-base-clash2.err
deleted file mode 100644
index e69de29..0000000
diff --git a/tests/qapi-schema/struct-base-clash2.exit
b/tests/qapi-schema/struct-base-clash2.exit
deleted file mode 100644
index 573541a..0000000
--- a/tests/qapi-schema/struct-base-clash2.exit
+++ /dev/null
@@ -1 +0,0 @@
-0
diff --git a/tests/qapi-schema/struct-base-clash2.json
b/tests/qapi-schema/struct-base-clash2.json
deleted file mode 100644
index 56166e0..0000000
--- a/tests/qapi-schema/struct-base-clash2.json
+++ /dev/null
@@ -1,5 +0,0 @@
-# FIXME - a base class collides with a member named base
-{ 'struct': 'Base', 'data': {} }
-{ 'struct': 'Sub',
- 'base': 'Base',
- 'data': { 'base': 'str' } }
diff --git a/tests/qapi-schema/struct-base-clash2.out
b/tests/qapi-schema/struct-base-clash2.out
deleted file mode 100644
index e69a416..0000000
--- a/tests/qapi-schema/struct-base-clash2.out
+++ /dev/null
@@ -1,5 +0,0 @@
-object :empty
-object Base
-object Sub
- base Base
- member base: str optional=False
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index d3b8d8f..89a3b47 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -25,11 +25,9 @@ UserDefTwo *qmp_user_def_cmd2(UserDefOne *ud1a,
UserDefOne *ud1d = g_malloc0(sizeof(UserDefOne));
ud1c->string = strdup(ud1a->string);
- ud1c->base = g_new0(UserDefZero, 1);
- ud1c->base->integer = ud1a->base->integer;
+ ud1c->integer = ud1a->integer;
ud1d->string = strdup(has_udb1 ? ud1b->string : "blah0");
- ud1d->base = g_new0(UserDefZero, 1);
- ud1d->base->integer = has_udb1 ? ud1b->base->integer : 0;
+ ud1d->integer = has_udb1 ? ud1b->integer : 0;
ret = g_new0(UserDefTwo, 1);
ret->string0 = strdup("blah1");
@@ -176,20 +174,17 @@ static void test_dealloc_types(void)
UserDefOneList *ud1list;
ud1test = g_malloc0(sizeof(UserDefOne));
- ud1test->base = g_new0(UserDefZero, 1);
- ud1test->base->integer = 42;
+ ud1test->integer = 42;
ud1test->string = g_strdup("hi there 42");
qapi_free_UserDefOne(ud1test);
ud1a = g_malloc0(sizeof(UserDefOne));
- ud1a->base = g_new0(UserDefZero, 1);
- ud1a->base->integer = 43;
+ ud1a->integer = 43;
ud1a->string = g_strdup("hi there 43");
ud1b = g_malloc0(sizeof(UserDefOne));
- ud1b->base = g_new0(UserDefZero, 1);
- ud1b->base->integer = 44;
+ ud1b->integer = 44;
ud1b->string = g_strdup("hi there 44");
ud1list = g_malloc0(sizeof(UserDefOneList));
diff --git a/tests/test-qmp-event.c b/tests/test-qmp-event.c
index 28f146d..035c65c 100644
--- a/tests/test-qmp-event.c
+++ b/tests/test-qmp-event.c
@@ -179,9 +179,7 @@ static void test_event_c(TestEventData *data,
QDict *d, *d_data, *d_b;
UserDefOne b;
- UserDefZero z;
- z.integer = 2;
- b.base = &z;
+ b.integer = 2;
b.string = g_strdup("test1");
b.has_enum1 = false;
@@ -209,11 +207,9 @@ static void test_event_d(TestEventData *data,
{
UserDefOne struct1;
EventStructOne a;
- UserDefZero z;
QDict *d, *d_data, *d_a, *d_struct1;
- z.integer = 2;
- struct1.base = &z;
+ struct1.integer = 2;
struct1.string = g_strdup("test1");
struct1.has_enum1 = true;
struct1.enum1 = ENUM_ONE_VALUE1;
diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
index 8928f86..2da1b8b 100644
--- a/tests/test-qmp-input-visitor.c
+++ b/tests/test-qmp-input-visitor.c
@@ -272,7 +272,7 @@ static void
test_visitor_in_struct_nested(TestInputVisitorData *data,
check_and_free_str(udp->string0, "string0");
check_and_free_str(udp->dict1->string1, "string1");
- g_assert_cmpint(udp->dict1->dict2->userdef->base->integer, ==, 42);
+ g_assert_cmpint(udp->dict1->dict2->userdef->integer, ==, 42);
check_and_free_str(udp->dict1->dict2->userdef->string, "string");
check_and_free_str(udp->dict1->dict2->string, "string2");
g_assert(udp->dict1->has_dict3 == false);
@@ -303,7 +303,7 @@ static void test_visitor_in_list(TestInputVisitorData *data,
snprintf(string, sizeof(string), "string%d", i);
g_assert_cmpstr(item->value->string, ==, string);
- g_assert_cmpint(item->value->base->integer, ==, 42 + i);
+ g_assert_cmpint(item->value->integer, ==, 42 + i);
}
qapi_free_UserDefOneList(head);
diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c
index 6d6f79c..02ad5a7d 100644
--- a/tests/test-qmp-output-visitor.c
+++ b/tests/test-qmp-output-visitor.c
@@ -250,16 +250,14 @@ static void
test_visitor_out_struct_nested(TestOutputVisitorData *data,
ud2->dict1->dict2 = g_malloc0(sizeof(*ud2->dict1->dict2));
ud2->dict1->dict2->userdef = g_new0(UserDefOne, 1);
ud2->dict1->dict2->userdef->string = g_strdup(string);
- ud2->dict1->dict2->userdef->base = g_new0(UserDefZero, 1);
- ud2->dict1->dict2->userdef->base->integer = value;
+ ud2->dict1->dict2->userdef->integer = value;
ud2->dict1->dict2->string = g_strdup(strings[2]);
ud2->dict1->dict3 = g_malloc0(sizeof(*ud2->dict1->dict3));
ud2->dict1->has_dict3 = true;
ud2->dict1->dict3->userdef = g_new0(UserDefOne, 1);
ud2->dict1->dict3->userdef->string = g_strdup(string);
- ud2->dict1->dict3->userdef->base = g_new0(UserDefZero, 1);
- ud2->dict1->dict3->userdef->base->integer = value;
+ ud2->dict1->dict3->userdef->integer = value;
ud2->dict1->dict3->string = g_strdup(strings[3]);
visit_type_UserDefTwo(data->ov, &ud2, "unused", &err);
@@ -301,8 +299,7 @@ static void
test_visitor_out_struct_errors(TestOutputVisitorData *data,
const void *unused)
{
EnumOne bad_values[] = { ENUM_ONE_MAX, -1 };
- UserDefZero b;
- UserDefOne u = { .base = &b }, *pu = &u;
+ UserDefOne u, *pu = &u;
Error *err;
int i;
@@ -416,8 +413,7 @@ static void
test_visitor_out_list_qapi_free(TestOutputVisitorData *data,
p->value->dict1->dict2 = g_new0(UserDefTwoDictDict, 1);
p->value->dict1->dict2->userdef = g_new0(UserDefOne, 1);
p->value->dict1->dict2->userdef->string = g_strdup(string);
- p->value->dict1->dict2->userdef->base = g_new0(UserDefZero, 1);
- p->value->dict1->dict2->userdef->base->integer = 42;
+ p->value->dict1->dict2->userdef->integer = 42;
p->value->dict1->dict2->string = g_strdup(string);
p->value->dict1->has_dict3 = false;
diff --git a/tests/test-visitor-serialization.c
b/tests/test-visitor-serialization.c
index fa86cae..634563b 100644
--- a/tests/test-visitor-serialization.c
+++ b/tests/test-visitor-serialization.c
@@ -258,15 +258,13 @@ static UserDefTwo *nested_struct_create(void)
udnp->dict1->string1 = strdup("test_string1");
udnp->dict1->dict2 = g_malloc0(sizeof(*udnp->dict1->dict2));
udnp->dict1->dict2->userdef = g_new0(UserDefOne, 1);
- udnp->dict1->dict2->userdef->base = g_new0(UserDefZero, 1);
- udnp->dict1->dict2->userdef->base->integer = 42;
+ udnp->dict1->dict2->userdef->integer = 42;
udnp->dict1->dict2->userdef->string = strdup("test_string");
udnp->dict1->dict2->string = strdup("test_string2");
udnp->dict1->dict3 = g_malloc0(sizeof(*udnp->dict1->dict3));
udnp->dict1->has_dict3 = true;
udnp->dict1->dict3->userdef = g_new0(UserDefOne, 1);
- udnp->dict1->dict3->userdef->base = g_new0(UserDefZero, 1);
- udnp->dict1->dict3->userdef->base->integer = 43;
+ udnp->dict1->dict3->userdef->integer = 43;
udnp->dict1->dict3->userdef->string = strdup("test_string");
udnp->dict1->dict3->string = strdup("test_string3");
return udnp;
@@ -278,15 +276,15 @@ static void nested_struct_compare(UserDefTwo *udnp1,
UserDefTwo *udnp2)
g_assert(udnp2);
g_assert_cmpstr(udnp1->string0, ==, udnp2->string0);
g_assert_cmpstr(udnp1->dict1->string1, ==, udnp2->dict1->string1);
- g_assert_cmpint(udnp1->dict1->dict2->userdef->base->integer, ==,
- udnp2->dict1->dict2->userdef->base->integer);
+ g_assert_cmpint(udnp1->dict1->dict2->userdef->integer, ==,
+ udnp2->dict1->dict2->userdef->integer);
g_assert_cmpstr(udnp1->dict1->dict2->userdef->string, ==,
udnp2->dict1->dict2->userdef->string);
g_assert_cmpstr(udnp1->dict1->dict2->string, ==,
udnp2->dict1->dict2->string);
g_assert(udnp1->dict1->has_dict3 == udnp2->dict1->has_dict3);
- g_assert_cmpint(udnp1->dict1->dict3->userdef->base->integer, ==,
- udnp2->dict1->dict3->userdef->base->integer);
+ g_assert_cmpint(udnp1->dict1->dict3->userdef->integer, ==,
+ udnp2->dict1->dict3->userdef->integer);
g_assert_cmpstr(udnp1->dict1->dict3->userdef->string, ==,
udnp2->dict1->dict3->userdef->string);
g_assert_cmpstr(udnp1->dict1->dict3->string, ==,
diff --git a/ui/spice-core.c b/ui/spice-core.c
index bf4fd07..86f4441 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -200,8 +200,6 @@ static void channel_event(int event, SpiceChannelEventInfo
*info)
{
SpiceServerInfo *server = g_malloc0(sizeof(*server));
SpiceChannel *client = g_malloc0(sizeof(*client));
- server->base = g_malloc0(sizeof(*server->base));
- client->base = g_malloc0(sizeof(*client->base));
/*
* Spice server might have called us from spice worker thread
@@ -218,9 +216,11 @@ static void channel_event(int event, SpiceChannelEventInfo
*info)
}
if (info->flags & SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT) {
- add_addr_info(client->base, (struct sockaddr *)&info->paddr_ext,
+ add_addr_info((SpiceBasicInfo *)client,
+ (struct sockaddr *)&info->paddr_ext,
info->plen_ext);
- add_addr_info(server->base, (struct sockaddr *)&info->laddr_ext,
+ add_addr_info((SpiceBasicInfo *)server,
+ (struct sockaddr *)&info->laddr_ext,
info->llen_ext);
} else {
error_report("spice: %s, extended address is expected",
@@ -229,7 +229,9 @@ static void channel_event(int event, SpiceChannelEventInfo
*info)
switch (event) {
case SPICE_CHANNEL_EVENT_CONNECTED:
- qapi_event_send_spice_connected(server->base, client->base,
&error_abort);
+ qapi_event_send_spice_connected((SpiceBasicInfo *)server,
+ (SpiceBasicInfo *)client,
+ &error_abort);
break;
case SPICE_CHANNEL_EVENT_INITIALIZED:
if (auth) {
@@ -242,7 +244,9 @@ static void channel_event(int event, SpiceChannelEventInfo
*info)
break;
case SPICE_CHANNEL_EVENT_DISCONNECTED:
channel_list_del(info);
- qapi_event_send_spice_disconnected(server->base, client->base,
&error_abort);
+ qapi_event_send_spice_disconnected((SpiceBasicInfo *)server,
+ (SpiceBasicInfo *)client,
+ &error_abort);
break;
default:
break;
@@ -378,16 +382,15 @@ static SpiceChannelList *qmp_query_spice_channels(void)
chan = g_malloc0(sizeof(*chan));
chan->value = g_malloc0(sizeof(*chan->value));
- chan->value->base = g_malloc0(sizeof(*chan->value->base));
paddr = (struct sockaddr *)&item->info->paddr_ext;
plen = item->info->plen_ext;
getnameinfo(paddr, plen,
host, sizeof(host), port, sizeof(port),
NI_NUMERICHOST | NI_NUMERICSERV);
- chan->value->base->host = g_strdup(host);
- chan->value->base->port = g_strdup(port);
- chan->value->base->family = inet_netfamily(paddr->sa_family);
+ chan->value->host = g_strdup(host);
+ chan->value->port = g_strdup(port);
+ chan->value->family = inet_netfamily(paddr->sa_family);
chan->value->connection_id = item->info->connection_id;
chan->value->channel_type = item->info->type;
diff --git a/ui/vnc.c b/ui/vnc.c
index 61af4ba..e7c29fe 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -261,8 +261,7 @@ static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
VncServerInfo *info;
info = g_malloc(sizeof(*info));
- info->base = g_malloc(sizeof(*info->base));
- vnc_basic_info_get_from_server_addr(vd->lsock, info->base, NULL);
+ vnc_basic_info_get_from_server_addr(vd->lsock, (VncBasicInfo *)info, NULL);
info->has_auth = true;
info->auth = g_strdup(vnc_auth_name(vd));
return info;
@@ -293,8 +292,8 @@ static void vnc_client_cache_addr(VncState *client)
{
Error *err = NULL;
client->info = g_malloc0(sizeof(*client->info));
- client->info->base = g_malloc0(sizeof(*client->info->base));
- vnc_basic_info_get_from_remote_addr(client->csock, client->info->base,
+ vnc_basic_info_get_from_remote_addr(client->csock,
+ (VncBasicInfo *)client->info,
&err);
if (err) {
qapi_free_VncClientInfo(client->info);
@@ -310,7 +309,6 @@ static void vnc_qmp_event(VncState *vs, QAPIEvent event)
if (!vs->info) {
return;
}
- g_assert(vs->info->base);
si = vnc_server_info_get(vs->vd);
if (!si) {
@@ -319,7 +317,8 @@ static void vnc_qmp_event(VncState *vs, QAPIEvent event)
switch (event) {
case QAPI_EVENT_VNC_CONNECTED:
- qapi_event_send_vnc_connected(si, vs->info->base, &error_abort);
+ qapi_event_send_vnc_connected(si, (VncBasicInfo *)vs->info,
+ &error_abort);
break;
case QAPI_EVENT_VNC_INITIALIZED:
qapi_event_send_vnc_initialized(si, vs->info, &error_abort);
@@ -354,11 +353,10 @@ static VncClientInfo *qmp_query_vnc_client(const VncState
*client)
}
info = g_malloc0(sizeof(*info));
- info->base = g_malloc0(sizeof(*info->base));
- info->base->host = g_strdup(host);
- info->base->service = g_strdup(serv);
- info->base->family = inet_netfamily(sa.ss_family);
- info->base->websocket = client->websocket;
+ info->host = g_strdup(host);
+ info->service = g_strdup(serv);
+ info->family = inet_netfamily(sa.ss_family);
+ info->websocket = client->websocket;
if (client->tls) {
info->x509_dname = qcrypto_tls_session_get_peer_name(client->tls);
--
2.4.3
- [Qemu-devel] [PATCH v5 27/46] qapi: Simplify visits of optional fields, (continued)
- [Qemu-devel] [PATCH v5 27/46] qapi: Simplify visits of optional fields, Eric Blake, 2015/09/21
- [Qemu-devel] [PATCH v5 25/46] qapi: Plug leaks in test-qmp-input-visitor, Eric Blake, 2015/09/21
- [Qemu-devel] [PATCH v5 24/46] qapi: Document visitor interfaces, Eric Blake, 2015/09/21
- [Qemu-devel] [PATCH v5 28/46] qapi: Rework deallocation of partial struct, Eric Blake, 2015/09/21
- [Qemu-devel] [PATCH v5 29/46] qapi: Change visit_type_FOO() to no longer return partial objects, Eric Blake, 2015/09/21
- [Qemu-devel] [PATCH v5 30/46] net: use Netdev instead of NetClientOptions in client init, Eric Blake, 2015/09/21
- [Qemu-devel] [PATCH v5 33/46] vnc: hoist allocation of VncBasicInfo to callers, Eric Blake, 2015/09/21
- [Qemu-devel] [PATCH v5 32/46] qapi: Hide tag_name data member of variants, Eric Blake, 2015/09/21
- [Qemu-devel] [PATCH v5 35/46] qapi-visit: Remove redundant functions for flat union base, Eric Blake, 2015/09/21
- [Qemu-devel] [PATCH v5 34/46] qapi: Unbox base members,
Eric Blake <=
- [Qemu-devel] [PATCH v5 36/46] qapi: Avoid use of 'data' member of qapi unions, Eric Blake, 2015/09/21
- [Qemu-devel] [PATCH v5 38/46] qapi: Drop useless 'data' member of unions, Eric Blake, 2015/09/21
- [Qemu-devel] [PATCH v5 37/46] qapi: Forbid empty unions and useless alternates, Eric Blake, 2015/09/21
- [Qemu-devel] [PATCH v5 39/46] qapi: Plumb in 'box' to qapi generator lower levels, Eric Blake, 2015/09/21
- [Qemu-devel] [PATCH v5 41/46] qapi: Support boxed unions, Eric Blake, 2015/09/21
- [Qemu-devel] [PATCH v5 40/46] qapi: Implement boxed structs for commands/events, Eric Blake, 2015/09/21
- [Qemu-devel] [PATCH v5 42/46] qapi: support implicit structs in OptsVisitor, Eric Blake, 2015/09/21
- [Qemu-devel] [PATCH v5 31/46] qapi: use 'type' in generated C code to match QMP union wire form, Eric Blake, 2015/09/21
- [Qemu-devel] [PATCH v5 44/46] net: Use correct type for bool flag, Eric Blake, 2015/09/21
- [Qemu-devel] [PATCH v5 46/46] qapi: Allow anonymous base for flat union, Eric Blake, 2015/09/21