Rizin
unix-like reverse engineering framework and cli tools
types_parser.h File Reference

Go to the source code of this file.

Classes

struct  CParserAnonymousTypesState
 
struct  CParserState
 
struct  ParserTypePair
 

Functions

CParserStatec_parser_state_new (HtPP *base_types, HtPP *callable_types)
 
void c_parser_state_free (CParserState *state)
 
int parse_type_nodes_save (CParserState *state, TSNode node, const char *text)
 
int parse_type_node_single (CParserState *state, TSNode node, const char *text, ParserTypePair **tpair, bool is_const)
 
int parse_declaration_node (CParserState *state, TSNode node, const char *text, ParserTypePair **tpair)
 
int parse_type_descriptor_single (CParserState *state, TSNode node, const char *text, ParserTypePair **tpair)
 
int parse_type_declarator_node (CParserState *state, TSNode node, const char *text, ParserTypePair **tpair, char **identifier)
 
int parse_type_abstract_declarator_node (CParserState *state, TSNode node, const char *text, ParserTypePair **tpair)
 
void parser_debug (CParserState *state, const char *fmt,...)
 
void parser_error (CParserState *state, const char *fmt,...)
 
void parser_warning (CParserState *state, const char *fmt,...)
 
RzBaseTypec_parser_base_type_find (CParserState *state, RZ_NONNULL const char *name)
 
bool c_parser_base_type_is_forward_definition (CParserState *state, RZ_NONNULL const char *name)
 
bool c_parser_base_type_exists (CParserState *state, RZ_NONNULL const char *name)
 
bool c_parser_base_type_store (CParserState *state, RZ_NONNULL const char *name, ParserTypePair *tpair)
 
bool c_parser_forward_definition_store (CParserState *state, RZ_NONNULL const char *name)
 
bool c_parser_forward_definition_remove (CParserState *state, RZ_NONNULL const char *name)
 
RzCallablec_parser_callable_type_find (CParserState *state, RZ_NONNULL const char *name)
 
bool c_parser_callable_type_exists (CParserState *state, RZ_NONNULL const char *name)
 
bool c_parser_callable_type_store (CParserState *state, RZ_NONNULL const char *name, RZ_NONNULL RzType *type)
 
RZ_OWN ParserTypePairc_parser_new_unspecified_naked_type (CParserState *state, RZ_NONNULL const char *name, bool is_const)
 Creates new unspecified naked type (without base type) based on the name. More...
 
RZ_OWN ParserTypePairc_parser_new_primitive_type (CParserState *state, RZ_NONNULL const char *name, bool is_const)
 Creates new primitive type based on the name. More...
 
RZ_OWN ParserTypePairc_parser_get_primitive_type (CParserState *state, RZ_NONNULL const char *name, bool is_const)
 Returns the primitive type if matching in the types hashtable. More...
 
RZ_OWN ParserTypePairc_parser_new_structure_naked_type (CParserState *state, RZ_NONNULL const char *name)
 Creates new structure naked type (without base type) based on the name. More...
 
RZ_OWN ParserTypePairc_parser_new_structure_type (CParserState *state, RZ_NONNULL const char *name, size_t members_count)
 Creates new structure "type + base type" pair based on the name. More...
 
RZ_OWN ParserTypePairc_parser_get_structure_type (CParserState *state, RZ_NONNULL const char *name)
 Returns the structure type if matching in the types hashtable. More...
 
RZ_OWN ParserTypePairc_parser_new_structure_forward_definition (CParserState *state, RZ_NONNULL const char *name)
 Creates new structure forward definition. More...
 
RZ_OWN ParserTypePairc_parser_new_union_naked_type (CParserState *state, RZ_NONNULL const char *name)
 Creates new union naked type (without base type) based on the name. More...
 
RZ_OWN ParserTypePairc_parser_new_union_type (CParserState *state, RZ_NONNULL const char *name, size_t members_count)
 Creates new union "type + base type" pair based on the name. More...
 
RZ_OWN ParserTypePairc_parser_get_union_type (CParserState *state, RZ_NONNULL const char *name)
 Returns the union type if matching in the types hashtable. More...
 
RZ_OWN ParserTypePairc_parser_new_union_forward_definition (CParserState *state, RZ_NONNULL const char *name)
 Creates new union forward definition. More...
 
RZ_OWN ParserTypePairc_parser_new_enum_naked_type (CParserState *state, RZ_NONNULL const char *name)
 Creates new enum naked type (without base type) based on the name. More...
 
RZ_OWN ParserTypePairc_parser_new_enum_type (CParserState *state, RZ_NONNULL const char *name, size_t cases_count)
 Creates new enumeration type based on the name. More...
 
RZ_OWN ParserTypePairc_parser_get_enum_type (CParserState *state, RZ_NONNULL const char *name)
 Returns the enum type if matching in the types hashtable. More...
 
RZ_OWN ParserTypePairc_parser_new_enum_forward_definition (CParserState *state, RZ_NONNULL const char *name)
 Creates new enum forward definition. More...
 
RZ_OWN ParserTypePairc_parser_new_typedef (CParserState *state, RZ_NONNULL const char *name, RZ_NONNULL const char *base)
 Creates new type alias based on the name. More...
 
RZ_OWN ParserTypePairc_parser_get_typedef (CParserState *state, RZ_NONNULL const char *name)
 Returns the type if matching in the types hashtable. More...
 
RZ_OWN RzTypec_parser_new_naked_callable (CParserState *state)
 Creates new naked callable without storing it. More...
 
RZ_OWN RzTypec_parser_new_callable (CParserState *state, RZ_NONNULL const char *name)
 Creates new callable based on the name. More...
 
bool c_parser_new_callable_argument (CParserState *state, RZ_NONNULL RzCallable *callable, RZ_NONNULL const char *name, RZ_OWN RZ_NONNULL RzType *type)
 Adds a new argument to the callable. More...
 
RZ_OWN ParserTypePairc_parser_type_wrap_to_pointer (CParserState *state, ParserTypePair *tpair, bool is_const)
 
RZ_OWN ParserTypePairc_parser_type_wrap_to_array (CParserState *state, ParserTypePair *tpair, size_t size)
 
bool c_parser_pointer_set_subtype (CParserState *state, RZ_BORROW ParserTypePair *tpair, RZ_OWN ParserTypePair *subpair)
 
bool c_parser_array_set_subtype (CParserState *state, RZ_BORROW ParserTypePair *tpair, RZ_OWN ParserTypePair *subpair)
 
RZ_OWN char * c_parser_new_anonymous_structure_name (CParserState *state)
 
RZ_OWN char * c_parser_new_anonymous_union_name (CParserState *state)
 
RZ_OWN char * c_parser_new_anonymous_enum_name (CParserState *state)
 
RZ_OWN char * c_parser_new_anonymous_callable_name (CParserState *state)
 

Function Documentation

◆ c_parser_array_set_subtype()

bool c_parser_array_set_subtype ( CParserState state,
RZ_BORROW ParserTypePair tpair,
RZ_OWN ParserTypePair subpair 
)

Definition at line 889 of file types_storage.c.

889  {
890  rz_return_val_if_fail(state && tpair, false);
891  rz_return_val_if_fail(tpair->type->kind == RZ_TYPE_KIND_ARRAY, false);
892  tpair->type->array.type = subpair->type;
893  tpair->btype = subpair->btype;
894  return true;
895 }
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
@ RZ_TYPE_KIND_ARRAY
Definition: rz_type.h:130
Definition: dis.h:43

References rz_return_val_if_fail, and RZ_TYPE_KIND_ARRAY.

◆ c_parser_base_type_exists()

◆ c_parser_base_type_find()

RzBaseType* c_parser_base_type_find ( CParserState state,
RZ_NONNULL const char *  name 
)

Definition at line 17 of file types_storage.c.

17  {
18  bool found = false;
19  RzBaseType *base_type = ht_pp_find(state->types, name, &found);
20  if (!found || !base_type) {
21  return NULL;
22  }
23  return base_type;
24 }
RZ_API const KEY_TYPE bool * found
Definition: ht_inc.h:130

References found, and NULL.

Referenced by c_parser_base_type_exists(), c_parser_get_enum_type(), c_parser_get_primitive_type(), c_parser_get_structure_type(), c_parser_get_typedef(), and c_parser_get_union_type().

◆ c_parser_base_type_is_forward_definition()

◆ c_parser_base_type_store()

bool c_parser_base_type_store ( CParserState state,
RZ_NONNULL const char *  name,
ParserTypePair tpair 
)

Definition at line 36 of file types_storage.c.

36  {
37  rz_return_val_if_fail(state && name && tpair && tpair->btype, -1);
38 
40  // We don't create the type if it exists already in the parser
41  // state with the same name
42  return false;
43  }
44 
45  // We store only RzBaseType part of the type pair
46  ht_pp_insert(state->types, name, tpair->btype);
47  return true;
48 }
RzBaseType * btype
Definition: types_parser.h:23
bool c_parser_base_type_exists(CParserState *state, RZ_NONNULL const char *name)
Definition: types_storage.c:32

References ParserTypePair::btype, c_parser_base_type_exists(), and rz_return_val_if_fail.

Referenced by parse_enum_node(), parse_primitive_type(), parse_sized_primitive_type(), parse_struct_node(), parse_typedef_node(), and parse_union_node().

◆ c_parser_callable_type_exists()

bool c_parser_callable_type_exists ( CParserState state,
RZ_NONNULL const char *  name 
)

Definition at line 94 of file types_storage.c.

94  {
96 }
RzCallable * c_parser_callable_type_find(CParserState *state, RZ_NONNULL const char *name)
Definition: types_storage.c:85

References c_parser_callable_type_find(), and NULL.

Referenced by c_parser_callable_type_store().

◆ c_parser_callable_type_find()

RzCallable* c_parser_callable_type_find ( CParserState state,
RZ_NONNULL const char *  name 
)

Definition at line 85 of file types_storage.c.

85  {
86  bool found = false;
87  RzCallable *callable = ht_pp_find(state->callables, name, &found);
88  if (!found || !callable) {
89  return NULL;
90  }
91  return callable;
92 }

References found, and NULL.

Referenced by c_parser_callable_type_exists().

◆ c_parser_callable_type_store()

bool c_parser_callable_type_store ( CParserState state,
RZ_NONNULL const char *  name,
RZ_NONNULL RzType type 
)

