qapi-visit: Remove redundant functions for flat union base
The code for visiting the base class of a child struct created visit_type_Base_fields() which covers all fields of Base; while the code for visiting the base class of a flat union created visit_type_Union_fields() covering all fields of the base except the discriminator. But since the base class includes the discriminator of a flat union, we can just visit the entire base, without needing a separate visit of the discriminator. Not only is consistently visiting all fields easier to understand, it lets us share code. The generated code in qapi-visit.c loses several now-unused visit_type_UNION_fields(), along with changes like: |@@ -1654,11 +1557,7 @@ void visit_type_BlockdevOptions(Visitor | if (!*obj) { | goto out_obj; | } |- visit_type_BlockdevOptions_fields(v, obj, &err); |- if (err) { |- goto out_obj; |- } |- visit_type_BlockdevDriver(v, &(*obj)->driver, "driver", &err); |+ visit_type_BlockdevOptionsBase_fields(v, (BlockdevOptionsBase **)obj, &err); | if (err) { | goto out_obj; | } and forward declarations where needed. Note that the cast of obj to BASE ** is necessary to call visit_type_BASE_fields() (and we can't use our upcast wrappers, because those work on pointers while we have a pointer-to-pointer). Signed-off-by: Eric Blake <eblake@redhat.com> Message-Id: <1445898903-12082-12-git-send-email-eblake@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
parent
ddf2190896
commit
5c5e51a05b
@ -228,8 +228,7 @@ def gen_visit_union(name, base, variants):
|
||||
ret = ''
|
||||
|
||||
if base:
|
||||
members = [m for m in base.members if m != variants.tag_member]
|
||||
ret += gen_visit_struct_fields(name, None, members)
|
||||
ret += gen_visit_fields_decl(base)
|
||||
|
||||
for var in variants.variants:
|
||||
# Ugly special case for simple union TODO get rid of it
|
||||
@ -254,31 +253,30 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error
|
||||
|
||||
if base:
|
||||
ret += mcgen('''
|
||||
visit_type_%(c_name)s_fields(v, obj, &err);
|
||||
visit_type_%(c_name)s_fields(v, (%(c_name)s **)obj, &err);
|
||||
''',
|
||||
c_name=c_name(name))
|
||||
ret += gen_err_check(label='out_obj')
|
||||
|
||||
tag_key = variants.tag_member.name
|
||||
if not variants.tag_name:
|
||||
# we pointlessly use a different key for simple unions
|
||||
tag_key = 'type'
|
||||
ret += mcgen('''
|
||||
c_name=base.c_name())
|
||||
else:
|
||||
ret += mcgen('''
|
||||
visit_type_%(c_type)s(v, &(*obj)->%(c_name)s, "%(name)s", &err);
|
||||
if (err) {
|
||||
goto out_obj;
|
||||
}
|
||||
''',
|
||||
c_type=variants.tag_member.type.c_name(),
|
||||
# TODO ugly special case for simple union
|
||||
# Use same tag name in C as on the wire to get rid of
|
||||
# it, then: c_name=c_name(variants.tag_member.name)
|
||||
c_name='kind',
|
||||
name=variants.tag_member.name)
|
||||
ret += gen_err_check(label='out_obj')
|
||||
ret += mcgen('''
|
||||
if (!visit_start_union(v, !!(*obj)->data, &err) || err) {
|
||||
goto out_obj;
|
||||
}
|
||||
switch ((*obj)->%(c_name)s) {
|
||||
''',
|
||||
c_type=variants.tag_member.type.c_name(),
|
||||
# TODO ugly special case for simple union
|
||||
# Use same tag name in C as on the wire to get rid of
|
||||
# it, then: c_name=c_name(variants.tag_member.name)
|
||||
c_name=c_name(variants.tag_name or 'kind'),
|
||||
name=tag_key)
|
||||
c_name=c_name(variants.tag_name or 'kind'))
|
||||
|
||||
for var in variants.variants:
|
||||
# TODO ugly special case for simple union
|
||||
|
Loading…
Reference in New Issue
Block a user