unicorn/qemu/include/qapi/visitor-impl.h
Eric Blake 7f741a6c9b
qapi: Add new visit_free() function
Making each visitor provide its own (awkwardly-named) FOO_cleanup()
is unusual, when we can instead have a polymorphic visit_free()
interface. Over the next few patches, we can use the polymorphic
functions to eliminate the need for a FOO_get_visitor() function
for accessing specific visitor functionality, once everything can
be accessed directly through the Visitor* interfaces.

The dealloc visitor is the first one converted to completely use
the new entry point, since qapi_dealloc_visitor_cleanup() was the
only reason that qapi_dealloc_get_visitor() existed, and only
generated and testsuite code was even using it. With the new
visit_free() entry point in place, we no longer need to expose
the QapiDeallocVisitor subtype through qapi_dealloc_visitor_new(),
and can get by with less generated code, with diffs that look like:

| void qapi_free_ACPIOSTInfo(ACPIOSTInfo *obj)
| {
|- QapiDeallocVisitor *qdv;
| Visitor *v;
|
| if (!obj) {
| return;
| }
|
|- qdv = qapi_dealloc_visitor_new();
|- v = qapi_dealloc_get_visitor(qdv);
|+ v = qapi_dealloc_visitor_new();
| visit_type_ACPIOSTInfo(v, NULL, &obj, NULL);
|- qapi_dealloc_visitor_cleanup(qdv);
|+ visit_free(v);
|}

Backports commit 2c0ef9f411ae6081efa9eca5b3eab2dbeee45a6c from qemu
2018-02-25 01:05:41 -05:00

114 lines
3.7 KiB
C

/*
* Core Definitions for QAPI Visitor implementations
*
* Copyright (C) 2012-2016 Red Hat, Inc.
*
* Author: Paolo Bonizni <pbonzini@redhat.com>
*
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
* See the COPYING.LIB file in the top-level directory.
*
*/
#ifndef QAPI_VISITOR_IMPL_H
#define QAPI_VISITOR_IMPL_H
#include "qapi/error.h"
#include "qapi/visitor.h"
/*
* This file describes the callback interface for implementing a QAPI
* visitor. For the client interface, see visitor.h. When
* implementing the callbacks, it is easiest to declare a struct with
* 'Visitor visitor;' as the first member. A callback's contract
* matches the corresponding public functions' contract unless stated
* otherwise. In the comments below, some callbacks are marked "must
* be set for $TYPE visits to work"; if a visitor implementation omits
* that callback, it should also document that it is only useful for a
* subset of QAPI.
*/
/*
* There are three classes of visitors; setting the class determines
* how QAPI enums are visited, as well as what additional restrictions
* can be asserted.
*/
typedef enum VisitorType {
VISITOR_INPUT,
VISITOR_OUTPUT,
VISITOR_DEALLOC,
} VisitorType;
struct Visitor
{
/* Must be set to visit structs */
void (*start_struct)(Visitor *v, const char *name, void **obj,
size_t size, Error **errp);
/* Optional; intended for input visitors */
void (*check_struct)(Visitor *v, Error **errp);
/* Must be set to visit structs */
void (*end_struct)(Visitor *v, void **obj);
/* Must be set; implementations may require @list to be non-null,
* but must document it. */
void (*start_list)(Visitor *v, const char *name, GenericList **list,
size_t size, Error **errp);
/* Must be set */
GenericList *(*next_list)(Visitor *v, GenericList *tail, size_t size);
/* Must be set */
void (*end_list)(Visitor *v, void **list);
/* Must be set by input and dealloc visitors to visit alternates;
* optional for output visitors. */
void (*start_alternate)(Visitor *v, const char *name,
GenericAlternate **obj, size_t size,
bool promote_int, Error **errp);
/* Optional, needed for dealloc visitor */
void (*end_alternate)(Visitor *v, void **obj);
/* Must be set */
void (*type_int64)(Visitor *v, const char *name, int64_t *obj,
Error **errp);
/* Must be set */
void (*type_uint64)(Visitor *v, const char *name, uint64_t *obj,
Error **errp);
/* Optional; fallback is type_uint64() */
void (*type_size)(Visitor *v, const char *name, uint64_t *obj,
Error **errp);
/* Must be set */
void (*type_bool)(Visitor *v, const char *name, bool *obj, Error **errp);
/* Must be set */
void (*type_str)(Visitor *v, const char *name, char **obj, Error **errp);
/* Must be set to visit numbers */
void (*type_number)(Visitor *v, const char *name, double *obj,
Error **errp);
/* Must be set to visit arbitrary QTypes */
void (*type_any)(Visitor *v, const char *name, QObject **obj,
Error **errp);
/* Must be set to visit explicit null values. */
void (*type_null)(Visitor *v, const char *name, Error **errp);
/* Must be set for input visitors, optional otherwise. The core
* takes care of the return type in the public interface. */
void (*optional)(Visitor *v, const char *name, bool *present);
/* Must be set */
VisitorType type;
/* Must be set */
void (*free)(Visitor *v);
};
#endif