Definition at line 98 of file types_storage.c.

98  {
101  rz_return_val_if_fail(type->callable, -1);
102 
104  // We don't create the type if it exists already in the parser
105  // state with the same name
106  return false;
107  }
108 
109  ht_pp_insert(state->callables, name, type->callable);
110  parser_debug(state, "Stored \"%s\" callable type\n", name);
111  return true;
112 }
int type
Definition: mipsasm.c:17
@ RZ_TYPE_KIND_CALLABLE
Definition: rz_type.h:131
void parser_debug(CParserState *state, const char *fmt,...)
Definition: types_parser.c:37
bool c_parser_callable_type_exists(CParserState *state, RZ_NONNULL const char *name)
Definition: types_storage.c:94

References c_parser_callable_type_exists(), parser_debug(), rz_return_val_if_fail, RZ_TYPE_KIND_CALLABLE, and type.

Referenced by parse_type_abstract_declarator_node(), and parse_type_declarator_node().

◆ c_parser_forward_definition_remove()

bool c_parser_forward_definition_remove ( CParserState state,
RZ_NONNULL const char *  name 
)

Definition at line 70 of file types_storage.c.

70  {
72 
74  // We don't create the forward definition if it exists already in the parser
75  // types table state with the same name
76  return false;
77  }
78 
79  ht_pp_delete(state->forward, name);
80  return true;
81 }

References c_parser_base_type_exists(), and rz_return_val_if_fail.

Referenced by parse_enum_node(), parse_struct_node(), parse_typedef_node(), and parse_union_node().

◆ c_parser_forward_definition_store()

bool c_parser_forward_definition_store ( CParserState state,
RZ_NONNULL const char *  name 
)

Definition at line 50 of file types_storage.c.

50  {
52 
54  // We don't create the forward definition if it exists already in the parser
55  // types table state with the same name
56  return false;
57  }
58 
60  // We don't create the forward definition if it already stored
61  // as the forward definition with the same name
62  return false;
63  }
64 
65  // We store only the type name
66  ht_pp_insert(state->forward, name, NULL);
67  return true;
68 }
bool c_parser_base_type_is_forward_definition(CParserState *state, RZ_NONNULL const char *name)
Definition: types_storage.c:26

References c_parser_base_type_exists(), c_parser_base_type_is_forward_definition(), NULL, and rz_return_val_if_fail.

Referenced by c_parser_new_typedef(), and parse_sole_type_name().

◆ c_parser_get_enum_type()

RZ_OWN ParserTypePair* c_parser_get_enum_type ( CParserState state,
RZ_NONNULL const char *  name 
)

Returns the enum type if matching in the types hashtable.

If the name matches with the name of one of the base types that are in the hashtable of the existing types in the parser state, then it creates new RzType with the found RzBaseType as a base. Then it wraps boths in the "type pair"

Parameters
stateThe parser state
nameName of the enum type to fetch

Definition at line 573 of file types_storage.c.

573  {
575 
577  if (!base_type || base_type->kind != RZ_BASE_TYPE_KIND_ENUM) {
578  return NULL;
579  }
580 
582  if (!tpair) {
583  return NULL;
584  }
585 
586  tpair->btype = base_type;
587  return tpair;
588 }
@ RZ_BASE_TYPE_KIND_ENUM
Definition: rz_type.h:75
RzBaseTypeKind kind
Definition: rz_type.h:115
RZ_OWN ParserTypePair * c_parser_new_enum_naked_type(CParserState *state, RZ_NONNULL const char *name)
Creates new enum naked type (without base type) based on the name.

References ParserTypePair::btype, c_parser_base_type_find(), c_parser_new_enum_naked_type(), rz_base_type_t::kind, NULL, RZ_BASE_TYPE_KIND_ENUM, and rz_return_val_if_fail.

Referenced by parse_enum_node().

◆ c_parser_get_primitive_type()

RZ_OWN ParserTypePair* c_parser_get_primitive_type ( CParserState state,
RZ_NONNULL const char *  name,
bool  is_const 
)

Returns the primitive type if matching in the types hashtable.

If the name matches with the name of one of the base types that are in the hashtable of the existing types in the parser state, then it creates new RzType with the found RzBaseType as a base. Then it wraps boths in the "type pair"

Parameters
stateThe parser state
nameName of the primitive type to fetch
is_constIf the primitive type is const

Definition at line 209 of file types_storage.c.

209  {
211 
213  if (!base_type || base_type->kind != RZ_BASE_TYPE_KIND_ATOMIC) {
214  return NULL;
215  }
216 
218  if (!type) {
219  return NULL;
220  }
222  type->identifier.is_const = is_const;
223  type->identifier.name = strdup(name);
224  type->identifier.kind = RZ_TYPE_IDENTIFIER_KIND_UNSPECIFIED;
225 
227  if (!tpair) {
229  return NULL;
230  }
231  tpair->btype = base_type;
232  tpair->type = type;
233  return tpair;
234 }
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")
@ RZ_BASE_TYPE_KIND_ATOMIC
Definition: rz_type.h:77
@ RZ_TYPE_IDENTIFIER_KIND_UNSPECIFIED
Definition: rz_type.h:135
@ RZ_TYPE_KIND_IDENTIFIER
Definition: rz_type.h:128
#define RZ_NEW0(x)
Definition: rz_types.h:284
RzType * type
Definition: types_parser.h:24
RZ_API void rz_type_free(RZ_NULLABLE RzType *type)
Frees the RzType.
Definition: type.c:1273

References ParserTypePair::btype, c_parser_base_type_find(), rz_base_type_t::kind, NULL, RZ_BASE_TYPE_KIND_ATOMIC, RZ_NEW0, rz_return_val_if_fail, rz_type_free(), RZ_TYPE_IDENTIFIER_KIND_UNSPECIFIED, RZ_TYPE_KIND_IDENTIFIER, strdup(), type, and ParserTypePair::type.

Referenced by parse_primitive_type(), parse_sized_primitive_type(), and parse_sole_type_name().

◆ c_parser_get_structure_type()

RZ_OWN ParserTypePair* c_parser_get_structure_type ( CParserState state,
RZ_NONNULL const char *  name 
)

Returns the structure type if matching in the types hashtable.

If the name matches with the name of one of the base types that are in the hashtable of the existing types in the parser state, then it creates new RzType with the found RzBaseType as a base. Then it wraps boths in the "type pair"

Parameters
stateThe parser state
nameName of the structure type to fetch

Definition at line 317 of file types_storage.c.

317  {
319 
321  if (!base_type || base_type->kind != RZ_BASE_TYPE_KIND_STRUCT) {
322  return NULL;
323  }
324 
326  if (!tpair) {
327  return NULL;
328  }
329 
330  tpair->btype = base_type;
331  return tpair;
332 }
@ RZ_BASE_TYPE_KIND_STRUCT
Definition: rz_type.h:73
RZ_OWN ParserTypePair * c_parser_new_structure_naked_type(CParserState *state, RZ_NONNULL const char *name)
Creates new structure naked type (without base type) based on the name.

References ParserTypePair::btype, c_parser_base_type_find(), c_parser_new_structure_naked_type(), rz_base_type_t::kind, NULL, RZ_BASE_TYPE_KIND_STRUCT, and rz_return_val_if_fail.

Referenced by parse_sole_type_name(), and parse_struct_node().

◆ c_parser_get_typedef()

RZ_OWN ParserTypePair* c_parser_get_typedef ( CParserState state,
RZ_NONNULL const char *  name 
)

Returns the type if matching in the types hashtable.

If the name matches with the name of one of the type aliases that are in the hashtable of the existing types in the parser state, then it creates new RzType with the found RzBaseType as a base. Then it wraps boths in the "type pair"

Parameters
stateThe parser state
nameName of the type alias to fetch

Definition at line 739 of file types_storage.c.

739  {
741 
743  if (!base_type || base_type->kind != RZ_BASE_TYPE_KIND_TYPEDEF) {
744  return NULL;
745  }
746 
748  if (!type) {
749  return NULL;
750  }
752  type->identifier.is_const = false;
753  type->identifier.name = strdup(name);
754  type->identifier.kind = RZ_TYPE_IDENTIFIER_KIND_UNSPECIFIED;
755 
757  if (!tpair) {
759  return NULL;
760  }
761  tpair->btype = base_type;
762  tpair->type = type;
763  return tpair;
764 }
@ RZ_BASE_TYPE_KIND_TYPEDEF
Definition: rz_type.h:76

References ParserTypePair::btype, c_parser_base_type_find(), rz_base_type_t::kind, NULL, RZ_BASE_TYPE_KIND_TYPEDEF, RZ_NEW0, rz_return_val_if_fail, rz_type_free(), RZ_TYPE_IDENTIFIER_KIND_UNSPECIFIED, RZ_TYPE_KIND_IDENTIFIER, strdup(), type, and ParserTypePair::type.

Referenced by parse_sole_type_name().

◆ c_parser_get_union_type()

RZ_OWN ParserTypePair* c_parser_get_union_type ( CParserState state,
RZ_NONNULL const char *  name 
)

Returns the union type if matching in the types hashtable.

If the name matches with the name of one of the base types that are in the hashtable of the existing types in the parser state, then it creates new RzType with the found RzBaseType as a base. Then it wraps boths in the "type pair"

Parameters
stateThe parser state
nameName of the union type to fetch

Definition at line 445 of file types_storage.c.

445  {
447 
449  if (!base_type || base_type->kind != RZ_BASE_TYPE_KIND_UNION) {
450  return NULL;
451  }
452 
454  if (!tpair) {
455  return NULL;
456  }
457 
458  tpair->btype = base_type;
459  return tpair;
460 }
@ RZ_BASE_TYPE_KIND_UNION
Definition: rz_type.h:74
RZ_OWN ParserTypePair * c_parser_new_union_naked_type(CParserState *state, RZ_NONNULL const char *name)
Creates new union naked type (without base type) based on the name.

References ParserTypePair::btype, c_parser_base_type_find(), c_parser_new_union_naked_type(), rz_base_type_t::kind, NULL, RZ_BASE_TYPE_KIND_UNION, and rz_return_val_if_fail.

Referenced by parse_sole_type_name(), and parse_union_node().

◆ c_parser_new_anonymous_callable_name()

RZ_OWN char* c_parser_new_anonymous_callable_name ( CParserState state)

Definition at line 915 of file types_storage.c.

