qapi: Hoist tag collision check to Variants.check()

Checking that a given QAPISchemaObjectTypeVariant.name is a
member of the corresponding QAPISchemaEnumType of the owning
QAPISchemaObjectTypeVariants.tag_member ensures that there are
no collisions in the generated C union for those tag values
(since the enum itself should have no collisions).

However, ever since its introduction in f51d8c3d, this was the
only additional action of of Variant.check(), beyond calling
the superclass Member.check(). This forces a difference in
.check() signatures, just to pass the enum type down.

Simplify things by instead doing the tag name check as part of
Variants.check(), at which point we can rely on inheritance
instead of overriding Variant.check().

Backports commit 10565ca92a8d3f8a34559329acfbdb25a791b594 from qemu
This commit is contained in:
Eric Blake 2018-02-19 20:24:24 -05:00 committed by Lioncash
parent 51b4313b34
commit 2f45c9ff99
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -548,8 +548,7 @@ def check_union(expr, expr_info):
base = expr.get('base')
discriminator = expr.get('discriminator')
members = expr['data']
values = {'MAX': '(automatic)', 'KIND': '(automatic)',
'TYPE': '(automatic)'}
values = {'MAX': '(automatic)'}
# Two types of unions, determined by discriminator.
@ -607,19 +606,13 @@ def check_union(expr, expr_info):
" of branch '%s'" % key)
# If the discriminator names an enum type, then all members
# of 'data' must also be members of the enum type, which in turn
# must not collide with the discriminator name.
# of 'data' must also be members of the enum type.
if enum_define:
if key not in enum_define['enum_values']:
raise QAPIExprError(expr_info,
"Discriminator value '%s' is not found in "
"enum '%s'" %
(key, enum_define["enum_name"]))
if discriminator in enum_define['enum_values']:
raise QAPIExprError(expr_info,
"Discriminator name '%s' collides with "
"enum value in '%s'" %
(discriminator, enum_define["enum_name"]))
# Otherwise, check for conflicts in the generated enum
else:
@ -1059,7 +1052,8 @@ class QAPISchemaObjectTypeVariants(object):
self.tag_member = seen[self.tag_name]
assert isinstance(self.tag_member.type, QAPISchemaEnumType)
for v in self.variants:
v.check(schema, self.tag_member.type)
v.check(schema)
assert v.name in self.tag_member.type.values
if isinstance(v.type, QAPISchemaObjectType):
v.type.check(schema)
@ -1075,10 +1069,6 @@ class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
def __init__(self, name, typ):
QAPISchemaObjectTypeMember.__init__(self, name, typ, False)
def check(self, schema, tag_type):
QAPISchemaObjectTypeMember.check(self, schema)
assert self.name in tag_type.values
# This function exists to support ugly simple union special cases
# TODO get rid of them, and drop the function
def simple_union_type(self):