diff options
author | 2018-02-26 16:29:21 -0600 | |
---|---|---|
committer | 2018-03-02 13:14:10 -0600 | |
commit | cdb6610ae4283720037bae2af1f78bd40eb5fe71 (patch) | |
tree | a32a7d2a3575d8438f3e88eccd6832ff55fdad0a /scripts/qapi/types.py | |
parent | qapi: Make code-generating visitors use QAPIGen more (diff) | |
download | qemu-cdb6610ae4283720037bae2af1f78bd40eb5fe71.tar.xz qemu-cdb6610ae4283720037bae2af1f78bd40eb5fe71.zip |
qapi/types qapi/visit: Generate built-in stuff into separate files
Linking code from multiple separate QAPI schemata into the same
program is possible, but involves some weirdness around built-in
types:
* We generate code for built-in types into .c only with option
--builtins. The user is responsible for generating code for exactly
one QAPI schema per program with --builtins.
* We generate code for built-in types into .h regardless of
--builtins, but guarded by #ifndef QAPI_VISIT_BUILTIN. Because all
copies of this code are exactly the same, including any combination
of these headers works.
Replace this contraption by something more conventional: generate code
for built-in types into their very own files: qapi-builtin-types.c,
qapi-builtin-visit.c, qapi-builtin-types.h, qapi-builtin-visit.h, but
only with --builtins. Obey --output-dir, but ignore --prefix for
them.
Make qapi-types.h include qapi-builtin-types.h. With multiple
schemata you now have multiple qapi-types.[ch], but only one
qapi-builtin-types.[ch]. Same for qapi-visit.[ch] and
qapi-builtin-visit.[ch].
Bonus: if all you need is built-in stuff, you can include a much
smaller header. To be exploited shortly.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20180211093607.27351-21-armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>
[eblake: fix octal constant for python 3]
Signed-off-by: Eric Blake <eblake@redhat.com>
Diffstat (limited to 'scripts/qapi/types.py')
-rw-r--r-- | scripts/qapi/types.py | 61 |
1 files changed, 24 insertions, 37 deletions
diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py index d2b8423479..59826b1162 100644 --- a/scripts/qapi/types.py +++ b/scripts/qapi/types.py @@ -167,64 +167,51 @@ void qapi_free_%(c_name)s(%(c_name)s *obj) return ret -class QAPISchemaGenTypeVisitor(QAPISchemaMonolithicCVisitor): +class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor): - def __init__(self, prefix, opt_builtins): - QAPISchemaMonolithicCVisitor.__init__( + def __init__(self, prefix): + QAPISchemaModularCVisitor.__init__( self, prefix, 'qapi-types', ' * Schema-defined QAPI types', __doc__) - self._opt_builtins = opt_builtins + self._add_module(None, ' * Built-in QAPI types') + self._genc.preamble_add(mcgen(''' +#include "qemu/osdep.h" +#include "qapi/dealloc-visitor.h" +#include "qapi-builtin-types.h" +#include "qapi-builtin-visit.h" +''')) + self._genh.preamble_add(mcgen(''' +#include "qapi/util.h" +''')) + + def _begin_module(self, name): self._genc.preamble_add(mcgen(''' #include "qemu/osdep.h" #include "qapi/dealloc-visitor.h" #include "%(prefix)sqapi-types.h" #include "%(prefix)sqapi-visit.h" ''', - prefix=prefix)) + prefix=self._prefix)) self._genh.preamble_add(mcgen(''' -#include "qapi/util.h" +#include "qapi-builtin-types.h" ''')) - self._btin = '\n' + guardstart('QAPI_TYPES_BUILTIN') def visit_begin(self, schema): # gen_object() is recursive, ensure it doesn't visit the empty type objects_seen.add(schema.the_empty_object_type.name) - def visit_end(self): - # To avoid header dependency hell, we always generate - # declarations for built-in types in our header files and - # simply guard them. See also opt_builtins (command line - # option -b). - self._btin += guardend('QAPI_TYPES_BUILTIN') - self._genh.preamble_add(self._btin) - self._btin = None - def _gen_type_cleanup(self, name): self._genh.add(gen_type_cleanup_decl(name)) self._genc.add(gen_type_cleanup(name)) def visit_enum_type(self, name, info, values, prefix): - # Special case for our lone builtin enum type - # TODO use something cleaner than existence of info - if not info: - self._btin += gen_enum(name, values, prefix) - if self._opt_builtins: - self._genc.add(gen_enum_lookup(name, values, prefix)) - else: - self._genh.preamble_add(gen_enum(name, values, prefix)) - self._genc.add(gen_enum_lookup(name, values, prefix)) + self._genh.preamble_add(gen_enum(name, values, prefix)) + self._genc.add(gen_enum_lookup(name, values, prefix)) def visit_array_type(self, name, info, element_type): - if isinstance(element_type, QAPISchemaBuiltinType): - self._btin += gen_fwd_object_or_array(name) - self._btin += gen_array(name, element_type) - self._btin += gen_type_cleanup_decl(name) - if self._opt_builtins: - self._genc.add(gen_type_cleanup(name)) - else: - self._genh.preamble_add(gen_fwd_object_or_array(name)) - self._genh.add(gen_array(name, element_type)) - self._gen_type_cleanup(name) + self._genh.preamble_add(gen_fwd_object_or_array(name)) + self._genh.add(gen_array(name, element_type)) + self._gen_type_cleanup(name) def visit_object_type(self, name, info, base, members, variants): # Nothing to do for the special empty builtin @@ -248,6 +235,6 @@ class QAPISchemaGenTypeVisitor(QAPISchemaMonolithicCVisitor): def gen_types(schema, output_dir, prefix, opt_builtins): - vis = QAPISchemaGenTypeVisitor(prefix, opt_builtins) + vis = QAPISchemaGenTypeVisitor(prefix) schema.visit(vis) - vis.write(output_dir) + vis.write(output_dir, opt_builtins) |