[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC v3 07/32] scripts/qapi: generate CABI dump for C types
From: |
marcandre . lureau |
Subject: |
[RFC v3 07/32] scripts/qapi: generate CABI dump for C types |
Date: |
Tue, 7 Sep 2021 16:19:18 +0400 |
From: Marc-André Lureau <marcandre.lureau@redhat.com>
With type units, generate the C ABI dump functions (as blocks protected
with QAPI_CABI define). The top-level function is qapi_cabi(), and it
calls the sub-modules dump functions.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi/types.py | 58 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 57 insertions(+), 1 deletion(-)
diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py
index 831294fe42..7ac3645d18 100644
--- a/scripts/qapi/types.py
+++ b/scripts/qapi/types.py
@@ -13,8 +13,15 @@
# See the COPYING file in the top-level directory.
"""
-from typing import List, Optional
+from pathlib import Path
+from typing import (
+ Dict,
+ List,
+ Optional,
+ Set,
+)
+from .cabi import CABI, CABIEnum, gen_object_cabi
from .common import c_enum_const, c_name, mcgen
from .gen import QAPISchemaModularCVisitor, ifcontext
from .schema import (
@@ -22,6 +29,7 @@
QAPISchemaEnumMember,
QAPISchemaFeature,
QAPISchemaIfCond,
+ QAPISchemaModule,
QAPISchemaObjectType,
QAPISchemaObjectTypeMember,
QAPISchemaType,
@@ -265,6 +273,13 @@ def __init__(self, prefix: str):
super().__init__(
prefix, 'qapi-types', ' * Schema-defined QAPI types',
' * Built-in QAPI types', __doc__)
+ self._cabi_functions: List[str] = []
+ self._cabi_functions_called: Set[str] = set()
+ self._cabi: Dict[str, CABI] = {}
+
+ def _cabi_add(self, cabis: List[CABI]) -> None:
+ for cabi in cabis:
+ self._cabi.setdefault(cabi.name, cabi)
def _begin_builtin_module(self) -> None:
self._genc.preamble_add(mcgen('''
@@ -295,6 +310,43 @@ def visit_begin(self, schema: QAPISchema) -> None:
# gen_object() is recursive, ensure it doesn't visit the empty type
objects_seen.add(schema.the_empty_object_type.name)
+ def _get_qapi_cabi_fn(self, name: str) -> str:
+ fn_name = 'qapi_cabi'
+ if QAPISchemaModule.is_builtin_module(name):
+ fn_name += '_builtin'
+ elif name != self._main_module:
+ name = Path(name).stem
+ fn_name += '_' + c_name(name)
+ return fn_name
+
+ def visit_include(self, name: str, info: Optional[QAPISourceInfo]) -> None:
+ super().visit_include(name, info)
+ cabi_fn = self._get_qapi_cabi_fn(name)
+ if cabi_fn not in self._cabi_functions_called:
+ self._cabi_functions.append(cabi_fn)
+
+ def visit_module_end(self, name: str) -> None:
+ cabi_gen = "".join(f' {fn}();\n' for fn in self._cabi_functions)
+ self._cabi_functions_called |= set(self._cabi_functions)
+ self._cabi_functions = []
+ cabi_gen += "".join([c.gen_c() for _, c in sorted(self._cabi.items())])
+ self._cabi = {}
+ fn_name = self._get_qapi_cabi_fn(name)
+ self._genh.add(mcgen('''
+
+#ifdef QAPI_CABI
+void %(fn_name)s(void);
+#endif
+''', fn_name=fn_name))
+ self._genc.add(mcgen('''
+
+#ifdef QAPI_CABI
+void %(fn_name)s(void) {
+%(cabi_gen)s
+}
+#endif
+''', fn_name=fn_name, cabi_gen=cabi_gen))
+
def _gen_type_cleanup(self, name: str) -> None:
self._genh.add(gen_type_cleanup_decl(name))
self._genc.add(gen_type_cleanup(name))
@@ -309,6 +361,7 @@ def visit_enum_type(self,
with ifcontext(ifcond, self._genh, self._genc):
self._genh.preamble_add(gen_enum(name, members, prefix))
self._genc.add(gen_enum_lookup(name, members, prefix))
+ self._cabi_add([CABIEnum(name, ifcond, members, prefix)])
def visit_array_type(self,
name: str,
@@ -334,6 +387,7 @@ def visit_object_type(self,
with ifcontext(ifcond, self._genh):
self._genh.preamble_add(gen_fwd_object_or_array(name))
self._genh.add(gen_object(name, ifcond, base, members, variants))
+ self._cabi_add(gen_object_cabi(name, ifcond, base, members, variants))
with ifcontext(ifcond, self._genh, self._genc):
if base and not base.is_implicit():
self._genh.add(gen_upcast(name, base))
@@ -353,6 +407,8 @@ def visit_alternate_type(self,
self._genh.preamble_add(gen_fwd_object_or_array(name))
self._genh.add(gen_object(name, ifcond, None,
[variants.tag_member], variants))
+ self._cabi_add(gen_object_cabi(name, ifcond, None,
+ [variants.tag_member], variants))
with ifcontext(ifcond, self._genh, self._genc):
self._gen_type_cleanup(name)
--
2.33.0.113.g6c40894d24
- Re: [RFC v3 02/32] build-sys: add HAVE_IPPROTO_MPTCP, (continued)
- [RFC v3 03/32] scripts/qapi: teach c_param_type() to return const argument type, marcandre . lureau, 2021/09/07
- [RFC v3 04/32] glib-compat: add G_SIZEOF_MEMBER, marcandre . lureau, 2021/09/07
- [RFC v3 05/32] scripts/qapi: add QAPISchemaVisitor.visit_module_end, marcandre . lureau, 2021/09/07
- [RFC v3 06/32] scripts/qapi: add a CABI module, marcandre . lureau, 2021/09/07
- [RFC v3 07/32] scripts/qapi: generate CABI dump for C types,
marcandre . lureau <=
- [RFC v3 08/32] tests: build qapi-cabi (C ABI dump), marcandre . lureau, 2021/09/07
- [RFC v3 09/32] build-sys: add i686 cpu target, marcandre . lureau, 2021/09/07
- [RFC v3 10/32] build-sys: add --with-rust{-target} & basic build infrastructure, marcandre . lureau, 2021/09/07
- [RFC v3 11/32] build-sys: add a cargo-wrapper script, marcandre . lureau, 2021/09/07
- [RFC v3 12/32] rust: provide a common crate for QEMU, marcandre . lureau, 2021/09/07