summary refs log tree commit diff stats
path: root/scripts/qapi-visit.py
diff options
context:
space:
mode:
authorEric Blake <eblake@redhat.com>2015-10-26 16:34:50 -0600
committerMarkus Armbruster <armbru@redhat.com>2015-11-02 08:30:27 +0100
commit5c5e51a05b567fd48fb155d94ca6f7679dd0d478 (patch)
tree236dd693ffbc94aa1b94033071c76d1d5db671e4 /scripts/qapi-visit.py
parentddf21908961073199f3d186204da4810f2ea150b (diff)
downloadfocaccia-qemu-5c5e51a05b567fd48fb155d94ca6f7679dd0d478.tar.gz
focaccia-qemu-5c5e51a05b567fd48fb155d94ca6f7679dd0d478.zip
qapi-visit: Remove redundant functions for flat union base
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 since the base class includes
the discriminator of a flat union, we can just visit the entire
base, without needing a separate visit of the discriminator.
Not only is consistently visiting all fields easier to
understand, it lets us share code.

The generated code in qapi-visit.c loses several now-unused
visit_type_UNION_fields(), along with changes like:

|@@ -1654,11 +1557,7 @@ void visit_type_BlockdevOptions(Visitor
|     if (!*obj) {
|         goto out_obj;
|     }
|-    visit_type_BlockdevOptions_fields(v, obj, &err);
|-    if (err) {
|-        goto out_obj;
|-    }
|-    visit_type_BlockdevDriver(v, &(*obj)->driver, "driver", &err);
|+    visit_type_BlockdevOptionsBase_fields(v, (BlockdevOptionsBase **)obj, &err);
|     if (err) {
|         goto out_obj;
|     }

and forward declarations where needed.  Note that the cast of obj
to BASE ** is necessary to call visit_type_BASE_fields() (and we
can't use our upcast wrappers, because those work on pointers while
we have a pointer-to-pointer).

Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1445898903-12082-12-git-send-email-eblake@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Diffstat (limited to '')
-rw-r--r--scripts/qapi-visit.py32
1 files changed, 15 insertions, 17 deletions
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index f711a720f3..33c013a7fb 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -228,8 +228,7 @@ 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_fields_decl(base)
 
     for var in variants.variants:
         # Ugly special case for simple union TODO get rid of it
@@ -254,31 +253,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