aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-07-06 11:38:09 +0100
committerPeter Maydell <peter.maydell@linaro.org>2016-07-06 11:38:09 +0100
commit975b1c3ac6ae57b3e1356b0156c68f63a8a349dc (patch)
treeecd35419f10196800c44176645084c3691f660df /include
parentfc5d0a2b243ad7bd4db1f29e6e274507df54a8a8 (diff)
parentb6954712abea03afd686b724060f9873e2c61f2b (diff)
Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2016-07-06' into staging
QAPI patches for 2016-07-06 # gpg: Signature made Wed 06 Jul 2016 10:00:51 BST # gpg: using RSA key 0x3870B400EB918653 # gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" # gpg: aka "Markus Armbruster <armbru@pond.sub.org>" # Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867 4E5F 3870 B400 EB91 8653 * remotes/armbru/tags/pull-qapi-2016-07-06: replay: Use new QAPI cloning sockets: Use new QAPI cloning qapi: Add new clone visitor qapi: Add new visit_complete() function tests: Factor out common code in qapi output tests tests: Clean up test-string-output-visitor qmp-output-visitor: Favor new visit_free() function string-output-visitor: Favor new visit_free() function qmp-input-visitor: Favor new visit_free() function string-input-visitor: Favor new visit_free() function opts-visitor: Favor new visit_free() function qapi: Add new visit_free() function qapi: Add parameter to visit_end_* qemu-img: Don't leak errors when outputting JSON qapi: Improve use of qmp/types.h Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'include')
-rw-r--r--include/io/task.h2
-rw-r--r--include/qapi/clone-visitor.h39
-rw-r--r--include/qapi/dealloc-visitor.h5
-rw-r--r--include/qapi/opts-visitor.h4
-rw-r--r--include/qapi/qmp-input-visitor.h6
-rw-r--r--include/qapi/qmp-output-visitor.h12
-rw-r--r--include/qapi/qmp/types.h1
-rw-r--r--include/qapi/string-input-visitor.h5
-rw-r--r--include/qapi/string-output-visitor.h14
-rw-r--r--include/qapi/visitor-impl.h26
-rw-r--r--include/qapi/visitor.h161
-rw-r--r--include/qemu/sockets.h4
12 files changed, 187 insertions, 92 deletions
diff --git a/include/io/task.h b/include/io/task.h
index a993212ad9..df9499aa3a 100644
--- a/include/io/task.h
+++ b/include/io/task.h
@@ -159,7 +159,7 @@ typedef int (*QIOTaskWorker)(QIOTask *task,
* QIOTask *task;
* SocketAddress *addrCopy;
*
- * qapi_copy_SocketAddress(&addrCopy, addr);
+ * addrCopy = QAPI_CLONE(SocketAddress, addr);
* task = qio_task_new(OBJECT(obj), func, opaque, notify);
*
* qio_task_run_in_thread(task, myobject_listen_worker,
diff --git a/include/qapi/clone-visitor.h b/include/qapi/clone-visitor.h
new file mode 100644
index 0000000000..b16177e1ee
--- /dev/null
+++ b/include/qapi/clone-visitor.h
@@ -0,0 +1,39 @@
+/*
+ * Clone Visitor
+ *
+ * Copyright (C) 2016 Red Hat, Inc.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QAPI_CLONE_VISITOR_H
+#define QAPI_CLONE_VISITOR_H
+
+#include "qemu/typedefs.h"
+#include "qapi/visitor.h"
+#include "qapi-visit.h"
+
+/*
+ * The clone visitor is for direct use only by the QAPI_CLONE() macro;
+ * it requires that the root visit occur on an object, list, or
+ * alternate, and is not usable directly on built-in QAPI types.
+ */
+typedef struct QapiCloneVisitor QapiCloneVisitor;
+
+void *qapi_clone(const void *src, void (*visit_type)(Visitor *, const char *,
+ void **, Error **));
+
+/*
+ * Deep-clone QAPI object @src of the given @type, and return the result.
+ *
+ * Not usable on QAPI scalars (integers, strings, enums), nor on a
+ * QAPI object that references the 'any' type. Safe when @src is NULL.
+ */
+#define QAPI_CLONE(type, src) \
+ ((type *)qapi_clone(src, \
+ (void (*)(Visitor *, const char *, void**, \
+ Error **))visit_type_ ## type))
+
+#endif
diff --git a/include/qapi/dealloc-visitor.h b/include/qapi/dealloc-visitor.h
index 45b06b248c..b3e5c85fd8 100644
--- a/include/qapi/dealloc-visitor.h
+++ b/include/qapi/dealloc-visitor.h
@@ -23,9 +23,6 @@ typedef struct QapiDeallocVisitor QapiDeallocVisitor;
* qapi_free_FOO() functions, and is the only visitor designed to work
* correctly in the face of a partially-constructed QAPI tree.
*/
-QapiDeallocVisitor *qapi_dealloc_visitor_new(void);
-void qapi_dealloc_visitor_cleanup(QapiDeallocVisitor *d);
-
-Visitor *qapi_dealloc_get_visitor(QapiDeallocVisitor *v);
+Visitor *qapi_dealloc_visitor_new(void);
#endif
diff --git a/include/qapi/opts-visitor.h b/include/qapi/opts-visitor.h
index ae1bf7cf51..6462c96c29 100644
--- a/include/qapi/opts-visitor.h
+++ b/include/qapi/opts-visitor.h
@@ -35,8 +35,6 @@ typedef struct OptsVisitor OptsVisitor;
* QTypes. It also requires a non-null list argument to
* visit_start_list().
*/
-OptsVisitor *opts_visitor_new(const QemuOpts *opts);
-void opts_visitor_cleanup(OptsVisitor *nv);
-Visitor *opts_get_visitor(OptsVisitor *nv);
+Visitor *opts_visitor_new(const QemuOpts *opts);
#endif
diff --git a/include/qapi/qmp-input-visitor.h b/include/qapi/qmp-input-visitor.h
index b0624d8683..f3ff5f3e98 100644
--- a/include/qapi/qmp-input-visitor.h
+++ b/include/qapi/qmp-input-visitor.h
@@ -25,10 +25,6 @@ typedef struct QmpInputVisitor QmpInputVisitor;
* Set @strict to reject a parse that doesn't consume all keys of a
* dictionary; otherwise excess input is ignored.
*/
-QmpInputVisitor *qmp_input_visitor_new(QObject *obj, bool strict);
-
-void qmp_input_visitor_cleanup(QmpInputVisitor *v);
-
-Visitor *qmp_input_get_visitor(QmpInputVisitor *v);
+Visitor *qmp_input_visitor_new(QObject *obj, bool strict);
#endif
diff --git a/include/qapi/qmp-output-visitor.h b/include/qapi/qmp-output-visitor.h
index 22667706ab..040fdda142 100644
--- a/include/qapi/qmp-output-visitor.h
+++ b/include/qapi/qmp-output-visitor.h
@@ -19,10 +19,12 @@
typedef struct QmpOutputVisitor QmpOutputVisitor;
-QmpOutputVisitor *qmp_output_visitor_new(void);
-void qmp_output_visitor_cleanup(QmpOutputVisitor *v);
-
-QObject *qmp_output_get_qobject(QmpOutputVisitor *v);
-Visitor *qmp_output_get_visitor(QmpOutputVisitor *v);
+/*
+ * Create a new QMP output visitor.
+ *
+ * If everything else succeeds, pass @result to visit_complete() to
+ * collect the result of the visit.
+ */
+Visitor *qmp_output_visitor_new(QObject **result);
#endif
diff --git a/include/qapi/qmp/types.h b/include/qapi/qmp/types.h
index 7782ec5a60..f21ecf48fe 100644
--- a/include/qapi/qmp/types.h
+++ b/include/qapi/qmp/types.h
@@ -20,6 +20,5 @@
#include "qapi/qmp/qstring.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qlist.h"
-#include "qapi/qmp/qjson.h"
#endif /* QEMU_OBJECTS_H */
diff --git a/include/qapi/string-input-visitor.h b/include/qapi/string-input-visitor.h
index 7b76c2b9e3..33551340e3 100644
--- a/include/qapi/string-input-visitor.h
+++ b/include/qapi/string-input-visitor.h
@@ -22,9 +22,6 @@ typedef struct StringInputVisitor StringInputVisitor;
* QAPI structs, alternates, null, or arbitrary QTypes. It also
* requires a non-null list argument to visit_start_list().
*/
-StringInputVisitor *string_input_visitor_new(const char *str);
-void string_input_visitor_cleanup(StringInputVisitor *v);
-
-Visitor *string_input_get_visitor(StringInputVisitor *v);
+Visitor *string_input_visitor_new(const char *str);
#endif
diff --git a/include/qapi/string-output-visitor.h b/include/qapi/string-output-visitor.h
index e10522a35b..268dfe9986 100644
--- a/include/qapi/string-output-visitor.h
+++ b/include/qapi/string-output-visitor.h
@@ -18,14 +18,18 @@
typedef struct StringOutputVisitor StringOutputVisitor;
/*
+ * Create a new string output visitor.
+ *
+ * Using @human creates output that is a bit easier for humans to read
+ * (for example, showing integer values in both decimal and hex).
+ *
+ * If everything else succeeds, pass @result to visit_complete() to
+ * collect the result of the visit.
+ *
* The string output visitor does not implement support for visiting
* QAPI structs, alternates, null, or arbitrary QTypes. It also
* requires a non-null list argument to visit_start_list().
*/
-StringOutputVisitor *string_output_visitor_new(bool human);
-void string_output_visitor_cleanup(StringOutputVisitor *v);
-
-char *string_output_get_string(StringOutputVisitor *v);
-Visitor *string_output_get_visitor(StringOutputVisitor *v);
+Visitor *string_output_visitor_new(bool human, char **result);
#endif
diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index 145afd03e7..8bd47ee4bb 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -27,14 +27,18 @@
*/
/*
- * There are three classes of visitors; setting the class determines
+ * There are four classes of visitors; setting the class determines
* how QAPI enums are visited, as well as what additional restrictions
- * can be asserted.
+ * can be asserted. The values are intentionally chosen so as to
+ * permit some assertions based on whether a given bit is set (that
+ * is, some assertions apply to input and clone visitors, some
+ * assertions apply to output and clone visitors).
*/
typedef enum VisitorType {
- VISITOR_INPUT,
- VISITOR_OUTPUT,
- VISITOR_DEALLOC,
+ VISITOR_INPUT = 1,
+ VISITOR_OUTPUT = 2,
+ VISITOR_CLONE = 3,
+ VISITOR_DEALLOC = 4,
} VisitorType;
struct Visitor
@@ -47,7 +51,7 @@ struct Visitor
void (*check_struct)(Visitor *v, Error **errp);
/* Must be set to visit structs */
- void (*end_struct)(Visitor *v);
+ void (*end_struct)(Visitor *v, void **obj);
/* Must be set; implementations may require @list to be non-null,
* but must document it. */
@@ -58,7 +62,7 @@ struct Visitor
GenericList *(*next_list)(Visitor *v, GenericList *tail, size_t size);
/* Must be set */
- void (*end_list)(Visitor *v);
+ void (*end_list)(Visitor *v, void **list);
/* Must be set by input and dealloc visitors to visit alternates;
* optional for output visitors. */
@@ -67,7 +71,7 @@ struct Visitor
bool promote_int, Error **errp);
/* Optional, needed for dealloc visitor */
- void (*end_alternate)(Visitor *v);
+ void (*end_alternate)(Visitor *v, void **obj);
/* Must be set */
void (*type_int64)(Visitor *v, const char *name, int64_t *obj,
@@ -104,6 +108,12 @@ struct Visitor
/* Must be set */
VisitorType type;
+
+ /* Must be set for output visitors, optional otherwise. */
+ void (*complete)(Visitor *v, void *opaque);
+
+ /* Must be set */
+ void (*free)(Visitor *v);
};
#endif
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index 4d12167bdc..fb8f4eb6ec 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -24,19 +24,32 @@
* for doing work at each node of a QAPI graph; it can also be used
* for a virtual walk, where there is no actual QAPI C struct.
*
- * There are three kinds of visitor classes: input visitors (QMP,
+ * There are four kinds of visitor classes: input visitors (QMP,
* string, and QemuOpts) parse an external representation and build
* the corresponding QAPI graph, output visitors (QMP and string) take
- * a completed QAPI graph and generate an external representation, and
- * the dealloc visitor can take a QAPI graph (possibly partially
- * constructed) and recursively free its resources. While the dealloc
- * and QMP input/output visitors are general, the string and QemuOpts
- * visitors have some implementation limitations; see the
- * documentation for each visitor for more details on what it
+ * a completed QAPI graph and generate an external representation, the
+ * dealloc visitor can take a QAPI graph (possibly partially
+ * constructed) and recursively free its resources, and the clone
+ * visitor performs a deep clone of one QAPI object to another. While
+ * the dealloc and QMP input/output visitors are general, the string,
+ * QemuOpts, and clone visitors have some implementation limitations;
+ * see the documentation for each visitor for more details on what it
* supports. Also, see visitor-impl.h for the callback contracts
* implemented by each visitor, and docs/qapi-code-gen.txt for more
* about the QAPI code generator.
*
+ * All of the visitors are created via:
+ *
+ * Visitor *subtype_visitor_new(parameters...);
+ *
+ * A visitor should be used for exactly one top-level visit_type_FOO()
+ * or virtual walk; if that is successful, the caller can optionally
+ * call visit_complete() (for now, useful only for output visits, but
+ * safe to call on all visits). Then, regardless of success or
+ * failure, the user should call visit_free() to clean up resources.
+ * It is okay to free the visitor without completing the visit, if
+ * some other error is detected in the meantime.
+ *
* All QAPI types have a corresponding function with a signature
* roughly compatible with this:
*
@@ -68,9 +81,9 @@
*
* If an error is detected during visit_type_FOO() with an input
* visitor, then *@obj will be NULL for pointer types, and left
- * unchanged for scalar types. Using an output visitor with an
- * incomplete object has undefined behavior (other than a special case
- * for visit_type_str() treating NULL like ""), while the dealloc
+ * unchanged for scalar types. Using an output or clone visitor with
+ * an incomplete object has undefined behavior (other than a special
+ * case for visit_type_str() treating NULL like ""), while the dealloc
* visitor safely handles incomplete objects. Since input visitors
* never produce an incomplete object, such an object is possible only
* by manual construction.
@@ -90,11 +103,19 @@
*
* void qapi_free_FOO(FOO *obj);
*
- * which behaves like free() in that @obj may be NULL. Because of
- * these functions, the dealloc visitor is seldom used directly
- * outside of generated code. QAPI types can also inherit from a base
- * class; when this happens, a function is generated for easily going
- * from the derived type to the base type:
+ * where behaves like free() in that @obj may be NULL. Such objects
+ * may also be used with the following macro, provided alongside the
+ * clone visitor:
+ *
+ * Type *QAPI_CLONE(Type, src);
+ *
+ * in order to perform a deep clone of @src. Because of the generated
+ * qapi_free functions and the QAPI_CLONE() macro, the clone and
+ * dealloc visitor should not be used directly outside of QAPI code.
+ *
+ * QAPI types can also inherit from a base class; when this happens, a
+ * function is generated for easily going from the derived type to the
+ * base type:
*
* BASE *qapi_CHILD_base(CHILD *obj);
*
@@ -105,14 +126,14 @@
* Error *err = NULL;
* Visitor *v;
*
- * v = ...obtain input visitor...
+ * v = FOO_visitor_new(...);
* visit_type_Foo(v, NULL, &f, &err);
* if (err) {
* ...handle error...
* } else {
* ...use f...
* }
- * ...clean up v...
+ * visit_free(v);
* qapi_free_Foo(f);
* </example>
*
@@ -122,7 +143,7 @@
* Error *err = NULL;
* Visitor *v;
*
- * v = ...obtain input visitor...
+ * v = FOO_visitor_new(...);
* visit_type_FooList(v, NULL, &l, &err);
* if (err) {
* ...handle error...
@@ -131,7 +152,7 @@
* ...use l->value...
* }
* }
- * ...clean up v...
+ * visit_free(v);
* qapi_free_FooList(l);
* </example>
*
@@ -141,13 +162,17 @@
* Foo *f = ...obtain populated object...
* Error *err = NULL;
* Visitor *v;
+ * Type *result;
*
- * v = ...obtain output visitor...
+ * v = FOO_visitor_new(..., &result);
* visit_type_Foo(v, NULL, &f, &err);
* if (err) {
* ...handle error...
+ * } else {
+ * visit_complete(v, &result);
+ * ...use result...
* }
- * ...clean up v...
+ * visit_free(v);
* </example>
*
* When visiting a real QAPI struct, this file provides several
@@ -173,7 +198,7 @@
* Error *err = NULL;
* int value;
*
- * v = ...obtain visitor...
+ * v = FOO_visitor_new(...);
* visit_start_struct(v, NULL, NULL, 0, &err);
* if (err) {
* goto out;
@@ -193,15 +218,15 @@
* goto outlist;
* }
* outlist:
- * visit_end_list(v);
+ * visit_end_list(v, NULL);
* if (!err) {
* visit_check_struct(v, &err);
* }
* outobj:
- * visit_end_struct(v);
+ * visit_end_struct(v, NULL);
* out:
* error_propagate(errp, err);
- * ...clean up v...
+ * visit_free(v);
* </example>
*/
@@ -222,6 +247,31 @@ typedef struct GenericAlternate {
char padding[];
} GenericAlternate;
+/*** Visitor cleanup ***/
+
+/*
+ * Complete the visit, collecting any output.
+ *
+ * May only be called only once after a successful top-level
+ * visit_type_FOO() or visit_end_ITEM(), and marks the end of the
+ * visit. The @opaque pointer should match the output parameter
+ * passed to the subtype_visitor_new() used to create an output
+ * visitor, or NULL for any other visitor. Needed for output
+ * visitors, but may also be called with other visitors.
+ */
+void visit_complete(Visitor *v, void *opaque);
+
+/*
+ * Free @v and any resources it has tied up.
+ *
+ * May be called whether or not the visit has been successfully
+ * completed, but should not be called until a top-level
+ * visit_type_FOO() or visit_start_ITEM() has been performed on the
+ * visitor. Safe if @v is NULL.
+ */
+void visit_free(Visitor *v);
+
+
/*** Visiting structures ***/
/*
@@ -231,9 +281,9 @@ typedef struct GenericAlternate {
* container; see the general description of @name above.
*
* @obj must be non-NULL for a real walk, in which case @size
- * determines how much memory an input visitor will allocate into
- * *@obj. @obj may also be NULL for a virtual walk, in which case
- * @size is ignored.
+ * determines how much memory an input or clone visitor will allocate
+ * into *@obj. @obj may also be NULL for a virtual walk, in which
+ * case @size is ignored.
*
* @errp obeys typical error usage, and reports failures such as a
* member @name is not present, or present but not an object. On
@@ -242,8 +292,8 @@ typedef struct GenericAlternate {
* After visit_start_struct() succeeds, the caller may visit its
* members one after the other, passing the member's name and address
* within the struct. Finally, visit_end_struct() needs to be called
- * to clean up, even if intermediate visits fail. See the examples
- * above.
+ * with the same @obj to clean up, even if intermediate visits fail.
+ * See the examples above.
*
* FIXME Should this be named visit_start_object, since it is also
* used for QAPI unions, and maps to JSON objects?
@@ -267,12 +317,14 @@ void visit_check_struct(Visitor *v, Error **errp);
/*
* Complete an object visit started earlier.
*
+ * @obj must match what was passed to the paired visit_start_struct().
+ *
* Must be called after any successful use of visit_start_struct(),
* even if intermediate processing was skipped due to errors, to allow
* the backend to release any resources. Destroying the visitor early
- * behaves as if this was implicitly called.
+ * with visit_free() behaves as if this was implicitly called.
*/
-void visit_end_struct(Visitor *v);
+void visit_end_struct(Visitor *v, void **obj);
/*** Visiting lists ***/
@@ -284,9 +336,9 @@ void visit_end_struct(Visitor *v);
* container; see the general description of @name above.
*
* @list must be non-NULL for a real walk, in which case @size
- * determines how much memory an input visitor will allocate into
- * *@list (at least sizeof(GenericList)). Some visitors also allow
- * @list to be NULL for a virtual walk, in which case @size is
+ * determines how much memory an input or clone visitor will allocate
+ * into *@list (at least sizeof(GenericList)). Some visitors also
+ * allow @list to be NULL for a virtual walk, in which case @size is
* ignored.
*
* @errp obeys typical error usage, and reports failures such as a
@@ -299,8 +351,9 @@ void visit_end_struct(Visitor *v);
* visit (where @obj is NULL) uses other means. For each list
* element, call the appropriate visit_type_FOO() with name set to
* NULL and obj set to the address of the value member of the list
- * element. Finally, visit_end_list() needs to be called to clean up,
- * even if intermediate visits fail. See the examples above.
+ * element. Finally, visit_end_list() needs to be called with the
+ * same @list to clean up, even if intermediate visits fail. See the
+ * examples above.
*/
void visit_start_list(Visitor *v, const char *name, GenericList **list,
size_t size, Error **errp);
@@ -324,12 +377,14 @@ GenericList *visit_next_list(Visitor *v, GenericList *tail, size_t size);
/*
* Complete a list visit started earlier.
*
+ * @list must match what was passed to the paired visit_start_list().
+ *
* Must be called after any successful use of visit_start_list(), even
* if intermediate processing was skipped due to errors, to allow the
* backend to release any resources. Destroying the visitor early
- * behaves as if this was implicitly called.
+ * with visit_free() behaves as if this was implicitly called.
*/
-void visit_end_list(Visitor *v);
+void visit_end_list(Visitor *v, void **list);
/*** Visiting alternates ***/
@@ -340,15 +395,16 @@ void visit_end_list(Visitor *v);
* @name expresses the relationship of this alternate to its parent
* container; see the general description of @name above.
*
- * @obj must not be NULL. Input visitors use @size to determine how
- * much memory to allocate into *@obj, then determine the qtype of the
- * next thing to be visited, stored in (*@obj)->type. Other visitors
- * will leave @obj unchanged.
+ * @obj must not be NULL. Input and clone visitors use @size to
+ * determine how much memory to allocate into *@obj, then determine
+ * the qtype of the next thing to be visited, stored in (*@obj)->type.
+ * Other visitors will leave @obj unchanged.
*
* If @promote_int, treat integers as QTYPE_FLOAT.
*
- * If successful, this must be paired with visit_end_alternate() to
- * clean up, even if visiting the contents of the alternate fails.
+ * If successful, this must be paired with visit_end_alternate() with
+ * the same @obj to clean up, even if visiting the contents of the
+ * alternate fails.
*/
void visit_start_alternate(Visitor *v, const char *name,
GenericAlternate **obj, size_t size,
@@ -357,15 +413,15 @@ void visit_start_alternate(Visitor *v, const char *name,
/*
* Finish visiting an alternate type.
*
+ * @obj must match what was passed to the paired visit_start_alternate().
+ *
* Must be called after any successful use of visit_start_alternate(),
* even if intermediate processing was skipped due to errors, to allow
* the backend to release any resources. Destroying the visitor early
- * behaves as if this was implicitly called.
+ * with visit_free() behaves as if this was implicitly called.
*
- * TODO: Should all the visit_end_* interfaces take obj parameter, so
- * that dealloc visitor need not track what was passed in visit_start?
*/
-void visit_end_alternate(Visitor *v);
+void visit_end_alternate(Visitor *v, void **obj);
/*** Other helpers ***/
@@ -507,9 +563,10 @@ void visit_type_bool(Visitor *v, const char *name, bool *obj, Error **errp);
* @name expresses the relationship of this string to its parent
* container; see the general description of @name above.
*
- * @obj must be non-NULL. Input visitors set *@obj to the value
- * (never NULL). Other visitors leave *@obj unchanged, and commonly
- * treat NULL like "".
+ * @obj must be non-NULL. Input and clone visitors set *@obj to the
+ * value (always using "" rather than NULL for an empty string).
+ * Other visitors leave *@obj unchanged, and commonly treat NULL like
+ * "".
*
* It is safe to cast away const when preparing a (const char *) value
* into @obj for use by an output visitor.
diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h
index 462033a4de..2f3763f781 100644
--- a/include/qemu/sockets.h
+++ b/include/qemu/sockets.h
@@ -107,10 +107,6 @@ SocketAddress *socket_local_address(int fd, Error **errp);
*/
SocketAddress *socket_remote_address(int fd, Error **errp);
-
-void qapi_copy_SocketAddress(SocketAddress **p_dest,
- SocketAddress *src);
-
/**
* socket_address_to_string:
* @addr: the socket address struct