915  {
916  char *name = rz_str_newf("anonymous function %zu", state->anon.callables);
917  state->anon.enums++;
918  return name;
919 }
const char * name
Definition: op.c:541
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1

References name, and rz_str_newf().

Referenced by parse_type_abstract_declarator_node().

◆ c_parser_new_anonymous_enum_name()

RZ_OWN char* c_parser_new_anonymous_enum_name ( CParserState state)

Definition at line 909 of file types_storage.c.

909  {
910  char *name = rz_str_newf("anonymous enum %zu", state->anon.enums);
911  state->anon.enums++;
912  return name;
913 }

References name, and rz_str_newf().

Referenced by parse_enum_node().

◆ c_parser_new_anonymous_structure_name()

RZ_OWN char* c_parser_new_anonymous_structure_name ( CParserState state)

Definition at line 897 of file types_storage.c.

897  {
898  char *name = rz_str_newf("anonymous struct %zu", state->anon.structs);
899  state->anon.structs++;
900  return name;
901 }

References name, and rz_str_newf().

Referenced by parse_struct_node().

◆ c_parser_new_anonymous_union_name()

RZ_OWN char* c_parser_new_anonymous_union_name ( CParserState state)

Definition at line 903 of file types_storage.c.

903  {
904  char *name = rz_str_newf("anonymous union %zu", state->anon.unions);
905  state->anon.unions++;
906  return name;
907 }

References name, and rz_str_newf().

Referenced by parse_union_node().

◆ c_parser_new_callable()

RZ_OWN RzType* c_parser_new_callable ( CParserState state,
RZ_NONNULL const char *  name 
)

Creates new callable based on the name.

If the name matches with the name of one of the base types that are in the hashtable of the existing types in the parser state, then it creates new RzType with the found RzCallable as a base.

In case of the callable found in the hashtable the ownership transfer doesn't happen. If not - it does.

Parameters
stateThe parser state
nameName of the callable type to create

Definition at line 802 of file types_storage.c.

802  {
805  if (!type) {
806  return NULL;
807  }
808  // We check if there is already a callable in the hashtable with the same name
809  bool found = false;
810  RzCallable *callable = ht_pp_find(state->callables, name, &found);
811  if (!found || !callable) {
812  // If not found - create a new one
813  callable = RZ_NEW0(RzCallable);
814  if (!callable) {
815  free(type);
816  return NULL;
817  }
818  callable->name = strdup(name);
820  }
821  type->kind = RZ_TYPE_KIND_CALLABLE;
822  type->callable = callable;
823  return type;
824 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
RZ_API RzPVector * rz_pvector_new(RzPVectorFree free)
Definition: vector.c:302
void(* RzPVectorFree)(void *e)
Definition: rz_vector.h:43
RzPVector * args
optional for the time being
Definition: rz_type.h:149
RZ_NULLABLE char * name
Definition: rz_type.h:147
RZ_API void rz_type_callable_arg_free(RzCallableArg *arg)
Frees the RzCallableArg.
Definition: function.c:101

References rz_callable_at::args, found, free(), rz_callable_at::name, NULL, RZ_NEW0, rz_pvector_new(), rz_return_val_if_fail, rz_type_callable_arg_free(), RZ_TYPE_KIND_CALLABLE, strdup(), and type.

Referenced by parse_type_abstract_declarator_node().

◆ c_parser_new_callable_argument()

bool c_parser_new_callable_argument ( CParserState state,
RZ_NONNULL RzCallable callable,
RZ_NONNULL const char *  name,
RZ_OWN RZ_NONNULL RzType type 
)

Adds a new argument to the callable.

Parameters
stateThe parser state
callableCallable type
nameName of the argument
typeType of the argument

Definition at line 834 of file types_storage.c.

834  {
835  rz_return_val_if_fail(state && callable && name && type, false);
836  // At first we check if there is an argument with the same name already - error if yes
837  void **it;
838  rz_pvector_foreach (callable->args, it) {
839  RzCallableArg *arg = *it;
840  if (!strcmp(arg->name, name)) {
841  return false;
842  }
843  }
844  // And only if there is no argument with the same name - proceed to insert it
846  if (!arg) {
847  return false;
848  }
849  arg->name = strdup(name);
850  arg->type = type;
851  rz_pvector_push(callable->args, arg);
852  return true;
853 }
static void ** rz_pvector_push(RzPVector *vec, void *x)
Definition: rz_vector.h:300
#define rz_pvector_foreach(vec, it)
Definition: rz_vector.h:334
const char * name
Definition: sparc-opc.c:1838

References arg::name, RZ_NEW0, rz_pvector_foreach, rz_pvector_push(), rz_return_val_if_fail, strdup(), and type.

Referenced by parse_parameter_list().

◆ c_parser_new_enum_forward_definition()

RZ_OWN ParserTypePair* c_parser_new_enum_forward_definition ( CParserState state,
RZ_NONNULL const char *  name 
)

Creates new enum forward definition.

Parameters
stateThe parser state
nameName of the enum C type to create

Definition at line 596 of file types_storage.c.

596  {
598 
600  // We don't create the enum if it exists already in the parser
601  // state with the same name
602  return NULL;
603  }
604 
606  // We don't create the enum if it exists already in the forward
607  // definitions table with the same name
608  return NULL;
609  }
610 
612  if (!tpair) {
613  return NULL;
614  }
615 
616  return tpair;
617 }

References c_parser_base_type_exists(), c_parser_base_type_is_forward_definition(), c_parser_new_enum_naked_type(), NULL, and rz_return_val_if_fail.

Referenced by parse_enum_node().

◆ c_parser_new_enum_naked_type()

RZ_OWN ParserTypePair* c_parser_new_enum_naked_type ( CParserState state,
RZ_NONNULL const char *  name 
)

Creates new enum naked type (without base type) based on the name.

Parameters
stateThe parser state
nameName of the enum C type to create

Definition at line 497 of file types_storage.c.

497  {
499 
501  if (!type) {
502  return NULL;
503  }
505  type->identifier.is_const = false;
506  type->identifier.name = strdup(name);
507  type->identifier.kind = RZ_TYPE_IDENTIFIER_KIND_ENUM;
508 
510  if (!tpair) {
512  return NULL;
513  }
514  tpair->btype = NULL;
515  tpair->type = type;
516  return tpair;
517 }
@ RZ_TYPE_IDENTIFIER_KIND_ENUM
Definition: rz_type.h:138

References ParserTypePair::btype, NULL, RZ_NEW0, rz_return_val_if_fail, rz_type_free(), RZ_TYPE_IDENTIFIER_KIND_ENUM, RZ_TYPE_KIND_IDENTIFIER, strdup(), type, and ParserTypePair::type.

Referenced by c_parser_get_enum_type(), c_parser_new_enum_forward_definition(), c_parser_new_enum_type(), and parse_enum_node().

◆ c_parser_new_enum_type()

RZ_OWN ParserTypePair* c_parser_new_enum_type ( CParserState state,
RZ_NONNULL const char *  name,
size_t  cases_count 
)

Creates new enumeration type based on the name.

Parameters
stateThe parser state
nameName of the primitive C type to create
cases_countThe count of the enum cases

Definition at line 526 of file types_storage.c.

526  {
528 
530  // We don't create the structure if it exists already in the parser
531  // state with the same name
532  parser_error(state, "Enum type \"%s\" already exists\n", name);
533  return NULL;
534  }
535 
537  if (!tpair) {
538  return NULL;
539  }
540 
542  if (!base_type) {
543  rz_type_free(tpair->type);
544  free(tpair);
545  return NULL;
546  }
547 
548  base_type->name = strdup(name);
549  base_type->type = NULL;
550  tpair->btype = base_type;
551 
552  RzVector *cases = &base_type->enum_data.cases;
553  if (cases_count > 0 && !rz_vector_reserve(cases, cases_count)) {
554  rz_type_free(tpair->type);
556  free(tpair);
557  return NULL;
558  }
559  return tpair;
560 }
RZ_API void rz_type_base_type_free(RzBaseType *type)
Frees the RzBaseType instance and all of its members.
Definition: base.c:132
RZ_API RZ_OWN RzBaseType * rz_type_base_type_new(RzBaseTypeKind kind)
Allocates a new instance of RzBaseType given the kind.
Definition: base.c:162
RZ_API void * rz_vector_reserve(RzVector *vec, size_t capacity)
Definition: vector.c:214
RzVector cases
Definition: rz_type.h:108
char * name
Definition: rz_type.h:112
RzType * type
Definition: rz_type.h:113
RzBaseTypeEnum enum_data
Definition: rz_type.h:119
void parser_error(CParserState *state, const char *fmt,...)
Definition: types_parser.c:47

References ParserTypePair::btype, c_parser_base_type_exists(), c_parser_new_enum_naked_type(), rz_base_type_enum_t::cases, rz_base_type_t::enum_data, free(), rz_base_type_t::name, NULL, parser_error(), RZ_BASE_TYPE_KIND_ENUM, rz_return_val_if_fail, rz_type_base_type_free(), rz_type_base_type_new(), rz_type_free(), rz_vector_reserve(), strdup(), rz_base_type_t::type, and ParserTypePair::type.

Referenced by parse_enum_node().

◆ c_parser_new_naked_callable()

RZ_OWN RzType* c_parser_new_naked_callable ( CParserState state)

Creates new naked callable without storing it.

Parameters
stateThe parser state

Definition at line 771 of file types_storage.c.

771  {
774  if (!type) {
775  return NULL;
776  }
777  RzCallable *callable = RZ_NEW0(RzCallable);
778  if (!callable) {
779  free(type);
780  return NULL;
781  }
782  callable->name = NULL;
784  type->kind = RZ_TYPE_KIND_CALLABLE;
785  type->callable = callable;
786  return type;
787 }

References rz_callable_at::args, free(), rz_callable_at::name, NULL, RZ_NEW0, rz_pvector_new(), rz_return_val_if_fail, rz_type_callable_arg_free(), RZ_TYPE_KIND_CALLABLE, and type.

Referenced by parse_type_declarator_node().

◆ c_parser_new_primitive_type()

RZ_OWN ParserTypePair* c_parser_new_primitive_type ( CParserState state,
RZ_NONNULL const char *  name,
bool  is_const 
)

Creates new primitive type based on the name.

Parameters
stateThe parser state
nameName of the primitive C type to create
is_constIf the primitive type is const

