summaryrefslogtreecommitdiffstats
path: root/qemu/tests/qapi-schema
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/tests/qapi-schema')
-rw-r--r--qemu/tests/qapi-schema/alternate-any.err1
-rw-r--r--qemu/tests/qapi-schema/alternate-any.exit (renamed from qemu/tests/qapi-schema/data-array-empty.exit)0
-rw-r--r--qemu/tests/qapi-schema/alternate-any.json4
-rw-r--r--qemu/tests/qapi-schema/alternate-any.out (renamed from qemu/tests/qapi-schema/alternate-good.err)0
-rw-r--r--qemu/tests/qapi-schema/alternate-clash.err2
-rw-r--r--qemu/tests/qapi-schema/alternate-clash.json9
-rw-r--r--qemu/tests/qapi-schema/alternate-empty.err1
-rw-r--r--qemu/tests/qapi-schema/alternate-empty.exit (renamed from qemu/tests/qapi-schema/data-array-unknown.exit)0
-rw-r--r--qemu/tests/qapi-schema/alternate-empty.json2
-rw-r--r--qemu/tests/qapi-schema/alternate-empty.out (renamed from qemu/tests/qapi-schema/data-array-empty.out)0
-rw-r--r--qemu/tests/qapi-schema/alternate-good.exit1
-rw-r--r--qemu/tests/qapi-schema/alternate-good.json9
-rw-r--r--qemu/tests/qapi-schema/alternate-good.out6
-rw-r--r--qemu/tests/qapi-schema/alternate-nested.json2
-rw-r--r--qemu/tests/qapi-schema/alternate-unknown.json2
-rw-r--r--qemu/tests/qapi-schema/args-alternate.err1
-rw-r--r--qemu/tests/qapi-schema/args-alternate.exit (renamed from qemu/tests/qapi-schema/data-int.exit)0
-rw-r--r--qemu/tests/qapi-schema/args-alternate.json3
-rw-r--r--qemu/tests/qapi-schema/args-alternate.out (renamed from qemu/tests/qapi-schema/data-array-unknown.out)0
-rw-r--r--qemu/tests/qapi-schema/args-any.err1
-rw-r--r--qemu/tests/qapi-schema/args-any.exit (renamed from qemu/tests/qapi-schema/data-member-array-bad.exit)0
-rw-r--r--qemu/tests/qapi-schema/args-any.json2
-rw-r--r--qemu/tests/qapi-schema/args-any.out (renamed from qemu/tests/qapi-schema/data-int.out)0
-rw-r--r--qemu/tests/qapi-schema/args-array-empty.err (renamed from qemu/tests/qapi-schema/data-array-empty.err)2
-rw-r--r--qemu/tests/qapi-schema/args-array-empty.exit (renamed from qemu/tests/qapi-schema/data-member-unknown.exit)0
-rw-r--r--qemu/tests/qapi-schema/args-array-empty.json (renamed from qemu/tests/qapi-schema/data-array-empty.json)0
-rw-r--r--qemu/tests/qapi-schema/args-array-empty.out (renamed from qemu/tests/qapi-schema/data-member-array-bad.out)0
-rw-r--r--qemu/tests/qapi-schema/args-array-unknown.err1
-rw-r--r--qemu/tests/qapi-schema/args-array-unknown.exit (renamed from qemu/tests/qapi-schema/data-unknown.exit)0
-rw-r--r--qemu/tests/qapi-schema/args-array-unknown.json (renamed from qemu/tests/qapi-schema/data-array-unknown.json)0
-rw-r--r--qemu/tests/qapi-schema/args-array-unknown.out (renamed from qemu/tests/qapi-schema/data-member-array.err)0
-rw-r--r--qemu/tests/qapi-schema/args-int.err1
-rw-r--r--qemu/tests/qapi-schema/args-int.exit (renamed from qemu/tests/qapi-schema/enum-max-member.exit)0
-rw-r--r--qemu/tests/qapi-schema/args-int.json (renamed from qemu/tests/qapi-schema/data-int.json)0
-rw-r--r--qemu/tests/qapi-schema/args-int.out (renamed from qemu/tests/qapi-schema/data-member-unknown.out)0
-rw-r--r--qemu/tests/qapi-schema/args-invalid.err1
-rw-r--r--qemu/tests/qapi-schema/args-invalid.exit (renamed from qemu/tests/qapi-schema/enum-union-clash.exit)0
-rw-r--r--qemu/tests/qapi-schema/args-invalid.json2
-rw-r--r--qemu/tests/qapi-schema/args-invalid.out (renamed from qemu/tests/qapi-schema/data-unknown.out)0
-rw-r--r--qemu/tests/qapi-schema/args-member-array-bad.err (renamed from qemu/tests/qapi-schema/data-member-array-bad.err)2
-rw-r--r--qemu/tests/qapi-schema/args-member-array-bad.exit (renamed from qemu/tests/qapi-schema/event-max.exit)0
-rw-r--r--qemu/tests/qapi-schema/args-member-array-bad.json (renamed from qemu/tests/qapi-schema/data-member-array-bad.json)0
-rw-r--r--qemu/tests/qapi-schema/args-member-array-bad.out (renamed from qemu/tests/qapi-schema/enum-empty.err)0
-rw-r--r--qemu/tests/qapi-schema/args-member-case.err1
-rw-r--r--qemu/tests/qapi-schema/args-member-case.exit (renamed from qemu/tests/qapi-schema/flat-union-base-star.exit)0
-rw-r--r--qemu/tests/qapi-schema/args-member-case.json2
-rw-r--r--qemu/tests/qapi-schema/args-member-case.out (renamed from qemu/tests/qapi-schema/enum-max-member.out)0
-rw-r--r--qemu/tests/qapi-schema/args-member-unknown.err1
-rw-r--r--qemu/tests/qapi-schema/args-member-unknown.exit (renamed from qemu/tests/qapi-schema/flat-union-branch-clash.exit)0
-rw-r--r--qemu/tests/qapi-schema/args-member-unknown.json (renamed from qemu/tests/qapi-schema/data-member-unknown.json)0
-rw-r--r--qemu/tests/qapi-schema/args-member-unknown.out (renamed from qemu/tests/qapi-schema/enum-union-clash.out)0
-rw-r--r--qemu/tests/qapi-schema/args-name-clash.err1
-rw-r--r--qemu/tests/qapi-schema/args-name-clash.exit (renamed from qemu/tests/qapi-schema/nested-struct-returns.exit)0
-rw-r--r--qemu/tests/qapi-schema/args-name-clash.json4
-rw-r--r--qemu/tests/qapi-schema/args-name-clash.out (renamed from qemu/tests/qapi-schema/event-max.out)0
-rw-r--r--qemu/tests/qapi-schema/args-union.err1
-rw-r--r--qemu/tests/qapi-schema/args-union.exit (renamed from qemu/tests/qapi-schema/type-bypass-no-gen.exit)0
-rw-r--r--qemu/tests/qapi-schema/args-union.json4
-rw-r--r--qemu/tests/qapi-schema/args-union.out (renamed from qemu/tests/qapi-schema/flat-union-base-star.out)0
-rw-r--r--qemu/tests/qapi-schema/args-unknown.err1
-rw-r--r--qemu/tests/qapi-schema/args-unknown.exit (renamed from qemu/tests/qapi-schema/union-bad-branch.exit)0
-rw-r--r--qemu/tests/qapi-schema/args-unknown.json (renamed from qemu/tests/qapi-schema/data-unknown.json)0
-rw-r--r--qemu/tests/qapi-schema/args-unknown.out (renamed from qemu/tests/qapi-schema/flat-union-branch-clash.out)0
-rw-r--r--qemu/tests/qapi-schema/base-cycle-direct.err1
-rw-r--r--qemu/tests/qapi-schema/base-cycle-direct.exit (renamed from qemu/tests/qapi-schema/union-max.exit)0
-rw-r--r--qemu/tests/qapi-schema/base-cycle-direct.json2
-rw-r--r--qemu/tests/qapi-schema/base-cycle-direct.out (renamed from qemu/tests/qapi-schema/flat-union-reverse-define.err)0
-rw-r--r--qemu/tests/qapi-schema/base-cycle-indirect.err1
-rw-r--r--qemu/tests/qapi-schema/base-cycle-indirect.exit1
-rw-r--r--qemu/tests/qapi-schema/base-cycle-indirect.json3
-rw-r--r--qemu/tests/qapi-schema/base-cycle-indirect.out (renamed from qemu/tests/qapi-schema/nested-struct-returns.out)0
-rw-r--r--qemu/tests/qapi-schema/command-int.json3
-rw-r--r--qemu/tests/qapi-schema/comments.out7
-rw-r--r--qemu/tests/qapi-schema/data-array-unknown.err1
-rw-r--r--qemu/tests/qapi-schema/data-int.err1
-rw-r--r--qemu/tests/qapi-schema/data-member-array.exit1
-rw-r--r--qemu/tests/qapi-schema/data-member-array.json4
-rw-r--r--qemu/tests/qapi-schema/data-member-array.out5
-rw-r--r--qemu/tests/qapi-schema/data-member-unknown.err1
-rw-r--r--qemu/tests/qapi-schema/data-unknown.err1
-rw-r--r--qemu/tests/qapi-schema/duplicate-key.err2
-rw-r--r--qemu/tests/qapi-schema/duplicate-key.json1
-rw-r--r--qemu/tests/qapi-schema/empty.out6
-rw-r--r--qemu/tests/qapi-schema/enum-bad-prefix.err1
-rw-r--r--qemu/tests/qapi-schema/enum-bad-prefix.exit1
-rw-r--r--qemu/tests/qapi-schema/enum-bad-prefix.json2
-rw-r--r--qemu/tests/qapi-schema/enum-bad-prefix.out (renamed from qemu/tests/qapi-schema/returns-int.err)0
-rw-r--r--qemu/tests/qapi-schema/enum-clash-member.err2
-rw-r--r--qemu/tests/qapi-schema/enum-clash-member.json2
-rw-r--r--qemu/tests/qapi-schema/enum-empty.exit1
-rw-r--r--qemu/tests/qapi-schema/enum-empty.json2
-rw-r--r--qemu/tests/qapi-schema/enum-empty.out3
-rw-r--r--qemu/tests/qapi-schema/enum-max-member.err1
-rw-r--r--qemu/tests/qapi-schema/enum-max-member.json3
-rw-r--r--qemu/tests/qapi-schema/enum-member-case.err1
-rw-r--r--qemu/tests/qapi-schema/enum-member-case.exit1
-rw-r--r--qemu/tests/qapi-schema/enum-member-case.json3
-rw-r--r--qemu/tests/qapi-schema/enum-member-case.out (renamed from qemu/tests/qapi-schema/type-bypass-no-gen.out)0
-rw-r--r--qemu/tests/qapi-schema/enum-union-clash.err1
-rw-r--r--qemu/tests/qapi-schema/event-case.out7
-rw-r--r--qemu/tests/qapi-schema/event-max.err1
-rw-r--r--qemu/tests/qapi-schema/event-max.json2
-rw-r--r--qemu/tests/qapi-schema/flat-union-bad-base.err2
-rw-r--r--qemu/tests/qapi-schema/flat-union-bad-base.json5
-rw-r--r--qemu/tests/qapi-schema/flat-union-base-any.err1
-rw-r--r--qemu/tests/qapi-schema/flat-union-base-any.exit1
-rw-r--r--qemu/tests/qapi-schema/flat-union-base-any.json (renamed from qemu/tests/qapi-schema/flat-union-base-star.json)2
-rw-r--r--qemu/tests/qapi-schema/flat-union-base-any.out (renamed from qemu/tests/qapi-schema/type-bypass.err)0
-rw-r--r--qemu/tests/qapi-schema/flat-union-base-star.err1
-rw-r--r--qemu/tests/qapi-schema/flat-union-base-union.err2
-rw-r--r--qemu/tests/qapi-schema/flat-union-base-union.json5
-rw-r--r--qemu/tests/qapi-schema/flat-union-branch-clash.err1
-rw-r--r--qemu/tests/qapi-schema/flat-union-clash-member.err1
-rw-r--r--qemu/tests/qapi-schema/flat-union-clash-member.exit1
-rw-r--r--qemu/tests/qapi-schema/flat-union-clash-member.json (renamed from qemu/tests/qapi-schema/flat-union-branch-clash.json)3
-rw-r--r--qemu/tests/qapi-schema/flat-union-clash-member.out (renamed from qemu/tests/qapi-schema/union-bad-branch.out)0
-rw-r--r--qemu/tests/qapi-schema/flat-union-empty.err1
-rw-r--r--qemu/tests/qapi-schema/flat-union-empty.exit1
-rw-r--r--qemu/tests/qapi-schema/flat-union-empty.json4
-rw-r--r--qemu/tests/qapi-schema/flat-union-empty.out (renamed from qemu/tests/qapi-schema/union-max.out)0
-rw-r--r--qemu/tests/qapi-schema/flat-union-inline.err2
-rw-r--r--qemu/tests/qapi-schema/flat-union-inline.json4
-rw-r--r--qemu/tests/qapi-schema/flat-union-no-base.err2
-rw-r--r--qemu/tests/qapi-schema/flat-union-reverse-define.exit1
-rw-r--r--qemu/tests/qapi-schema/flat-union-reverse-define.json17
-rw-r--r--qemu/tests/qapi-schema/flat-union-reverse-define.out9
-rw-r--r--qemu/tests/qapi-schema/ident-with-escape.out10
-rw-r--r--qemu/tests/qapi-schema/include-non-file.err2
-rw-r--r--qemu/tests/qapi-schema/include-non-file.json2
-rw-r--r--qemu/tests/qapi-schema/include-relpath.out7
-rw-r--r--qemu/tests/qapi-schema/include-repetition.out7
-rw-r--r--qemu/tests/qapi-schema/include-simple.out7
-rw-r--r--qemu/tests/qapi-schema/indented-expr.out10
-rw-r--r--qemu/tests/qapi-schema/leading-comma-list.err1
-rw-r--r--qemu/tests/qapi-schema/leading-comma-list.exit1
-rw-r--r--qemu/tests/qapi-schema/leading-comma-list.json2
-rw-r--r--qemu/tests/qapi-schema/leading-comma-list.out0
-rw-r--r--qemu/tests/qapi-schema/leading-comma-object.err1
-rw-r--r--qemu/tests/qapi-schema/leading-comma-object.exit1
-rw-r--r--qemu/tests/qapi-schema/leading-comma-object.json2
-rw-r--r--qemu/tests/qapi-schema/leading-comma-object.out0
-rw-r--r--qemu/tests/qapi-schema/nested-struct-data.json3
-rw-r--r--qemu/tests/qapi-schema/nested-struct-returns.err1
-rw-r--r--qemu/tests/qapi-schema/nested-struct-returns.json3
-rw-r--r--qemu/tests/qapi-schema/qapi-schema-test.json100
-rw-r--r--qemu/tests/qapi-schema/qapi-schema-test.out266
-rw-r--r--qemu/tests/qapi-schema/reserved-command-q.err1
-rw-r--r--qemu/tests/qapi-schema/reserved-command-q.exit1
-rw-r--r--qemu/tests/qapi-schema/reserved-command-q.json5
-rw-r--r--qemu/tests/qapi-schema/reserved-command-q.out0
-rw-r--r--qemu/tests/qapi-schema/reserved-enum-q.err1
-rw-r--r--qemu/tests/qapi-schema/reserved-enum-q.exit1
-rw-r--r--qemu/tests/qapi-schema/reserved-enum-q.json4
-rw-r--r--qemu/tests/qapi-schema/reserved-enum-q.out0
-rw-r--r--qemu/tests/qapi-schema/reserved-member-has.err1
-rw-r--r--qemu/tests/qapi-schema/reserved-member-has.exit1
-rw-r--r--qemu/tests/qapi-schema/reserved-member-has.json5
-rw-r--r--qemu/tests/qapi-schema/reserved-member-has.out0
-rw-r--r--qemu/tests/qapi-schema/reserved-member-q.err1
-rw-r--r--qemu/tests/qapi-schema/reserved-member-q.exit1
-rw-r--r--qemu/tests/qapi-schema/reserved-member-q.json4
-rw-r--r--qemu/tests/qapi-schema/reserved-member-q.out0
-rw-r--r--qemu/tests/qapi-schema/reserved-member-u.err1
-rw-r--r--qemu/tests/qapi-schema/reserved-member-u.exit1
-rw-r--r--qemu/tests/qapi-schema/reserved-member-u.json7
-rw-r--r--qemu/tests/qapi-schema/reserved-member-u.out0
-rw-r--r--qemu/tests/qapi-schema/reserved-member-underscore.err1
-rw-r--r--qemu/tests/qapi-schema/reserved-member-underscore.exit1
-rw-r--r--qemu/tests/qapi-schema/reserved-member-underscore.json4
-rw-r--r--qemu/tests/qapi-schema/reserved-member-underscore.out0
-rw-r--r--qemu/tests/qapi-schema/reserved-type-kind.err1
-rw-r--r--qemu/tests/qapi-schema/reserved-type-kind.exit1
-rw-r--r--qemu/tests/qapi-schema/reserved-type-kind.json (renamed from qemu/tests/qapi-schema/enum-union-clash.json)2
-rw-r--r--qemu/tests/qapi-schema/reserved-type-kind.out0
-rw-r--r--qemu/tests/qapi-schema/reserved-type-list.err1
-rw-r--r--qemu/tests/qapi-schema/reserved-type-list.exit1
-rw-r--r--qemu/tests/qapi-schema/reserved-type-list.json5
-rw-r--r--qemu/tests/qapi-schema/reserved-type-list.out0
-rw-r--r--qemu/tests/qapi-schema/returns-dict.err1
-rw-r--r--qemu/tests/qapi-schema/returns-dict.exit1
-rw-r--r--qemu/tests/qapi-schema/returns-dict.json2
-rw-r--r--qemu/tests/qapi-schema/returns-dict.out0
-rw-r--r--qemu/tests/qapi-schema/returns-int.exit1
-rw-r--r--qemu/tests/qapi-schema/returns-int.json3
-rw-r--r--qemu/tests/qapi-schema/returns-int.out3
-rw-r--r--qemu/tests/qapi-schema/returns-whitelist.err2
-rw-r--r--qemu/tests/qapi-schema/struct-base-clash-deep.err2
-rw-r--r--qemu/tests/qapi-schema/struct-base-clash-deep.json5
-rw-r--r--qemu/tests/qapi-schema/struct-base-clash.err2
-rw-r--r--qemu/tests/qapi-schema/struct-base-clash.json3
-rw-r--r--qemu/tests/qapi-schema/struct-data-invalid.err1
-rw-r--r--qemu/tests/qapi-schema/struct-data-invalid.exit1
-rw-r--r--qemu/tests/qapi-schema/struct-data-invalid.json2
-rw-r--r--qemu/tests/qapi-schema/struct-data-invalid.out0
-rw-r--r--qemu/tests/qapi-schema/struct-member-invalid.err1
-rw-r--r--qemu/tests/qapi-schema/struct-member-invalid.exit1
-rw-r--r--qemu/tests/qapi-schema/struct-member-invalid.json2
-rw-r--r--qemu/tests/qapi-schema/struct-member-invalid.out0
-rw-r--r--qemu/tests/qapi-schema/test-qapi.py47
-rw-r--r--qemu/tests/qapi-schema/type-bypass-no-gen.err1
-rw-r--r--qemu/tests/qapi-schema/type-bypass-no-gen.json2
-rw-r--r--qemu/tests/qapi-schema/type-bypass.exit1
-rw-r--r--qemu/tests/qapi-schema/type-bypass.json2
-rw-r--r--qemu/tests/qapi-schema/type-bypass.out3
-rw-r--r--qemu/tests/qapi-schema/union-bad-branch.err1
-rw-r--r--qemu/tests/qapi-schema/union-bad-branch.json8
-rw-r--r--qemu/tests/qapi-schema/union-base-no-discriminator.err2
-rw-r--r--qemu/tests/qapi-schema/union-branch-case.err1
-rw-r--r--qemu/tests/qapi-schema/union-branch-case.exit1
-rw-r--r--qemu/tests/qapi-schema/union-branch-case.json2
-rw-r--r--qemu/tests/qapi-schema/union-branch-case.out0
-rw-r--r--qemu/tests/qapi-schema/union-clash-branches.err1
-rw-r--r--qemu/tests/qapi-schema/union-clash-branches.exit1
-rw-r--r--qemu/tests/qapi-schema/union-clash-branches.json5
-rw-r--r--qemu/tests/qapi-schema/union-clash-branches.out0
-rw-r--r--qemu/tests/qapi-schema/union-empty.err1
-rw-r--r--qemu/tests/qapi-schema/union-empty.exit1
-rw-r--r--qemu/tests/qapi-schema/union-empty.json2
-rw-r--r--qemu/tests/qapi-schema/union-empty.out0
-rw-r--r--qemu/tests/qapi-schema/union-invalid-base.err2
-rw-r--r--qemu/tests/qapi-schema/union-max.err1
-rw-r--r--qemu/tests/qapi-schema/union-max.json3
222 files changed, 554 insertions, 256 deletions
diff --git a/qemu/tests/qapi-schema/alternate-any.err b/qemu/tests/qapi-schema/alternate-any.err
new file mode 100644
index 000000000..aaa015473
--- /dev/null
+++ b/qemu/tests/qapi-schema/alternate-any.err
@@ -0,0 +1 @@
+tests/qapi-schema/alternate-any.json:2: Alternate 'Alt' member 'one' cannot use type 'any'
diff --git a/qemu/tests/qapi-schema/data-array-empty.exit b/qemu/tests/qapi-schema/alternate-any.exit
index d00491fd7..d00491fd7 100644
--- a/qemu/tests/qapi-schema/data-array-empty.exit
+++ b/qemu/tests/qapi-schema/alternate-any.exit
diff --git a/qemu/tests/qapi-schema/alternate-any.json b/qemu/tests/qapi-schema/alternate-any.json
new file mode 100644
index 000000000..e47a73a11
--- /dev/null
+++ b/qemu/tests/qapi-schema/alternate-any.json
@@ -0,0 +1,4 @@
+# we do not allow the 'any' type as an alternate branch
+{ 'alternate': 'Alt',
+ 'data': { 'one': 'any',
+ 'two': 'int' } }
diff --git a/qemu/tests/qapi-schema/alternate-good.err b/qemu/tests/qapi-schema/alternate-any.out
index e69de29bb..e69de29bb 100644
--- a/qemu/tests/qapi-schema/alternate-good.err
+++ b/qemu/tests/qapi-schema/alternate-any.out
diff --git a/qemu/tests/qapi-schema/alternate-clash.err b/qemu/tests/qapi-schema/alternate-clash.err
index 51bea3e27..604d8495e 100644
--- a/qemu/tests/qapi-schema/alternate-clash.err
+++ b/qemu/tests/qapi-schema/alternate-clash.err
@@ -1 +1 @@
-tests/qapi-schema/alternate-clash.json:2: Alternate 'Alt1' member 'ONE' clashes with 'one'
+tests/qapi-schema/alternate-clash.json:7: 'a_b' (branch of Alt1) collides with 'a-b' (branch of Alt1)
diff --git a/qemu/tests/qapi-schema/alternate-clash.json b/qemu/tests/qapi-schema/alternate-clash.json
index 39479353b..6d73bc527 100644
--- a/qemu/tests/qapi-schema/alternate-clash.json
+++ b/qemu/tests/qapi-schema/alternate-clash.json
@@ -1,3 +1,8 @@
-# we detect C enum collisions in an alternate
+# Alternate branch name collision
+# Reject an alternate that would result in a collision in generated C
+# names (this would try to generate two enum values 'ALT1_KIND_A_B').
+# TODO: In the future, if alternates are simplified to not generate
+# the implicit Alt1Kind enum, we would still have a collision with the
+# resulting C union trying to have two members named 'a_b'.
{ 'alternate': 'Alt1',
- 'data': { 'one': 'str', 'ONE': 'int' } }
+ 'data': { 'a-b': 'str', 'a_b': 'int' } }
diff --git a/qemu/tests/qapi-schema/alternate-empty.err b/qemu/tests/qapi-schema/alternate-empty.err
new file mode 100644
index 000000000..bb06c5bfe
--- /dev/null
+++ b/qemu/tests/qapi-schema/alternate-empty.err
@@ -0,0 +1 @@
+tests/qapi-schema/alternate-empty.json:2: Alternate 'Alt' should have at least two branches in 'data'
diff --git a/qemu/tests/qapi-schema/data-array-unknown.exit b/qemu/tests/qapi-schema/alternate-empty.exit
index d00491fd7..d00491fd7 100644
--- a/qemu/tests/qapi-schema/data-array-unknown.exit
+++ b/qemu/tests/qapi-schema/alternate-empty.exit
diff --git a/qemu/tests/qapi-schema/alternate-empty.json b/qemu/tests/qapi-schema/alternate-empty.json
new file mode 100644
index 000000000..fff15baf1
--- /dev/null
+++ b/qemu/tests/qapi-schema/alternate-empty.json
@@ -0,0 +1,2 @@
+# alternates must list at least two types to be useful
+{ 'alternate': 'Alt', 'data': { 'i': 'int' } }
diff --git a/qemu/tests/qapi-schema/data-array-empty.out b/qemu/tests/qapi-schema/alternate-empty.out
index e69de29bb..e69de29bb 100644
--- a/qemu/tests/qapi-schema/data-array-empty.out
+++ b/qemu/tests/qapi-schema/alternate-empty.out
diff --git a/qemu/tests/qapi-schema/alternate-good.exit b/qemu/tests/qapi-schema/alternate-good.exit
deleted file mode 100644
index 573541ac9..000000000
--- a/qemu/tests/qapi-schema/alternate-good.exit
+++ /dev/null
@@ -1 +0,0 @@
-0
diff --git a/qemu/tests/qapi-schema/alternate-good.json b/qemu/tests/qapi-schema/alternate-good.json
deleted file mode 100644
index 33717704c..000000000
--- a/qemu/tests/qapi-schema/alternate-good.json
+++ /dev/null
@@ -1,9 +0,0 @@
-# Working example of alternate
-{ 'struct': 'Data',
- 'data': { '*number': 'int', '*name': 'str' } }
-{ 'enum': 'Enum',
- 'data': [ 'hello', 'world' ] }
-{ 'alternate': 'Alt',
- 'data': { 'value': 'int',
- 'string': 'Enum',
- 'struct': 'Data' } }
diff --git a/qemu/tests/qapi-schema/alternate-good.out b/qemu/tests/qapi-schema/alternate-good.out
deleted file mode 100644
index 99848eefb..000000000
--- a/qemu/tests/qapi-schema/alternate-good.out
+++ /dev/null
@@ -1,6 +0,0 @@
-[OrderedDict([('struct', 'Data'), ('data', OrderedDict([('*number', 'int'), ('*name', 'str')]))]),
- OrderedDict([('enum', 'Enum'), ('data', ['hello', 'world'])]),
- OrderedDict([('alternate', 'Alt'), ('data', OrderedDict([('value', 'int'), ('string', 'Enum'), ('struct', 'Data')]))])]
-[{'enum_name': 'Enum', 'enum_values': ['hello', 'world']},
- {'enum_name': 'AltKind', 'enum_values': None}]
-[OrderedDict([('struct', 'Data'), ('data', OrderedDict([('*number', 'int'), ('*name', 'str')]))])]
diff --git a/qemu/tests/qapi-schema/alternate-nested.json b/qemu/tests/qapi-schema/alternate-nested.json
index c4233b9f3..8e2218649 100644
--- a/qemu/tests/qapi-schema/alternate-nested.json
+++ b/qemu/tests/qapi-schema/alternate-nested.json
@@ -2,4 +2,4 @@
{ 'alternate': 'Alt1',
'data': { 'name': 'str', 'value': 'int' } }
{ 'alternate': 'Alt2',
- 'data': { 'nested': 'Alt1' } }
+ 'data': { 'nested': 'Alt1', 'b': 'bool' } }
diff --git a/qemu/tests/qapi-schema/alternate-unknown.json b/qemu/tests/qapi-schema/alternate-unknown.json
index ad5c10302..08c80dced 100644
--- a/qemu/tests/qapi-schema/alternate-unknown.json
+++ b/qemu/tests/qapi-schema/alternate-unknown.json
@@ -1,3 +1,3 @@
# we reject an alternate with unknown type in branch
{ 'alternate': 'Alt',
- 'data': { 'unknown': 'MissingType' } }
+ 'data': { 'unknown': 'MissingType', 'i': 'int' } }
diff --git a/qemu/tests/qapi-schema/args-alternate.err b/qemu/tests/qapi-schema/args-alternate.err
new file mode 100644
index 000000000..3086eae56
--- /dev/null
+++ b/qemu/tests/qapi-schema/args-alternate.err
@@ -0,0 +1 @@
+tests/qapi-schema/args-alternate.json:3: 'data' for command 'oops' cannot use alternate type 'Alt'
diff --git a/qemu/tests/qapi-schema/data-int.exit b/qemu/tests/qapi-schema/args-alternate.exit
index d00491fd7..d00491fd7 100644
--- a/qemu/tests/qapi-schema/data-int.exit
+++ b/qemu/tests/qapi-schema/args-alternate.exit
diff --git a/qemu/tests/qapi-schema/args-alternate.json b/qemu/tests/qapi-schema/args-alternate.json
new file mode 100644
index 000000000..69e94d481
--- /dev/null
+++ b/qemu/tests/qapi-schema/args-alternate.json
@@ -0,0 +1,3 @@
+# we do not allow alternate arguments
+{ 'alternate': 'Alt', 'data': { 'case1': 'int', 'case2': 'str' } }
+{ 'command': 'oops', 'data': 'Alt' }
diff --git a/qemu/tests/qapi-schema/data-array-unknown.out b/qemu/tests/qapi-schema/args-alternate.out
index e69de29bb..e69de29bb 100644
--- a/qemu/tests/qapi-schema/data-array-unknown.out
+++ b/qemu/tests/qapi-schema/args-alternate.out
diff --git a/qemu/tests/qapi-schema/args-any.err b/qemu/tests/qapi-schema/args-any.err
new file mode 100644
index 000000000..bf9b5e073
--- /dev/null
+++ b/qemu/tests/qapi-schema/args-any.err
@@ -0,0 +1 @@
+tests/qapi-schema/args-any.json:2: 'data' for command 'oops' cannot use built-in type 'any'
diff --git a/qemu/tests/qapi-schema/data-member-array-bad.exit b/qemu/tests/qapi-schema/args-any.exit
index d00491fd7..d00491fd7 100644
--- a/qemu/tests/qapi-schema/data-member-array-bad.exit
+++ b/qemu/tests/qapi-schema/args-any.exit
diff --git a/qemu/tests/qapi-schema/args-any.json b/qemu/tests/qapi-schema/args-any.json
new file mode 100644
index 000000000..58fe5e470
--- /dev/null
+++ b/qemu/tests/qapi-schema/args-any.json
@@ -0,0 +1,2 @@
+# we do not allow an 'any' argument
+{ 'command': 'oops', 'data': 'any' }
diff --git a/qemu/tests/qapi-schema/data-int.out b/qemu/tests/qapi-schema/args-any.out
index e69de29bb..e69de29bb 100644
--- a/qemu/tests/qapi-schema/data-int.out
+++ b/qemu/tests/qapi-schema/args-any.out
diff --git a/qemu/tests/qapi-schema/data-array-empty.err b/qemu/tests/qapi-schema/args-array-empty.err
index f713f1489..cb7ed33b3 100644
--- a/qemu/tests/qapi-schema/data-array-empty.err
+++ b/qemu/tests/qapi-schema/args-array-empty.err
@@ -1 +1 @@
-tests/qapi-schema/data-array-empty.json:2: Member 'empty' of 'data' for command 'oops': array type must contain single type name
+tests/qapi-schema/args-array-empty.json:2: Member 'empty' of 'data' for command 'oops': array type must contain single type name
diff --git a/qemu/tests/qapi-schema/data-member-unknown.exit b/qemu/tests/qapi-schema/args-array-empty.exit
index d00491fd7..d00491fd7 100644
--- a/qemu/tests/qapi-schema/data-member-unknown.exit
+++ b/qemu/tests/qapi-schema/args-array-empty.exit
diff --git a/qemu/tests/qapi-schema/data-array-empty.json b/qemu/tests/qapi-schema/args-array-empty.json
index 652dcfb24..652dcfb24 100644
--- a/qemu/tests/qapi-schema/data-array-empty.json
+++ b/qemu/tests/qapi-schema/args-array-empty.json
diff --git a/qemu/tests/qapi-schema/data-member-array-bad.out b/qemu/tests/qapi-schema/args-array-empty.out
index e69de29bb..e69de29bb 100644
--- a/qemu/tests/qapi-schema/data-member-array-bad.out
+++ b/qemu/tests/qapi-schema/args-array-empty.out
diff --git a/qemu/tests/qapi-schema/args-array-unknown.err b/qemu/tests/qapi-schema/args-array-unknown.err
new file mode 100644
index 000000000..cd7a0f98d
--- /dev/null
+++ b/qemu/tests/qapi-schema/args-array-unknown.err
@@ -0,0 +1 @@
+tests/qapi-schema/args-array-unknown.json:2: Member 'array' of 'data' for command 'oops' uses unknown type 'NoSuchType'
diff --git a/qemu/tests/qapi-schema/data-unknown.exit b/qemu/tests/qapi-schema/args-array-unknown.exit
index d00491fd7..d00491fd7 100644
--- a/qemu/tests/qapi-schema/data-unknown.exit
+++ b/qemu/tests/qapi-schema/args-array-unknown.exit
diff --git a/qemu/tests/qapi-schema/data-array-unknown.json b/qemu/tests/qapi-schema/args-array-unknown.json
index 6f3e88331..6f3e88331 100644
--- a/qemu/tests/qapi-schema/data-array-unknown.json
+++ b/qemu/tests/qapi-schema/args-array-unknown.json
diff --git a/qemu/tests/qapi-schema/data-member-array.err b/qemu/tests/qapi-schema/args-array-unknown.out
index e69de29bb..e69de29bb 100644
--- a/qemu/tests/qapi-schema/data-member-array.err
+++ b/qemu/tests/qapi-schema/args-array-unknown.out
diff --git a/qemu/tests/qapi-schema/args-int.err b/qemu/tests/qapi-schema/args-int.err
new file mode 100644
index 000000000..dc1d2504f
--- /dev/null
+++ b/qemu/tests/qapi-schema/args-int.err
@@ -0,0 +1 @@
+tests/qapi-schema/args-int.json:2: 'data' for command 'oops' cannot use built-in type 'int'
diff --git a/qemu/tests/qapi-schema/enum-max-member.exit b/qemu/tests/qapi-schema/args-int.exit
index d00491fd7..d00491fd7 100644
--- a/qemu/tests/qapi-schema/enum-max-member.exit
+++ b/qemu/tests/qapi-schema/args-int.exit
diff --git a/qemu/tests/qapi-schema/data-int.json b/qemu/tests/qapi-schema/args-int.json
index a334d92e8..a334d92e8 100644
--- a/qemu/tests/qapi-schema/data-int.json
+++ b/qemu/tests/qapi-schema/args-int.json
diff --git a/qemu/tests/qapi-schema/data-member-unknown.out b/qemu/tests/qapi-schema/args-int.out
index e69de29bb..e69de29bb 100644
--- a/qemu/tests/qapi-schema/data-member-unknown.out
+++ b/qemu/tests/qapi-schema/args-int.out
diff --git a/qemu/tests/qapi-schema/args-invalid.err b/qemu/tests/qapi-schema/args-invalid.err
new file mode 100644
index 000000000..fe1e94975
--- /dev/null
+++ b/qemu/tests/qapi-schema/args-invalid.err
@@ -0,0 +1 @@
+tests/qapi-schema/args-invalid.json:1: 'data' for command 'foo' should be a dictionary or type name
diff --git a/qemu/tests/qapi-schema/enum-union-clash.exit b/qemu/tests/qapi-schema/args-invalid.exit
index d00491fd7..d00491fd7 100644
--- a/qemu/tests/qapi-schema/enum-union-clash.exit
+++ b/qemu/tests/qapi-schema/args-invalid.exit
diff --git a/qemu/tests/qapi-schema/args-invalid.json b/qemu/tests/qapi-schema/args-invalid.json
new file mode 100644
index 000000000..db0981341
--- /dev/null
+++ b/qemu/tests/qapi-schema/args-invalid.json
@@ -0,0 +1,2 @@
+{ 'command': 'foo',
+ 'data': false }
diff --git a/qemu/tests/qapi-schema/data-unknown.out b/qemu/tests/qapi-schema/args-invalid.out
index e69de29bb..e69de29bb 100644
--- a/qemu/tests/qapi-schema/data-unknown.out
+++ b/qemu/tests/qapi-schema/args-invalid.out
diff --git a/qemu/tests/qapi-schema/data-member-array-bad.err b/qemu/tests/qapi-schema/args-member-array-bad.err
index 2c072d598..881b4d954 100644
--- a/qemu/tests/qapi-schema/data-member-array-bad.err
+++ b/qemu/tests/qapi-schema/args-member-array-bad.err
@@ -1 +1 @@
-tests/qapi-schema/data-member-array-bad.json:2: Member 'member' of 'data' for command 'oops': array type must contain single type name
+tests/qapi-schema/args-member-array-bad.json:2: Member 'member' of 'data' for command 'oops': array type must contain single type name
diff --git a/qemu/tests/qapi-schema/event-max.exit b/qemu/tests/qapi-schema/args-member-array-bad.exit
index d00491fd7..d00491fd7 100644
--- a/qemu/tests/qapi-schema/event-max.exit
+++ b/qemu/tests/qapi-schema/args-member-array-bad.exit
diff --git a/qemu/tests/qapi-schema/data-member-array-bad.json b/qemu/tests/qapi-schema/args-member-array-bad.json
index b2ff144ec..b2ff144ec 100644
--- a/qemu/tests/qapi-schema/data-member-array-bad.json
+++ b/qemu/tests/qapi-schema/args-member-array-bad.json
diff --git a/qemu/tests/qapi-schema/enum-empty.err b/qemu/tests/qapi-schema/args-member-array-bad.out
index e69de29bb..e69de29bb 100644
--- a/qemu/tests/qapi-schema/enum-empty.err
+++ b/qemu/tests/qapi-schema/args-member-array-bad.out
diff --git a/qemu/tests/qapi-schema/args-member-case.err b/qemu/tests/qapi-schema/args-member-case.err
new file mode 100644
index 000000000..19c442660
--- /dev/null
+++ b/qemu/tests/qapi-schema/args-member-case.err
@@ -0,0 +1 @@
+tests/qapi-schema/args-member-case.json:2: 'Arg' (parameter of no-way-this-will-get-whitelisted) should not use uppercase
diff --git a/qemu/tests/qapi-schema/flat-union-base-star.exit b/qemu/tests/qapi-schema/args-member-case.exit
index d00491fd7..d00491fd7 100644
--- a/qemu/tests/qapi-schema/flat-union-base-star.exit
+++ b/qemu/tests/qapi-schema/args-member-case.exit
diff --git a/qemu/tests/qapi-schema/args-member-case.json b/qemu/tests/qapi-schema/args-member-case.json
new file mode 100644
index 000000000..93439bee8
--- /dev/null
+++ b/qemu/tests/qapi-schema/args-member-case.json
@@ -0,0 +1,2 @@
+# Member names should be 'lower-case' unless the struct/command is whitelisted
+{ 'command': 'no-way-this-will-get-whitelisted', 'data': { 'Arg': 'int' } }
diff --git a/qemu/tests/qapi-schema/enum-max-member.out b/qemu/tests/qapi-schema/args-member-case.out
index e69de29bb..e69de29bb 100644
--- a/qemu/tests/qapi-schema/enum-max-member.out
+++ b/qemu/tests/qapi-schema/args-member-case.out
diff --git a/qemu/tests/qapi-schema/args-member-unknown.err b/qemu/tests/qapi-schema/args-member-unknown.err
new file mode 100644
index 000000000..f6f82828c
--- /dev/null
+++ b/qemu/tests/qapi-schema/args-member-unknown.err
@@ -0,0 +1 @@
+tests/qapi-schema/args-member-unknown.json:2: Member 'member' of 'data' for command 'oops' uses unknown type 'NoSuchType'
diff --git a/qemu/tests/qapi-schema/flat-union-branch-clash.exit b/qemu/tests/qapi-schema/args-member-unknown.exit
index d00491fd7..d00491fd7 100644
--- a/qemu/tests/qapi-schema/flat-union-branch-clash.exit
+++ b/qemu/tests/qapi-schema/args-member-unknown.exit
diff --git a/qemu/tests/qapi-schema/data-member-unknown.json b/qemu/tests/qapi-schema/args-member-unknown.json
index 342a41ec9..342a41ec9 100644
--- a/qemu/tests/qapi-schema/data-member-unknown.json
+++ b/qemu/tests/qapi-schema/args-member-unknown.json
diff --git a/qemu/tests/qapi-schema/enum-union-clash.out b/qemu/tests/qapi-schema/args-member-unknown.out
index e69de29bb..e69de29bb 100644
--- a/qemu/tests/qapi-schema/enum-union-clash.out
+++ b/qemu/tests/qapi-schema/args-member-unknown.out
diff --git a/qemu/tests/qapi-schema/args-name-clash.err b/qemu/tests/qapi-schema/args-name-clash.err
new file mode 100644
index 000000000..d953e8d24
--- /dev/null
+++ b/qemu/tests/qapi-schema/args-name-clash.err
@@ -0,0 +1 @@
+tests/qapi-schema/args-name-clash.json:4: 'a_b' (parameter of oops) collides with 'a-b' (parameter of oops)
diff --git a/qemu/tests/qapi-schema/nested-struct-returns.exit b/qemu/tests/qapi-schema/args-name-clash.exit
index d00491fd7..d00491fd7 100644
--- a/qemu/tests/qapi-schema/nested-struct-returns.exit
+++ b/qemu/tests/qapi-schema/args-name-clash.exit
diff --git a/qemu/tests/qapi-schema/args-name-clash.json b/qemu/tests/qapi-schema/args-name-clash.json
new file mode 100644
index 000000000..61423cb89
--- /dev/null
+++ b/qemu/tests/qapi-schema/args-name-clash.json
@@ -0,0 +1,4 @@
+# C member name collision
+# Reject members that clash when mapped to C names (we would have two 'a_b'
+# members).
+{ 'command': 'oops', 'data': { 'a-b': 'str', 'a_b': 'str' } }
diff --git a/qemu/tests/qapi-schema/event-max.out b/qemu/tests/qapi-schema/args-name-clash.out
index e69de29bb..e69de29bb 100644
--- a/qemu/tests/qapi-schema/event-max.out
+++ b/qemu/tests/qapi-schema/args-name-clash.out
diff --git a/qemu/tests/qapi-schema/args-union.err b/qemu/tests/qapi-schema/args-union.err
new file mode 100644
index 000000000..1d693d74d
--- /dev/null
+++ b/qemu/tests/qapi-schema/args-union.err
@@ -0,0 +1 @@
+tests/qapi-schema/args-union.json:4: 'data' for command 'oops' cannot use union type 'Uni'
diff --git a/qemu/tests/qapi-schema/type-bypass-no-gen.exit b/qemu/tests/qapi-schema/args-union.exit
index d00491fd7..d00491fd7 100644
--- a/qemu/tests/qapi-schema/type-bypass-no-gen.exit
+++ b/qemu/tests/qapi-schema/args-union.exit
diff --git a/qemu/tests/qapi-schema/args-union.json b/qemu/tests/qapi-schema/args-union.json
new file mode 100644
index 000000000..7bdcbb7f0
--- /dev/null
+++ b/qemu/tests/qapi-schema/args-union.json
@@ -0,0 +1,4 @@
+# we do not allow union arguments
+# TODO should we support this?
+{ 'union': 'Uni', 'data': { 'case1': 'int', 'case2': 'str' } }
+{ 'command': 'oops', 'data': 'Uni' }
diff --git a/qemu/tests/qapi-schema/flat-union-base-star.out b/qemu/tests/qapi-schema/args-union.out
index e69de29bb..e69de29bb 100644
--- a/qemu/tests/qapi-schema/flat-union-base-star.out
+++ b/qemu/tests/qapi-schema/args-union.out
diff --git a/qemu/tests/qapi-schema/args-unknown.err b/qemu/tests/qapi-schema/args-unknown.err
new file mode 100644
index 000000000..4d91ec869
--- /dev/null
+++ b/qemu/tests/qapi-schema/args-unknown.err
@@ -0,0 +1 @@
+tests/qapi-schema/args-unknown.json:2: 'data' for command 'oops' uses unknown type 'NoSuchType'
diff --git a/qemu/tests/qapi-schema/union-bad-branch.exit b/qemu/tests/qapi-schema/args-unknown.exit
index d00491fd7..d00491fd7 100644
--- a/qemu/tests/qapi-schema/union-bad-branch.exit
+++ b/qemu/tests/qapi-schema/args-unknown.exit
diff --git a/qemu/tests/qapi-schema/data-unknown.json b/qemu/tests/qapi-schema/args-unknown.json
index 32aba43b3..32aba43b3 100644
--- a/qemu/tests/qapi-schema/data-unknown.json
+++ b/qemu/tests/qapi-schema/args-unknown.json
diff --git a/qemu/tests/qapi-schema/flat-union-branch-clash.out b/qemu/tests/qapi-schema/args-unknown.out
index e69de29bb..e69de29bb 100644
--- a/qemu/tests/qapi-schema/flat-union-branch-clash.out
+++ b/qemu/tests/qapi-schema/args-unknown.out
diff --git a/qemu/tests/qapi-schema/base-cycle-direct.err b/qemu/tests/qapi-schema/base-cycle-direct.err
new file mode 100644
index 000000000..9c68f6543
--- /dev/null
+++ b/qemu/tests/qapi-schema/base-cycle-direct.err
@@ -0,0 +1 @@
+tests/qapi-schema/base-cycle-direct.json:2: Object Loopy contains itself
diff --git a/qemu/tests/qapi-schema/union-max.exit b/qemu/tests/qapi-schema/base-cycle-direct.exit
index d00491fd7..d00491fd7 100644
--- a/qemu/tests/qapi-schema/union-max.exit
+++ b/qemu/tests/qapi-schema/base-cycle-direct.exit
diff --git a/qemu/tests/qapi-schema/base-cycle-direct.json b/qemu/tests/qapi-schema/base-cycle-direct.json
new file mode 100644
index 000000000..4fc66d051
--- /dev/null
+++ b/qemu/tests/qapi-schema/base-cycle-direct.json
@@ -0,0 +1,2 @@
+# we reject a loop in base classes
+{ 'struct': 'Loopy', 'base': 'Loopy', 'data': {} }
diff --git a/qemu/tests/qapi-schema/flat-union-reverse-define.err b/qemu/tests/qapi-schema/base-cycle-direct.out
index e69de29bb..e69de29bb 100644
--- a/qemu/tests/qapi-schema/flat-union-reverse-define.err
+++ b/qemu/tests/qapi-schema/base-cycle-direct.out
diff --git a/qemu/tests/qapi-schema/base-cycle-indirect.err b/qemu/tests/qapi-schema/base-cycle-indirect.err
new file mode 100644
index 000000000..fc92fe47f
--- /dev/null
+++ b/qemu/tests/qapi-schema/base-cycle-indirect.err
@@ -0,0 +1 @@
+tests/qapi-schema/base-cycle-indirect.json:2: Object Base1 contains itself
diff --git a/qemu/tests/qapi-schema/base-cycle-indirect.exit b/qemu/tests/qapi-schema/base-cycle-indirect.exit
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/qemu/tests/qapi-schema/base-cycle-indirect.exit
@@ -0,0 +1 @@
+1
diff --git a/qemu/tests/qapi-schema/base-cycle-indirect.json b/qemu/tests/qapi-schema/base-cycle-indirect.json
new file mode 100644
index 000000000..28667721a
--- /dev/null
+++ b/qemu/tests/qapi-schema/base-cycle-indirect.json
@@ -0,0 +1,3 @@
+# we reject a loop in base classes
+{ 'struct': 'Base1', 'base': 'Base2', 'data': {} }
+{ 'struct': 'Base2', 'base': 'Base1', 'data': {} }
diff --git a/qemu/tests/qapi-schema/nested-struct-returns.out b/qemu/tests/qapi-schema/base-cycle-indirect.out
index e69de29bb..e69de29bb 100644
--- a/qemu/tests/qapi-schema/nested-struct-returns.out
+++ b/qemu/tests/qapi-schema/base-cycle-indirect.out
diff --git a/qemu/tests/qapi-schema/command-int.json b/qemu/tests/qapi-schema/command-int.json
index c90d408ab..9a62554fc 100644
--- a/qemu/tests/qapi-schema/command-int.json
+++ b/qemu/tests/qapi-schema/command-int.json
@@ -1,3 +1,2 @@
# we reject collisions between commands and types
-{ 'command': 'int', 'data': { 'character': 'str' },
- 'returns': { 'value': 'int' } }
+{ 'command': 'int', 'data': { 'character': 'str' } }
diff --git a/qemu/tests/qapi-schema/comments.out b/qemu/tests/qapi-schema/comments.out
index 4ce3dcf12..5d7c13cad 100644
--- a/qemu/tests/qapi-schema/comments.out
+++ b/qemu/tests/qapi-schema/comments.out
@@ -1,3 +1,4 @@
-[OrderedDict([('enum', 'Status'), ('data', ['good', 'bad', 'ugly'])])]
-[{'enum_name': 'Status', 'enum_values': ['good', 'bad', 'ugly']}]
-[]
+enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+ prefix QTYPE
+enum Status ['good', 'bad', 'ugly']
+object q_empty
diff --git a/qemu/tests/qapi-schema/data-array-unknown.err b/qemu/tests/qapi-schema/data-array-unknown.err
deleted file mode 100644
index 8b731bbcc..000000000
--- a/qemu/tests/qapi-schema/data-array-unknown.err
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/data-array-unknown.json:2: Member 'array' of 'data' for command 'oops' uses unknown type 'array of NoSuchType'
diff --git a/qemu/tests/qapi-schema/data-int.err b/qemu/tests/qapi-schema/data-int.err
deleted file mode 100644
index 1a9b077c0..000000000
--- a/qemu/tests/qapi-schema/data-int.err
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/data-int.json:2: 'data' for command 'oops' cannot use built-in type 'int'
diff --git a/qemu/tests/qapi-schema/data-member-array.exit b/qemu/tests/qapi-schema/data-member-array.exit
deleted file mode 100644
index 573541ac9..000000000
--- a/qemu/tests/qapi-schema/data-member-array.exit
+++ /dev/null
@@ -1 +0,0 @@
-0
diff --git a/qemu/tests/qapi-schema/data-member-array.json b/qemu/tests/qapi-schema/data-member-array.json
deleted file mode 100644
index e6f7f5da1..000000000
--- a/qemu/tests/qapi-schema/data-member-array.json
+++ /dev/null
@@ -1,4 +0,0 @@
-# valid array members
-{ 'enum': 'abc', 'data': [ 'a', 'b', 'c' ] }
-{ 'struct': 'def', 'data': { 'array': [ 'abc' ] } }
-{ 'command': 'okay', 'data': { 'member1': [ 'int' ], 'member2': [ 'def' ] } }
diff --git a/qemu/tests/qapi-schema/data-member-array.out b/qemu/tests/qapi-schema/data-member-array.out
deleted file mode 100644
index c39fa2548..000000000
--- a/qemu/tests/qapi-schema/data-member-array.out
+++ /dev/null
@@ -1,5 +0,0 @@
-[OrderedDict([('enum', 'abc'), ('data', ['a', 'b', 'c'])]),
- OrderedDict([('struct', 'def'), ('data', OrderedDict([('array', ['abc'])]))]),
- OrderedDict([('command', 'okay'), ('data', OrderedDict([('member1', ['int']), ('member2', ['def'])]))])]
-[{'enum_name': 'abc', 'enum_values': ['a', 'b', 'c']}]
-[OrderedDict([('struct', 'def'), ('data', OrderedDict([('array', ['abc'])]))])]
diff --git a/qemu/tests/qapi-schema/data-member-unknown.err b/qemu/tests/qapi-schema/data-member-unknown.err
deleted file mode 100644
index ab905db80..000000000
--- a/qemu/tests/qapi-schema/data-member-unknown.err
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/data-member-unknown.json:2: Member 'member' of 'data' for command 'oops' uses unknown type 'NoSuchType'
diff --git a/qemu/tests/qapi-schema/data-unknown.err b/qemu/tests/qapi-schema/data-unknown.err
deleted file mode 100644
index 5b07277a9..000000000
--- a/qemu/tests/qapi-schema/data-unknown.err
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/data-unknown.json:2: 'data' for command 'oops' uses unknown type 'NoSuchType'
diff --git a/qemu/tests/qapi-schema/duplicate-key.err b/qemu/tests/qapi-schema/duplicate-key.err
index 768b276f8..6d02f8353 100644
--- a/qemu/tests/qapi-schema/duplicate-key.err
+++ b/qemu/tests/qapi-schema/duplicate-key.err
@@ -1 +1 @@
-tests/qapi-schema/duplicate-key.json:2:10: Duplicate key "key"
+tests/qapi-schema/duplicate-key.json:3:10: Duplicate key "key"
diff --git a/qemu/tests/qapi-schema/duplicate-key.json b/qemu/tests/qapi-schema/duplicate-key.json
index 1b55d8810..14ac0e8a4 100644
--- a/qemu/tests/qapi-schema/duplicate-key.json
+++ b/qemu/tests/qapi-schema/duplicate-key.json
@@ -1,2 +1,3 @@
+# QAPI cannot include the same key more than once in any {}
{ 'key': 'value',
'key': 'value' }
diff --git a/qemu/tests/qapi-schema/empty.out b/qemu/tests/qapi-schema/empty.out
index b7f89a45c..8a5b03442 100644
--- a/qemu/tests/qapi-schema/empty.out
+++ b/qemu/tests/qapi-schema/empty.out
@@ -1,3 +1,3 @@
-[]
-[]
-[]
+enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+ prefix QTYPE
+object q_empty
diff --git a/qemu/tests/qapi-schema/enum-bad-prefix.err b/qemu/tests/qapi-schema/enum-bad-prefix.err
new file mode 100644
index 000000000..399f5f7af
--- /dev/null
+++ b/qemu/tests/qapi-schema/enum-bad-prefix.err
@@ -0,0 +1 @@
+tests/qapi-schema/enum-bad-prefix.json:2: Enum 'MyEnum' requires a string for 'prefix'
diff --git a/qemu/tests/qapi-schema/enum-bad-prefix.exit b/qemu/tests/qapi-schema/enum-bad-prefix.exit
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/qemu/tests/qapi-schema/enum-bad-prefix.exit
@@ -0,0 +1 @@
+1
diff --git a/qemu/tests/qapi-schema/enum-bad-prefix.json b/qemu/tests/qapi-schema/enum-bad-prefix.json
new file mode 100644
index 000000000..996f628f6
--- /dev/null
+++ b/qemu/tests/qapi-schema/enum-bad-prefix.json
@@ -0,0 +1,2 @@
+# The prefix must be a string type
+{ 'enum': 'MyEnum', 'data': [ 'one' ], 'prefix': [ 'fish' ] }
diff --git a/qemu/tests/qapi-schema/returns-int.err b/qemu/tests/qapi-schema/enum-bad-prefix.out
index e69de29bb..e69de29bb 100644
--- a/qemu/tests/qapi-schema/returns-int.err
+++ b/qemu/tests/qapi-schema/enum-bad-prefix.out
diff --git a/qemu/tests/qapi-schema/enum-clash-member.err b/qemu/tests/qapi-schema/enum-clash-member.err
index 48bd1360e..5403c7850 100644
--- a/qemu/tests/qapi-schema/enum-clash-member.err
+++ b/qemu/tests/qapi-schema/enum-clash-member.err
@@ -1 +1 @@
-tests/qapi-schema/enum-clash-member.json:2: Enum 'MyEnum' member 'ONE' clashes with 'one'
+tests/qapi-schema/enum-clash-member.json:2: 'one_two' (member of MyEnum) collides with 'one-two' (member of MyEnum)
diff --git a/qemu/tests/qapi-schema/enum-clash-member.json b/qemu/tests/qapi-schema/enum-clash-member.json
index b7dc02a28..b6928b8bf 100644
--- a/qemu/tests/qapi-schema/enum-clash-member.json
+++ b/qemu/tests/qapi-schema/enum-clash-member.json
@@ -1,2 +1,2 @@
# we reject enums where members will clash when mapped to C enum
-{ 'enum': 'MyEnum', 'data': [ 'one', 'ONE' ] }
+{ 'enum': 'MyEnum', 'data': [ 'one-two', 'one_two' ] }
diff --git a/qemu/tests/qapi-schema/enum-empty.exit b/qemu/tests/qapi-schema/enum-empty.exit
deleted file mode 100644
index 573541ac9..000000000
--- a/qemu/tests/qapi-schema/enum-empty.exit
+++ /dev/null
@@ -1 +0,0 @@
-0
diff --git a/qemu/tests/qapi-schema/enum-empty.json b/qemu/tests/qapi-schema/enum-empty.json
deleted file mode 100644
index 40d4e85a2..000000000
--- a/qemu/tests/qapi-schema/enum-empty.json
+++ /dev/null
@@ -1,2 +0,0 @@
-# An empty enum, although unusual, is currently acceptable
-{ 'enum': 'MyEnum', 'data': [ ] }
diff --git a/qemu/tests/qapi-schema/enum-empty.out b/qemu/tests/qapi-schema/enum-empty.out
deleted file mode 100644
index 3b75c1613..000000000
--- a/qemu/tests/qapi-schema/enum-empty.out
+++ /dev/null
@@ -1,3 +0,0 @@
-[OrderedDict([('enum', 'MyEnum'), ('data', [])])]
-[{'enum_name': 'MyEnum', 'enum_values': []}]
-[]
diff --git a/qemu/tests/qapi-schema/enum-max-member.err b/qemu/tests/qapi-schema/enum-max-member.err
deleted file mode 100644
index f77837fb4..000000000
--- a/qemu/tests/qapi-schema/enum-max-member.err
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/enum-max-member.json:3: Enum 'MyEnum' member 'max' clashes with '(automatic)'
diff --git a/qemu/tests/qapi-schema/enum-max-member.json b/qemu/tests/qapi-schema/enum-max-member.json
deleted file mode 100644
index 4bcda0bf0..000000000
--- a/qemu/tests/qapi-schema/enum-max-member.json
+++ /dev/null
@@ -1,3 +0,0 @@
-# we reject user-supplied 'max' for clashing with implicit enum end
-# TODO: should we instead munge the implicit value to avoid the clash?
-{ 'enum': 'MyEnum', 'data': [ 'max' ] }
diff --git a/qemu/tests/qapi-schema/enum-member-case.err b/qemu/tests/qapi-schema/enum-member-case.err
new file mode 100644
index 000000000..b652e9aac
--- /dev/null
+++ b/qemu/tests/qapi-schema/enum-member-case.err
@@ -0,0 +1 @@
+tests/qapi-schema/enum-member-case.json:3: 'Value' (member of NoWayThisWillGetWhitelisted) should not use uppercase
diff --git a/qemu/tests/qapi-schema/enum-member-case.exit b/qemu/tests/qapi-schema/enum-member-case.exit
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/qemu/tests/qapi-schema/enum-member-case.exit
@@ -0,0 +1 @@
+1
diff --git a/qemu/tests/qapi-schema/enum-member-case.json b/qemu/tests/qapi-schema/enum-member-case.json
new file mode 100644
index 000000000..2096b350c
--- /dev/null
+++ b/qemu/tests/qapi-schema/enum-member-case.json
@@ -0,0 +1,3 @@
+# Member names should be 'lower-case' unless the enum is whitelisted
+{ 'enum': 'UuidInfo', 'data': [ 'Value' ] } # UuidInfo is whitelisted
+{ 'enum': 'NoWayThisWillGetWhitelisted', 'data': [ 'Value' ] }
diff --git a/qemu/tests/qapi-schema/type-bypass-no-gen.out b/qemu/tests/qapi-schema/enum-member-case.out
index e69de29bb..e69de29bb 100644
--- a/qemu/tests/qapi-schema/type-bypass-no-gen.out
+++ b/qemu/tests/qapi-schema/enum-member-case.out
diff --git a/qemu/tests/qapi-schema/enum-union-clash.err b/qemu/tests/qapi-schema/enum-union-clash.err
deleted file mode 100644
index c04e1a806..000000000
--- a/qemu/tests/qapi-schema/enum-union-clash.err
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/enum-union-clash.json:2: enum 'UnionKind' should not end in 'Kind'
diff --git a/qemu/tests/qapi-schema/event-case.out b/qemu/tests/qapi-schema/event-case.out
index 3764bc781..b6b4134a8 100644
--- a/qemu/tests/qapi-schema/event-case.out
+++ b/qemu/tests/qapi-schema/event-case.out
@@ -1,3 +1,4 @@
-[OrderedDict([('event', 'oops')])]
-[]
-[]
+enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+ prefix QTYPE
+event oops None
+object q_empty
diff --git a/qemu/tests/qapi-schema/event-max.err b/qemu/tests/qapi-schema/event-max.err
deleted file mode 100644
index c85653437..000000000
--- a/qemu/tests/qapi-schema/event-max.err
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/event-max.json:2: Event name 'MAX' cannot be created
diff --git a/qemu/tests/qapi-schema/event-max.json b/qemu/tests/qapi-schema/event-max.json
deleted file mode 100644
index f3d7de2a3..000000000
--- a/qemu/tests/qapi-schema/event-max.json
+++ /dev/null
@@ -1,2 +0,0 @@
-# an event named 'MAX' would conflict with implicit C enum
-{ 'event': 'MAX' }
diff --git a/qemu/tests/qapi-schema/flat-union-bad-base.err b/qemu/tests/qapi-schema/flat-union-bad-base.err
index f9c31b2bf..bee24a217 100644
--- a/qemu/tests/qapi-schema/flat-union-bad-base.err
+++ b/qemu/tests/qapi-schema/flat-union-bad-base.err
@@ -1 +1 @@
-tests/qapi-schema/flat-union-bad-base.json:9: Flat union 'TestUnion' must have a string base field
+tests/qapi-schema/flat-union-bad-base.json:8: 'string' (member of TestTypeA) collides with 'string' (base of TestUnion)
diff --git a/qemu/tests/qapi-schema/flat-union-bad-base.json b/qemu/tests/qapi-schema/flat-union-bad-base.json
index e2e622bb6..74dd42170 100644
--- a/qemu/tests/qapi-schema/flat-union-bad-base.json
+++ b/qemu/tests/qapi-schema/flat-union-bad-base.json
@@ -1,5 +1,4 @@
-# we require the base to be an existing struct
-# TODO: should we allow an anonymous inline base type?
+# we allow anonymous base, but enforce no duplicate keys
{ 'enum': 'TestEnum',
'data': [ 'value1', 'value2' ] }
{ 'struct': 'TestTypeA',
@@ -7,7 +6,7 @@
{ 'struct': 'TestTypeB',
'data': { 'integer': 'int' } }
{ 'union': 'TestUnion',
- 'base': { 'enum1': 'TestEnum', 'kind': 'str' },
+ 'base': { 'enum1': 'TestEnum', 'string': 'str' },
'discriminator': 'enum1',
'data': { 'value1': 'TestTypeA',
'value2': 'TestTypeB' } }
diff --git a/qemu/tests/qapi-schema/flat-union-base-any.err b/qemu/tests/qapi-schema/flat-union-base-any.err
new file mode 100644
index 000000000..646f1c9cd
--- /dev/null
+++ b/qemu/tests/qapi-schema/flat-union-base-any.err
@@ -0,0 +1 @@
+tests/qapi-schema/flat-union-base-any.json:8: 'base' for union 'TestUnion' cannot use built-in type 'any'
diff --git a/qemu/tests/qapi-schema/flat-union-base-any.exit b/qemu/tests/qapi-schema/flat-union-base-any.exit
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/qemu/tests/qapi-schema/flat-union-base-any.exit
@@ -0,0 +1 @@
+1
diff --git a/qemu/tests/qapi-schema/flat-union-base-star.json b/qemu/tests/qapi-schema/flat-union-base-any.json
index 5099439a9..fe66b713e 100644
--- a/qemu/tests/qapi-schema/flat-union-base-star.json
+++ b/qemu/tests/qapi-schema/flat-union-base-any.json
@@ -6,7 +6,7 @@
{ 'struct': 'TestTypeB',
'data': { 'integer': 'int' } }
{ 'union': 'TestUnion',
- 'base': '**',
+ 'base': 'any',
'discriminator': 'enum1',
'data': { 'value1': 'TestTypeA',
'value2': 'TestTypeB' } }
diff --git a/qemu/tests/qapi-schema/type-bypass.err b/qemu/tests/qapi-schema/flat-union-base-any.out
index e69de29bb..e69de29bb 100644
--- a/qemu/tests/qapi-schema/type-bypass.err
+++ b/qemu/tests/qapi-schema/flat-union-base-any.out
diff --git a/qemu/tests/qapi-schema/flat-union-base-star.err b/qemu/tests/qapi-schema/flat-union-base-star.err
deleted file mode 100644
index b7748f08b..000000000
--- a/qemu/tests/qapi-schema/flat-union-base-star.err
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/flat-union-base-star.json:8: Base '**' is not a valid struct
diff --git a/qemu/tests/qapi-schema/flat-union-base-union.err b/qemu/tests/qapi-schema/flat-union-base-union.err
index ede9859a3..f138395e4 100644
--- a/qemu/tests/qapi-schema/flat-union-base-union.err
+++ b/qemu/tests/qapi-schema/flat-union-base-union.err
@@ -1 +1 @@
-tests/qapi-schema/flat-union-base-union.json:11: Base 'UnionBase' is not a valid struct
+tests/qapi-schema/flat-union-base-union.json:14: 'base' for union 'TestUnion' cannot use union type 'UnionBase'
diff --git a/qemu/tests/qapi-schema/flat-union-base-union.json b/qemu/tests/qapi-schema/flat-union-base-union.json
index 6a8ea687a..98b4eba18 100644
--- a/qemu/tests/qapi-schema/flat-union-base-union.json
+++ b/qemu/tests/qapi-schema/flat-union-base-union.json
@@ -1,4 +1,7 @@
-# we require the base to be a struct
+# For now, we require the base to be a struct without variants
+# TODO: It would be possible to allow a union as a base, as long as all
+# permutations of QMP names exposed by base do not clash with any QMP
+# member names added by local variants.
{ 'enum': 'TestEnum',
'data': [ 'value1', 'value2' ] }
{ 'struct': 'TestTypeA',
diff --git a/qemu/tests/qapi-schema/flat-union-branch-clash.err b/qemu/tests/qapi-schema/flat-union-branch-clash.err
deleted file mode 100644
index f11276688..000000000
--- a/qemu/tests/qapi-schema/flat-union-branch-clash.err
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/flat-union-branch-clash.json:10: Member name 'name' of branch 'value1' clashes with base 'Base'
diff --git a/qemu/tests/qapi-schema/flat-union-clash-member.err b/qemu/tests/qapi-schema/flat-union-clash-member.err
new file mode 100644
index 000000000..2adf69755
--- /dev/null
+++ b/qemu/tests/qapi-schema/flat-union-clash-member.err
@@ -0,0 +1 @@
+tests/qapi-schema/flat-union-clash-member.json:11: 'name' (member of Branch1) collides with 'name' (member of Base)
diff --git a/qemu/tests/qapi-schema/flat-union-clash-member.exit b/qemu/tests/qapi-schema/flat-union-clash-member.exit
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/qemu/tests/qapi-schema/flat-union-clash-member.exit
@@ -0,0 +1 @@
+1
diff --git a/qemu/tests/qapi-schema/flat-union-branch-clash.json b/qemu/tests/qapi-schema/flat-union-clash-member.json
index 8fb054f00..9efc7719b 100644
--- a/qemu/tests/qapi-schema/flat-union-branch-clash.json
+++ b/qemu/tests/qapi-schema/flat-union-clash-member.json
@@ -1,4 +1,5 @@
-# we check for no duplicate keys between branches and base
+# We check for no duplicate keys between branch members and base
+# base's member 'name' clashes with Branch1's
{ 'enum': 'TestEnum',
'data': [ 'value1', 'value2' ] }
{ 'struct': 'Base',
diff --git a/qemu/tests/qapi-schema/union-bad-branch.out b/qemu/tests/qapi-schema/flat-union-clash-member.out
index e69de29bb..e69de29bb 100644
--- a/qemu/tests/qapi-schema/union-bad-branch.out
+++ b/qemu/tests/qapi-schema/flat-union-clash-member.out
diff --git a/qemu/tests/qapi-schema/flat-union-empty.err b/qemu/tests/qapi-schema/flat-union-empty.err
new file mode 100644
index 000000000..15754f54e
--- /dev/null
+++ b/qemu/tests/qapi-schema/flat-union-empty.err
@@ -0,0 +1 @@
+tests/qapi-schema/flat-union-empty.json:4: Union 'Union' cannot have empty 'data'
diff --git a/qemu/tests/qapi-schema/flat-union-empty.exit b/qemu/tests/qapi-schema/flat-union-empty.exit
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/qemu/tests/qapi-schema/flat-union-empty.exit
@@ -0,0 +1 @@
+1
diff --git a/qemu/tests/qapi-schema/flat-union-empty.json b/qemu/tests/qapi-schema/flat-union-empty.json
new file mode 100644
index 000000000..77f1d9abf
--- /dev/null
+++ b/qemu/tests/qapi-schema/flat-union-empty.json
@@ -0,0 +1,4 @@
+# flat unions cannot be empty
+{ 'enum': 'Empty', 'data': [ ] }
+{ 'struct': 'Base', 'data': { 'type': 'Empty' } }
+{ 'union': 'Union', 'base': 'Base', 'discriminator': 'type', 'data': { } }
diff --git a/qemu/tests/qapi-schema/union-max.out b/qemu/tests/qapi-schema/flat-union-empty.out
index e69de29bb..e69de29bb 100644
--- a/qemu/tests/qapi-schema/union-max.out
+++ b/qemu/tests/qapi-schema/flat-union-empty.out
diff --git a/qemu/tests/qapi-schema/flat-union-inline.err b/qemu/tests/qapi-schema/flat-union-inline.err
index ec586277b..2333358d2 100644
--- a/qemu/tests/qapi-schema/flat-union-inline.err
+++ b/qemu/tests/qapi-schema/flat-union-inline.err
@@ -1 +1 @@
-tests/qapi-schema/flat-union-inline.json:7: Flat union 'TestUnion' must have a string base field
+tests/qapi-schema/flat-union-inline.json:7: Member 'value1' of union 'TestUnion' should be a type name
diff --git a/qemu/tests/qapi-schema/flat-union-inline.json b/qemu/tests/qapi-schema/flat-union-inline.json
index 6bfdd6581..62c7cda61 100644
--- a/qemu/tests/qapi-schema/flat-union-inline.json
+++ b/qemu/tests/qapi-schema/flat-union-inline.json
@@ -1,11 +1,11 @@
# we require branches to be a struct name
-# TODO: should we allow anonymous inline types?
+# TODO: should we allow anonymous inline branch types?
{ 'enum': 'TestEnum',
'data': [ 'value1', 'value2' ] }
{ 'struct': 'Base',
'data': { 'enum1': 'TestEnum', 'kind': 'str' } }
{ 'union': 'TestUnion',
- 'base': { 'enum1': 'TestEnum', 'kind': 'str' },
+ 'base': 'Base',
'discriminator': 'enum1',
'data': { 'value1': { 'string': 'str' },
'value2': { 'integer': 'int' } } }
diff --git a/qemu/tests/qapi-schema/flat-union-no-base.err b/qemu/tests/qapi-schema/flat-union-no-base.err
index bb3f70874..841c93b55 100644
--- a/qemu/tests/qapi-schema/flat-union-no-base.err
+++ b/qemu/tests/qapi-schema/flat-union-no-base.err
@@ -1 +1 @@
-tests/qapi-schema/flat-union-no-base.json:9: Flat union 'TestUnion' must have a string base field
+tests/qapi-schema/flat-union-no-base.json:9: Flat union 'TestUnion' must have a base
diff --git a/qemu/tests/qapi-schema/flat-union-reverse-define.exit b/qemu/tests/qapi-schema/flat-union-reverse-define.exit
deleted file mode 100644
index 573541ac9..000000000
--- a/qemu/tests/qapi-schema/flat-union-reverse-define.exit
+++ /dev/null
@@ -1 +0,0 @@
-0
diff --git a/qemu/tests/qapi-schema/flat-union-reverse-define.json b/qemu/tests/qapi-schema/flat-union-reverse-define.json
deleted file mode 100644
index 648bbfe2b..000000000
--- a/qemu/tests/qapi-schema/flat-union-reverse-define.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{ 'union': 'TestUnion',
- 'base': 'TestBase',
- 'discriminator': 'enum1',
- 'data': { 'value1': 'TestTypeA',
- 'value2': 'TestTypeB' } }
-
-{ 'struct': 'TestBase',
- 'data': { 'enum1': 'TestEnum' } }
-
-{ 'enum': 'TestEnum',
- 'data': [ 'value1', 'value2' ] }
-
-{ 'struct': 'TestTypeA',
- 'data': { 'string': 'str' } }
-
-{ 'struct': 'TestTypeB',
- 'data': { 'integer': 'int' } }
diff --git a/qemu/tests/qapi-schema/flat-union-reverse-define.out b/qemu/tests/qapi-schema/flat-union-reverse-define.out
deleted file mode 100644
index 1ed7b8a51..000000000
--- a/qemu/tests/qapi-schema/flat-union-reverse-define.out
+++ /dev/null
@@ -1,9 +0,0 @@
-[OrderedDict([('union', 'TestUnion'), ('base', 'TestBase'), ('discriminator', 'enum1'), ('data', OrderedDict([('value1', 'TestTypeA'), ('value2', 'TestTypeB')]))]),
- OrderedDict([('struct', 'TestBase'), ('data', OrderedDict([('enum1', 'TestEnum')]))]),
- OrderedDict([('enum', 'TestEnum'), ('data', ['value1', 'value2'])]),
- OrderedDict([('struct', 'TestTypeA'), ('data', OrderedDict([('string', 'str')]))]),
- OrderedDict([('struct', 'TestTypeB'), ('data', OrderedDict([('integer', 'int')]))])]
-[{'enum_name': 'TestEnum', 'enum_values': ['value1', 'value2']}]
-[OrderedDict([('struct', 'TestBase'), ('data', OrderedDict([('enum1', 'TestEnum')]))]),
- OrderedDict([('struct', 'TestTypeA'), ('data', OrderedDict([('string', 'str')]))]),
- OrderedDict([('struct', 'TestTypeB'), ('data', OrderedDict([('integer', 'int')]))])]
diff --git a/qemu/tests/qapi-schema/ident-with-escape.out b/qemu/tests/qapi-schema/ident-with-escape.out
index 402843081..382ce2fa2 100644
--- a/qemu/tests/qapi-schema/ident-with-escape.out
+++ b/qemu/tests/qapi-schema/ident-with-escape.out
@@ -1,3 +1,7 @@
-[OrderedDict([('command', 'fooA'), ('data', OrderedDict([('bar1', 'str')]))])]
-[]
-[]
+enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+ prefix QTYPE
+command fooA q_obj_fooA-arg -> None
+ gen=True success_response=True
+object q_empty
+object q_obj_fooA-arg
+ member bar1: str optional=False
diff --git a/qemu/tests/qapi-schema/include-non-file.err b/qemu/tests/qapi-schema/include-non-file.err
index 9658c7880..faae1eacf 100644
--- a/qemu/tests/qapi-schema/include-non-file.err
+++ b/qemu/tests/qapi-schema/include-non-file.err
@@ -1 +1 @@
-tests/qapi-schema/include-non-file.json:1: Expected a file name (string), got: ['foo', 'bar']
+tests/qapi-schema/include-non-file.json:1: Value of 'include' must be a string
diff --git a/qemu/tests/qapi-schema/include-non-file.json b/qemu/tests/qapi-schema/include-non-file.json
index cd43c3f9d..4711aa42e 100644
--- a/qemu/tests/qapi-schema/include-non-file.json
+++ b/qemu/tests/qapi-schema/include-non-file.json
@@ -1 +1 @@
-{ 'include': [ 'foo', 'bar' ] }
+{ 'include': {} }
diff --git a/qemu/tests/qapi-schema/include-relpath.out b/qemu/tests/qapi-schema/include-relpath.out
index 4ce3dcf12..5d7c13cad 100644
--- a/qemu/tests/qapi-schema/include-relpath.out
+++ b/qemu/tests/qapi-schema/include-relpath.out
@@ -1,3 +1,4 @@
-[OrderedDict([('enum', 'Status'), ('data', ['good', 'bad', 'ugly'])])]
-[{'enum_name': 'Status', 'enum_values': ['good', 'bad', 'ugly']}]
-[]
+enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+ prefix QTYPE
+enum Status ['good', 'bad', 'ugly']
+object q_empty
diff --git a/qemu/tests/qapi-schema/include-repetition.out b/qemu/tests/qapi-schema/include-repetition.out
index 4ce3dcf12..5d7c13cad 100644
--- a/qemu/tests/qapi-schema/include-repetition.out
+++ b/qemu/tests/qapi-schema/include-repetition.out
@@ -1,3 +1,4 @@
-[OrderedDict([('enum', 'Status'), ('data', ['good', 'bad', 'ugly'])])]
-[{'enum_name': 'Status', 'enum_values': ['good', 'bad', 'ugly']}]
-[]
+enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+ prefix QTYPE
+enum Status ['good', 'bad', 'ugly']
+object q_empty
diff --git a/qemu/tests/qapi-schema/include-simple.out b/qemu/tests/qapi-schema/include-simple.out
index 4ce3dcf12..5d7c13cad 100644
--- a/qemu/tests/qapi-schema/include-simple.out
+++ b/qemu/tests/qapi-schema/include-simple.out
@@ -1,3 +1,4 @@
-[OrderedDict([('enum', 'Status'), ('data', ['good', 'bad', 'ugly'])])]
-[{'enum_name': 'Status', 'enum_values': ['good', 'bad', 'ugly']}]
-[]
+enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+ prefix QTYPE
+enum Status ['good', 'bad', 'ugly']
+object q_empty
diff --git a/qemu/tests/qapi-schema/indented-expr.out b/qemu/tests/qapi-schema/indented-expr.out
index b5ce9151b..ae3293a3a 100644
--- a/qemu/tests/qapi-schema/indented-expr.out
+++ b/qemu/tests/qapi-schema/indented-expr.out
@@ -1,3 +1,7 @@
-[OrderedDict([('command', 'eins')]), OrderedDict([('command', 'zwei')])]
-[]
-[]
+enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+ prefix QTYPE
+command eins None -> None
+ gen=True success_response=True
+object q_empty
+command zwei None -> None
+ gen=True success_response=True
diff --git a/qemu/tests/qapi-schema/leading-comma-list.err b/qemu/tests/qapi-schema/leading-comma-list.err
new file mode 100644
index 000000000..f5c870bb9
--- /dev/null
+++ b/qemu/tests/qapi-schema/leading-comma-list.err
@@ -0,0 +1 @@
+tests/qapi-schema/leading-comma-list.json:2:13: Expected "{", "[", "]", string, boolean or "null"
diff --git a/qemu/tests/qapi-schema/leading-comma-list.exit b/qemu/tests/qapi-schema/leading-comma-list.exit
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/qemu/tests/qapi-schema/leading-comma-list.exit
@@ -0,0 +1 @@
+1
diff --git a/qemu/tests/qapi-schema/leading-comma-list.json b/qemu/tests/qapi-schema/leading-comma-list.json
new file mode 100644
index 000000000..c5ba50159
--- /dev/null
+++ b/qemu/tests/qapi-schema/leading-comma-list.json
@@ -0,0 +1,2 @@
+{ 'enum': 'Status',
+ 'data': [ , 'good', 'bad', 'ugly' ] }
diff --git a/qemu/tests/qapi-schema/leading-comma-list.out b/qemu/tests/qapi-schema/leading-comma-list.out
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/qemu/tests/qapi-schema/leading-comma-list.out
diff --git a/qemu/tests/qapi-schema/leading-comma-object.err b/qemu/tests/qapi-schema/leading-comma-object.err
new file mode 100644
index 000000000..f767b9554
--- /dev/null
+++ b/qemu/tests/qapi-schema/leading-comma-object.err
@@ -0,0 +1 @@
+tests/qapi-schema/leading-comma-object.json:1:3: Expected string or "}"
diff --git a/qemu/tests/qapi-schema/leading-comma-object.exit b/qemu/tests/qapi-schema/leading-comma-object.exit
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/qemu/tests/qapi-schema/leading-comma-object.exit
@@ -0,0 +1 @@
+1
diff --git a/qemu/tests/qapi-schema/leading-comma-object.json b/qemu/tests/qapi-schema/leading-comma-object.json
new file mode 100644
index 000000000..c89023ff3
--- /dev/null
+++ b/qemu/tests/qapi-schema/leading-comma-object.json
@@ -0,0 +1,2 @@
+{ , 'enum': 'Status',
+ 'data': [ 'good', 'bad', 'ugly' ] }
diff --git a/qemu/tests/qapi-schema/leading-comma-object.out b/qemu/tests/qapi-schema/leading-comma-object.out
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/qemu/tests/qapi-schema/leading-comma-object.out
diff --git a/qemu/tests/qapi-schema/nested-struct-data.json b/qemu/tests/qapi-schema/nested-struct-data.json
index 3d52d2b39..efbe773de 100644
--- a/qemu/tests/qapi-schema/nested-struct-data.json
+++ b/qemu/tests/qapi-schema/nested-struct-data.json
@@ -1,4 +1,3 @@
# inline subtypes collide with our desired future use of defaults
{ 'command': 'foo',
- 'data': { 'a' : { 'string' : 'str', 'integer': 'int' }, 'b' : 'str' },
- 'returns': {} }
+ 'data': { 'a' : { 'string' : 'str', 'integer': 'int' }, 'b' : 'str' } }
diff --git a/qemu/tests/qapi-schema/nested-struct-returns.err b/qemu/tests/qapi-schema/nested-struct-returns.err
deleted file mode 100644
index 5238d075b..000000000
--- a/qemu/tests/qapi-schema/nested-struct-returns.err
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/nested-struct-returns.json:2: Member 'a' of 'returns' for command 'foo' should be a type name
diff --git a/qemu/tests/qapi-schema/nested-struct-returns.json b/qemu/tests/qapi-schema/nested-struct-returns.json
deleted file mode 100644
index d2cd047f0..000000000
--- a/qemu/tests/qapi-schema/nested-struct-returns.json
+++ /dev/null
@@ -1,3 +0,0 @@
-# inline subtypes collide with our desired future use of defaults
-{ 'command': 'foo',
- 'returns': { 'a' : { 'string' : 'str', 'integer': 'int' }, 'b' : 'str' } }
diff --git a/qemu/tests/qapi-schema/qapi-schema-test.json b/qemu/tests/qapi-schema/qapi-schema-test.json
index c7eaa865d..f571e1bb3 100644
--- a/qemu/tests/qapi-schema/qapi-schema-test.json
+++ b/qemu/tests/qapi-schema/qapi-schema-test.json
@@ -1,19 +1,42 @@
# *-*- Mode: Python -*-*
+# This file is a stress test of supported qapi constructs that must
+# parse and compile correctly.
+
+{ 'struct': 'TestStruct',
+ 'data': { 'integer': 'int', 'boolean': 'bool', 'string': 'str' } }
+
# for testing enums
-{ 'enum': 'EnumOne',
- 'data': [ 'value1', 'value2', 'value3' ] }
{ 'struct': 'NestedEnumsOne',
- 'data': { 'enum1': 'EnumOne', '*enum2': 'EnumOne', 'enum3': 'EnumOne', '*enum4': 'EnumOne' } }
+ 'data': { 'enum1': 'EnumOne', # Intentional forward reference
+ '*enum2': 'EnumOne', 'enum3': 'EnumOne', '*enum4': 'EnumOne' } }
+
+# An empty enum, although unusual, is currently acceptable
+{ 'enum': 'MyEnum', 'data': [ ] }
+
+# Likewise for an empty struct, including an empty base
+{ 'struct': 'Empty1', 'data': { } }
+{ 'struct': 'Empty2', 'base': 'Empty1', 'data': { } }
+
+{ 'command': 'user_def_cmd0', 'data': 'Empty2', 'returns': 'Empty2' }
+
+# for testing override of default naming heuristic
+{ 'enum': 'QEnumTwo',
+ 'prefix': 'QENUM_TWO',
+ 'data': [ 'value1', 'value2' ] }
# for testing nested structs
+{ 'struct': 'UserDefOne',
+ 'base': 'UserDefZero', # intentional forward reference
+ 'data': { 'string': 'str',
+ '*enum1': 'EnumOne' } } # intentional forward reference
+
+{ 'enum': 'EnumOne',
+ 'data': [ 'value1', 'value2', 'value3' ] }
+
{ 'struct': 'UserDefZero',
'data': { 'integer': 'int' } }
-{ 'struct': 'UserDefOne',
- 'base': 'UserDefZero',
- 'data': { 'string': 'str', '*enum1': 'EnumOne' } }
-
{ 'struct': 'UserDefTwoDictDict',
'data': { 'userdef': 'UserDefOne', 'string': 'str' } }
@@ -26,35 +49,55 @@
'data': { 'string0': 'str',
'dict1': 'UserDefTwoDict' } }
+# dummy struct to force generation of array types not otherwise mentioned
+{ 'struct': 'ForceArrays',
+ 'data': { 'unused1':['UserDefOne'], 'unused2':['UserDefTwo'],
+ 'unused3':['TestStruct'] } }
+
# for testing unions
+# Among other things, test that a name collision between branches does
+# not cause any problems (since only one branch can be in use at a time),
+# by intentionally using two branches that both have a C member 'a_b'
{ 'struct': 'UserDefA',
- 'data': { 'boolean': 'bool' } }
+ 'data': { 'boolean': 'bool', '*a_b': 'int' } }
{ 'struct': 'UserDefB',
- 'data': { 'integer': 'int' } }
+ 'data': { 'intb': 'int', '*a-b': 'bool' } }
-{ 'struct': 'UserDefC',
- 'data': { 'string1': 'str', 'string2': 'str' } }
+{ 'union': 'UserDefFlatUnion',
+ 'base': 'UserDefUnionBase', # intentional forward reference
+ 'discriminator': 'enum1',
+ 'data': { 'value1' : 'UserDefA',
+ 'value2' : 'UserDefB',
+ 'value3' : 'UserDefB' } }
{ 'struct': 'UserDefUnionBase',
+ 'base': 'UserDefZero',
'data': { 'string': 'str', 'enum1': 'EnumOne' } }
-{ 'union': 'UserDefFlatUnion',
- 'base': 'UserDefUnionBase',
- 'discriminator': 'enum1',
- 'data': { 'value1' : 'UserDefA', 'value2' : 'UserDefB', 'value3' : 'UserDefB' } }
-# FIXME generated struct UserDefFlatUnion has members for direct base
-# UserDefOne, but lacks members for indirect base UserDefZero
-
-# this variant of UserDefFlatUnion defaults to a union that uses fields with
+# this variant of UserDefFlatUnion defaults to a union that uses members with
# allocated types to test corner cases in the cleanup/dealloc visitor
{ 'union': 'UserDefFlatUnion2',
- 'base': 'UserDefUnionBase',
+ 'base': { '*integer': 'int', 'string': 'str', 'enum1': 'QEnumTwo' },
'discriminator': 'enum1',
- 'data': { 'value1' : 'UserDefC', 'value2' : 'UserDefB', 'value3' : 'UserDefA' } }
+ 'data': { 'value1' : 'UserDefC', # intentional forward reference
+ 'value2' : 'UserDefB' } }
+{ 'struct': 'WrapAlternate',
+ 'data': { 'alt': 'UserDefAlternate' } }
{ 'alternate': 'UserDefAlternate',
- 'data': { 'uda': 'UserDefA', 's': 'str', 'i': 'int' } }
+ 'data': { 'udfu': 'UserDefFlatUnion', 's': 'str', 'i': 'int' } }
+
+{ 'struct': 'UserDefC',
+ 'data': { 'string1': 'str', 'string2': 'str' } }
+
+# for testing use of 'number' within alternates
+{ 'alternate': 'AltStrBool', 'data': { 's': 'str', 'b': 'bool' } }
+{ 'alternate': 'AltStrNum', 'data': { 's': 'str', 'n': 'number' } }
+{ 'alternate': 'AltNumStr', 'data': { 'n': 'number', 's': 'str' } }
+{ 'alternate': 'AltStrInt', 'data': { 's': 'str', 'i': 'int' } }
+{ 'alternate': 'AltIntNum', 'data': { 'i': 'int', 'n': 'number' } }
+{ 'alternate': 'AltNumInt', 'data': { 'n': 'number', 'i': 'int' } }
# for testing native lists
{ 'union': 'UserDefNativeListUnion',
@@ -70,7 +113,8 @@
'number': ['number'],
'boolean': ['bool'],
'string': ['str'],
- 'sizes': ['size'] } }
+ 'sizes': ['size'],
+ 'any': ['any'] } }
# testing commands
{ 'command': 'user_def_cmd', 'data': {} }
@@ -78,8 +122,11 @@
{ 'command': 'user_def_cmd2',
'data': {'ud1a': 'UserDefOne', '*ud1b': 'UserDefOne'},
'returns': 'UserDefTwo' }
-{ 'command': 'user_def_cmd3', 'data': {'a': 'int', '*b': 'int' },
+
+# Returning a non-dictionary requires a name from the whitelist
+{ 'command': 'guest-get-time', 'data': {'a': 'int', '*b': 'int' },
'returns': 'int' }
+{ 'command': 'guest-sync', 'data': { 'arg': 'any' }, 'returns': 'any' }
# For testing integer range flattening in opts-visitor. The following schema
# corresponds to the option format:
@@ -108,12 +155,13 @@
{ 'event': 'EVENT_D',
'data': { 'a' : 'EventStructOne', 'b' : 'str', '*c': 'str', '*enum3': 'EnumOne' } }
-# test that we correctly compile downstream extensions
+# test that we correctly compile downstream extensions, as well as munge
+# ticklish names
{ 'enum': '__org.qemu_x-Enum', 'data': [ '__org.qemu_x-value' ] }
{ 'struct': '__org.qemu_x-Base',
'data': { '__org.qemu_x-member1': '__org.qemu_x-Enum' } }
{ 'struct': '__org.qemu_x-Struct', 'base': '__org.qemu_x-Base',
- 'data': { '__org.qemu_x-member2': 'str' } }
+ 'data': { '__org.qemu_x-member2': 'str', '*wchar-t': 'int' } }
{ 'union': '__org.qemu_x-Union1', 'data': { '__org.qemu_x-branch': 'str' } }
{ 'struct': '__org.qemu_x-Struct2',
'data': { 'array': ['__org.qemu_x-Union1'] } }
diff --git a/qemu/tests/qapi-schema/qapi-schema-test.out b/qemu/tests/qapi-schema/qapi-schema-test.out
index cf0ccc402..19cd214f6 100644
--- a/qemu/tests/qapi-schema/qapi-schema-test.out
+++ b/qemu/tests/qapi-schema/qapi-schema-test.out
@@ -1,55 +1,211 @@
-[OrderedDict([('enum', 'EnumOne'), ('data', ['value1', 'value2', 'value3'])]),
- OrderedDict([('struct', 'NestedEnumsOne'), ('data', OrderedDict([('enum1', 'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4', 'EnumOne')]))]),
- OrderedDict([('struct', 'UserDefZero'), ('data', OrderedDict([('integer', 'int')]))]),
- OrderedDict([('struct', 'UserDefOne'), ('base', 'UserDefZero'), ('data', OrderedDict([('string', 'str'), ('*enum1', 'EnumOne')]))]),
- OrderedDict([('struct', 'UserDefTwoDictDict'), ('data', OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')]))]),
- OrderedDict([('struct', 'UserDefTwoDict'), ('data', OrderedDict([('string1', 'str'), ('dict2', 'UserDefTwoDictDict'), ('*dict3', 'UserDefTwoDictDict')]))]),
- OrderedDict([('struct', 'UserDefTwo'), ('data', OrderedDict([('string0', 'str'), ('dict1', 'UserDefTwoDict')]))]),
- OrderedDict([('struct', 'UserDefA'), ('data', OrderedDict([('boolean', 'bool')]))]),
- OrderedDict([('struct', 'UserDefB'), ('data', OrderedDict([('integer', 'int')]))]),
- OrderedDict([('struct', 'UserDefC'), ('data', OrderedDict([('string1', 'str'), ('string2', 'str')]))]),
- OrderedDict([('struct', 'UserDefUnionBase'), ('data', OrderedDict([('string', 'str'), ('enum1', 'EnumOne')]))]),
- OrderedDict([('union', 'UserDefFlatUnion'), ('base', 'UserDefUnionBase'), ('discriminator', 'enum1'), ('data', OrderedDict([('value1', 'UserDefA'), ('value2', 'UserDefB'), ('value3', 'UserDefB')]))]),
- OrderedDict([('union', 'UserDefFlatUnion2'), ('base', 'UserDefUnionBase'), ('discriminator', 'enum1'), ('data', OrderedDict([('value1', 'UserDefC'), ('value2', 'UserDefB'), ('value3', 'UserDefA')]))]),
- OrderedDict([('alternate', 'UserDefAlternate'), ('data', OrderedDict([('uda', 'UserDefA'), ('s', 'str'), ('i', 'int')]))]),
- OrderedDict([('union', 'UserDefNativeListUnion'), ('data', OrderedDict([('integer', ['int']), ('s8', ['int8']), ('s16', ['int16']), ('s32', ['int32']), ('s64', ['int64']), ('u8', ['uint8']), ('u16', ['uint16']), ('u32', ['uint32']), ('u64', ['uint64']), ('number', ['number']), ('boolean', ['bool']), ('string', ['str']), ('sizes', ['size'])]))]),
- OrderedDict([('command', 'user_def_cmd'), ('data', OrderedDict())]),
- OrderedDict([('command', 'user_def_cmd1'), ('data', OrderedDict([('ud1a', 'UserDefOne')]))]),
- OrderedDict([('command', 'user_def_cmd2'), ('data', OrderedDict([('ud1a', 'UserDefOne'), ('*ud1b', 'UserDefOne')])), ('returns', 'UserDefTwo')]),
- OrderedDict([('command', 'user_def_cmd3'), ('data', OrderedDict([('a', 'int'), ('*b', 'int')])), ('returns', 'int')]),
- OrderedDict([('struct', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))]),
- OrderedDict([('struct', 'EventStructOne'), ('data', OrderedDict([('struct1', 'UserDefOne'), ('string', 'str'), ('*enum2', 'EnumOne')]))]),
- OrderedDict([('event', 'EVENT_A')]),
- OrderedDict([('event', 'EVENT_B'), ('data', OrderedDict())]),
- OrderedDict([('event', 'EVENT_C'), ('data', OrderedDict([('*a', 'int'), ('*b', 'UserDefOne'), ('c', 'str')]))]),
- OrderedDict([('event', 'EVENT_D'), ('data', OrderedDict([('a', 'EventStructOne'), ('b', 'str'), ('*c', 'str'), ('*enum3', 'EnumOne')]))]),
- OrderedDict([('enum', '__org.qemu_x-Enum'), ('data', ['__org.qemu_x-value'])]),
- OrderedDict([('struct', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member1', '__org.qemu_x-Enum')]))]),
- OrderedDict([('struct', '__org.qemu_x-Struct'), ('base', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member2', 'str')]))]),
- OrderedDict([('union', '__org.qemu_x-Union1'), ('data', OrderedDict([('__org.qemu_x-branch', 'str')]))]),
- OrderedDict([('struct', '__org.qemu_x-Struct2'), ('data', OrderedDict([('array', ['__org.qemu_x-Union1'])]))]),
- OrderedDict([('union', '__org.qemu_x-Union2'), ('base', '__org.qemu_x-Base'), ('discriminator', '__org.qemu_x-member1'), ('data', OrderedDict([('__org.qemu_x-value', '__org.qemu_x-Struct2')]))]),
- OrderedDict([('alternate', '__org.qemu_x-Alt'), ('data', OrderedDict([('__org.qemu_x-branch', 'str'), ('b', '__org.qemu_x-Base')]))]),
- OrderedDict([('event', '__ORG.QEMU_X-EVENT'), ('data', '__org.qemu_x-Struct')]),
- OrderedDict([('command', '__org.qemu_x-command'), ('data', OrderedDict([('a', ['__org.qemu_x-Enum']), ('b', ['__org.qemu_x-Struct']), ('c', '__org.qemu_x-Union2'), ('d', '__org.qemu_x-Alt')])), ('returns', '__org.qemu_x-Union1')])]
-[{'enum_name': 'EnumOne', 'enum_values': ['value1', 'value2', 'value3']},
- {'enum_name': '__org.qemu_x-Enum', 'enum_values': ['__org.qemu_x-value']},
- {'enum_name': 'UserDefAlternateKind', 'enum_values': None},
- {'enum_name': 'UserDefNativeListUnionKind', 'enum_values': None},
- {'enum_name': '__org.qemu_x-Union1Kind', 'enum_values': None},
- {'enum_name': '__org.qemu_x-AltKind', 'enum_values': None}]
-[OrderedDict([('struct', 'NestedEnumsOne'), ('data', OrderedDict([('enum1', 'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4', 'EnumOne')]))]),
- OrderedDict([('struct', 'UserDefZero'), ('data', OrderedDict([('integer', 'int')]))]),
- OrderedDict([('struct', 'UserDefOne'), ('base', 'UserDefZero'), ('data', OrderedDict([('string', 'str'), ('*enum1', 'EnumOne')]))]),
- OrderedDict([('struct', 'UserDefTwoDictDict'), ('data', OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')]))]),
- OrderedDict([('struct', 'UserDefTwoDict'), ('data', OrderedDict([('string1', 'str'), ('dict2', 'UserDefTwoDictDict'), ('*dict3', 'UserDefTwoDictDict')]))]),
- OrderedDict([('struct', 'UserDefTwo'), ('data', OrderedDict([('string0', 'str'), ('dict1', 'UserDefTwoDict')]))]),
- OrderedDict([('struct', 'UserDefA'), ('data', OrderedDict([('boolean', 'bool')]))]),
- OrderedDict([('struct', 'UserDefB'), ('data', OrderedDict([('integer', 'int')]))]),
- OrderedDict([('struct', 'UserDefC'), ('data', OrderedDict([('string1', 'str'), ('string2', 'str')]))]),
- OrderedDict([('struct', 'UserDefUnionBase'), ('data', OrderedDict([('string', 'str'), ('enum1', 'EnumOne')]))]),
- OrderedDict([('struct', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))]),
- OrderedDict([('struct', 'EventStructOne'), ('data', OrderedDict([('struct1', 'UserDefOne'), ('string', 'str'), ('*enum2', 'EnumOne')]))]),
- OrderedDict([('struct', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member1', '__org.qemu_x-Enum')]))]),
- OrderedDict([('struct', '__org.qemu_x-Struct'), ('base', '__org.qemu_x-Base'), ('data', OrderedDict([('__org.qemu_x-member2', 'str')]))]),
- OrderedDict([('struct', '__org.qemu_x-Struct2'), ('data', OrderedDict([('array', ['__org.qemu_x-Union1'])]))])]
+alternate AltIntNum
+ case i: int
+ case n: number
+alternate AltNumInt
+ case n: number
+ case i: int
+alternate AltNumStr
+ case n: number
+ case s: str
+alternate AltStrBool
+ case s: str
+ case b: bool
+alternate AltStrInt
+ case s: str
+ case i: int
+alternate AltStrNum
+ case s: str
+ case n: number
+event EVENT_A None
+event EVENT_B None
+event EVENT_C q_obj_EVENT_C-arg
+event EVENT_D q_obj_EVENT_D-arg
+object Empty1
+object Empty2
+ base Empty1
+enum EnumOne ['value1', 'value2', 'value3']
+object EventStructOne
+ member struct1: UserDefOne optional=False
+ member string: str optional=False
+ member enum2: EnumOne optional=True
+object ForceArrays
+ member unused1: UserDefOneList optional=False
+ member unused2: UserDefTwoList optional=False
+ member unused3: TestStructList optional=False
+enum MyEnum []
+object NestedEnumsOne
+ member enum1: EnumOne optional=False
+ member enum2: EnumOne optional=True
+ member enum3: EnumOne optional=False
+ member enum4: EnumOne optional=True
+enum QEnumTwo ['value1', 'value2']
+ prefix QENUM_TWO
+enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+ prefix QTYPE
+object TestStruct
+ member integer: int optional=False
+ member boolean: bool optional=False
+ member string: str optional=False
+object UserDefA
+ member boolean: bool optional=False
+ member a_b: int optional=True
+alternate UserDefAlternate
+ case udfu: UserDefFlatUnion
+ case s: str
+ case i: int
+object UserDefB
+ member intb: int optional=False
+ member a-b: bool optional=True
+object UserDefC
+ member string1: str optional=False
+ member string2: str optional=False
+object UserDefFlatUnion
+ base UserDefUnionBase
+ tag enum1
+ case value1: UserDefA
+ case value2: UserDefB
+ case value3: UserDefB
+object UserDefFlatUnion2
+ base q_obj_UserDefFlatUnion2-base
+ tag enum1
+ case value1: UserDefC
+ case value2: UserDefB
+object UserDefNativeListUnion
+ member type: UserDefNativeListUnionKind optional=False
+ case integer: q_obj_intList-wrapper
+ case s8: q_obj_int8List-wrapper
+ case s16: q_obj_int16List-wrapper
+ case s32: q_obj_int32List-wrapper
+ case s64: q_obj_int64List-wrapper
+ case u8: q_obj_uint8List-wrapper
+ case u16: q_obj_uint16List-wrapper
+ case u32: q_obj_uint32List-wrapper
+ case u64: q_obj_uint64List-wrapper
+ case number: q_obj_numberList-wrapper
+ case boolean: q_obj_boolList-wrapper
+ case string: q_obj_strList-wrapper
+ case sizes: q_obj_sizeList-wrapper
+ case any: q_obj_anyList-wrapper
+enum UserDefNativeListUnionKind ['integer', 's8', 's16', 's32', 's64', 'u8', 'u16', 'u32', 'u64', 'number', 'boolean', 'string', 'sizes', 'any']
+object UserDefOne
+ base UserDefZero
+ member string: str optional=False
+ member enum1: EnumOne optional=True
+object UserDefOptions
+ member i64: intList optional=True
+ member u64: uint64List optional=True
+ member u16: uint16List optional=True
+ member i64x: int optional=True
+ member u64x: uint64 optional=True
+object UserDefTwo
+ member string0: str optional=False
+ member dict1: UserDefTwoDict optional=False
+object UserDefTwoDict
+ member string1: str optional=False
+ member dict2: UserDefTwoDictDict optional=False
+ member dict3: UserDefTwoDictDict optional=True
+object UserDefTwoDictDict
+ member userdef: UserDefOne optional=False
+ member string: str optional=False
+object UserDefUnionBase
+ base UserDefZero
+ member string: str optional=False
+ member enum1: EnumOne optional=False
+object UserDefZero
+ member integer: int optional=False
+object WrapAlternate
+ member alt: UserDefAlternate optional=False
+event __ORG.QEMU_X-EVENT __org.qemu_x-Struct
+alternate __org.qemu_x-Alt
+ case __org.qemu_x-branch: str
+ case b: __org.qemu_x-Base
+object __org.qemu_x-Base
+ member __org.qemu_x-member1: __org.qemu_x-Enum optional=False
+enum __org.qemu_x-Enum ['__org.qemu_x-value']
+object __org.qemu_x-Struct
+ base __org.qemu_x-Base
+ member __org.qemu_x-member2: str optional=False
+ member wchar-t: int optional=True
+object __org.qemu_x-Struct2
+ member array: __org.qemu_x-Union1List optional=False
+object __org.qemu_x-Union1
+ member type: __org.qemu_x-Union1Kind optional=False
+ case __org.qemu_x-branch: q_obj_str-wrapper
+enum __org.qemu_x-Union1Kind ['__org.qemu_x-branch']
+object __org.qemu_x-Union2
+ base __org.qemu_x-Base
+ tag __org.qemu_x-member1
+ case __org.qemu_x-value: __org.qemu_x-Struct2
+command __org.qemu_x-command q_obj___org.qemu_x-command-arg -> __org.qemu_x-Union1
+ gen=True success_response=True
+command guest-get-time q_obj_guest-get-time-arg -> int
+ gen=True success_response=True
+command guest-sync q_obj_guest-sync-arg -> any
+ gen=True success_response=True
+object q_empty
+object q_obj_EVENT_C-arg
+ member a: int optional=True
+ member b: UserDefOne optional=True
+ member c: str optional=False
+object q_obj_EVENT_D-arg
+ member a: EventStructOne optional=False
+ member b: str optional=False
+ member c: str optional=True
+ member enum3: EnumOne optional=True
+object q_obj_UserDefFlatUnion2-base
+ member integer: int optional=True
+ member string: str optional=False
+ member enum1: QEnumTwo optional=False
+object q_obj___org.qemu_x-command-arg
+ member a: __org.qemu_x-EnumList optional=False
+ member b: __org.qemu_x-StructList optional=False
+ member c: __org.qemu_x-Union2 optional=False
+ member d: __org.qemu_x-Alt optional=False
+object q_obj_anyList-wrapper
+ member data: anyList optional=False
+object q_obj_boolList-wrapper
+ member data: boolList optional=False
+object q_obj_guest-get-time-arg
+ member a: int optional=False
+ member b: int optional=True
+object q_obj_guest-sync-arg
+ member arg: any optional=False
+object q_obj_int16List-wrapper
+ member data: int16List optional=False
+object q_obj_int32List-wrapper
+ member data: int32List optional=False
+object q_obj_int64List-wrapper
+ member data: int64List optional=False
+object q_obj_int8List-wrapper
+ member data: int8List optional=False
+object q_obj_intList-wrapper
+ member data: intList optional=False
+object q_obj_numberList-wrapper
+ member data: numberList optional=False
+object q_obj_sizeList-wrapper
+ member data: sizeList optional=False
+object q_obj_str-wrapper
+ member data: str optional=False
+object q_obj_strList-wrapper
+ member data: strList optional=False
+object q_obj_uint16List-wrapper
+ member data: uint16List optional=False
+object q_obj_uint32List-wrapper
+ member data: uint32List optional=False
+object q_obj_uint64List-wrapper
+ member data: uint64List optional=False
+object q_obj_uint8List-wrapper
+ member data: uint8List optional=False
+object q_obj_user_def_cmd1-arg
+ member ud1a: UserDefOne optional=False
+object q_obj_user_def_cmd2-arg
+ member ud1a: UserDefOne optional=False
+ member ud1b: UserDefOne optional=True
+command user_def_cmd None -> None
+ gen=True success_response=True
+command user_def_cmd0 Empty2 -> Empty2
+ gen=True success_response=True
+command user_def_cmd1 q_obj_user_def_cmd1-arg -> None
+ gen=True success_response=True
+command user_def_cmd2 q_obj_user_def_cmd2-arg -> UserDefTwo
+ gen=True success_response=True
diff --git a/qemu/tests/qapi-schema/reserved-command-q.err b/qemu/tests/qapi-schema/reserved-command-q.err
new file mode 100644
index 000000000..f939e044e
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-command-q.err
@@ -0,0 +1 @@
+tests/qapi-schema/reserved-command-q.json:5: 'command' uses invalid name 'q-unix'
diff --git a/qemu/tests/qapi-schema/reserved-command-q.exit b/qemu/tests/qapi-schema/reserved-command-q.exit
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-command-q.exit
@@ -0,0 +1 @@
+1
diff --git a/qemu/tests/qapi-schema/reserved-command-q.json b/qemu/tests/qapi-schema/reserved-command-q.json
new file mode 100644
index 000000000..99f8aae31
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-command-q.json
@@ -0,0 +1,5 @@
+# C entity name collision
+# We reject names like 'q-unix', because they can collide with the mangled
+# name for 'unix' in generated C.
+{ 'command': 'unix' }
+{ 'command': 'q-unix' }
diff --git a/qemu/tests/qapi-schema/reserved-command-q.out b/qemu/tests/qapi-schema/reserved-command-q.out
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-command-q.out
diff --git a/qemu/tests/qapi-schema/reserved-enum-q.err b/qemu/tests/qapi-schema/reserved-enum-q.err
new file mode 100644
index 000000000..e1c3480ee
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-enum-q.err
@@ -0,0 +1 @@
+tests/qapi-schema/reserved-enum-q.json:4: Member of enum 'Foo' uses invalid name 'q-Unix'
diff --git a/qemu/tests/qapi-schema/reserved-enum-q.exit b/qemu/tests/qapi-schema/reserved-enum-q.exit
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-enum-q.exit
@@ -0,0 +1 @@
+1
diff --git a/qemu/tests/qapi-schema/reserved-enum-q.json b/qemu/tests/qapi-schema/reserved-enum-q.json
new file mode 100644
index 000000000..3593a765e
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-enum-q.json
@@ -0,0 +1,4 @@
+# C entity name collision
+# We reject names like 'q-unix', because they can collide with the mangled
+# name for 'unix' in generated C.
+{ 'enum': 'Foo', 'data': [ 'unix', 'q-Unix' ] }
diff --git a/qemu/tests/qapi-schema/reserved-enum-q.out b/qemu/tests/qapi-schema/reserved-enum-q.out
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-enum-q.out
diff --git a/qemu/tests/qapi-schema/reserved-member-has.err b/qemu/tests/qapi-schema/reserved-member-has.err
new file mode 100644
index 000000000..e75577144
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-member-has.err
@@ -0,0 +1 @@
+tests/qapi-schema/reserved-member-has.json:5: Member of 'data' for command 'oops' uses reserved name 'has-a'
diff --git a/qemu/tests/qapi-schema/reserved-member-has.exit b/qemu/tests/qapi-schema/reserved-member-has.exit
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-member-has.exit
@@ -0,0 +1 @@
+1
diff --git a/qemu/tests/qapi-schema/reserved-member-has.json b/qemu/tests/qapi-schema/reserved-member-has.json
new file mode 100644
index 000000000..45b9109bd
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-member-has.json
@@ -0,0 +1,5 @@
+# C member name collision
+# We reject names like 'has-a', because they can collide with the flag
+# for an optional 'a' in generated C.
+# TODO we could munge the optional flag name to avoid the collision.
+{ 'command': 'oops', 'data': { '*a': 'str', 'has-a': 'str' } }
diff --git a/qemu/tests/qapi-schema/reserved-member-has.out b/qemu/tests/qapi-schema/reserved-member-has.out
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-member-has.out
diff --git a/qemu/tests/qapi-schema/reserved-member-q.err b/qemu/tests/qapi-schema/reserved-member-q.err
new file mode 100644
index 000000000..f3d5dd781
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-member-q.err
@@ -0,0 +1 @@
+tests/qapi-schema/reserved-member-q.json:4: Member of 'data' for struct 'Foo' uses invalid name 'q-unix'
diff --git a/qemu/tests/qapi-schema/reserved-member-q.exit b/qemu/tests/qapi-schema/reserved-member-q.exit
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-member-q.exit
@@ -0,0 +1 @@
+1
diff --git a/qemu/tests/qapi-schema/reserved-member-q.json b/qemu/tests/qapi-schema/reserved-member-q.json
new file mode 100644
index 000000000..62fed8fdd
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-member-q.json
@@ -0,0 +1,4 @@
+# C member name collision
+# We reject names like 'q-unix', because they can collide with the mangled
+# name for 'unix' in generated C.
+{ 'struct': 'Foo', 'data': { 'unix':'int', 'q-unix':'bool' } }
diff --git a/qemu/tests/qapi-schema/reserved-member-q.out b/qemu/tests/qapi-schema/reserved-member-q.out
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-member-q.out
diff --git a/qemu/tests/qapi-schema/reserved-member-u.err b/qemu/tests/qapi-schema/reserved-member-u.err
new file mode 100644
index 000000000..87d42296c
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-member-u.err
@@ -0,0 +1 @@
+tests/qapi-schema/reserved-member-u.json:7: Member of 'data' for struct 'Oops' uses reserved name 'u'
diff --git a/qemu/tests/qapi-schema/reserved-member-u.exit b/qemu/tests/qapi-schema/reserved-member-u.exit
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-member-u.exit
@@ -0,0 +1 @@
+1
diff --git a/qemu/tests/qapi-schema/reserved-member-u.json b/qemu/tests/qapi-schema/reserved-member-u.json
new file mode 100644
index 000000000..1eaf0f301
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-member-u.json
@@ -0,0 +1,7 @@
+# Potential C member name collision
+# We reject use of 'u' as a member name, to allow it for internal use in
+# putting union branch members in a separate namespace from QMP members.
+# This is true even for non-unions, because it is possible to convert a
+# struct to flat union while remaining backwards compatible in QMP.
+# TODO - we could munge the member name to 'q_u' to avoid the collision
+{ 'struct': 'Oops', 'data': { 'u': 'str' } }
diff --git a/qemu/tests/qapi-schema/reserved-member-u.out b/qemu/tests/qapi-schema/reserved-member-u.out
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-member-u.out
diff --git a/qemu/tests/qapi-schema/reserved-member-underscore.err b/qemu/tests/qapi-schema/reserved-member-underscore.err
new file mode 100644
index 000000000..65ff0da8c
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-member-underscore.err
@@ -0,0 +1 @@
+tests/qapi-schema/reserved-member-underscore.json:4: Member of 'data' for struct 'Oops' uses invalid name '_oops'
diff --git a/qemu/tests/qapi-schema/reserved-member-underscore.exit b/qemu/tests/qapi-schema/reserved-member-underscore.exit
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-member-underscore.exit
@@ -0,0 +1 @@
+1
diff --git a/qemu/tests/qapi-schema/reserved-member-underscore.json b/qemu/tests/qapi-schema/reserved-member-underscore.json
new file mode 100644
index 000000000..4a3a01763
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-member-underscore.json
@@ -0,0 +1,4 @@
+# C member name collision
+# We reject use of a single leading underscore in all names (names must
+# begin with a letter or a downstream extension double-underscore prefix).
+{ 'struct': 'Oops', 'data': { '_oops': 'str' } }
diff --git a/qemu/tests/qapi-schema/reserved-member-underscore.out b/qemu/tests/qapi-schema/reserved-member-underscore.out
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-member-underscore.out
diff --git a/qemu/tests/qapi-schema/reserved-type-kind.err b/qemu/tests/qapi-schema/reserved-type-kind.err
new file mode 100644
index 000000000..0a38efaad
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-type-kind.err
@@ -0,0 +1 @@
+tests/qapi-schema/reserved-type-kind.json:2: enum 'UnionKind' should not end in 'Kind'
diff --git a/qemu/tests/qapi-schema/reserved-type-kind.exit b/qemu/tests/qapi-schema/reserved-type-kind.exit
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-type-kind.exit
@@ -0,0 +1 @@
+1
diff --git a/qemu/tests/qapi-schema/enum-union-clash.json b/qemu/tests/qapi-schema/reserved-type-kind.json
index 593282b6c..9ecaba12b 100644
--- a/qemu/tests/qapi-schema/enum-union-clash.json
+++ b/qemu/tests/qapi-schema/reserved-type-kind.json
@@ -1,4 +1,2 @@
# we reject types that would conflict with implicit union enum
{ 'enum': 'UnionKind', 'data': [ 'oops' ] }
-{ 'union': 'Union',
- 'data': { 'a': 'int' } }
diff --git a/qemu/tests/qapi-schema/reserved-type-kind.out b/qemu/tests/qapi-schema/reserved-type-kind.out
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-type-kind.out
diff --git a/qemu/tests/qapi-schema/reserved-type-list.err b/qemu/tests/qapi-schema/reserved-type-list.err
new file mode 100644
index 000000000..4510fa6d9
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-type-list.err
@@ -0,0 +1 @@
+tests/qapi-schema/reserved-type-list.json:5: struct 'FooList' should not end in 'List'
diff --git a/qemu/tests/qapi-schema/reserved-type-list.exit b/qemu/tests/qapi-schema/reserved-type-list.exit
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-type-list.exit
@@ -0,0 +1 @@
+1
diff --git a/qemu/tests/qapi-schema/reserved-type-list.json b/qemu/tests/qapi-schema/reserved-type-list.json
new file mode 100644
index 000000000..98d53bf80
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-type-list.json
@@ -0,0 +1,5 @@
+# Potential C name collision
+# We reserve names ending in 'List' for use by array types.
+# TODO - we could choose array names to avoid collision with user types,
+# in order to let this compile
+{ 'struct': 'FooList', 'data': { 's': 'str' } }
diff --git a/qemu/tests/qapi-schema/reserved-type-list.out b/qemu/tests/qapi-schema/reserved-type-list.out
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/qemu/tests/qapi-schema/reserved-type-list.out
diff --git a/qemu/tests/qapi-schema/returns-dict.err b/qemu/tests/qapi-schema/returns-dict.err
new file mode 100644
index 000000000..eb2d0c466
--- /dev/null
+++ b/qemu/tests/qapi-schema/returns-dict.err
@@ -0,0 +1 @@
+tests/qapi-schema/returns-dict.json:2: 'returns' for command 'oops' should be a type name
diff --git a/qemu/tests/qapi-schema/returns-dict.exit b/qemu/tests/qapi-schema/returns-dict.exit
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/qemu/tests/qapi-schema/returns-dict.exit
@@ -0,0 +1 @@
+1
diff --git a/qemu/tests/qapi-schema/returns-dict.json b/qemu/tests/qapi-schema/returns-dict.json
new file mode 100644
index 000000000..1cfef3ede
--- /dev/null
+++ b/qemu/tests/qapi-schema/returns-dict.json
@@ -0,0 +1,2 @@
+# we reject inline struct return type
+{ 'command': 'oops', 'returns': { 'a': 'str' } }
diff --git a/qemu/tests/qapi-schema/returns-dict.out b/qemu/tests/qapi-schema/returns-dict.out
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/qemu/tests/qapi-schema/returns-dict.out
diff --git a/qemu/tests/qapi-schema/returns-int.exit b/qemu/tests/qapi-schema/returns-int.exit
deleted file mode 100644
index 573541ac9..000000000
--- a/qemu/tests/qapi-schema/returns-int.exit
+++ /dev/null
@@ -1 +0,0 @@
-0
diff --git a/qemu/tests/qapi-schema/returns-int.json b/qemu/tests/qapi-schema/returns-int.json
deleted file mode 100644
index 870ec6366..000000000
--- a/qemu/tests/qapi-schema/returns-int.json
+++ /dev/null
@@ -1,3 +0,0 @@
-# It is okay (although not extensible) to return a non-dictionary
-# But to make it work, the name must be in a whitelist
-{ 'command': 'guest-get-time', 'returns': 'int' }
diff --git a/qemu/tests/qapi-schema/returns-int.out b/qemu/tests/qapi-schema/returns-int.out
deleted file mode 100644
index 70b3ac5e6..000000000
--- a/qemu/tests/qapi-schema/returns-int.out
+++ /dev/null
@@ -1,3 +0,0 @@
-[OrderedDict([('command', 'guest-get-time'), ('returns', 'int')])]
-[]
-[]
diff --git a/qemu/tests/qapi-schema/returns-whitelist.err b/qemu/tests/qapi-schema/returns-whitelist.err
index a41f019a5..f47c1ee7c 100644
--- a/qemu/tests/qapi-schema/returns-whitelist.err
+++ b/qemu/tests/qapi-schema/returns-whitelist.err
@@ -1 +1 @@
-tests/qapi-schema/returns-whitelist.json:10: 'returns' for command 'no-way-this-will-get-whitelisted' cannot use built-in type 'array of int'
+tests/qapi-schema/returns-whitelist.json:10: 'returns' for command 'no-way-this-will-get-whitelisted' cannot use built-in type 'int'
diff --git a/qemu/tests/qapi-schema/struct-base-clash-deep.err b/qemu/tests/qapi-schema/struct-base-clash-deep.err
index e3e9f8d28..e2d7943f2 100644
--- a/qemu/tests/qapi-schema/struct-base-clash-deep.err
+++ b/qemu/tests/qapi-schema/struct-base-clash-deep.err
@@ -1 +1 @@
-tests/qapi-schema/struct-base-clash-deep.json:7: Member name 'name' clashes with base 'Base'
+tests/qapi-schema/struct-base-clash-deep.json:10: 'name' (member of Sub) collides with 'name' (member of Base)
diff --git a/qemu/tests/qapi-schema/struct-base-clash-deep.json b/qemu/tests/qapi-schema/struct-base-clash-deep.json
index 552fe9431..fa873ab5d 100644
--- a/qemu/tests/qapi-schema/struct-base-clash-deep.json
+++ b/qemu/tests/qapi-schema/struct-base-clash-deep.json
@@ -1,4 +1,7 @@
-# we check for no duplicate keys with indirect base
+# Reject attempts to duplicate QMP members
+# Here, 'name' would have to appear twice on the wire, locally and
+# indirectly for the grandparent base; the collision doesn't care that
+# one instance is optional.
{ 'struct': 'Base',
'data': { 'name': 'str' } }
{ 'struct': 'Mid',
diff --git a/qemu/tests/qapi-schema/struct-base-clash.err b/qemu/tests/qapi-schema/struct-base-clash.err
index 3ac37fb26..c52f33d27 100644
--- a/qemu/tests/qapi-schema/struct-base-clash.err
+++ b/qemu/tests/qapi-schema/struct-base-clash.err
@@ -1 +1 @@
-tests/qapi-schema/struct-base-clash.json:4: Member name 'name' clashes with base 'Base'
+tests/qapi-schema/struct-base-clash.json:5: 'name' (member of Sub) collides with 'name' (member of Base)
diff --git a/qemu/tests/qapi-schema/struct-base-clash.json b/qemu/tests/qapi-schema/struct-base-clash.json
index f2afc9b6f..11aec80fe 100644
--- a/qemu/tests/qapi-schema/struct-base-clash.json
+++ b/qemu/tests/qapi-schema/struct-base-clash.json
@@ -1,4 +1,5 @@
-# we check for no duplicate keys with base
+# Reject attempts to duplicate QMP members
+# Here, 'name' would have to appear twice on the wire, locally and for base.
{ 'struct': 'Base',
'data': { 'name': 'str' } }
{ 'struct': 'Sub',
diff --git a/qemu/tests/qapi-schema/struct-data-invalid.err b/qemu/tests/qapi-schema/struct-data-invalid.err
new file mode 100644
index 000000000..6644f4c2a
--- /dev/null
+++ b/qemu/tests/qapi-schema/struct-data-invalid.err
@@ -0,0 +1 @@
+tests/qapi-schema/struct-data-invalid.json:1: 'data' for struct 'foo' should be a dictionary or type name
diff --git a/qemu/tests/qapi-schema/struct-data-invalid.exit b/qemu/tests/qapi-schema/struct-data-invalid.exit
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/qemu/tests/qapi-schema/struct-data-invalid.exit
@@ -0,0 +1 @@
+1
diff --git a/qemu/tests/qapi-schema/struct-data-invalid.json b/qemu/tests/qapi-schema/struct-data-invalid.json
new file mode 100644
index 000000000..9adbc3bb6
--- /dev/null
+++ b/qemu/tests/qapi-schema/struct-data-invalid.json
@@ -0,0 +1,2 @@
+{ 'struct': 'foo',
+ 'data': false }
diff --git a/qemu/tests/qapi-schema/struct-data-invalid.out b/qemu/tests/qapi-schema/struct-data-invalid.out
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/qemu/tests/qapi-schema/struct-data-invalid.out
diff --git a/qemu/tests/qapi-schema/struct-member-invalid.err b/qemu/tests/qapi-schema/struct-member-invalid.err
new file mode 100644
index 000000000..69a326d45
--- /dev/null
+++ b/qemu/tests/qapi-schema/struct-member-invalid.err
@@ -0,0 +1 @@
+tests/qapi-schema/struct-member-invalid.json:1: Member 'a' of 'data' for struct 'foo' should be a type name
diff --git a/qemu/tests/qapi-schema/struct-member-invalid.exit b/qemu/tests/qapi-schema/struct-member-invalid.exit
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/qemu/tests/qapi-schema/struct-member-invalid.exit
@@ -0,0 +1 @@
+1
diff --git a/qemu/tests/qapi-schema/struct-member-invalid.json b/qemu/tests/qapi-schema/struct-member-invalid.json
new file mode 100644
index 000000000..8f172f7a8
--- /dev/null
+++ b/qemu/tests/qapi-schema/struct-member-invalid.json
@@ -0,0 +1,2 @@
+{ 'struct': 'foo',
+ 'data': { 'a': false } }
diff --git a/qemu/tests/qapi-schema/struct-member-invalid.out b/qemu/tests/qapi-schema/struct-member-invalid.out
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/qemu/tests/qapi-schema/struct-member-invalid.out
diff --git a/qemu/tests/qapi-schema/test-qapi.py b/qemu/tests/qapi-schema/test-qapi.py
index 634ef2d00..649677e01 100644
--- a/qemu/tests/qapi-schema/test-qapi.py
+++ b/qemu/tests/qapi-schema/test-qapi.py
@@ -15,11 +15,42 @@ from pprint import pprint
import os
import sys
-try:
- exprs = parse_schema(sys.argv[1])
-except SystemExit:
- raise
-
-pprint(exprs)
-pprint(enum_types)
-pprint(struct_types)
+
+class QAPISchemaTestVisitor(QAPISchemaVisitor):
+ def visit_enum_type(self, name, info, values, prefix):
+ print 'enum %s %s' % (name, values)
+ if prefix:
+ print ' prefix %s' % prefix
+
+ def visit_object_type(self, name, info, base, members, variants):
+ print 'object %s' % name
+ if base:
+ print ' base %s' % base.name
+ for m in members:
+ print ' member %s: %s optional=%s' % \
+ (m.name, m.type.name, m.optional)
+ self._print_variants(variants)
+
+ def visit_alternate_type(self, name, info, variants):
+ print 'alternate %s' % name
+ self._print_variants(variants)
+
+ def visit_command(self, name, info, arg_type, ret_type,
+ gen, success_response):
+ print 'command %s %s -> %s' % \
+ (name, arg_type and arg_type.name, ret_type and ret_type.name)
+ print ' gen=%s success_response=%s' % (gen, success_response)
+
+ def visit_event(self, name, info, arg_type):
+ print 'event %s %s' % (name, arg_type and arg_type.name)
+
+ @staticmethod
+ def _print_variants(variants):
+ if variants:
+ if variants.tag_name:
+ print ' tag %s' % variants.tag_name
+ for v in variants.variants:
+ print ' case %s: %s' % (v.name, v.type.name)
+
+schema = QAPISchema(sys.argv[1])
+schema.visit(QAPISchemaTestVisitor())
diff --git a/qemu/tests/qapi-schema/type-bypass-no-gen.err b/qemu/tests/qapi-schema/type-bypass-no-gen.err
deleted file mode 100644
index 20cef0a8a..000000000
--- a/qemu/tests/qapi-schema/type-bypass-no-gen.err
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/type-bypass-no-gen.json:2: Member 'arg' of 'data' for command 'unsafe' uses '**' but did not request 'gen':false
diff --git a/qemu/tests/qapi-schema/type-bypass-no-gen.json b/qemu/tests/qapi-schema/type-bypass-no-gen.json
deleted file mode 100644
index 4feae3719..000000000
--- a/qemu/tests/qapi-schema/type-bypass-no-gen.json
+++ /dev/null
@@ -1,2 +0,0 @@
-# type bypass only works with 'gen':false
-{ 'command': 'unsafe', 'data': { 'arg': '**' }, 'returns': '**' }
diff --git a/qemu/tests/qapi-schema/type-bypass.exit b/qemu/tests/qapi-schema/type-bypass.exit
deleted file mode 100644
index 573541ac9..000000000
--- a/qemu/tests/qapi-schema/type-bypass.exit
+++ /dev/null
@@ -1 +0,0 @@
-0
diff --git a/qemu/tests/qapi-schema/type-bypass.json b/qemu/tests/qapi-schema/type-bypass.json
deleted file mode 100644
index 48b213783..000000000
--- a/qemu/tests/qapi-schema/type-bypass.json
+++ /dev/null
@@ -1,2 +0,0 @@
-# Use of 'gen':false allows bypassing type system
-{ 'command': 'unsafe', 'data': { 'arg': '**' }, 'returns': '**', 'gen': false }
diff --git a/qemu/tests/qapi-schema/type-bypass.out b/qemu/tests/qapi-schema/type-bypass.out
deleted file mode 100644
index eaf20f834..000000000
--- a/qemu/tests/qapi-schema/type-bypass.out
+++ /dev/null
@@ -1,3 +0,0 @@
-[OrderedDict([('command', 'unsafe'), ('data', OrderedDict([('arg', '**')])), ('returns', '**'), ('gen', False)])]
-[]
-[]
diff --git a/qemu/tests/qapi-schema/union-bad-branch.err b/qemu/tests/qapi-schema/union-bad-branch.err
deleted file mode 100644
index 882273556..000000000
--- a/qemu/tests/qapi-schema/union-bad-branch.err
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/union-bad-branch.json:6: Union 'MyUnion' member 'ONE' clashes with 'one'
diff --git a/qemu/tests/qapi-schema/union-bad-branch.json b/qemu/tests/qapi-schema/union-bad-branch.json
deleted file mode 100644
index 913aa38bc..000000000
--- a/qemu/tests/qapi-schema/union-bad-branch.json
+++ /dev/null
@@ -1,8 +0,0 @@
-# we reject normal unions where branches would collide in C
-{ 'struct': 'One',
- 'data': { 'string': 'str' } }
-{ 'struct': 'Two',
- 'data': { 'number': 'int' } }
-{ 'union': 'MyUnion',
- 'data': { 'one': 'One',
- 'ONE': 'Two' } }
diff --git a/qemu/tests/qapi-schema/union-base-no-discriminator.err b/qemu/tests/qapi-schema/union-base-no-discriminator.err
index fc8b79c45..8b7a24260 100644
--- a/qemu/tests/qapi-schema/union-base-no-discriminator.err
+++ b/qemu/tests/qapi-schema/union-base-no-discriminator.err
@@ -1 +1 @@
-tests/qapi-schema/union-base-no-discriminator.json:11: Union 'TestUnion' requires a discriminator to go along with base
+tests/qapi-schema/union-base-no-discriminator.json:11: Simple union 'TestUnion' must not have a base
diff --git a/qemu/tests/qapi-schema/union-branch-case.err b/qemu/tests/qapi-schema/union-branch-case.err
new file mode 100644
index 000000000..11521901d
--- /dev/null
+++ b/qemu/tests/qapi-schema/union-branch-case.err
@@ -0,0 +1 @@
+tests/qapi-schema/union-branch-case.json:2: 'Branch' (branch of NoWayThisWillGetWhitelisted) should not use uppercase
diff --git a/qemu/tests/qapi-schema/union-branch-case.exit b/qemu/tests/qapi-schema/union-branch-case.exit
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/qemu/tests/qapi-schema/union-branch-case.exit
@@ -0,0 +1 @@
+1
diff --git a/qemu/tests/qapi-schema/union-branch-case.json b/qemu/tests/qapi-schema/union-branch-case.json
new file mode 100644
index 000000000..e6565dc3b
--- /dev/null
+++ b/qemu/tests/qapi-schema/union-branch-case.json
@@ -0,0 +1,2 @@
+# Branch names should be 'lower-case' unless the union is whitelisted
+{ 'union': 'NoWayThisWillGetWhitelisted', 'data': { 'Branch': 'int' } }
diff --git a/qemu/tests/qapi-schema/union-branch-case.out b/qemu/tests/qapi-schema/union-branch-case.out
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/qemu/tests/qapi-schema/union-branch-case.out
diff --git a/qemu/tests/qapi-schema/union-clash-branches.err b/qemu/tests/qapi-schema/union-clash-branches.err
new file mode 100644
index 000000000..e5b21135b
--- /dev/null
+++ b/qemu/tests/qapi-schema/union-clash-branches.err
@@ -0,0 +1 @@
+tests/qapi-schema/union-clash-branches.json:4: 'a_b' (branch of TestUnion) collides with 'a-b' (branch of TestUnion)
diff --git a/qemu/tests/qapi-schema/union-clash-branches.exit b/qemu/tests/qapi-schema/union-clash-branches.exit
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/qemu/tests/qapi-schema/union-clash-branches.exit
@@ -0,0 +1 @@
+1
diff --git a/qemu/tests/qapi-schema/union-clash-branches.json b/qemu/tests/qapi-schema/union-clash-branches.json
new file mode 100644
index 000000000..3bece8c94
--- /dev/null
+++ b/qemu/tests/qapi-schema/union-clash-branches.json
@@ -0,0 +1,5 @@
+# Union branch name collision
+# Reject a union that would result in a collision in generated C names (this
+# would try to generate two members 'a_b').
+{ 'union': 'TestUnion',
+ 'data': { 'a-b': 'int', 'a_b': 'str' } }
diff --git a/qemu/tests/qapi-schema/union-clash-branches.out b/qemu/tests/qapi-schema/union-clash-branches.out
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/qemu/tests/qapi-schema/union-clash-branches.out
diff --git a/qemu/tests/qapi-schema/union-empty.err b/qemu/tests/qapi-schema/union-empty.err
new file mode 100644
index 000000000..12c20221b
--- /dev/null
+++ b/qemu/tests/qapi-schema/union-empty.err
@@ -0,0 +1 @@
+tests/qapi-schema/union-empty.json:2: Union 'Union' cannot have empty 'data'
diff --git a/qemu/tests/qapi-schema/union-empty.exit b/qemu/tests/qapi-schema/union-empty.exit
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/qemu/tests/qapi-schema/union-empty.exit
@@ -0,0 +1 @@
+1
diff --git a/qemu/tests/qapi-schema/union-empty.json b/qemu/tests/qapi-schema/union-empty.json
new file mode 100644
index 000000000..1f0b13ca2
--- /dev/null
+++ b/qemu/tests/qapi-schema/union-empty.json
@@ -0,0 +1,2 @@
+# unions cannot be empty
+{ 'union': 'Union', 'data': { } }
diff --git a/qemu/tests/qapi-schema/union-empty.out b/qemu/tests/qapi-schema/union-empty.out
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/qemu/tests/qapi-schema/union-empty.out
diff --git a/qemu/tests/qapi-schema/union-invalid-base.err b/qemu/tests/qapi-schema/union-invalid-base.err
index 9f637963e..03d7b97a9 100644
--- a/qemu/tests/qapi-schema/union-invalid-base.err
+++ b/qemu/tests/qapi-schema/union-invalid-base.err
@@ -1 +1 @@
-tests/qapi-schema/union-invalid-base.json:8: Base 'int' is not a valid struct
+tests/qapi-schema/union-invalid-base.json:8: 'base' for union 'TestUnion' cannot use built-in type 'int'
diff --git a/qemu/tests/qapi-schema/union-max.err b/qemu/tests/qapi-schema/union-max.err
deleted file mode 100644
index 55ce4399d..000000000
--- a/qemu/tests/qapi-schema/union-max.err
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/union-max.json:2: Union 'Union' member 'max' clashes with '(automatic)'
diff --git a/qemu/tests/qapi-schema/union-max.json b/qemu/tests/qapi-schema/union-max.json
deleted file mode 100644
index d6ad98699..000000000
--- a/qemu/tests/qapi-schema/union-max.json
+++ /dev/null
@@ -1,3 +0,0 @@
-# we reject 'max' branch in a union, for collision with C enum
-{ 'union': 'Union',
- 'data': { 'max': 'int' } }