@@ -61,8 +61,7 @@ def gen_object(name, base, members, variants):
ret = ''
if variants:
for v in variants.variants:
- if (isinstance(v.type, QAPISchemaObjectType) and
- not v.type.is_implicit()):
+ if isinstance(v.type, QAPISchemaObjectType):
ret += gen_object(v.type.name, v.type.base,
v.type.local_members, v.type.variants)
@@ -180,6 +179,8 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
self._btin = None
def visit_begin(self, schema):
+ # gen_object() is recursive, ensure it doesn't visit the empty type
+ objects_seen.add(schema.the_empty_object_type.name)
self.decl = ''
self.defn = ''
self._fwdecl = ''
@@ -196,11 +197,6 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
self.decl = self._btin + self.decl
self._btin = None
- def visit_needed(self, entity):
- # Visit everything except implicit objects
- return not (entity.is_implicit() and
- isinstance(entity, QAPISchemaObjectType))
-
def _gen_type_cleanup(self, name):
self.decl += gen_type_cleanup_decl(name)
self.defn += gen_type_cleanup(name)
@@ -229,11 +225,18 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
self._gen_type_cleanup(name)
def visit_object_type(self, name, info, base, members, variants):
+ # Nothing to do for the special empty builtin
+ if name == 'q_empty':
+ return
self._fwdecl += gen_fwd_object_or_array(name)
self.decl += gen_object(name, base, members, variants)
if base:
self.decl += gen_upcast(name, base)
- self._gen_type_cleanup(name)
+ # TODO Worth changing the visitor signature, so we could
+ # directly use rather than repeat type.is_implicit()?
+ if not name.startswith('q_'):
+ # implicit types won't be directly allocated/freed
+ self._gen_type_cleanup(name)
def visit_alternate_type(self, name, info, variants):
self._fwdecl += gen_fwd_object_or_array(name)
@@ -215,13 +215,11 @@ out:
def gen_visit_object(name, base, members, variants):
- ret = gen_visit_object_members(name, base, members, variants)
-
# FIXME: if *obj is NULL on entry, and visit_start_struct() assigns to
# *obj, but then visit_type_FOO_members() fails, we should clean up *obj
# rather than leaving it non-NULL. As currently written, the caller must
# call qapi_free_FOO() to avoid a memory leak of the partial FOO.
- ret += mcgen('''
+ return mcgen('''
void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error **errp)
{
@@ -245,8 +243,6 @@ out:
''',
c_name=c_name(name))
- return ret
-
class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
def __init__(self):
@@ -268,11 +264,6 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
self.decl = self._btin + self.decl
self._btin = None
- def visit_needed(self, entity):
- # Visit everything except implicit objects
- return not (entity.is_implicit() and
- isinstance(entity, QAPISchemaObjectType))
-
def visit_enum_type(self, name, info, values, prefix):
# Special case for our lone builtin enum type
# TODO use something cleaner than existence of info
@@ -296,9 +287,17 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
self.defn += defn
def visit_object_type(self, name, info, base, members, variants):
+ # Nothing to do for the special empty builtin
+ if name == 'q_empty':
+ return
self.decl += gen_visit_members_decl(name)
- self.decl += gen_visit_decl(name)
- self.defn += gen_visit_object(name, base, members, variants)
+ self.defn += gen_visit_object_members(name, base, members, variants)
+ # TODO Worth changing the visitor signature, so we could
+ # directly use rather than repeat type.is_implicit()?
+ if not name.startswith('q_'):
+ # only explicit types need an allocating visit
+ self.decl += gen_visit_decl(name)
+ self.defn += gen_visit_object(name, base, members, variants)
def visit_alternate_type(self, name, info, variants):
self.decl += gen_visit_decl(name)
@@ -1000,7 +1000,6 @@ class QAPISchemaObjectType(QAPISchemaType):
return self.name.startswith('q_')
def c_name(self):
- assert not self.is_implicit()
return QAPISchemaType.c_name(self)
def c_type(self):
@@ -1008,7 +1007,6 @@ class QAPISchemaObjectType(QAPISchemaType):
return c_name(self.name) + pointer_suffix
def c_unboxed_type(self):
- assert not self.is_implicit()
return c_name(self.name)
def json_type(self):