qapi-visit: Expose visit_type_FOO_members()
Dan Berrange reported a case where he needs to work with a QCryptoBlockOptions union type using the OptsVisitor, but only visit one of the branches of that type (the discriminator is not visited directly, but learned externally). When things were boxed, it was easy: just visit the variant directly, which took care of both allocating the variant and visiting its members, then store that pointer in the union type. But now that things are unboxed, we need a way to visit the members without allocation, done by exposing visit_type_FOO_members() to the user. Before the patch, we had quite a bit of code associated with object_members_seen to make sure that a declaration of the helper was in scope before any use of the function. But now that the helper is public and declared in the header, the .c file no longer needs to worry about topological sorting (the helper is always in scope), which leads to some nice cleanups. Signed-off-by: Eric Blake <eblake@redhat.com> Message-Id: <1457021813-10704-4-git-send-email-eblake@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
parent
c81200b014
commit
4d91e9115c
@ -15,10 +15,6 @@
|
|||||||
from qapi import *
|
from qapi import *
|
||||||
import re
|
import re
|
||||||
|
|
||||||
# visit_type_FOO_members() is always emitted; track if a forward declaration
|
|
||||||
# or implementation has already been output.
|
|
||||||
object_members_seen = set()
|
|
||||||
|
|
||||||
|
|
||||||
def gen_visit_decl(name, scalar=False):
|
def gen_visit_decl(name, scalar=False):
|
||||||
c_type = c_name(name) + ' *'
|
c_type = c_name(name) + ' *'
|
||||||
@ -30,37 +26,23 @@ void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_type)sobj, Error **
|
|||||||
c_name=c_name(name), c_type=c_type)
|
c_name=c_name(name), c_type=c_type)
|
||||||
|
|
||||||
|
|
||||||
def gen_visit_members_decl(typ):
|
def gen_visit_members_decl(name):
|
||||||
if typ.name in object_members_seen:
|
|
||||||
return ''
|
|
||||||
object_members_seen.add(typ.name)
|
|
||||||
return mcgen('''
|
return mcgen('''
|
||||||
|
|
||||||
static void visit_type_%(c_type)s_members(Visitor *v, %(c_type)s *obj, Error **errp);
|
void visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp);
|
||||||
''',
|
''',
|
||||||
c_type=typ.c_name())
|
c_name=c_name(name))
|
||||||
|
|
||||||
|
|
||||||
def gen_visit_object_members(name, base, members, variants):
|
def gen_visit_object_members(name, base, members, variants):
|
||||||
ret = ''
|
ret = mcgen('''
|
||||||
|
|
||||||
if base:
|
void visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
|
||||||
ret += gen_visit_members_decl(base)
|
|
||||||
if variants:
|
|
||||||
for var in variants.variants:
|
|
||||||
# Ugly special case for simple union TODO get rid of it
|
|
||||||
if not var.simple_union_type():
|
|
||||||
ret += gen_visit_members_decl(var.type)
|
|
||||||
|
|
||||||
object_members_seen.add(name)
|
|
||||||
ret += mcgen('''
|
|
||||||
|
|
||||||
static void visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
|
|
||||||
{
|
{
|
||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
''',
|
''',
|
||||||
c_name=c_name(name))
|
c_name=c_name(name))
|
||||||
|
|
||||||
if base:
|
if base:
|
||||||
ret += mcgen('''
|
ret += mcgen('''
|
||||||
@ -173,8 +155,6 @@ def gen_visit_alternate(name, variants):
|
|||||||
for var in variants.variants:
|
for var in variants.variants:
|
||||||
if var.type.alternate_qtype() == 'QTYPE_QINT':
|
if var.type.alternate_qtype() == 'QTYPE_QINT':
|
||||||
promote_int = 'false'
|
promote_int = 'false'
|
||||||
if isinstance(var.type, QAPISchemaObjectType):
|
|
||||||
ret += gen_visit_members_decl(var.type)
|
|
||||||
|
|
||||||
ret += mcgen('''
|
ret += mcgen('''
|
||||||
|
|
||||||
@ -316,6 +296,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
|
|||||||
self.defn += defn
|
self.defn += defn
|
||||||
|
|
||||||
def visit_object_type(self, name, info, base, members, variants):
|
def visit_object_type(self, name, info, base, members, variants):
|
||||||
|
self.decl += gen_visit_members_decl(name)
|
||||||
self.decl += gen_visit_decl(name)
|
self.decl += gen_visit_decl(name)
|
||||||
self.defn += gen_visit_object(name, base, members, variants)
|
self.defn += gen_visit_object(name, base, members, variants)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user