qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 2/3] qapi-visit: Expose visit_type_FOO_fields()


From: Eric Blake
Subject: [Qemu-devel] [PATCH 2/3] qapi-visit: Expose visit_type_FOO_fields()
Date: Tue, 23 Feb 2016 14:14:34 -0700

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 fields.  But
now that things are unboxed, we need a way to visit the fields
without allocation, done by exposing visit_type_FOO_fields() to
the user.  Of course, this should only be done for objects, not
lists, so we need another flag to gen_visit_decl().

Since the function is now public, we no longer need to preserve
topological ordering via struct_fields_seen.

Signed-off-by: Eric Blake <address@hidden>

---
Minor conflicts with pending series "qapi implicit types"; I can
rebase whichever series gets reviewed second.
---
 scripts/qapi-visit.py | 47 +++++++++++++----------------------------------
 1 file changed, 13 insertions(+), 34 deletions(-)

diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 2308268..35efe7c 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -15,52 +15,33 @@
 from qapi import *
 import re

-# visit_type_FOO_fields() is always emitted; track if a forward declaration
-# or implementation has already been output.
-struct_fields_seen = set()

-
-def gen_visit_decl(name, scalar=False):
+def gen_visit_decl(name, scalar=False, list=False):
+    ret = ''
     c_type = c_name(name) + ' *'
     if not scalar:
+        if not list:
+            ret += mcgen('''
+void visit_type_%(c_name)s_fields(Visitor *v, %(c_type)sobj, Error **errp);
+''',
+                         c_name=c_name(name), c_type=c_type)
         c_type += '*'
-    return mcgen('''
+    ret += mcgen('''
 void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_type)sobj, Error 
**errp);
 ''',
                  c_name=c_name(name), c_type=c_type)
-
-
-def gen_visit_fields_decl(typ):
-    if typ.name in struct_fields_seen:
-        return ''
-    struct_fields_seen.add(typ.name)
-    return mcgen('''
-
-static void visit_type_%(c_type)s_fields(Visitor *v, %(c_type)s *obj, Error 
**errp);
-''',
-                 c_type=typ.c_name())
+    return ret


 def gen_visit_struct_fields(name, base, members, variants):
-    ret = ''
+    ret = mcgen('''

-    if base:
-        ret += gen_visit_fields_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_fields_decl(var.type)
-
-    struct_fields_seen.add(name)
-    ret += mcgen('''
-
-static void visit_type_%(c_name)s_fields(Visitor *v, %(c_name)s *obj, Error 
**errp)
+void visit_type_%(c_name)s_fields(Visitor *v, %(c_name)s *obj, Error **errp)
 {
     Error *err = NULL;

 ''',
-                 c_name=c_name(name))
+                c_name=c_name(name))

     if base:
         ret += mcgen('''
@@ -173,8 +154,6 @@ def gen_visit_alternate(name, variants):
     for var in variants.variants:
         if var.type.alternate_qtype() == 'QTYPE_QINT':
             promote_int = 'false'
-        if isinstance(var.type, QAPISchemaObjectType):
-            ret += gen_visit_fields_decl(var.type)

     ret += mcgen('''

@@ -305,7 +284,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
             self.defn += gen_visit_enum(name)

     def visit_array_type(self, name, info, element_type):
-        decl = gen_visit_decl(name)
+        decl = gen_visit_decl(name, list=True)
         defn = gen_visit_list(name, element_type)
         if isinstance(element_type, QAPISchemaBuiltinType):
             self._btin += decl
-- 
2.5.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]