Definition at line 150 of file types_storage.c.

150  {
152 
154  // We don't create the type if it exists already in the parser
155  // state with the same name
156  parser_error(state, "Primitive type \"%s\" already exists\n", name);
157  return NULL;
158  }
159 
161  if (!type) {
162  return NULL;
163  }
165  type->identifier.is_const = is_const;
166  type->identifier.name = strdup(name);
167  if (!type->identifier.name) {
168  free(type);
169  return NULL;
170  }
171  type->identifier.kind = RZ_TYPE_IDENTIFIER_KIND_UNSPECIFIED;
172 
174  if (!base_type) {
176  return NULL;
177  }
178  base_type->name = strdup(name);
179  if (!base_type->name) {
181  rz_type_base_type_free(base_type);
182  return NULL;
183  }
184 
186  if (!tpair) {
188  rz_type_base_type_free(base_type);
189  return NULL;
190  }
191  tpair->btype = base_type;
192  tpair->type = type;
193 
194  return tpair;
195 }

References ParserTypePair::btype, c_parser_base_type_exists(), free(), rz_base_type_t::name, NULL, parser_error(), RZ_BASE_TYPE_KIND_ATOMIC, RZ_NEW0, rz_return_val_if_fail, rz_type_base_type_free(), rz_type_base_type_new(), rz_type_free(), RZ_TYPE_IDENTIFIER_KIND_UNSPECIFIED, RZ_TYPE_KIND_IDENTIFIER, strdup(), type, and ParserTypePair::type.

Referenced by parse_primitive_type(), parse_sized_primitive_type(), and parse_sole_type_name().

◆ c_parser_new_structure_forward_definition()

RZ_OWN ParserTypePair* c_parser_new_structure_forward_definition ( CParserState state,
RZ_NONNULL const char *  name 
)

Creates new structure forward definition.

Parameters
stateThe parser state
nameName of the structure C type to create

Definition at line 340 of file types_storage.c.

340  {
342 
344  // We don't create the structure if it exists already in the parser
345  // state with the same name
346  return NULL;
347  }
348 
350  // We don't create the structure if it exists already in the forward
351  // definitions table with the same name
352  return NULL;
353  }
354 
356  if (!tpair) {
357  return NULL;
358  }
359 
360  return tpair;
361 }

References c_parser_base_type_exists(), c_parser_base_type_is_forward_definition(), c_parser_new_structure_naked_type(), NULL, and rz_return_val_if_fail.

Referenced by parse_struct_node().

◆ c_parser_new_structure_naked_type()

RZ_OWN ParserTypePair* c_parser_new_structure_naked_type ( CParserState state,
RZ_NONNULL const char *  name 
)

Creates new structure naked type (without base type) based on the name.

Parameters
stateThe parser state
nameName of the structure C type to create

Definition at line 242 of file types_storage.c.

242  {
244 
246  if (!type) {
247  return NULL;
248  }
250  type->identifier.is_const = false;
251  type->identifier.name = strdup(name);
252  type->identifier.kind = RZ_TYPE_IDENTIFIER_KIND_STRUCT;
253 
255  if (!tpair) {
257  return NULL;
258  }
259  tpair->btype = NULL;
260  tpair->type = type;
261  return tpair;
262 }
@ RZ_TYPE_IDENTIFIER_KIND_STRUCT
Definition: rz_type.h:136

References ParserTypePair::btype, NULL, RZ_NEW0, rz_return_val_if_fail, rz_type_free(), RZ_TYPE_IDENTIFIER_KIND_STRUCT, RZ_TYPE_KIND_IDENTIFIER, strdup(), type, and ParserTypePair::type.

Referenced by c_parser_get_structure_type(), c_parser_new_structure_forward_definition(), c_parser_new_structure_type(), and parse_struct_node().

◆ c_parser_new_structure_type()

RZ_OWN ParserTypePair* c_parser_new_structure_type ( CParserState state,
RZ_NONNULL const char *  name,
size_t  members_count 
)

Creates new structure "type + base type" pair based on the name.

Parameters
stateThe parser state
nameName of the structure C type to create
members_countThe count of the structure members

Definition at line 271 of file types_storage.c.

271  {
273 
275  // We don't create the structure if it exists already in the parser
276  // state with the same name
277  parser_error(state, "Structure type \"%s\" already exists\n", name);
278  return NULL;
279  }
280 
282  if (!tpair) {
283  return NULL;
284  }
285 
287  if (!base_type) {
288  rz_type_free(tpair->type);
289  free(tpair);
290  return NULL;
291  }
292  base_type->name = strdup(name);
293  base_type->type = NULL;
294  tpair->btype = base_type;
295 
296  RzVector *members = &base_type->struct_data.members;
297  if (members_count > 0 && !rz_vector_reserve(members, members_count)) {
298  rz_type_free(tpair->type);
300  free(tpair);
301  return NULL;
302  }
303  return tpair;
304 }
RzBaseTypeStruct struct_data
Definition: rz_type.h:118

References ParserTypePair::btype, c_parser_base_type_exists(), c_parser_new_structure_naked_type(), free(), rz_base_type_struct_t::members, rz_base_type_t::name, NULL, parser_error(), RZ_BASE_TYPE_KIND_STRUCT, rz_return_val_if_fail, rz_type_base_type_free(), rz_type_base_type_new(), rz_type_free(), rz_vector_reserve(), strdup(), rz_base_type_t::struct_data, rz_base_type_t::type, and ParserTypePair::type.

Referenced by parse_struct_node().

◆ c_parser_new_typedef()

RZ_OWN ParserTypePair* c_parser_new_typedef ( CParserState state,
RZ_NONNULL const char *  name,
RZ_NONNULL const char *  base 
)

Creates new type alias based on the name.

Parameters
stateThe parser state
nameName of the primitive C type to create
cases_countThe count of the enum cases

Definition at line 683 of file types_storage.c.

683  {
685 
687  // We don't create the type alias if it exists already in the parser
688  // state with the same name
689  parser_error(state, "Typedef \"%s\" already exists\n", name);
690  return NULL;
691  }
692 
694  if (!tpair) {
695  return NULL;
696  }
697 
699  if (!base_type) {
700  rz_type_free(tpair->type);
701  free(tpair);
702  return NULL;
703  }
704  base_type->name = strdup(name);
705 
706  if (!c_parser_base_type_exists(state, base)) {
707  // If it not exists already in the parser
708  // we create a forward type
709  base_type->type = NULL;
711  } else {
713  if (!type) {
714  rz_type_base_type_free(base_type);
715  free(tpair);
716  return NULL;
717  }
719  type->identifier.name = strdup(base);
720  type->identifier.is_const = false;
721  base_type->type = type;
722  }
723 
724  tpair->btype = base_type;
725  return tpair;
726 }
bool c_parser_forward_definition_store(CParserState *state, RZ_NONNULL const char *name)
Definition: types_storage.c:50
RZ_OWN ParserTypePair * c_parser_new_typedef_naked_type(CParserState *state, RZ_NONNULL const char *name)
Creates new type alias naked type (without base type) based on the name.

References ParserTypePair::btype, c_parser_base_type_exists(), c_parser_forward_definition_store(), c_parser_new_typedef_naked_type(), free(), rz_base_type_t::name, NULL, parser_error(), RZ_BASE_TYPE_KIND_TYPEDEF, RZ_NEW0, rz_return_val_if_fail, rz_type_base_type_free(), rz_type_base_type_new(), rz_type_free(), RZ_TYPE_KIND_IDENTIFIER, strdup(), type, rz_base_type_t::type, and ParserTypePair::type.

Referenced by parse_typedef_node().

◆ c_parser_new_union_forward_definition()

RZ_OWN ParserTypePair* c_parser_new_union_forward_definition ( CParserState state,
RZ_NONNULL const char *  name 
)

Creates new union forward definition.

Parameters
stateThe parser state
nameName of the union C type to create

Definition at line 468 of file types_storage.c.

468  {
470 
472  // We don't create the union if it exists already in the parser
473  // state with the same name
474  return NULL;
475  }
476 
478  // We don't create the union if it exists already in the forward
479  // definitions table with the same name
480  return NULL;
481  }
482 
484  if (!tpair) {
485  return NULL;
486  }
487 
488  return tpair;
489 }

References c_parser_base_type_exists(), c_parser_base_type_is_forward_definition(), c_parser_new_union_naked_type(), NULL, and rz_return_val_if_fail.

Referenced by parse_union_node().

◆ c_parser_new_union_naked_type()

RZ_OWN ParserTypePair* c_parser_new_union_naked_type ( CParserState state,
RZ_NONNULL const char *  name 
)

Creates new union naked type (without base type) based on the name.

Parameters
stateThe parser state
nameName of the union C type to create

Definition at line 369 of file types_storage.c.

369  {
371 
373  if (!type) {
374  return NULL;
375  }
377  type->identifier.is_const = false;
378  type->identifier.name = strdup(name);
379  type->identifier.kind = RZ_TYPE_IDENTIFIER_KIND_UNION;
380 
382  if (!tpair) {
384  return NULL;
385  }
386  tpair->btype = NULL;
387  tpair->type = type;
388  return tpair;
389 }
@ RZ_TYPE_IDENTIFIER_KIND_UNION
Definition: rz_type.h:137

References ParserTypePair::btype, NULL, RZ_NEW0, rz_return_val_if_fail, rz_type_free(), RZ_TYPE_IDENTIFIER_KIND_UNION, RZ_TYPE_KIND_IDENTIFIER, strdup(), type, and ParserTypePair::type.

Referenced by c_parser_get_union_type(), c_parser_new_union_forward_definition(), c_parser_new_union_type(), and parse_union_node().

◆ c_parser_new_union_type()

RZ_OWN ParserTypePair* c_parser_new_union_type ( CParserState state,
RZ_NONNULL const char *  name,
size_t  members_count 
)

Creates new union "type + base type" pair based on the name.

Parameters
stateThe parser state
nameName of the union C type to create
members_countThe count of the union members

Definition at line 398 of file types_storage.c.

