xref: /qemu/qapi/qapi-visit-core.c (revision faad584adb48737aa3b39984786442a1a9c42aa4)
12345c77cSMichael Roth /*
22345c77cSMichael Roth  * Core Definitions for QAPI Visitor Classes
32345c77cSMichael Roth  *
47c91aabdSEric Blake  * Copyright (C) 2012-2016 Red Hat, Inc.
52345c77cSMichael Roth  * Copyright IBM, Corp. 2011
62345c77cSMichael Roth  *
72345c77cSMichael Roth  * Authors:
82345c77cSMichael Roth  *  Anthony Liguori   <aliguori@us.ibm.com>
92345c77cSMichael Roth  *
102345c77cSMichael Roth  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
112345c77cSMichael Roth  * See the COPYING.LIB file in the top-level directory.
122345c77cSMichael Roth  *
132345c77cSMichael Roth  */
142345c77cSMichael Roth 
15cbf21151SPeter Maydell #include "qemu/osdep.h"
16da34e65cSMarkus Armbruster #include "qapi/error.h"
177b1b5d19SPaolo Bonzini #include "qapi/qmp/qerror.h"
187b1b5d19SPaolo Bonzini #include "qapi/visitor.h"
197b1b5d19SPaolo Bonzini #include "qapi/visitor-impl.h"
20ebfd93b6SDaniel P. Berrange #include "trace.h"
212345c77cSMichael Roth 
223b098d56SEric Blake void visit_complete(Visitor *v, void *opaque)
233b098d56SEric Blake {
243b098d56SEric Blake     assert(v->type != VISITOR_OUTPUT || v->complete);
25ebfd93b6SDaniel P. Berrange     trace_visit_complete(v, opaque);
263b098d56SEric Blake     if (v->complete) {
273b098d56SEric Blake         v->complete(v, opaque);
283b098d56SEric Blake     }
293b098d56SEric Blake }
303b098d56SEric Blake 
312c0ef9f4SEric Blake void visit_free(Visitor *v)
322c0ef9f4SEric Blake {
33ebfd93b6SDaniel P. Berrange     trace_visit_free(v);
342c0ef9f4SEric Blake     if (v) {
352c0ef9f4SEric Blake         v->free(v);
362c0ef9f4SEric Blake     }
372c0ef9f4SEric Blake }
382c0ef9f4SEric Blake 
3951e72bc1SEric Blake void visit_start_struct(Visitor *v, const char *name, void **obj,
40337283dfSEric Blake                         size_t size, Error **errp)
412345c77cSMichael Roth {
42e58d695eSEric Blake     Error *err = NULL;
43e58d695eSEric Blake 
44ebfd93b6SDaniel P. Berrange     trace_visit_start_struct(v, name, obj, size);
45adfb264cSEric Blake     if (obj) {
46adfb264cSEric Blake         assert(size);
47a15fcc3cSEric Blake         assert(!(v->type & VISITOR_OUTPUT) || *obj);
48adfb264cSEric Blake     }
49e58d695eSEric Blake     v->start_struct(v, name, obj, size, &err);
50a15fcc3cSEric Blake     if (obj && (v->type & VISITOR_INPUT)) {
51e58d695eSEric Blake         assert(!err != !*obj);
52e58d695eSEric Blake     }
53e58d695eSEric Blake     error_propagate(errp, err);
542345c77cSMichael Roth }
552345c77cSMichael Roth 
5615c2f669SEric Blake void visit_check_struct(Visitor *v, Error **errp)
572345c77cSMichael Roth {
58ebfd93b6SDaniel P. Berrange     trace_visit_check_struct(v);
5915c2f669SEric Blake     if (v->check_struct) {
6015c2f669SEric Blake         v->check_struct(v, errp);
6115c2f669SEric Blake     }
6215c2f669SEric Blake }
6315c2f669SEric Blake 
641158bb2aSEric Blake void visit_end_struct(Visitor *v, void **obj)
6515c2f669SEric Blake {
66ebfd93b6SDaniel P. Berrange     trace_visit_end_struct(v, obj);
671158bb2aSEric Blake     v->end_struct(v, obj);
682345c77cSMichael Roth }
692345c77cSMichael Roth 
70d9f62ddeSEric Blake void visit_start_list(Visitor *v, const char *name, GenericList **list,
71d9f62ddeSEric Blake                       size_t size, Error **errp)
722345c77cSMichael Roth {
73d9f62ddeSEric Blake     Error *err = NULL;
74d9f62ddeSEric Blake 
75d9f62ddeSEric Blake     assert(!list || size >= sizeof(GenericList));
76ebfd93b6SDaniel P. Berrange     trace_visit_start_list(v, name, list, size);
77d9f62ddeSEric Blake     v->start_list(v, name, list, size, &err);
78a15fcc3cSEric Blake     if (list && (v->type & VISITOR_INPUT)) {
79d9f62ddeSEric Blake         assert(!(err && *list));
80d9f62ddeSEric Blake     }
81d9f62ddeSEric Blake     error_propagate(errp, err);
822345c77cSMichael Roth }
832345c77cSMichael Roth 
84d9f62ddeSEric Blake GenericList *visit_next_list(Visitor *v, GenericList *tail, size_t size)
852345c77cSMichael Roth {
86d9f62ddeSEric Blake     assert(tail && size >= sizeof(GenericList));
87ebfd93b6SDaniel P. Berrange     trace_visit_next_list(v, tail, size);
88d9f62ddeSEric Blake     return v->next_list(v, tail, size);
892345c77cSMichael Roth }
902345c77cSMichael Roth 
91a4a1c70dSMarkus Armbruster void visit_check_list(Visitor *v, Error **errp)
92a4a1c70dSMarkus Armbruster {
93a4a1c70dSMarkus Armbruster     trace_visit_check_list(v);
94a4a1c70dSMarkus Armbruster     if (v->check_list) {
95a4a1c70dSMarkus Armbruster         v->check_list(v, errp);
96a4a1c70dSMarkus Armbruster     }
97a4a1c70dSMarkus Armbruster }
98a4a1c70dSMarkus Armbruster 
991158bb2aSEric Blake void visit_end_list(Visitor *v, void **obj)
1002345c77cSMichael Roth {
101ebfd93b6SDaniel P. Berrange     trace_visit_end_list(v, obj);
1021158bb2aSEric Blake     v->end_list(v, obj);
1032345c77cSMichael Roth }
1042345c77cSMichael Roth 
105dbf11922SEric Blake void visit_start_alternate(Visitor *v, const char *name,
106dbf11922SEric Blake                            GenericAlternate **obj, size_t size,
10760390d2dSMarc-André Lureau                            Error **errp)
108dbf11922SEric Blake {
109e58d695eSEric Blake     Error *err = NULL;
110e58d695eSEric Blake 
111dbf11922SEric Blake     assert(obj && size >= sizeof(GenericAlternate));
112a15fcc3cSEric Blake     assert(!(v->type & VISITOR_OUTPUT) || *obj);
11360390d2dSMarc-André Lureau     trace_visit_start_alternate(v, name, obj, size);
114dbf11922SEric Blake     if (v->start_alternate) {
11560390d2dSMarc-André Lureau         v->start_alternate(v, name, obj, size, &err);
116dbf11922SEric Blake     }
117a15fcc3cSEric Blake     if (v->type & VISITOR_INPUT) {
118e58d695eSEric Blake         assert(v->start_alternate && !err != !*obj);
119e58d695eSEric Blake     }
120e58d695eSEric Blake     error_propagate(errp, err);
121dbf11922SEric Blake }
122dbf11922SEric Blake 
1231158bb2aSEric Blake void visit_end_alternate(Visitor *v, void **obj)
124dbf11922SEric Blake {
125ebfd93b6SDaniel P. Berrange     trace_visit_end_alternate(v, obj);
126dbf11922SEric Blake     if (v->end_alternate) {
1271158bb2aSEric Blake         v->end_alternate(v, obj);
128dbf11922SEric Blake     }
129dbf11922SEric Blake }
130dbf11922SEric Blake 
13151e72bc1SEric Blake bool visit_optional(Visitor *v, const char *name, bool *present)
1322345c77cSMichael Roth {
133ebfd93b6SDaniel P. Berrange     trace_visit_optional(v, name, present);
134297a3646SMarkus Armbruster     if (v->optional) {
1350b2a0d6bSEric Blake         v->optional(v, name, present);
1362345c77cSMichael Roth     }
13729637a6eSEric Blake     return *present;
1382345c77cSMichael Roth }
1392345c77cSMichael Roth 
14068ab47e4SEric Blake bool visit_is_input(Visitor *v)
14168ab47e4SEric Blake {
14268ab47e4SEric Blake     return v->type == VISITOR_INPUT;
14368ab47e4SEric Blake }
14468ab47e4SEric Blake 
1458e08bf4eSMarkus Armbruster bool visit_is_dealloc(Visitor *v)
1468e08bf4eSMarkus Armbruster {
1478e08bf4eSMarkus Armbruster     return v->type == VISITOR_DEALLOC;
1488e08bf4eSMarkus Armbruster }
1498e08bf4eSMarkus Armbruster 
15051e72bc1SEric Blake void visit_type_int(Visitor *v, const char *name, int64_t *obj, Error **errp)
1512345c77cSMichael Roth {
152adfb264cSEric Blake     assert(obj);
153ebfd93b6SDaniel P. Berrange     trace_visit_type_int(v, name, obj);
1540b2a0d6bSEric Blake     v->type_int64(v, name, obj, errp);
1552345c77cSMichael Roth }
1562345c77cSMichael Roth 
15704e070d2SEric Blake static void visit_type_uintN(Visitor *v, uint64_t *obj, const char *name,
15804e070d2SEric Blake                              uint64_t max, const char *type, Error **errp)
15904e070d2SEric Blake {
16004e070d2SEric Blake     Error *err = NULL;
16104e070d2SEric Blake     uint64_t value = *obj;
16204e070d2SEric Blake 
163*faad584aSMarkus Armbruster     assert(v->type == VISITOR_INPUT || value <= max);
164*faad584aSMarkus Armbruster 
1650b2a0d6bSEric Blake     v->type_uint64(v, name, &value, &err);
16604e070d2SEric Blake     if (err) {
16704e070d2SEric Blake         error_propagate(errp, err);
16804e070d2SEric Blake     } else if (value > max) {
169*faad584aSMarkus Armbruster         assert(v->type == VISITOR_INPUT);
17004e070d2SEric Blake         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
17104e070d2SEric Blake                    name ? name : "null", type);
17204e070d2SEric Blake     } else {
17304e070d2SEric Blake         *obj = value;
17404e070d2SEric Blake     }
17504e070d2SEric Blake }
17604e070d2SEric Blake 
17751e72bc1SEric Blake void visit_type_uint8(Visitor *v, const char *name, uint8_t *obj,
17851e72bc1SEric Blake                       Error **errp)
1794e27e819SMichael Roth {
180ebfd93b6SDaniel P. Berrange     uint64_t value;
181ebfd93b6SDaniel P. Berrange 
182ebfd93b6SDaniel P. Berrange     trace_visit_type_uint8(v, name, obj);
183ebfd93b6SDaniel P. Berrange     value = *obj;
18404e070d2SEric Blake     visit_type_uintN(v, &value, name, UINT8_MAX, "uint8_t", errp);
1854e27e819SMichael Roth     *obj = value;
1864e27e819SMichael Roth }
1874e27e819SMichael Roth 
18851e72bc1SEric Blake void visit_type_uint16(Visitor *v, const char *name, uint16_t *obj,
18904e070d2SEric Blake                        Error **errp)
1904e27e819SMichael Roth {
191ebfd93b6SDaniel P. Berrange     uint64_t value;
192ebfd93b6SDaniel P. Berrange 
193ebfd93b6SDaniel P. Berrange     trace_visit_type_uint16(v, name, obj);
194ebfd93b6SDaniel P. Berrange     value = *obj;
19504e070d2SEric Blake     visit_type_uintN(v, &value, name, UINT16_MAX, "uint16_t", errp);
1964e27e819SMichael Roth     *obj = value;
1974e27e819SMichael Roth }
1984e27e819SMichael Roth 
19951e72bc1SEric Blake void visit_type_uint32(Visitor *v, const char *name, uint32_t *obj,
20004e070d2SEric Blake                        Error **errp)
2014e27e819SMichael Roth {
202ebfd93b6SDaniel P. Berrange     uint64_t value;
203ebfd93b6SDaniel P. Berrange 
204ebfd93b6SDaniel P. Berrange     trace_visit_type_uint32(v, name, obj);
205ebfd93b6SDaniel P. Berrange     value = *obj;
20604e070d2SEric Blake     visit_type_uintN(v, &value, name, UINT32_MAX, "uint32_t", errp);
2074e27e819SMichael Roth     *obj = value;
2084e27e819SMichael Roth }
2094e27e819SMichael Roth 
21051e72bc1SEric Blake void visit_type_uint64(Visitor *v, const char *name, uint64_t *obj,
21104e070d2SEric Blake                        Error **errp)
2124e27e819SMichael Roth {
213adfb264cSEric Blake     assert(obj);
214ebfd93b6SDaniel P. Berrange     trace_visit_type_uint64(v, name, obj);
2150b2a0d6bSEric Blake     v->type_uint64(v, name, obj, errp);
2164e27e819SMichael Roth }
2174e27e819SMichael Roth 
21804e070d2SEric Blake static void visit_type_intN(Visitor *v, int64_t *obj, const char *name,
21904e070d2SEric Blake                             int64_t min, int64_t max, const char *type,
22004e070d2SEric Blake                             Error **errp)
2214e27e819SMichael Roth {
22204e070d2SEric Blake     Error *err = NULL;
22304e070d2SEric Blake     int64_t value = *obj;
224297a3646SMarkus Armbruster 
225*faad584aSMarkus Armbruster     assert(v->type == VISITOR_INPUT || (value >= min && value <= max));
226*faad584aSMarkus Armbruster 
2270b2a0d6bSEric Blake     v->type_int64(v, name, &value, &err);
22804e070d2SEric Blake     if (err) {
22904e070d2SEric Blake         error_propagate(errp, err);
23004e070d2SEric Blake     } else if (value < min || value > max) {
231*faad584aSMarkus Armbruster         assert(v->type == VISITOR_INPUT);
232c6bd8c70SMarkus Armbruster         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
23304e070d2SEric Blake                    name ? name : "null", type);
23404e070d2SEric Blake     } else {
2354e27e819SMichael Roth         *obj = value;
2364e27e819SMichael Roth     }
2374e27e819SMichael Roth }
2384e27e819SMichael Roth 
23951e72bc1SEric Blake void visit_type_int8(Visitor *v, const char *name, int8_t *obj, Error **errp)
24004e070d2SEric Blake {
241ebfd93b6SDaniel P. Berrange     int64_t value;
242ebfd93b6SDaniel P. Berrange 
243ebfd93b6SDaniel P. Berrange     trace_visit_type_int8(v, name, obj);
244ebfd93b6SDaniel P. Berrange     value = *obj;
24504e070d2SEric Blake     visit_type_intN(v, &value, name, INT8_MIN, INT8_MAX, "int8_t", errp);
24604e070d2SEric Blake     *obj = value;
24704e070d2SEric Blake }
24804e070d2SEric Blake 
24951e72bc1SEric Blake void visit_type_int16(Visitor *v, const char *name, int16_t *obj,
25051e72bc1SEric Blake                       Error **errp)
2514e27e819SMichael Roth {
252ebfd93b6SDaniel P. Berrange     int64_t value;
253ebfd93b6SDaniel P. Berrange 
254ebfd93b6SDaniel P. Berrange     trace_visit_type_int16(v, name, obj);
255ebfd93b6SDaniel P. Berrange     value = *obj;
25604e070d2SEric Blake     visit_type_intN(v, &value, name, INT16_MIN, INT16_MAX, "int16_t", errp);
2574e27e819SMichael Roth     *obj = value;
2584e27e819SMichael Roth }
2594e27e819SMichael Roth 
26051e72bc1SEric Blake void visit_type_int32(Visitor *v, const char *name, int32_t *obj,
26151e72bc1SEric Blake                       Error **errp)
2624e27e819SMichael Roth {
263ebfd93b6SDaniel P. Berrange     int64_t value;
264ebfd93b6SDaniel P. Berrange 
265ebfd93b6SDaniel P. Berrange     trace_visit_type_int32(v, name, obj);
266ebfd93b6SDaniel P. Berrange     value = *obj;
26704e070d2SEric Blake     visit_type_intN(v, &value, name, INT32_MIN, INT32_MAX, "int32_t", errp);
2684e27e819SMichael Roth     *obj = value;
2694e27e819SMichael Roth }
2704e27e819SMichael Roth 
27151e72bc1SEric Blake void visit_type_int64(Visitor *v, const char *name, int64_t *obj,
27251e72bc1SEric Blake                       Error **errp)
2734e27e819SMichael Roth {
274adfb264cSEric Blake     assert(obj);
275ebfd93b6SDaniel P. Berrange     trace_visit_type_int64(v, name, obj);
2760b2a0d6bSEric Blake     v->type_int64(v, name, obj, errp);
2774e27e819SMichael Roth }
2784e27e819SMichael Roth 
27951e72bc1SEric Blake void visit_type_size(Visitor *v, const char *name, uint64_t *obj,
28051e72bc1SEric Blake                      Error **errp)
281092705d4SLaszlo Ersek {
282adfb264cSEric Blake     assert(obj);
283ebfd93b6SDaniel P. Berrange     trace_visit_type_size(v, name, obj);
284b8877962SVasilis Liaskovitis     if (v->type_size) {
2850b2a0d6bSEric Blake         v->type_size(v, name, obj, errp);
286b8877962SVasilis Liaskovitis     } else {
2870b2a0d6bSEric Blake         v->type_uint64(v, name, obj, errp);
288b8877962SVasilis Liaskovitis     }
289092705d4SLaszlo Ersek }
290092705d4SLaszlo Ersek 
29151e72bc1SEric Blake void visit_type_bool(Visitor *v, const char *name, bool *obj, Error **errp)
2922345c77cSMichael Roth {
293adfb264cSEric Blake     assert(obj);
294ebfd93b6SDaniel P. Berrange     trace_visit_type_bool(v, name, obj);
2950b2a0d6bSEric Blake     v->type_bool(v, name, obj, errp);
2962345c77cSMichael Roth }
2972345c77cSMichael Roth 
29851e72bc1SEric Blake void visit_type_str(Visitor *v, const char *name, char **obj, Error **errp)
2992345c77cSMichael Roth {
300e58d695eSEric Blake     Error *err = NULL;
301e58d695eSEric Blake 
302e58d695eSEric Blake     assert(obj);
303adfb264cSEric Blake     /* TODO: Fix callers to not pass NULL when they mean "", so that we
304adfb264cSEric Blake      * can enable:
305a15fcc3cSEric Blake     assert(!(v->type & VISITOR_OUTPUT) || *obj);
306adfb264cSEric Blake      */
307ebfd93b6SDaniel P. Berrange     trace_visit_type_str(v, name, obj);
308e58d695eSEric Blake     v->type_str(v, name, obj, &err);
309a15fcc3cSEric Blake     if (v->type & VISITOR_INPUT) {
310e58d695eSEric Blake         assert(!err != !*obj);
311e58d695eSEric Blake     }
312e58d695eSEric Blake     error_propagate(errp, err);
3132345c77cSMichael Roth }
3142345c77cSMichael Roth 
31551e72bc1SEric Blake void visit_type_number(Visitor *v, const char *name, double *obj,
31651e72bc1SEric Blake                        Error **errp)
3172345c77cSMichael Roth {
318adfb264cSEric Blake     assert(obj);
319ebfd93b6SDaniel P. Berrange     trace_visit_type_number(v, name, obj);
3200b2a0d6bSEric Blake     v->type_number(v, name, obj, errp);
3212345c77cSMichael Roth }
3220f71a1e0SPaolo Bonzini 
32351e72bc1SEric Blake void visit_type_any(Visitor *v, const char *name, QObject **obj, Error **errp)
32428770e05SMarkus Armbruster {
325e58d695eSEric Blake     Error *err = NULL;
326e58d695eSEric Blake 
327e58d695eSEric Blake     assert(obj);
328adfb264cSEric Blake     assert(v->type != VISITOR_OUTPUT || *obj);
329ebfd93b6SDaniel P. Berrange     trace_visit_type_any(v, name, obj);
330e58d695eSEric Blake     v->type_any(v, name, obj, &err);
331e58d695eSEric Blake     if (v->type == VISITOR_INPUT) {
332e58d695eSEric Blake         assert(!err != !*obj);
333e58d695eSEric Blake     }
334e58d695eSEric Blake     error_propagate(errp, err);
33528770e05SMarkus Armbruster }
33628770e05SMarkus Armbruster 
337d2f95f4dSMarkus Armbruster void visit_type_null(Visitor *v, const char *name, QNull **obj,
338d2f95f4dSMarkus Armbruster                      Error **errp)
3393bc97fd5SEric Blake {
340d2f95f4dSMarkus Armbruster     trace_visit_type_null(v, name, obj);
341d2f95f4dSMarkus Armbruster     v->type_null(v, name, obj, errp);
3423bc97fd5SEric Blake }
3433bc97fd5SEric Blake 
344983f52d4SEric Blake static void output_type_enum(Visitor *v, const char *name, int *obj,
345f7abe0ecSMarc-André Lureau                              const QEnumLookup *lookup, Error **errp)
3460f71a1e0SPaolo Bonzini {
3470f71a1e0SPaolo Bonzini     int value = *obj;
3480f71a1e0SPaolo Bonzini     char *enum_str;
3490f71a1e0SPaolo Bonzini 
350f7abe0ecSMarc-André Lureau     enum_str = (char *)qapi_enum_lookup(lookup, value);
35151e72bc1SEric Blake     visit_type_str(v, name, &enum_str, errp);
3520f71a1e0SPaolo Bonzini }
3530f71a1e0SPaolo Bonzini 
354983f52d4SEric Blake static void input_type_enum(Visitor *v, const char *name, int *obj,
355f7abe0ecSMarc-André Lureau                             const QEnumLookup *lookup, Error **errp)
3560f71a1e0SPaolo Bonzini {
357297a3646SMarkus Armbruster     Error *local_err = NULL;
358113e47aeSMarkus Armbruster     int64_t value;
3590f71a1e0SPaolo Bonzini     char *enum_str;
3600f71a1e0SPaolo Bonzini 
36151e72bc1SEric Blake     visit_type_str(v, name, &enum_str, &local_err);
362297a3646SMarkus Armbruster     if (local_err) {
363297a3646SMarkus Armbruster         error_propagate(errp, local_err);
3640f71a1e0SPaolo Bonzini         return;
3650f71a1e0SPaolo Bonzini     }
3660f71a1e0SPaolo Bonzini 
367f7abe0ecSMarc-André Lureau     value = qapi_enum_parse(lookup, enum_str, -1, NULL);
368113e47aeSMarkus Armbruster     if (value < 0) {
369c6bd8c70SMarkus Armbruster         error_setg(errp, QERR_INVALID_PARAMETER, enum_str);
3700f71a1e0SPaolo Bonzini         g_free(enum_str);
3710f71a1e0SPaolo Bonzini         return;
3720f71a1e0SPaolo Bonzini     }
3730f71a1e0SPaolo Bonzini 
3740f71a1e0SPaolo Bonzini     g_free(enum_str);
3750f71a1e0SPaolo Bonzini     *obj = value;
3760f71a1e0SPaolo Bonzini }
377983f52d4SEric Blake 
378983f52d4SEric Blake void visit_type_enum(Visitor *v, const char *name, int *obj,
379f7abe0ecSMarc-André Lureau                      const QEnumLookup *lookup, Error **errp)
380983f52d4SEric Blake {
381f7abe0ecSMarc-André Lureau     assert(obj && lookup);
3826514532fSStefan Hajnoczi     trace_visit_type_enum(v, name, obj);
383a15fcc3cSEric Blake     switch (v->type) {
384a15fcc3cSEric Blake     case VISITOR_INPUT:
385f7abe0ecSMarc-André Lureau         input_type_enum(v, name, obj, lookup, errp);
386a15fcc3cSEric Blake         break;
387a15fcc3cSEric Blake     case VISITOR_OUTPUT:
388f7abe0ecSMarc-André Lureau         output_type_enum(v, name, obj, lookup, errp);
389a15fcc3cSEric Blake         break;
390a15fcc3cSEric Blake     case VISITOR_CLONE:
391a15fcc3cSEric Blake         /* nothing further to do, scalar value was already copied by
392a15fcc3cSEric Blake          * g_memdup() during visit_start_*() */
393a15fcc3cSEric Blake         break;
394a15fcc3cSEric Blake     case VISITOR_DEALLOC:
395a15fcc3cSEric Blake         /* nothing to deallocate for a scalar */
396a15fcc3cSEric Blake         break;
397983f52d4SEric Blake     }
398983f52d4SEric Blake }
399