• E
    qapi: Emit implicit structs in generated C · 7ce106a9
    Eric Blake 提交于
    We already have several places that want to visit all the members
    of an implicit object within a larger context (simple union variant,
    event with anonymous data, command with anonymous arguments struct);
    and will be adding another one soon (the ability to declare an
    anonymous base for a flat union).  Having a C struct declared for
    these implicit types, along with a visit_type_FOO_members() helper
    function, will make for fewer special cases in our generator.
    
    We do not, however, need qapi_free_FOO() or visit_type_FOO()
    functions for implicit types, because they should not be used
    directly outside of the generated code.  This is done by adding a
    conditional in visit_object_type() for both qapi-types.py and
    qapi-visit.py based on the object name.  The comparison of
    "name.startswith('q_')" is a bit hacky (it's basically duplicating
    what .is_implicit() already uses), but beats changing the signature
    of the visit_object_type() callback to pass a new 'implicit' flag.
    The hack should be temporary: we are considering adding a future
    patch that consolidates the narrow visit_object_type(..., base,
    local_members, variants) and visit_object_type_flat(...,
    all_members, variants) [where different sets of information are
    already broken out, and the QAPISchemaObjectType is no longer
    available] into a broader visit_object_type(obj_type) [where the
    visitor can query the needed fields from obj_type directly].
    
    Also, now that we WANT to output C code for implicits, we no longer
    need the visit_needed() filter, leaving 'q_empty' as the only object
    still needing a special case.  Remember, 'q_empty' is the only
    built-in generated object, which means that without a special case
    it would be emitted in multiple files (the main qapi-types.h and in
    qga-qapi-types.h) causing compilation failure due to redefinition.
    But since it has no members, it's easier to just avoid an attempt to
    visit that particular type; since gen_object() is called recursively,
    we also prime the objects_seen set to cover any recursion into the
    empty type.
    
    The patch relies on the changed naming of implicit types in the
    previous patch.  It is a bit unfortunate that the generated struct
    names and visit_type_FOO_members() don't match normal naming
    conventions, but it's not too bad, since they will only be used in
    generated code.
    
    The generated code grows substantially in size: the implicit
    '-wrapper' types must be emitted in qapi-types.h before any union
    can include an unboxed member of that type.  Arguably, the '-args'
    types could be emitted in a private header for just qapi-visit.c
    and qmp-marshal.c, rather than polluting qapi-types.h; but adding
    complexity to the generator to split the output location according
    to role doesn't seem worth the maintenance costs.
    Signed-off-by: NEric Blake <eblake@redhat.com>
    Message-Id: <1458254921-17042-6-git-send-email-eblake@redhat.com>
    Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
    7ce106a9
qapi.py 60.3 KB