qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH v9 06/17] qapi-visit: Remove redundant functions for


From: Eric Blake
Subject: [Qemu-devel] [PATCH v9 06/17] qapi-visit: Remove redundant functions for flat union base
Date: Thu, 15 Oct 2015 22:15:31 -0600

The code for visiting the base class of a child struct created
visit_type_Base_fields() which covers all fields of Base; while
the code for visiting the base class of a flat union created
visit_type_Union_fields() covering all fields of the base
except the discriminator.  But if the base class were to always
visit all its fields, then we wouldn't need a separate visit of
the discriminator for a union.  Not only is consistently
visiting all fields easier to understand, it lets us share code.

Now that gen_visit_struct_fields() can potentially collect more
than one function into 'ret', a regular expression searching for
whether a label was used may hit a false positive within the
body of the first function.  But using a regex was overkill,
since we can easily determine when we jumped to a label.

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

---
v9: (no v6-8): hoist from v5 35/46; rebase to master; fix indentation
botch in gen_visit_union(); polish commit message
---
 scripts/qapi-visit.py | 35 +++++++++++++++++------------------
 1 file changed, 17 insertions(+), 18 deletions(-)

diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 8aae8da..91bf350 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -90,7 +90,7 @@ static void visit_type_%(c_name)s_fields(Visitor *v, 
%(c_name)s **obj, Error **e

     ret += gen_visit_fields(members, prefix='(*obj)->')

-    if re.search('^ *goto out;', ret, re.MULTILINE):
+    if base or members:
         ret += mcgen('''

 out:
@@ -221,8 +221,8 @@ def gen_visit_union(name, base, variants):
     ret = ''

     if base:
-        members = [m for m in base.members if m != variants.tag_member]
-        ret += gen_visit_struct_fields(name, None, members)
+        ret += gen_visit_struct_fields(base.name, base.base,
+                                       base.local_members)

     for var in variants.variants:
         # Ugly special case for simple union TODO get rid of it
@@ -247,31 +247,30 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, 
const char *name, Error

     if base:
         ret += mcgen('''
-    visit_type_%(c_name)s_fields(v, obj, &err);
+    visit_type_%(c_name)s_fields(v, (%(c_name)s **)obj, &err);
 ''',
-                     c_name=c_name(name))
-        ret += gen_err_check(label='out_obj')
-
-    tag_key = variants.tag_member.name
-    if not variants.tag_name:
-        # we pointlessly use a different key for simple unions
-        tag_key = 'type'
-    ret += mcgen('''
+                     c_name=base.c_name())
+    else:
+        ret += mcgen('''
     visit_type_%(c_type)s(v, &(*obj)->%(c_name)s, "%(name)s", &err);
-    if (err) {
-        goto out_obj;
-    }
+''',
+                     c_type=variants.tag_member.type.c_name(),
+                     # 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='kind',
+                     name=variants.tag_member.name)
+    ret += gen_err_check(label='out_obj')
+    ret += mcgen('''
     if (!visit_start_union(v, !!(*obj)->data, &err) || err) {
         goto out_obj;
     }
     switch ((*obj)->%(c_name)s) {
 ''',
-                 c_type=variants.tag_member.type.c_name(),
                  # 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'),
-                 name=tag_key)
+                 c_name=c_name(variants.tag_name or 'kind'))

     for var in variants.variants:
         # TODO ugly special case for simple union
-- 
2.4.3




reply via email to

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