398  {
400 
402  // We don't create the structure if it exists already in the parser
403  // state with the same name
404  parser_error(state, "Union type \"%s\" already exists\n", name);
405  return NULL;
406  }
407 
409  if (!tpair) {
410  return NULL;
411  }
412 
414  if (!base_type) {
415  rz_type_free(tpair->type);
416  free(tpair);
417  return NULL;
418  }
419 
420  base_type->name = strdup(name);
421  base_type->type = NULL;
422  tpair->btype = base_type;
423 
424  RzVector *members = &base_type->union_data.members;
425  if (members_count > 0 && !rz_vector_reserve(members, members_count)) {
426  rz_type_free(tpair->type);
428  free(tpair);
429  return NULL;
430  }
431  return tpair;
432 }
RzBaseTypeUnion union_data
Definition: rz_type.h:120
RzVector members
Definition: rz_type.h:104

References ParserTypePair::btype, c_parser_base_type_exists(), c_parser_new_union_naked_type(), free(), rz_base_type_union_t::members, rz_base_type_t::name, NULL, parser_error(), RZ_BASE_TYPE_KIND_UNION, rz_return_val_if_fail, rz_type_base_type_free(), rz_type_base_type_new(), rz_type_free(), rz_vector_reserve(), strdup(), rz_base_type_t::type, ParserTypePair::type, and rz_base_type_t::union_data.

Referenced by parse_union_node().

◆ c_parser_new_unspecified_naked_type()

RZ_OWN ParserTypePair* c_parser_new_unspecified_naked_type ( CParserState state,
RZ_NONNULL const char *  name,
bool  is_const 
)

Creates new unspecified naked type (without base type) based on the name.

Parameters
stateThe parser state
nameName of the type to create
is_constIf the identifier is constant

Definition at line 121 of file types_storage.c.

121  {
123 
125  if (!type) {
126  return NULL;
127  }
129  type->identifier.is_const = is_const;
130  type->identifier.name = strdup(name);
131  type->identifier.kind = RZ_TYPE_IDENTIFIER_KIND_UNSPECIFIED;
132 
134  if (!tpair) {
136  return NULL;
137  }
138  tpair->btype = NULL;
139  tpair->type = type;
140  return tpair;
141 }

References ParserTypePair::btype, NULL, RZ_NEW0, rz_return_val_if_fail, rz_type_free(), RZ_TYPE_IDENTIFIER_KIND_UNSPECIFIED, RZ_TYPE_KIND_IDENTIFIER, strdup(), type, and ParserTypePair::type.

Referenced by parse_sole_type_name().

◆ c_parser_pointer_set_subtype()

bool c_parser_pointer_set_subtype ( CParserState state,
RZ_BORROW ParserTypePair tpair,
RZ_OWN ParserTypePair subpair 
)

Definition at line 881 of file types_storage.c.

881  {
882  rz_return_val_if_fail(state && tpair, false);
883  rz_return_val_if_fail(tpair->type->kind == RZ_TYPE_KIND_POINTER, false);
884  tpair->type->pointer.type = subpair->type;
885  tpair->btype = subpair->btype;
886  return true;
887 }
@ RZ_TYPE_KIND_POINTER
Definition: rz_type.h:129

References rz_return_val_if_fail, and RZ_TYPE_KIND_POINTER.

◆ c_parser_state_free()

void c_parser_state_free ( CParserState state)

Definition at line 55 of file c_cpp_parser.c.

55  {
56  ht_pp_free(state->forward);
57  ht_pp_free(state->types);
58  ht_pp_free(state->callables);
59  rz_strbuf_free(state->debug);
60  rz_strbuf_free(state->warnings);
61  rz_strbuf_free(state->errors);
62  free(state);
63  return;
64 }
RZ_API void rz_strbuf_free(RzStrBuf *sb)
Definition: strbuf.c:358

References free(), and rz_strbuf_free().

Referenced by rz_type_parser_free_purge().

◆ c_parser_state_new()

CParserState* c_parser_state_new ( HtPP *  base_types,
HtPP *  callable_types 
)

Definition at line 33 of file c_cpp_parser.c.

33  {
35  if (!base_types) {
36  state->types = ht_pp_new0();
37  } else {
38  state->types = base_types;
39  }
40  if (!callable_types) {
41  state->callables = ht_pp_new0();
42  } else {
43  state->callables = callable_types;
44  }
45  // Forward definitions require to have a special hashtable
46  state->forward = ht_pp_new0();
47  // Initializing error/warning/debug messages buffers
48  state->errors = rz_strbuf_new("");
49  state->warnings = rz_strbuf_new("");
50  state->debug = rz_strbuf_new("");
51  state->verbose = false;
52  return state;
53 }
RZ_API RzStrBuf * rz_strbuf_new(const char *s)
Definition: strbuf.c:8

References RZ_NEW0, and rz_strbuf_new().

Referenced by rz_type_parse_string(), rz_type_parser_init(), and rz_type_parser_new().

◆ c_parser_type_wrap_to_array()

RZ_OWN ParserTypePair* c_parser_type_wrap_to_array ( CParserState state,
ParserTypePair tpair,
size_t  size 
)

Definition at line 869 of file types_storage.c.

869  {
870  rz_return_val_if_fail(state && tpair, NULL);
872  type->kind = RZ_TYPE_KIND_ARRAY;
873  type->array.count = size;
874  type->array.type = tpair->type;
876  newtpair->btype = tpair->btype;
877  newtpair->type = type;
878  return newtpair;
879 }
voidpf void uLong size
Definition: ioapi.h:138

References ParserTypePair::btype, NULL, RZ_NEW0, rz_return_val_if_fail, RZ_TYPE_KIND_ARRAY, type, and ParserTypePair::type.

◆ c_parser_type_wrap_to_pointer()

RZ_OWN ParserTypePair* c_parser_type_wrap_to_pointer ( CParserState state,
ParserTypePair tpair,
bool  is_const 
)

Definition at line 857 of file types_storage.c.

857  {
858  rz_return_val_if_fail(state && tpair, NULL);
860  type->kind = RZ_TYPE_KIND_POINTER;
861  type->pointer.is_const = is_const;
862  type->pointer.type = tpair->type;
864  newtpair->btype = tpair->btype;
865  newtpair->type = type;
866  return newtpair;
867 }

References ParserTypePair::btype, NULL, RZ_NEW0, rz_return_val_if_fail, RZ_TYPE_KIND_POINTER, type, and ParserTypePair::type.

◆ parse_declaration_node()

int parse_declaration_node ( CParserState state,
TSNode  node,
const char *  text,
ParserTypePair **  tpair 
)

Definition at line 1788 of file types_parser.c.

1788  {
1789  rz_return_val_if_fail(state && text && tpair, -1);
1791  // We skip simple nodes (e.g. conditions and braces)
1792  if (!ts_node_is_named(node)) {
1793  return 0;
1794  }
1795  const char *node_type = ts_node_type(node);
1796  int result = -1;
1797  if (strcmp(node_type, "declaration")) {
1798  return -1;
1799  }
1800  parser_debug(state, "parse_type_declaration_node()\n");
1801 
1802  int declaration_node_child_count = ts_node_named_child_count(node);
1803  if (declaration_node_child_count < 1) {
1804  node_malformed_error(state, node, text, "declaration");
1805  return -1;
1806  }
1807  // Type declaration has three fields:
1808  // 0. type qualifier (optional)
1809  // 1. type itself
1810  // 2. declarator field (optional)
1811 
1812  // Parse the type qualifier first
1813  // FIXME: There could be multiple different type qualifiers in one declaration
1814  bool is_const = false;
1815  TSNode first_leaf = ts_node_named_child(node, 0);
1816  if (ts_node_is_null(first_leaf)) {
1817  node_malformed_error(state, node, text, "declaration");
1818  return -1;
1819  }
1820  const char *leaf_type = ts_node_type(first_leaf);
1821  if (!strcmp(leaf_type, "type_qualifier")) {
1822  char *qualifier = ts_node_sub_string(first_leaf, text);
1823  parser_debug(state, "has qualifier \"%s\"\n", qualifier);
1824  if (!strcmp(qualifier, "const")) {
1825  parser_debug(state, "set const\n");
1826  is_const = true;
1827  }
1828  free(qualifier);
1829  }
1830 
1831  TSNode type_node = ts_node_child_by_field_name(node, "type", 4);
1832  if (ts_node_is_null(type_node)) {
1833  node_malformed_error(state, node, text, "declaration");
1834  parser_error(state, "declaration's type field cannot be NULL\n");
1835  return -1;
1836  }
1837  if (parse_type_node_single(state, type_node, text, tpair, is_const)) {
1838  node_malformed_error(state, node, text, "declaration");
1839  parser_error(state, "Cannot parse declaration's type field\n");
1840  return -1;
1841  }
1842  if (!*tpair) {
1843  parser_error(state, "Failed to parse declaration's type field\n");
1844  return -1;
1845  }
1846  // 2. Optional declarator field
1847  TSNode type_declarator = ts_node_child_by_field_name(node, "declarator", 10);
1848  if (!ts_node_is_null(type_declarator)) {
1849  char *identifier = NULL;
1850  return parse_type_declarator_node(state, type_declarator, text, tpair, &identifier);
1851  } else {
1852  result = 0;
1853  }
1854  return result;
1855 }
const char * ts_node_type(TSNode)
Definition: node.c:420
TSNode ts_node_named_child(TSNode, uint32_t)
Definition: node.c:496
uint32_t ts_node_named_child_count(TSNode)
Definition: node.c:611
bool ts_node_is_null(TSNode)
Definition: node.c:434
TSNode ts_node_child_by_field_name(TSNode self, const char *field_name, uint32_t field_name_length)
Definition: node.c:589
bool ts_node_is_named(TSNode)
Definition: node.c:442
Definition: api.h:92
int parse_type_node_single(CParserState *state, TSNode node, const char *text, ParserTypePair **tpair, bool is_const)
void node_malformed_error(CParserState *state, TSNode node, const char *text, const char *nodetype)
Definition: types_parser.c:27
int parse_type_declarator_node(CParserState *state, TSNode node, const char *text, ParserTypePair **tpair, char **identifier)
static char * ts_node_sub_string(TSNode node, const char *cstr)
Definition: types_parser.c:21

References free(), node_malformed_error(), NULL, parse_type_declarator_node(), parse_type_node_single(), parser_debug(), parser_error(), rz_return_val_if_fail, create_tags_rz::text, ts_node_child_by_field_name(), ts_node_is_named(), ts_node_is_null(), ts_node_named_child(), ts_node_named_child_count(), ts_node_sub_string(), and ts_node_type().

Referenced by parse_type_nodes_save(), and rz_type_parse_string_declaration_single().

