aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorEric Blake <eblake@redhat.com>2016-02-17 23:48:24 -0700
committerMarkus Armbruster <armbru@redhat.com>2016-02-19 11:08:57 +0100
commit1de5d4ca0752138034305f3d4e8fe17ef6503569 (patch)
treec914df4f8dd7a66c0b00f040812da69f477b1488 /scripts
parente65d89bf1a4484e0db0f3dc820a8b209f2fb1e8b (diff)
qapi: Emit structs used as variants in topological order
Right now, we emit the branches of union types as a boxed pointer, and it suffices to have a forward declaration of the type. However, a future patch will swap things to directly use the branch type, instead of hiding it behind a pointer. For this to work, the compiler needs the full definition of the type, not just a forward declaration, prior to the union that is including the branch type. This patch just adds topological sorting to hoist all types mentioned in a branch of a union to be fully declared before the union itself. The sort is always possible, because we do not allow circular union types that include themselves as a direct branch (it is, however, still possible to include a branch type that itself has a pointer to the union, for a type that can indirectly recursively nest itself - that remains safe, because that the member of the branch type will remain a pointer, and the QMP representation of such a type adds another {} for each recurring layer of the union type). Signed-off-by: Eric Blake <eblake@redhat.com> Message-Id: <1455778109-6278-11-git-send-email-eblake@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/qapi-types.py23
1 files changed, 20 insertions, 3 deletions
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 83f230a662..6ea0ae6fb7 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -2,7 +2,7 @@
# QAPI types generator
#
# Copyright IBM, Corp. 2011
-# Copyright (c) 2013-2015 Red Hat Inc.
+# Copyright (c) 2013-2016 Red Hat Inc.
#
# Authors:
# Anthony Liguori <aliguori@us.ibm.com>
@@ -14,6 +14,11 @@
from qapi import *
+# variants must be emitted before their container; track what has already
+# been output
+objects_seen = set()
+
+
def gen_fwd_object_or_array(name):
return mcgen('''
@@ -49,11 +54,23 @@ def gen_struct_fields(members):
def gen_object(name, base, members, variants):
- ret = mcgen('''
+ if name in objects_seen:
+ return ''
+ objects_seen.add(name)
+
+ ret = ''
+ if variants:
+ for v in variants.variants:
+ if (isinstance(v.type, QAPISchemaObjectType) and
+ not v.type.is_implicit()):
+ ret += gen_object(v.type.name, v.type.base,
+ v.type.local_members, v.type.variants)
+
+ ret += mcgen('''
struct %(c_name)s {
''',
- c_name=c_name(name))
+ c_name=c_name(name))
if base:
ret += mcgen('''