|
@@ -149,11 +149,23 @@ def gen_union(name, base, variants):
|
|
if base:
|
|
if base:
|
|
ret += gen_struct_fields([], base)
|
|
ret += gen_struct_fields([], base)
|
|
else:
|
|
else:
|
|
|
|
+ # TODO As a hack, we emit both 'kind' and 'type'. Ultimately, we
|
|
|
|
+ # want to use only 'type', but the conversion is large enough to
|
|
|
|
+ # require staging over several commits.
|
|
ret += mcgen('''
|
|
ret += mcgen('''
|
|
- %(c_type)s kind;
|
|
|
|
|
|
+ union {
|
|
|
|
+ %(c_type)s kind;
|
|
|
|
+ %(c_type)s type;
|
|
|
|
+ };
|
|
''',
|
|
''',
|
|
c_type=c_name(variants.tag_member.type.name))
|
|
c_type=c_name(variants.tag_member.type.name))
|
|
|
|
|
|
|
|
+ # TODO As a hack, we emit the union twice, once as an anonymous union
|
|
|
|
+ # and once as a named union. Ultimately, we want to use only the
|
|
|
|
+ # named union version (as it avoids conflicts between tag values as
|
|
|
|
+ # branch names competing with non-variant QMP names), but the conversion
|
|
|
|
+ # is large enough to require staging over several commits.
|
|
|
|
+ tmp = ''
|
|
# FIXME: What purpose does data serve, besides preventing a union that
|
|
# FIXME: What purpose does data serve, besides preventing a union that
|
|
# has a branch named 'data'? We use it in qapi-visit.py to decide
|
|
# has a branch named 'data'? We use it in qapi-visit.py to decide
|
|
# whether to bypass the switch statement if visiting the discriminator
|
|
# whether to bypass the switch statement if visiting the discriminator
|
|
@@ -162,25 +174,25 @@ def gen_union(name, base, variants):
|
|
# should not be any data leaks even without a data pointer. Or, if
|
|
# should not be any data leaks even without a data pointer. Or, if
|
|
# 'data' is merely added to guarantee we don't have an empty union,
|
|
# 'data' is merely added to guarantee we don't have an empty union,
|
|
# shouldn't we enforce that at .json parse time?
|
|
# shouldn't we enforce that at .json parse time?
|
|
- ret += mcgen('''
|
|
|
|
|
|
+ tmp += mcgen('''
|
|
union { /* union tag is @%(c_name)s */
|
|
union { /* union tag is @%(c_name)s */
|
|
void *data;
|
|
void *data;
|
|
''',
|
|
''',
|
|
- # 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'))
|
|
|
|
|
|
+ c_name=c_name(variants.tag_member.name))
|
|
|
|
|
|
for var in variants.variants:
|
|
for var in variants.variants:
|
|
# Ugly special case for simple union TODO get rid of it
|
|
# Ugly special case for simple union TODO get rid of it
|
|
typ = var.simple_union_type() or var.type
|
|
typ = var.simple_union_type() or var.type
|
|
- ret += mcgen('''
|
|
|
|
|
|
+ tmp += mcgen('''
|
|
%(c_type)s %(c_name)s;
|
|
%(c_type)s %(c_name)s;
|
|
''',
|
|
''',
|
|
c_type=typ.c_type(),
|
|
c_type=typ.c_type(),
|
|
c_name=c_name(var.name))
|
|
c_name=c_name(var.name))
|
|
|
|
|
|
|
|
+ ret += tmp
|
|
|
|
+ ret += ' ' + '\n '.join(tmp.split('\n'))
|
|
ret += mcgen('''
|
|
ret += mcgen('''
|
|
|
|
+ } u;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
''')
|
|
''')
|