◆ parse_type_abstract_declarator_node()

int parse_type_abstract_declarator_node ( CParserState state,
TSNode  node,
const char *  text,
ParserTypePair **  tpair 
)

Definition at line 1295 of file types_parser.c.

1295  {
1296  rz_return_val_if_fail(state && text && tpair, -1);
1299 
1300  parser_debug(state, "parse_type_abstract_declarator_node()\n");
1301 
1302  // Parse the type qualifier first (if present)
1303  // FIXME: There could be multiple different type qualifiers in one declaration
1304  bool is_const = false;
1305  bool has_qualifiers = false;
1306 
1307  int node_child_count = ts_node_named_child_count(node);
1308  if (node_child_count > 0) {
1309  TSNode first_leaf = ts_node_named_child(node, 0);
1310  if (ts_node_is_null(first_leaf)) {
1311  node_malformed_error(state, node, text, "type_declarator_node");
1312  return -1;
1313  }
1314  const char *leaf_type = ts_node_type(first_leaf);
1315  // If we have type qualifier in this position it is related to
1316  // the declarator itself, not the type, e.g. constant pointer,
1317  // not pointer to the constant
1318  if (!strcmp(leaf_type, "type_qualifier")) {
1319  char *qualifier = ts_node_sub_string(first_leaf, text);
1320  parser_debug(state, "has qualifier %s\n", qualifier);
1321  if (!strcmp(qualifier, "const")) {
1322  is_const = true;
1323  }
1324  has_qualifiers = true;
1325  free(qualifier);
1326  }
1327  }
1328 
1329  const char *node_type = ts_node_type(node);
1330  int result = -1;
1331  if (!strcmp(node_type, "abstract_pointer_declarator")) {
1332  parser_debug(state, "abstract pointer declarator\n");
1333 
1334  // Now we wrap the existing type into the new one
1335  // The base type in the type pair remains the same
1336  RzType *type = RZ_NEW0(RzType);
1337  if (!type) {
1338  return -1;
1339  }
1340  type->kind = RZ_TYPE_KIND_POINTER;
1341  type->pointer.is_const = is_const;
1342  type->pointer.type = (*tpair)->type;
1343  (*tpair)->type = type;
1344 
1345  // It can contain additional children as:
1346  // - "abstract_array_declarator"
1347  // - "abstract_pointer_declarator"
1348  // - "abstract_function_declarator"
1349  // - Or multiple "type qualifiers"
1350  int pointer_node_child_count = ts_node_named_child_count(node);
1351  if (pointer_node_child_count > 0) {
1352  TSNode pointer_declarator = ts_node_child_by_field_name(node, "declarator", 10);
1353  if (ts_node_is_null(pointer_declarator) && !has_qualifiers) {
1354  parser_error(state, "ERROR: Abstract pointer declarator AST should contain at least one node!\n");
1355  node_malformed_error(state, node, text, "pointer declarator");
1356  free(type);
1357  (*tpair)->type = NULL;
1358  return -1;
1359  }
1360  if (!ts_node_is_null(pointer_declarator)) {
1361  const char *declarator_type = ts_node_type(pointer_declarator);
1362  if (!declarator_type) {
1363  node_malformed_error(state, pointer_declarator, text, "pointer declarator");
1364  free(type);
1365  (*tpair)->type = NULL;
1366  return -1;
1367  }
1368  if (is_abstract_declarator(declarator_type)) {
1369  result = parse_type_abstract_declarator_node(state, pointer_declarator, text, tpair);
1370  } else {
1371  result = 0;
1372  }
1373  } else {
1374  result = 0;
1375  }
1376  } else {
1377  parser_debug(state, "abstract pointer declarator has no children\n");
1378  result = 0;
1379  }
1380  } else if (!strcmp(node_type, "abstract_array_declarator")) {
1381  // It can have two states - with and without number literal
1382  int array_node_child_count = ts_node_named_child_count(node);
1383  if (array_node_child_count < 0 || array_node_child_count > 2) {
1384  node_malformed_error(state, node, text, "abstract_array_declarator");
1385  return -1;
1386  }
1387  // Now we wrap the existing type into the new one
1388  // The base type in the type pair remains the same
1389  RzType *type = RZ_NEW0(RzType);
1390  if (!type) {
1391  return -1;
1392  }
1393 
1394  type->kind = RZ_TYPE_KIND_ARRAY;
1395  // Optional number_literal node
1396  TSNode array_size = ts_node_child_by_field_name(node, "size", 4);
1397  if (ts_node_is_null(array_size)) {
1398  type->array.count = 0;
1399  } else {
1400  char *real_array_size = ts_node_sub_string(array_size, text);
1401  if (!real_array_size) {
1402  node_malformed_error(state, array_size, text, "abstract array size");
1403  free(type);
1404  return -1;
1405  }
1406  int array_sz = rz_num_get(NULL, real_array_size);
1407  type->array.count = array_sz;
1408  free(real_array_size);
1409  }
1410  type->array.type = (*tpair)->type;
1411  (*tpair)->type = type;
1412 
1413  // It also can contain the following abstract declarators as a child:
1414  // - abstract_array_declarator
1415  // - abstract_pointer_declarator
1416  TSNode array_declarator = ts_node_child_by_field_name(node, "declarator", 10);
1417  if (!ts_node_is_null(array_declarator)) {
1418  const char *declarator_type = ts_node_type(array_declarator);
1419  if (!declarator_type) {
1420  node_malformed_error(state, array_declarator, text, "declarator");
1421  return -1;
1422  }
1423  if (is_abstract_declarator(declarator_type)) {
1424  result = parse_type_abstract_declarator_node(state, array_declarator, text, tpair);
1425  } else {
1426  result = 0;
1427  }
1428  } else {
1429  result = 0;
1430  }
1431  } else if (!strcmp(node_type, "abstract_function_declarator")) {
1432  // It can only contain two nodes:
1433  // - abstract_parenthesized_declarator (usually empty)
1434  // - parameter_list
1435  int function_node_child_count = ts_node_named_child_count(node);
1436  if (function_node_child_count != 1) {
1437  node_malformed_error(state, node, text, "abstract_function_declarator");
1438  return -1;
1439  }
1440  TSNode parenthesized_declarator = ts_node_child_by_field_name(node, "declarator", 10);
1441  if (ts_node_is_null(parenthesized_declarator) || !ts_node_is_named(parenthesized_declarator)) {
1442  node_malformed_error(state, parenthesized_declarator, text, "parenthesized_declarator");
1443  return -1;
1444  }
1445  const char *declarator_type = ts_node_type(parenthesized_declarator);
1446  if (strcmp(declarator_type, "parenthesized_declarator")) {
1447  node_malformed_error(state, parenthesized_declarator, text, "parenthesized_declarator");
1448  return -1;
1449  }
1450  // Parsing parameters list
1451  TSNode parameter_list = ts_node_child_by_field_name(node, "parameters", 10);
1452  if (ts_node_is_null(parameter_list) || !ts_node_is_named(parameter_list)) {
1453  node_malformed_error(state, parameter_list, text, "parameter_list");
1454  return -1;
1455  }
1456  const char *param_list_type = ts_node_type(parameter_list);
1457  if (strcmp(param_list_type, "parameter_list")) {
1458  node_malformed_error(state, parameter_list, text, "parameter_list");
1459  return -1;
1460  }
1461  // Generate a sequential function type name if it's not specified
1463  RzType *parent_type = (*tpair)->type;
1464  (*tpair)->type = c_parser_new_callable(state, name);
1465  if (!(*tpair)->type) {
1466  parser_error(state, "ERROR: creating new callable type: \"%s\"\n", name);
1467  return -1;
1468  }
1469 
1470  result = parse_parameter_list(state, parameter_list, text, tpair);
1471  if (result) {
1472  parser_error(state, "ERROR: parsing parameters for callable type: \"%s\"\n", name);
1473  return -1;
1474  }
1475  // The previously fetched type in this case is the callable return type
1476  (*tpair)->type->callable->ret = parent_type;
1477  if (!c_parser_callable_type_store(state, name, (*tpair)->type)) {
1478  parser_error(state, "ERROR: storing the new callable type: \"%s\"\n", name);
1479  return -1;
1480  }
1481  }
1482  return result;
1483 }
RZ_API ut64 rz_num_get(RzNum *num, const char *str)
Definition: unum.c:172
RzType * type
Definition: rz_type.h:163
int parse_parameter_list(CParserState *state, TSNode paramlist, const char *text, ParserTypePair **tpair)
static bool is_abstract_declarator(const char *declarator)
Definition: types_parser.c:63
int parse_type_abstract_declarator_node(CParserState *state, TSNode node, const char *text, ParserTypePair **tpair)
RZ_OWN RzType * c_parser_new_callable(CParserState *state, RZ_NONNULL const char *name)
Creates new callable based on the name.
RZ_OWN char * c_parser_new_anonymous_callable_name(CParserState *state)
bool c_parser_callable_type_store(CParserState *state, RZ_NONNULL const char *name, RZ_NONNULL RzType *type)
Definition: types_storage.c:98

References c_parser_callable_type_store(), c_parser_new_anonymous_callable_name(), c_parser_new_callable(), free(), is_abstract_declarator(), node_malformed_error(), NULL, parse_parameter_list(), parser_debug(), parser_error(), RZ_NEW0, rz_num_get(), rz_return_val_if_fail, RZ_TYPE_KIND_ARRAY, RZ_TYPE_KIND_POINTER, create_tags_rz::text, ts_node_child_by_field_name(), ts_node_is_named(), ts_node_is_null(), ts_node_named_child(), ts_node_named_child_count(), ts_node_sub_string(), ts_node_type(), type, and rz_type_t::type.

Referenced by parse_parameter_declaration_node(), and parse_type_descriptor_single().

◆ parse_type_declarator_node()

int parse_type_declarator_node ( CParserState state,
TSNode  node,
const char *  text,
ParserTypePair **  tpair,
char **  identifier 
)

Definition at line 1492 of file types_parser.c.

