diff --git a/qemu/scripts/qapi-types.py b/qemu/scripts/qapi-types.py index f3324650..577cc0d9 100644 --- a/qemu/scripts/qapi-types.py +++ b/qemu/scripts/qapi-types.py @@ -73,16 +73,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; ''') @@ -275,11 +272,10 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor): if variants: assert not members # not implemented self.decl += gen_union(name, base, variants) - # TODO Use gen_upcast on structs too, once they have sane layout - if base: - self.decl += gen_upcast(name, base) else: self.decl += gen_struct(name, base, members) + if base: + self.decl += gen_upcast(name, base) self._gen_type_cleanup(name) def visit_alternate_type(self, name, info, variants): diff --git a/qemu/scripts/qapi-visit.py b/qemu/scripts/qapi-visit.py index d435133b..bf787d67 100644 --- a/qemu/scripts/qapi-visit.py +++ b/qemu/scripts/qapi-visit.py @@ -69,13 +69,12 @@ static void visit_type_implicit_%(c_type)s(Visitor *v, %(c_type)s **obj, Error * return ret def gen_visit_struct_fields(name, base, members): - struct_fields_seen.add(name) - ret = '' if base: - ret += gen_visit_implicit_struct(base) + ret += gen_visit_fields_decl(base) + struct_fields_seen.add(name) ret += mcgen(''' static void visit_type_%(c_name)s_fields(Visitor *v, %(c_name)s **obj, Error **errp) @@ -87,9 +86,9 @@ 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); ''', - c_type=base.c_name(), c_name=c_name('base')) + c_type=base.c_name()) ret += gen_err_check() ret += gen_visit_fields(members, prefix='(*obj)->')