summary refs log tree commit diff stats
path: root/scripts/qapi-types.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/qapi-types.py')
-rw-r--r--scripts/qapi-types.py65
1 files changed, 63 insertions, 2 deletions
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index ddcfed9f4b..5ee46ea1b3 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -150,7 +150,48 @@ typedef enum %(name)s
 
     return lookup_decl + enum_decl
 
-def generate_union(name, typeinfo):
+def generate_anon_union_qtypes(expr):
+
+    name = expr['union']
+    members = expr['data']
+
+    ret = mcgen('''
+const int %(name)s_qtypes[QTYPE_MAX] = {
+''',
+    name=name)
+
+    for key in members:
+        qapi_type = members[key]
+        if builtin_type_qtypes.has_key(qapi_type):
+            qtype = builtin_type_qtypes[qapi_type]
+        elif find_struct(qapi_type):
+            qtype = "QTYPE_QDICT"
+        elif find_union(qapi_type):
+            qtype = "QTYPE_QDICT"
+        else:
+            assert False, "Invalid anonymous union member"
+
+        ret += mcgen('''
+    [ %(qtype)s ] = %(abbrev)s_KIND_%(enum)s,
+''',
+        qtype = qtype,
+        abbrev = de_camel_case(name).upper(),
+        enum = c_fun(de_camel_case(key),False).upper())
+
+    ret += mcgen('''
+};
+''')
+    return ret
+
+
+def generate_union(expr):
+
+    name = expr['union']
+    typeinfo = expr['data']
+
+    base = expr.get('base')
+    discriminator = expr.get('discriminator')
+
     ret = mcgen('''
 struct %(name)s
 {
@@ -169,8 +210,26 @@ struct %(name)s
 
     ret += mcgen('''
     };
+''')
+
+    if base:
+        base_fields = find_struct(base)['data']
+        if discriminator:
+            base_fields = base_fields.copy()
+            del base_fields[discriminator]
+        ret += generate_struct_fields(base_fields)
+    else:
+        assert not discriminator
+
+    ret += mcgen('''
 };
 ''')
+    if discriminator == {}:
+        ret += mcgen('''
+extern const int %(name)s_qtypes[];
+''',
+            name=name)
+
 
     return ret
 
@@ -323,6 +382,8 @@ for expr in exprs:
         ret += generate_fwd_struct(expr['union'], expr['data']) + "\n"
         ret += generate_enum('%sKind' % expr['union'], expr['data'].keys())
         fdef.write(generate_enum_lookup('%sKind' % expr['union'], expr['data'].keys()))
+        if expr.get('discriminator') == {}:
+            fdef.write(generate_anon_union_qtypes(expr))
     else:
         continue
     fdecl.write(ret)
@@ -352,7 +413,7 @@ for expr in exprs:
         ret += generate_type_cleanup_decl(expr['type'])
         fdef.write(generate_type_cleanup(expr['type']) + "\n")
     elif expr.has_key('union'):
-        ret += generate_union(expr['union'], expr['data'])
+        ret += generate_union(expr)
         ret += generate_type_cleanup_decl(expr['union'] + "List")
         fdef.write(generate_type_cleanup(expr['union'] + "List") + "\n")
         ret += generate_type_cleanup_decl(expr['union'])