1492  {
1493  rz_return_val_if_fail(state && text && tpair, -1);
1496 
1497  parser_debug(state, "parse_type_declarator_node()\n");
1498  // Parse the type qualifier first
1499  // FIXME: There could be multiple different type qualifiers in one declaration
1500  bool is_const = false;
1501 
1502  int node_child_count = ts_node_named_child_count(node);
1503  if (node_child_count > 0) {
1504  TSNode first_leaf = ts_node_named_child(node, 0);
1505  if (ts_node_is_null(first_leaf)) {
1506  node_malformed_error(state, node, text, "type_declarator_node");
1507  return -1;
1508  }
1509  const char *leaf_type = ts_node_type(first_leaf);
1510  if (!strcmp(leaf_type, "type_qualifier")) {
1511  char *qualifier = ts_node_sub_string(first_leaf, text);
1512  parser_debug(state, "has qualifier %s\n", qualifier);
1513  if (!strcmp(qualifier, "const")) {
1514  is_const = true;
1515  }
1516  free(qualifier);
1517  }
1518  }
1519 
1520  const char *node_type = ts_node_type(node);
1521  int result = -1;
1522 
1523  if (is_identifier(node_type)) {
1524  // Identifier, usually the last leaf of the AST tree
1525  char *real_ident = ts_node_sub_string(node, text);
1526  parser_debug(state, "identifier: %s\n", real_ident);
1527  *identifier = real_ident;
1528  result = 0;
1529  } else if (!strcmp(node_type, "pointer_declarator")) {
1530  char *real_ident = ts_node_sub_string(node, text);
1531  parser_debug(state, "pointer declarator: %s\n", real_ident);
1532  // It can contain additional children recursively
1533  // - "array_declarator"
1534  // - "pointer_declarator"
1535  // - "function_declarator"
1536  // - "identifier"
1537  // Every pointer declarator should have at least declarator field
1538  TSNode pointer_declarator = ts_node_child_by_field_name(node, "declarator", 10);
1539  if (ts_node_is_null(pointer_declarator)) {
1540  parser_error(state, "ERROR: Pointer declarator AST should contain at least one node!\n");
1541  node_malformed_error(state, node, text, "pointer declarator");
1542  free(real_ident);
1543  return -1;
1544  }
1545  const char *declarator_type = ts_node_type(pointer_declarator);
1546  if (!declarator_type) {
1547  node_malformed_error(state, pointer_declarator, text, "pointer declarator");
1548  free(real_ident);
1549  return -1;
1550  }
1551 
1552  // Now we wrap the existing type into the new one
1553  // The base type in the type pair remains the same
1554  RzType *type = RZ_NEW0(RzType);
1555  if (!type) {
1556  free(real_ident);
1557  return -1;
1558  }
1559  type->kind = RZ_TYPE_KIND_POINTER;
1560  type->pointer.is_const = is_const;
1561  type->pointer.type = (*tpair)->type;
1562  (*tpair)->type = type;
1563 
1564  if (is_declarator(declarator_type) || is_identifier(declarator_type)) {
1565  result = parse_type_declarator_node(state, pointer_declarator, text, tpair, identifier);
1566  } else {
1567  result = 0;
1568  }
1569  free(real_ident);
1570  } else if (!strcmp(node_type, "array_declarator")) {
1571  char *real_ident = ts_node_sub_string(node, text);
1572  parser_debug(state, "array declarator: %s\n", real_ident);
1573  free(real_ident);
1574 
1575  // Every array declarator should have at least declarator field
1576  // The size field is optional
1577  TSNode array_declarator = ts_node_child_by_field_name(node, "declarator", 10);
1578  TSNode array_size = ts_node_child_by_field_name(node, "size", 4);
1579  if (ts_node_is_null(array_declarator)) {
1580  parser_error(state, "ERROR: Array declarator AST should contain at least one node!\n");
1581  node_malformed_error(state, node, text, "array declarator");
1582  return -1;
1583  }
1584 
1585  const char *declarator_type = ts_node_type(array_declarator);
1586  if (!declarator_type) {
1587  node_malformed_error(state, array_declarator, text, "array declarator");
1588  return -1;
1589  }
1590  // Now we wrap the existing type into the new one
1591  // The base type in the type pair remains the same
1592  RzType *type = RZ_NEW0(RzType);
1593  if (!type) {
1594  return -1;
1595  }
1596  type->kind = RZ_TYPE_KIND_ARRAY;
1597  if (ts_node_is_null(array_size)) {
1598  type->array.count = 0;
1599  } else {
1600  // number_literal node
1601  char *real_array_size = ts_node_sub_string(array_size, text);
1602  if (!real_array_size) {
1603  node_malformed_error(state, array_size, text, "array size");
1604  free(type);
1605  return -1;
1606  }
1607  int array_sz = rz_num_get(NULL, real_array_size);
1608  type->array.count = array_sz;
1609  free(real_array_size);
1610  }
1611  type->array.type = (*tpair)->type;
1612  (*tpair)->type = type;
1613 
1614  parser_debug(state, "array declarator type: %s\n", declarator_type);
1615  if (is_declarator(declarator_type) || is_identifier(declarator_type)) {
1616  result = parse_type_declarator_node(state, array_declarator, text, tpair, identifier);
1617  } else {
1618  return 0;
1619  }
1620  } else if (!strcmp(node_type, "function_declarator")) {
1621  char *real_ident = ts_node_sub_string(node, text);
1622  parser_debug(state, "function declarator: %s\n", real_ident);
1623  free(real_ident);
1624  // It can only contain two nodes:
1625  // - declarator
1626  // - parameters
1627  int function_node_child_count = ts_node_named_child_count(node);
1628  if (function_node_child_count > 2) {
1629  node_malformed_error(state, node, text, "function_declarator");
1630  return -1;
1631  }
1632  TSNode declarator = ts_node_child_by_field_name(node, "declarator", 10);
1633  if (ts_node_is_null(declarator) || !ts_node_is_named(declarator)) {
1634  node_malformed_error(state, declarator, text, "declarator");
1635  return -1;
1636  }
1637  const char *declarator_type = ts_node_type(declarator);
1638  // Declarator could be either parenthesized_declarator or identifier
1639  if (!is_function_declarator(declarator_type)) {
1640  node_malformed_error(state, declarator, text, "function declarator or identifier");
1641  return -1;
1642  }
1643  RzType *parent_type = (*tpair)->type;
1644  // At first we create "freestanding" unnamed callable
1645  RzType *naked_callable = c_parser_new_naked_callable(state);
1646  if (!naked_callable) {
1647  parser_error(state, "ERROR: creating naked callable type\n");
1648  return -1;
1649  }
1650  // The previously fetched type in this case is the callable return type
1651  naked_callable->callable->ret = parent_type;
1652  (*tpair)->type = naked_callable;
1653 
1654  // Declarator can be either "identifier" directly or have children
1655  if (is_identifier(declarator_type)) {
1656  parser_debug(state, "function declarator: simple identifier\n");
1657  if (parse_type_declarator_node(state, declarator, text, tpair, identifier)) {
1658  parser_error(state, "ERROR: parsing function declarator\n");
1659  node_malformed_error(state, declarator, text, "function identifier");
1660  return -1;
1661  }
1662  } else {
1663  TSNode function_declarator = ts_node_named_child(declarator, 0);
1664  const char *function_declarator_type = ts_node_type(function_declarator);
1665  if (!function_declarator_type) {
1666  node_malformed_error(state, function_declarator, text, "function declarator");
1667  return -1;
1668  }
1669 
1670  // Declarator can contain either "identifier" directly
1671  // Or the pointer_declarator instead (or multiple of them nested in each other)
1672  if (is_declarator(function_declarator_type) || is_identifier(function_declarator_type)) {
1673  if (parse_type_declarator_node(state, function_declarator, text, tpair, identifier)) {
1674  parser_error(state, "ERROR: parsing function declarator\n");
1675  node_malformed_error(state, function_declarator, text, "function declarator");
1676  return -1;
1677  }
1678  } else {
1679  parser_error(state, "ERROR: missing function declarator\n");
1680  node_malformed_error(state, function_declarator, text, "function declarator");
1681  return -1;
1682  }
1683  }
1684 
1685  // Parsing parameters list
1686  TSNode parameter_list = ts_node_child_by_field_name(node, "parameters", 10);
1687  if (ts_node_is_null(parameter_list) || !ts_node_is_named(parameter_list)) {
1688  node_malformed_error(state, parameter_list, text, "parameter_list");
1689  return -1;
1690  }
1691  const char *param_list_type = ts_node_type(parameter_list);
1692  if (strcmp(param_list_type, "parameter_list")) {
1693  node_malformed_error(state, parameter_list, text, "parameter_list");
1694  return -1;
1695  }
1696  naked_callable->callable->name = strdup(*identifier);
1697  // Preserve the parent callable type
1698  parent_type = (*tpair)->type;
1699  // Then override with the naked callable type to proceed with parameter parsing
1700  (*tpair)->type = naked_callable;
1701  result = parse_parameter_list(state, parameter_list, text, tpair);
1702  if (result) {
1703  parser_error(state, "ERROR: parsing parameters for callable type: \"%s\"\n", *identifier);
1704  return -1;
1705  }
1706  // Restore the true parent type
1707  (*tpair)->type = parent_type;
1708  if (!c_parser_callable_type_store(state, *identifier, naked_callable)) {
1709  parser_error(state, "ERROR: storing the new callable type: \"%s\"\n", *identifier);
1710  return -1;
1711  }
1712  }
1713  return result;
1714 }
RZ_NULLABLE RzType * ret
Definition: rz_type.h:148
RzCallable * callable
Definition: rz_type.h:170
static bool is_function_declarator(const char *declarator)
Definition: types_parser.c:77
static bool is_identifier(const char *type)
static bool is_declarator(const char *declarator)
Definition: types_parser.c:69
RZ_OWN RzType * c_parser_new_naked_callable(CParserState *state)
Creates new naked callable without storing it.

References c_parser_callable_type_store(), c_parser_new_naked_callable(), rz_type_t::callable, free(), is_declarator(), is_function_declarator(), is_identifier(), rz_callable_at::name, node_malformed_error(), NULL, parse_parameter_list(), parser_debug(), parser_error(), rz_callable_at::ret, RZ_NEW0, rz_num_get(), rz_return_val_if_fail, RZ_TYPE_KIND_ARRAY, RZ_TYPE_KIND_POINTER, strdup(), create_tags_rz::text, ts_node_child_by_field_name(), ts_node_is_named(), ts_node_is_null(), ts_node_named_child(), ts_node_named_child_count(), ts_node_sub_string(), ts_node_type(), type, and rz_type_t::type.

