Rizin
unix-like reverse engineering framework and cli tools
function.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2013-2020 pancake <pancake@nopcode.org>
2 // SPDX-FileCopyrightText: 2013-2020 oddcoder <ahmedsoliman@oddcoder.com>
3 // SPDX-FileCopyrightText: 2013-2020 sivaramaaa <sivaramaaa@gmail.com>
4 // SPDX-FileCopyrightText: 2021 Anton Kochkov <anton.kochkov@gmail.com>
5 // SPDX-License-Identifier: LGPL-3.0-only
6 
7 #include <rz_util.h>
8 #include <rz_type.h>
9 #include <string.h>
10 
18  RzCallable *callable = RZ_NEW0(RzCallable);
19  if (!callable) {
20  return NULL;
21  }
22  callable->ret = NULL;
23  callable->name = name ? strdup(name) : NULL;
25  return callable;
26 }
27 
34  rz_return_val_if_fail(callable, NULL);
35  RzCallable *newcallable = RZ_NEW0(RzCallable);
36  if (!newcallable) {
37  return NULL;
38  }
39  newcallable->ret = callable->ret ? rz_type_clone(callable->ret) : NULL;
40  newcallable->name = callable->name ? strdup(callable->name) : NULL;
42  void **it;
43  rz_pvector_foreach (callable->args, it) {
44  RzCallableArg *arg = *it;
46  }
47  return newcallable;
48 }
49 
56  rz_type_free(callable->ret);
57  rz_pvector_free(callable->args);
58  free(callable->name);
59  free(callable);
60 }
61 
70  rz_return_val_if_fail(typedb && name && type, NULL);
72  if (!arg) {
73  return NULL;
74  }
75  arg->name = strdup(name);
76  arg->type = type;
77  return arg;
78 }
79 
88  if (!newarg) {
89  return NULL;
90  }
91  newarg->name = strdup(arg->name);
92  newarg->type = rz_type_clone(arg->type);
93  return newarg;
94 }
95 
102  if (!arg) {
103  return;
104  }
105  free(arg->name);
106  rz_type_free(arg->type);
107  free(arg);
108 }
109 
117  rz_return_val_if_fail(callable && arg, false);
118  rz_pvector_push(callable->args, arg);
119  return true;
120 }
121 
122 // Function prototypes api
123 
132  rz_return_val_if_fail(typedb && name, NULL);
133  RzCallable *callable = rz_type_callable_new(name);
134  if (!callable) {
135  return NULL;
136  }
137  callable->ret = type;
138  return callable;
139 }
140 
148  rz_return_val_if_fail(typedb && callable && callable->name, false);
149  if (rz_type_func_exist(typedb, callable->name)) {
150  return false;
151  }
152  ht_pp_insert(typedb->callables, callable->name, callable);
153  return true;
154 }
155 
163  rz_return_val_if_fail(typedb && name, NULL);
164  bool found = false;
165  RzCallable *callable = ht_pp_find(typedb->callables, name, &found);
166  if (!found || !callable) {
167  RZ_LOG_DEBUG("Cannot find function type \"%s\"\n", name);
168  return NULL;
169  }
170  return callable;
171 }
172 
179 RZ_API bool rz_type_func_delete(RzTypeDB *typedb, RZ_NONNULL const char *name) {
180  rz_return_val_if_fail(typedb && name, false);
181  ht_pp_delete(typedb->callables, name);
182  return true;
183 }
184 
185 static void callables_ht_free(HtPPKv *kv) {
186  rz_type_callable_free(kv->value);
187 }
188 
193  ht_pp_free(typedb->callables);
194  typedb->callables = ht_pp_new(NULL, callables_ht_free, NULL);
195 }
196 
203 RZ_API bool rz_type_func_exist(RzTypeDB *typedb, RZ_NONNULL const char *name) {
204  rz_return_val_if_fail(typedb && name, false);
205  bool found = false;
206  return ht_pp_find(typedb->callables, name, &found) && found;
207 }
208 
216  rz_return_val_if_fail(typedb && name, NULL);
217  RzCallable *callable = rz_type_func_get(typedb, name);
218  if (!callable) {
219  return NULL;
220  }
221  return callable->ret;
222 }
223 
230 RZ_API RZ_BORROW const char *rz_type_func_cc(RzTypeDB *typedb, RZ_NONNULL const char *name) {
231  rz_return_val_if_fail(typedb && name, NULL);
232  RzCallable *callable = rz_type_func_get(typedb, name);
233  if (!callable) {
234  return NULL;
235  }
236  return callable->cc;
237 }
238 
246 RZ_API bool rz_type_func_cc_set(RzTypeDB *typedb, const char *name, const char *cc) {
247  rz_return_val_if_fail(typedb && name, false);
248  RzCallable *callable = rz_type_func_get(typedb, name);
249  if (!callable) {
250  return false;
251  }
252  callable->cc = strdup(cc);
253  return true;
254 }
255 
263  rz_return_val_if_fail(typedb && name, 0);
264  RzCallable *callable = rz_type_func_get(typedb, name);
265  if (!callable) {
266  return -1;
267  }
268  return rz_pvector_len(callable->args);
269 }
270 
279  rz_return_val_if_fail(typedb && name, NULL);
280  RzCallable *callable = rz_type_func_get(typedb, name);
281  if (!callable) {
282  return NULL;
283  }
284  if (i >= rz_pvector_len(callable->args)) {
285  return NULL;
286  }
287  RzCallableArg *arg = *rz_pvector_index_ptr(callable->args, i);
288  if (!arg) {
289  rz_warn_if_reached(); // should not happen in the types database
290  return NULL;
291  }
292  return arg->type;
293 }
294 
302 RZ_API RZ_BORROW const char *rz_type_func_args_name(RzTypeDB *typedb, RZ_NONNULL const char *name, int i) {
303  rz_return_val_if_fail(typedb && name, NULL);
304  RzCallable *callable = rz_type_func_get(typedb, name);
305  if (!callable) {
306  return NULL;
307  }
308  if (i >= rz_pvector_len(callable->args)) {
309  return NULL;
310  }
311  RzCallableArg *arg = *rz_pvector_index_ptr(callable->args, i);
312  if (!arg) {
313  rz_warn_if_reached(); // should not happen in the types database
314  return NULL;
315  }
316  return arg->name;
317 }
318 
327 RZ_API bool rz_type_func_arg_add(RzTypeDB *typedb, RZ_NONNULL const char *func_name, RZ_NONNULL const char *arg_name, RZ_OWN RZ_NONNULL RzType *arg_type) {
328  rz_return_val_if_fail(typedb && func_name, false);
329  RzCallable *callable = rz_type_func_get(typedb, func_name);
330  if (!callable) {
331  return false;
332  }
333  RzCallableArg *arg = rz_type_callable_arg_new(typedb, arg_name, arg_type);
334  if (!arg) {
335  return false;
336  }
337  rz_pvector_push(callable->args, arg);
338  return true;
339 }
340 
349  rz_return_val_if_fail(typedb && name && type, false);
350  RzCallable *callable = rz_type_func_get(typedb, name);
351  if (!callable) {
352  return false;
353  }
354  callable->ret = type;
355  return true;
356 }
357 
365  rz_return_val_if_fail(type, false);
366  return type->kind == RZ_TYPE_KIND_CALLABLE;
367 }
368 
376  rz_return_val_if_fail(type, false);
377  if (type->kind != RZ_TYPE_KIND_POINTER) {
378  return false;
379  }
380  if (type->pointer.type->kind == RZ_TYPE_KIND_CALLABLE) {
381  return true;
382  } else if (type->pointer.type->kind == RZ_TYPE_KIND_POINTER) {
383  return rz_type_is_callable_ptr(type->pointer.type);
384  }
385  return false;
386 }
387 
400  rz_return_val_if_fail(type, false);
401  if (type->kind != RZ_TYPE_KIND_POINTER) {
402  return false;
403  }
404  // There should not exist pointers to the empty types
405  RzType *ptr = type->pointer.type;
406  rz_return_val_if_fail(ptr, false);
407  if (ptr->kind == RZ_TYPE_KIND_POINTER) {
408  return rz_type_is_callable_ptr_nested(ptr);
409  }
410  return ptr->kind == RZ_TYPE_KIND_CALLABLE;
411 }
412 
413 static const RzCallable *callable_ptr_unwrap(RZ_NONNULL const RzType *type, size_t *acc) {
415  if (type->kind == RZ_TYPE_KIND_POINTER) {
416  *acc = *acc + 1;
417  return callable_ptr_unwrap(type->pointer.type, acc);
418  }
419  return type->kind == RZ_TYPE_KIND_CALLABLE ? type->callable : NULL;
420 }
421 
422 static inline char *callable_name_or_ptr(RZ_NONNULL const RzCallable *callable, size_t ptr_depth) {
423  if (ptr_depth > 0) {
424  // Due to the portability issues with other solutions we use this hack to repeat the '*' character
425  return rz_str_newf("(%.*s%s)", (int)ptr_depth, "****************", rz_str_get(callable->name));
426  } else {
427  return strdup(rz_str_get(callable->name));
428  }
429 }
430 
431 static bool callable_as_string(RzStrBuf *buf, const RzTypeDB *typedb, RZ_NONNULL const RzCallable *callable, size_t ptr_depth) {
432  rz_return_val_if_fail(buf && typedb && callable, false);
433 
434  if (callable->noret) {
435  rz_strbuf_append(buf, "__attribute__((noreturn)) ");
436  }
437  char *ret_str = callable->ret ? rz_type_as_string(typedb, callable->ret) : NULL;
438  char *callable_name = callable_name_or_ptr(callable, ptr_depth);
439  rz_strbuf_appendf(buf, "%s %s(", ret_str ? ret_str : "void", callable_name);
440  free(ret_str);
441  free(callable_name);
442  void **it;
443  bool first = true;
444  rz_pvector_foreach (callable->args, it) {
445  RzCallableArg *arg = *it;
446  if (arg) {
447  char *argstr = rz_type_identifier_declaration_as_string(typedb, arg->type, rz_str_get(arg->name));
448  const char *comma = first ? "" : ", ";
449  rz_strbuf_appendf(buf, "%s%s", comma, argstr);
450  first = false;
451  free(argstr);
452  }
453  }
454  rz_strbuf_append(buf, ")");
455  return true;
456 }
457 
465  rz_return_val_if_fail(typedb && type, NULL);
467 
468  size_t ptr_depth = 0;
469  const RzCallable *callable = callable_ptr_unwrap(type, &ptr_depth);
470  if (!callable) {
471  return NULL;
472  }
473  RzStrBuf *buf = rz_strbuf_new("");
474  if (!callable_as_string(buf, typedb, callable, ptr_depth)) {
476  return NULL;
477  }
478  return rz_strbuf_drain(buf);
479 }
480 
487 RZ_API RZ_OWN char *rz_type_callable_as_string(const RzTypeDB *typedb, RZ_NONNULL const RzCallable *callable) {
488  rz_return_val_if_fail(typedb && callable, NULL);
489  RzStrBuf *buf = rz_strbuf_new("");
490  if (!callable_as_string(buf, typedb, callable, 0)) {
492  return NULL;
493  }
494  return rz_strbuf_drain(buf);
495 }
496 
504  rz_return_val_if_fail(typedb && name, false);
505  RzCallable *callable = rz_type_func_get(typedb, name);
506  if (!callable) {
507  return false;
508  }
509  return callable->noret;
510 }
511 
519  rz_return_val_if_fail(typedb && name, false);
520  // If the function exists with the specified name already, we set the noreturn flag for it
521  RzCallable *callable = rz_type_func_get(typedb, name);
522  if (callable) {
523  callable->noret = true;
524  } else {
525  // If it doesn't - we create a new dummy RzCallable for it
526  // The return type is default and no arguments
527  callable = rz_type_func_new(typedb, name, NULL);
528  if (!callable) {
529  return false;
530  }
531  callable->noret = true;
532  rz_type_func_save(typedb, callable);
533  }
534  return true;
535 }
536 
544  rz_return_val_if_fail(typedb && name, false);
545  RzCallable *callable = rz_type_func_get(typedb, name);
546  if (!callable) {
547  return false;
548  }
549  callable->noret = false;
550  return true;
551 }
552 
553 // Listing function types
554 
555 static bool function_names_collect_cb(void *user, const void *k, const void *v) {
556  RzList *l = (RzList *)user;
557  RzCallable *callable = (RzCallable *)v;
558  rz_list_append(l, strdup(callable->name));
559  return true;
560 }
561 
568  rz_return_val_if_fail(typedb, NULL);
569  RzList *result = rz_list_newf(free);
570  ht_pp_foreach(typedb->callables, function_names_collect_cb, result);
571  return result;
572 }
573 
574 static bool noreturn_function_names_collect_cb(void *user, const void *k, const void *v) {
575  RzList *l = (RzList *)user;
576  RzCallable *callable = (RzCallable *)v;
577  if (callable->noret) {
578  rz_list_append(l, strdup(callable->name));
579  }
580  return true;
581 }
582 
589  rz_return_val_if_fail(typedb, NULL);
590  RzList *noretl = rz_list_newf(free);
591  ht_pp_foreach(typedb->callables, noreturn_function_names_collect_cb, noretl);
592  return noretl;
593 }
lzma_index ** i
Definition: index.h:629
static const char * arg(RzAnalysis *a, csh *handle, cs_insn *insn, char *buf, int n)
Definition: arm_esil32.c:136
#define RZ_API
#define NULL
Definition: cris-opc.c:27
const char * k
Definition: dsignal.c:11
const char * v
Definition: dsignal.c:12
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
RZ_API const KEY_TYPE bool * found
Definition: ht_inc.h:130
voidpf void * buf
Definition: ioapi.h:138
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
int type
Definition: mipsasm.c:17
#define rz_warn_if_reached()
Definition: rz_assert.h:29
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
#define RZ_LOG_DEBUG(fmtstr,...)
Definition: rz_log.h:49
static const char * rz_str_get(const char *str)
Definition: rz_str.h:187
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API RZ_OWN char * rz_strbuf_drain(RzStrBuf *sb)
Definition: strbuf.c:342
RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s)
Definition: strbuf.c:222
RZ_API RzStrBuf * rz_strbuf_new(const char *s)
Definition: strbuf.c:8
RZ_API void rz_strbuf_free(RzStrBuf *sb)
Definition: strbuf.c:358
RZ_API bool rz_strbuf_appendf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
@ RZ_TYPE_KIND_CALLABLE
Definition: rz_type.h:131
@ RZ_TYPE_KIND_POINTER
Definition: rz_type.h:129
#define RZ_NULLABLE
Definition: rz_types.h:65
#define RZ_OWN
Definition: rz_types.h:62
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_NONNULL
Definition: rz_types.h:64
#define RZ_BORROW
Definition: rz_types.h:63
static void ** rz_pvector_index_ptr(RzPVector *vec, size_t index)
Definition: rz_vector.h:251
static size_t rz_pvector_len(const RzPVector *vec)
Definition: rz_vector.h:231
RZ_API RzPVector * rz_pvector_new(RzPVectorFree free)
Definition: vector.c:302
void(* RzPVectorFree)(void *e)
Definition: rz_vector.h:43
static void ** rz_pvector_push(RzPVector *vec, void *x)
Definition: rz_vector.h:300
RZ_API void rz_pvector_free(RzPVector *vec)
Definition: vector.c:336
#define rz_pvector_foreach(vec, it)
Definition: rz_vector.h:334
const char * name
Definition: sparc-opc.c:1838
Definition: z80asm.h:102
RzType * type
Definition: rz_type.h:143
RZ_NULLABLE char * name
Definition: rz_type.h:142
RzPVector * args
optional for the time being
Definition: rz_type.h:149
RZ_NULLABLE const char * cc
Definition: rz_type.h:150
RZ_NULLABLE char * name
Definition: rz_type.h:147
RZ_NULLABLE RzType * ret
Definition: rz_type.h:148
HtPP * callables
Definition: rz_type.h:35
RzTypeKind kind
Definition: rz_type.h:155
RZ_API RZ_OWN RzCallable * rz_type_callable_clone(RZ_BORROW RZ_NONNULL const RzCallable *callable)
Creates an exact clone of the RzCallable type.
Definition: function.c:33
static bool callable_as_string(RzStrBuf *buf, const RzTypeDB *typedb, RZ_NONNULL const RzCallable *callable, size_t ptr_depth)
Definition: function.c:431
RZ_API RZ_BORROW RzCallable * rz_type_func_get(RzTypeDB *typedb, RZ_NONNULL const char *name)
Returns the RzCallable from the database by name.
Definition: function.c:162
RZ_API bool rz_type_func_cc_set(RzTypeDB *typedb, const char *name, const char *cc)
Searches for the RzCallable type in types database and set the calling convention.
Definition: function.c:246
RZ_API bool rz_type_callable_arg_add(RZ_NONNULL RzCallable *callable, RZ_OWN RZ_NONNULL RzCallableArg *arg)
Adds a new argument to the RzCallable.
Definition: function.c:116
RZ_API int rz_type_func_args_count(RzTypeDB *typedb, RZ_NONNULL const char *name)
Searches for the RzCallable type in types database and returns arguments' count.
Definition: function.c:262
RZ_API bool rz_type_func_noreturn_drop(RzTypeDB *typedb, RZ_NONNULL const char *name)
Drops the "noreturn" attribute from the RzCallable type.
Definition: function.c:543
RZ_API RZ_BORROW const char * rz_type_func_args_name(RzTypeDB *typedb, RZ_NONNULL const char *name, int i)
Searches for the RzCallable type in types database and returns argument name.
Definition: function.c:302
RZ_API bool rz_type_func_is_noreturn(RzTypeDB *typedb, RZ_NONNULL const char *name)
Checks if the RzCallable type is defined as "noreturn".
Definition: function.c:503
static bool noreturn_function_names_collect_cb(void *user, const void *k, const void *v)
Definition: function.c:574
RZ_API RZ_OWN RzCallable * rz_type_func_new(RzTypeDB *typedb, RZ_NONNULL const char *name, RZ_OWN RZ_NULLABLE RzType *type)
Creates a new RzCallable type.
Definition: function.c:131
RZ_API RZ_BORROW RzType * rz_type_func_ret(RzTypeDB *typedb, RZ_NONNULL const char *name)
Searches for the RzCallable type in types database and returns return type.
Definition: function.c:215
static const RzCallable * callable_ptr_unwrap(RZ_NONNULL const RzType *type, size_t *acc)
Definition: function.c:413
RZ_API bool rz_type_is_callable_ptr(RZ_NONNULL const RzType *type)
Checks if the RzType is the pointer to the RzCallable.
Definition: function.c:375
RZ_API void rz_type_func_delete_all(RzTypeDB *typedb)
Removes all RzCallable types.
Definition: function.c:192
RZ_API bool rz_type_func_exist(RzTypeDB *typedb, RZ_NONNULL const char *name)
Checks if the RzCallable type exists in the database given the name.
Definition: function.c:203
RZ_API bool rz_type_func_arg_add(RzTypeDB *typedb, RZ_NONNULL const char *func_name, RZ_NONNULL const char *arg_name, RZ_OWN RZ_NONNULL RzType *arg_type)
Adds a new argument to the RzCallable type at the end of the arguments vector.
Definition: function.c:327
RZ_API RZ_BORROW RzType * rz_type_func_args_type(RzTypeDB *typedb, RZ_NONNULL const char *name, int i)
Searches for the RzCallable type in types database and returns argument type.
Definition: function.c:278
RZ_API RZ_OWN RzCallableArg * rz_type_callable_arg_clone(RZ_BORROW RZ_NONNULL const RzCallableArg *arg)
Creates am exact clone of RzCallableArg.
Definition: function.c:85
RZ_API RZ_OWN char * rz_type_callable_ptr_as_string(const RzTypeDB *typedb, RZ_NONNULL const RzType *type)
Returns the callable pointer C representation.
Definition: function.c:464
RZ_API RZ_OWN RzCallableArg * rz_type_callable_arg_new(RzTypeDB *typedb, RZ_NONNULL const char *name, RZ_OWN RZ_NONNULL RzType *type)
Creates a new RzCallableArg given the name and type.
Definition: function.c:69
RZ_API RZ_OWN RzList * rz_type_noreturn_function_names(RzTypeDB *typedb)
Returns the list of all noreturn function type names.
Definition: function.c:588
static void callables_ht_free(HtPPKv *kv)
Definition: function.c:185
static char * callable_name_or_ptr(RZ_NONNULL const RzCallable *callable, size_t ptr_depth)
Definition: function.c:422
RZ_API RZ_OWN RzCallable * rz_type_callable_new(RZ_NULLABLE const char *name)
Creates a new RzCallable type.
Definition: function.c:17
RZ_API void rz_type_callable_free(RZ_NONNULL RzCallable *callable)
Frees the RzCallable.
Definition: function.c:55
static bool function_names_collect_cb(void *user, const void *k, const void *v)
Definition: function.c:555
RZ_API RZ_OWN RzList * rz_type_function_names(RzTypeDB *typedb)
Returns the list of all function type names.
Definition: function.c:567
RZ_API bool rz_type_func_delete(RzTypeDB *typedb, RZ_NONNULL const char *name)
Removes RzCallable type from the types database.
Definition: function.c:179
RZ_API bool rz_type_is_callable(RZ_NONNULL const RzType *type)
Checks if the RzType is the pointer to the RzCallable.
Definition: function.c:364
RZ_API RZ_OWN char * rz_type_callable_as_string(const RzTypeDB *typedb, RZ_NONNULL const RzCallable *callable)
Returns the callable C representation.
Definition: function.c:487
RZ_API bool rz_type_func_save(RzTypeDB *typedb, RZ_NONNULL RzCallable *callable)
Stores RzCallable type in the types database.
Definition: function.c:147
RZ_API void rz_type_callable_arg_free(RzCallableArg *arg)
Frees the RzCallableArg.
Definition: function.c:101
RZ_API RZ_BORROW const char * rz_type_func_cc(RzTypeDB *typedb, RZ_NONNULL const char *name)
Searches for the RzCallable type in types database and returns calling convention.
Definition: function.c:230
RZ_API bool rz_type_func_noreturn_add(RzTypeDB *typedb, RZ_NONNULL const char *name)
Adds the "noreturn" attribute to the RzCallable type.
Definition: function.c:518
RZ_API bool rz_type_func_ret_set(RzTypeDB *typedb, const char *name, RZ_OWN RZ_NONNULL RzType *type)
Sets the new return type for the RzCallable.
Definition: function.c:348
RZ_API bool rz_type_is_callable_ptr_nested(RZ_NONNULL const RzType *type)
Checks if the RzType is the nested pointer to the RzCallable.
Definition: function.c:399
RZ_API void rz_type_free(RZ_NULLABLE RzType *type)
Frees the RzType.
Definition: type.c:1273
RZ_API RZ_OWN RzType * rz_type_clone(RZ_BORROW RZ_NONNULL const RzType *type)
Creates an exact clone of the RzType.
Definition: type.c:1181
RZ_API RZ_OWN char * rz_type_identifier_declaration_as_string(const RzTypeDB *typedb, RZ_NONNULL const RzType *type, RZ_NONNULL const char *identifier)
Returns the type C representation with identifier.
Definition: type.c:841
RZ_API RZ_OWN char * rz_type_as_string(const RzTypeDB *typedb, RZ_NONNULL const RzType *type)
Returns the type C representation.
Definition: type.c:817
static int comma
Definition: z80asm.c:76