Referenced by parse_declaration_node(), parse_parameter_declaration_node(), parse_struct_node(), parse_typedef_node(), and parse_union_node().

◆ parse_type_descriptor_single()

int parse_type_descriptor_single ( CParserState state,
TSNode  node,
const char *  text,
ParserTypePair **  tpair 
)

Definition at line 1719 of file types_parser.c.

1719  {
1720  rz_return_val_if_fail(state && text && tpair, -1);
1722  // We skip simple nodes (e.g. conditions and braces)
1723  if (!ts_node_is_named(node)) {
1724  return 0;
1725  }
1726  const char *node_type = ts_node_type(node);
1727  int result = -1;
1728  if (strcmp(node_type, "type_descriptor")) {
1729  return -1;
1730  }
1731  parser_debug(state, "parse_type_descriptor_single()\n");
1732 
1733  int typedesc_node_child_count = ts_node_named_child_count(node);
1734  if (typedesc_node_child_count < 1) {
1735  node_malformed_error(state, node, text, "type_descriptor");
1736  return -1;
1737  }
1738  // Type descriptor has three fields:
1739  // 0. type qualifier (optional)
1740  // 1. type itself
1741  // 2. declarator field (optional)
1742 
1743  // Parse the type qualifier first
1744  // FIXME: There could be multiple different type qualifiers in one declaration
1745  bool is_const = false;
1746  TSNode first_leaf = ts_node_named_child(node, 0);
1747  if (ts_node_is_null(first_leaf)) {
1748  node_malformed_error(state, node, text, "type_descriptor");
1749  return -1;
1750  }
1751  const char *leaf_type = ts_node_type(first_leaf);
1752  if (!strcmp(leaf_type, "type_qualifier")) {
1753  char *qualifier = ts_node_sub_string(first_leaf, text);
1754  parser_debug(state, "has qualifier \"%s\"\n", qualifier);
1755  if (!strcmp(qualifier, "const")) {
1756  parser_debug(state, "set const\n");
1757  is_const = true;
1758  }
1759  free(qualifier);
1760  }
1761 
1762  TSNode type_node = ts_node_child_by_field_name(node, "type", 4);
1763  if (ts_node_is_null(type_node)) {
1764  node_malformed_error(state, node, text, "type_descriptor");
1765  parser_error(state, "type_descriptor's type field cannot be NULL\n");
1766  return -1;
1767  }
1768  if (parse_type_node_single(state, type_node, text, tpair, is_const)) {
1769  node_malformed_error(state, node, text, "type_descriptor");
1770  parser_error(state, "Cannot parse type_descriptor's type field\n");
1771  return -1;
1772  }
1773  if (!*tpair) {
1774  parser_error(state, "Failed to parse type_descriptor's type field\n");
1775  return -1;
1776  }
1777  // 2. Optional declarator field
1778  TSNode type_declarator = ts_node_child_by_field_name(node, "declarator", 10);
1779  if (!ts_node_is_null(type_declarator)) {
1780  return parse_type_abstract_declarator_node(state, type_declarator, text, tpair);
1781  } else {
1782  result = 0;
1783  }
1784  return result;
1785 }

References free(), node_malformed_error(), parse_type_abstract_declarator_node(), parse_type_node_single(), parser_debug(), parser_error(), rz_return_val_if_fail, create_tags_rz::text, ts_node_child_by_field_name(), ts_node_is_named(), ts_node_is_null(), ts_node_named_child(), ts_node_named_child_count(), ts_node_sub_string(), and ts_node_type().

Referenced by rz_type_parse_string_single().

◆ parse_type_node_single()

int parse_type_node_single ( CParserState state,
TSNode  node,
const char *  text,
ParserTypePair **  tpair,
bool  is_const 
)

Definition at line 1170 of file types_parser.c.

1170  {
1171  rz_return_val_if_fail(state && text && tpair, -1);
1173  // We skip simple nodes (e.g. conditions and braces)
1174  if (!ts_node_is_named(node)) {
1175  return 0;
1176  }
1177 
1178  const char *node_type = ts_node_type(node);
1179  int result = -1;
1180 
1181  parser_debug(state, "parse_type_node_single(\"%s\")\n", node_type);
1182 
1183  if (!strcmp(node_type, "struct_specifier")) {
1184  result = parse_struct_node(state, node, text, tpair, is_const);
1185  if (result || !*tpair) {
1186  return -1;
1187  }
1188  } else if (!strcmp(node_type, "union_specifier")) {
1189  result = parse_union_node(state, node, text, tpair, is_const);
1190  if (result || !*tpair) {
1191  return -1;
1192  }
1193  } else if (!strcmp(node_type, "enum_specifier")) {
1194  result = parse_enum_node(state, node, text, tpair, is_const);
1195  if (result || !*tpair) {
1196  return -1;
1197  }
1198  } else if (!strcmp(node_type, "type_definition")) {
1199  result = parse_typedef_node(state, node, text, tpair);
1200  if (result || !*tpair) {
1201  return -1;
1202  }
1203  } else if (!strcmp(node_type, "sized_type_specifier")) {
1204  result = parse_sized_primitive_type(state, node, text, tpair, is_const);
1205  if (result || !*tpair) {
1206  return -1;
1207  }
1208  } else if (!strcmp(node_type, "primitive_type")) {
1209  result = parse_primitive_type(state, node, text, tpair, is_const);
1210  if (result || !*tpair) {
1211  return -1;
1212  }
1213  } else if (!strcmp(node_type, "type_identifier")) {
1214  result = parse_sole_type_name(state, node, text, tpair, is_const);
1215  if (result || !*tpair) {
1216  return -1;
1217  }
1218  }
1219  // Another case where there is a declaration clause
1220  // In this case we should drop the declaration itself
1221  // and parse only the corresponding type
1222  // In case of anonymous type we could use identifier as a name for this type?
1223  //
1224  return result;
1225 }
int parse_primitive_type(CParserState *state, TSNode node, const char *text, ParserTypePair **tpair, bool is_const)
Definition: types_parser.c:83
int parse_union_node(CParserState *state, TSNode node, const char *text, ParserTypePair **tpair, bool is_const)
Definition: types_parser.c:598
int parse_typedef_node(CParserState *state, TSNode node, const char *text, ParserTypePair **tpair)
int parse_sole_type_name(CParserState *state, TSNode node, const char *text, ParserTypePair **tpair, bool is_const)
Definition: types_parser.c:155
int parse_struct_node(CParserState *state, TSNode node, const char *text, ParserTypePair **tpair, bool is_const)
Definition: types_parser.c:306
int parse_sized_primitive_type(CParserState *state, TSNode node, const char *text, ParserTypePair **tpair, bool is_const)
Definition: types_parser.c:119
int parse_enum_node(CParserState *state, TSNode node, const char *text, ParserTypePair **tpair, bool is_const)
Definition: types_parser.c:885

References parse_enum_node(), parse_primitive_type(), parse_sized_primitive_type(), parse_sole_type_name(), parse_struct_node(), parse_typedef_node(), parse_union_node(), parser_debug(), rz_return_val_if_fail, create_tags_rz::text, ts_node_is_named(), ts_node_is_null(), and ts_node_type().

Referenced by parse_declaration_node(), parse_parameter_declaration_node(), parse_struct_node(), parse_type_descriptor_single(), parse_typedef_node(), and parse_union_node().

◆ parse_type_nodes_save()

int parse_type_nodes_save ( CParserState state,
TSNode  node,
const char *  text 
)

Definition at line 1866 of file types_parser.c.

1866  {
1869  // We skip simple nodes (e.g. conditions and braces)
1870  if (!ts_node_is_named(node)) {
1871  return 0;
1872  }
1873  const char *node_type = ts_node_type(node);
1874  int result = -1;
1875  ParserTypePair *tpair = NULL;
1876  if (!strcmp(node_type, "struct_specifier")) {
1877  result = parse_struct_node(state, node, text, &tpair, false);
1878  if (result || !tpair) {
1879  return -1;
1880  }
1881  } else if (!strcmp(node_type, "union_specifier")) {
1882  result = parse_union_node(state, node, text, &tpair, false);
1883  if (result || !tpair) {
1884  return -1;
1885  }
1886  } else if (!strcmp(node_type, "enum_specifier")) {
1887  result = parse_enum_node(state, node, text, &tpair, false);
1888  if (result || !tpair) {
1889  return -1;
1890  }
1891  } else if (!strcmp(node_type, "type_definition")) {
1892  result = parse_typedef_node(state, node, text, &tpair);
1893  if (result || !tpair) {
1894  return -1;
1895  }
1896  }
1897 
1898  // Another case where there is a declaration clause
1899  // In this case we should drop the declaration itself
1900  // and parse only the corresponding type. An exception for this
1901  // rule is the function declaration.
1902  if (!strcmp(node_type, "declaration")) {
1903  result = parse_declaration_node(state, node, text, &tpair);
1904  if (result || !tpair) {
1905  return -1;
1906  }
1907  }
1908 
1909  if (result) {
1910  char *typetext = ts_node_sub_string(node, text);
1911  parser_error(state, "Unsupported type definition: %s\n", typetext);
1912  free(typetext);
1913  }
1914 
1915  // In case of anonymous type we could use identifier as a name for this type?
1916  return result;
1917 }
int parse_declaration_node(CParserState *state, TSNode node, const char *text, ParserTypePair **tpair)

References free(), NULL, parse_declaration_node(), parse_enum_node(), parse_struct_node(), parse_typedef_node(), parse_union_node(), parser_error(), rz_return_val_if_fail, create_tags_rz::text, ts_node_is_named(), ts_node_is_null(), ts_node_sub_string(), and ts_node_type().

Referenced by type_parse_string().

◆ parser_debug()

void parser_debug ( CParserState state,
const char *  fmt,
  ... 
)

◆ parser_error()

◆ parser_warning()

void parser_warning ( CParserState state,
const char *  fmt,
  ... 
)

Definition at line 55 of file types_parser.c.

55  {
56  rz_return_if_fail(state && fmt);
57  va_list ap;
58  va_start(ap, fmt);
59  rz_strbuf_vappendf(state->warnings, fmt, ap);
60  va_end(ap);
61 }

References rz_return_if_fail, and rz_strbuf_vappendf().

Referenced by parse_enum_node(), parse_struct_node(), parse_union_node(), rz_type_parse_string_declaration_single(), rz_type_parse_string_single(), and type_parse_string().