Rizin
unix-like reverse engineering framework and cli tools
types_parser.c File Reference
#include <stdio.h>
#include <rz_types.h>
#include <rz_list.h>
#include <rz_util/rz_str.h>
#include <rz_util/rz_file.h>
#include <rz_util/rz_assert.h>
#include <rz_type.h>
#include <tree_sitter/api.h>
#include <types_parser.h>

Go to the source code of this file.

Macros

#define TS_START_END(node, start, end)
 

Functions

static char * ts_node_sub_string (TSNode node, const char *cstr)
 
void node_malformed_error (CParserState *state, TSNode node, const char *text, const char *nodetype)
 
void parser_debug (CParserState *state, const char *fmt,...)
 
void parser_error (CParserState *state, const char *fmt,...)
 
void parser_warning (CParserState *state, const char *fmt,...)
 
static bool is_abstract_declarator (const char *declarator)
 
static bool is_declarator (const char *declarator)
 
static bool is_function_declarator (const char *declarator)
 
int parse_primitive_type (CParserState *state, TSNode node, const char *text, ParserTypePair **tpair, bool is_const)
 
int parse_sized_primitive_type (CParserState *state, TSNode node, const char *text, ParserTypePair **tpair, bool is_const)
 
int parse_sole_type_name (CParserState *state, TSNode node, const char *text, ParserTypePair **tpair, bool is_const)
 
int parse_parameter_declaration_node (CParserState *state, TSNode node, const char *text, ParserTypePair **tpair, char **identifier)
 
int parse_struct_node (CParserState *state, TSNode node, const char *text, ParserTypePair **tpair, bool is_const)
 
int parse_union_node (CParserState *state, TSNode node, const char *text, ParserTypePair **tpair, bool is_const)
 
int parse_enum_node (CParserState *state, TSNode node, const char *text, ParserTypePair **tpair, bool is_const)
 
int parse_typedef_node (CParserState *state, TSNode node, const char *text, ParserTypePair **tpair)
 
int parse_type_node_single (CParserState *state, TSNode node, const char *text, ParserTypePair **tpair, bool is_const)
 
int parse_parameter_list (CParserState *state, TSNode paramlist, const char *text, ParserTypePair **tpair)
 
int parse_type_abstract_declarator_node (CParserState *state, TSNode node, const char *text, ParserTypePair **tpair)
 
static bool is_identifier (const char *type)
 
int parse_type_declarator_node (CParserState *state, TSNode node, const char *text, ParserTypePair **tpair, char **identifier)
 
int parse_type_descriptor_single (CParserState *state, TSNode node, const char *text, ParserTypePair **tpair)
 
int parse_declaration_node (CParserState *state, TSNode node, const char *text, ParserTypePair **tpair)
 
int parse_type_nodes_save (CParserState *state, TSNode node, const char *text)
 

Macro Definition Documentation

◆ TS_START_END

#define TS_START_END (   node,
  start,
  end 
)
Value:
do { \
start = ts_node_start_byte(node); \
end = ts_node_end_byte(node); \
} while (0)
uint32_t ts_node_start_byte(TSNode)
Definition: node.c:36
uint32_t ts_node_end_byte(TSNode)
Definition: node.c:406

Definition at line 15 of file types_parser.c.

Function Documentation

◆ is_abstract_declarator()

static bool is_abstract_declarator ( const char *  declarator)
static

Definition at line 63 of file types_parser.c.

63  {
64  return !strcmp(declarator, "abstract_pointer_declarator") ||
65  !strcmp(declarator, "abstract_array_declarator") ||
66  !strcmp(declarator, "abstract_function_declarator");
67 }

Referenced by parse_parameter_declaration_node(), and parse_type_abstract_declarator_node().

◆ is_declarator()

static bool is_declarator ( const char *  declarator)
static

Definition at line 69 of file types_parser.c.

69  {
70  return !strcmp(declarator, "pointer_declarator") ||
71  !strcmp(declarator, "array_declarator") ||
72  !strcmp(declarator, "function_declarator") ||
73  !strcmp(declarator, "identifier") ||
74  !strcmp(declarator, "field_identifier");
75 }

Referenced by parse_parameter_declaration_node(), and parse_type_declarator_node().

◆ is_function_declarator()

static bool is_function_declarator ( const char *  declarator)
static

Definition at line 77 of file types_parser.c.

77  {
78  return !strcmp(declarator, "parenthesized_declarator") ||
79  !strcmp(declarator, "identifier");
80 }

Referenced by parse_type_declarator_node().

◆ is_identifier()

static bool is_identifier ( const char *  type)
static

Definition at line 1485 of file types_parser.c.

1485  {
1486  return (!strcmp(type, "identifier") || !strcmp(type, "field_identifier") || !strcmp(type, "type_identifier"));
1487 }
int type
Definition: mipsasm.c:17

References type.

Referenced by parse_type_declarator_node().

◆ node_malformed_error()

void node_malformed_error ( CParserState state,
TSNode  node,
const char *  text,
const char *  nodetype 
)

Definition at line 27 of file types_parser.c.

27  {
28  rz_return_if_fail(nodetype);
29  char *string = ts_node_is_null(node) ? NULL : ts_node_string(node);
30  char *piece = ts_node_is_null(node) ? NULL : ts_node_sub_string(node, text);
31  rz_strbuf_appendf(state->errors, "Wrongly formed \"(%s)\": \"%s\"\n", nodetype, rz_str_get_null(string));
32  rz_strbuf_appendf(state->errors, "\"(%s)\": \"%s\"\n", nodetype, rz_str_get_null(piece));
33  free(piece);
34  free(string);
35 }
char * ts_node_string(TSNode)
Definition: node.c:426
bool ts_node_is_null(TSNode)
Definition: node.c:434
#define NULL
Definition: cris-opc.c:27
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
static const char * rz_str_get_null(const char *str)
Definition: rz_str.h:190
RZ_API bool rz_strbuf_appendf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
Definition: dis.h:43
static char * ts_node_sub_string(TSNode node, const char *cstr)
Definition: types_parser.c:21

References free(), NULL, rz_return_if_fail, rz_str_get_null(), rz_strbuf_appendf(), create_tags_rz::text, ts_node_is_null(), ts_node_string(), and ts_node_sub_string().

Referenced by parse_declaration_node(), parse_enum_node(), parse_parameter_declaration_node(), parse_parameter_list(), parse_primitive_type(), parse_sized_primitive_type(), parse_sole_type_name(), parse_struct_node(), parse_type_abstract_declarator_node(), parse_type_declarator_node(), parse_type_descriptor_single(), parse_typedef_node(), and parse_union_node().

◆ 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
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
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
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)
void parser_debug(CParserState *state, const char *fmt,...)
Definition: types_parser.c:37
void parser_error(CParserState *state, const char *fmt,...)
Definition: types_parser.c:47

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_enum_node()

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

Definition at line 885 of file types_parser.c.

885  {
886  rz_return_val_if_fail(state && text && tpair, -1);
889 
890  parser_debug(state, "parse_enum_node()\n");
891 
892  int enum_node_child_count = ts_node_named_child_count(node);
893  if (enum_node_child_count < 1 || enum_node_child_count > 2) {
894  node_malformed_error(state, node, text, "enum");
895  return -1;
896  }
897  int result = 0;
898  // Name is optional, in abstract definitions or as the member of nested types
899  char *name = NULL;
900  TSNode enum_name = ts_node_child_by_field_name(node, "name", 4);
901  if (ts_node_is_null(enum_name)) {
902  parser_debug(state, "Anonymous enum\n");
904  } else {
905  name = ts_node_sub_string(enum_name, text);
906  if (!name) {
907  parser_error(state, "ERROR: Enum name should not be NULL!\n");
908  node_malformed_error(state, node, text, "enum");
909  return -1;
910  }
911  parser_debug(state, "enum name: %s\n", name);
912  }
913 
914  // Parsing the enum body
915  // If the enum doesn't have body but has a name
916  // it means that it uses the type predefined before
917  // e.g. "const enum FOO a;"
918  TSNode enum_body = ts_node_child_by_field_name(node, "body", 4);
919  if (ts_node_is_null(enum_body) && !ts_node_is_null(enum_name)) {
920  parser_debug(state, "Fetching predefined enum: \"%s\"\n", name);
921  if (!(*tpair = c_parser_get_enum_type(state, name))) {
922  parser_warning(state, "Cannot find \"%s\" enum in the context\n", name);
923  // At first we check if there is a forward definion already
925  parser_debug(state, "Enum \"%s\" was forward-defined before\n", name);
926  if (!(*tpair = c_parser_new_enum_naked_type(state, name))) {
927  parser_error(state, "Cannot create \"%s\" naked enum type in the context\n", name);
928  result = -1;
929  goto rexit;
930  }
931  goto rexit;
932  }
933  // We still could create the "forward looking enum declaration"
934  // The parser then can augment the definition
935  if (!(*tpair = c_parser_new_enum_forward_definition(state, name))) {
936  parser_error(state, "Cannot create \"%s\" forward enum definition in the context\n", name);
937  result = -1;
938  goto rexit;
939  }
940  goto rexit;
941  } else {
942  goto rexit;
943  }
944  }
945 
946  parser_debug(state, "enum name: %s\n", name);
947 
948  int body_child_count = ts_node_named_child_count(enum_body);
949  // Now we form both RzType and RzBaseType to store in the Types database
950  ParserTypePair *enum_pair = c_parser_new_enum_type(state, name, body_child_count);
951  if (!enum_pair) {
952  parser_error(state, "Error forming RzType and RzBaseType pair out of enum: \"%s\"\n", name);
953  result = -1;
954  goto rexit;
955  }
956  // Then we process all enumeration cases and add one by one
957  int i;
958  for (i = 0; i < body_child_count; i++) {
959  parser_debug(state, "enum: processing %d field...\n", i);
960  TSNode child = ts_node_named_child(enum_body, i);
961  const char *node_type = ts_node_type(child);
962 
963  // Skip comments
964  if (!strcmp(node_type, "comment")) {
965  continue;
966  }
967 
968  // Every field should have (field_declaration) AST clause
969  if (strcmp(node_type, "enumerator")) {
970  parser_error(state, "ERROR: Enum member AST should contain (enumerator) node!\n");
971  node_malformed_error(state, child, text, "enum field");
972  free(enum_pair);
973  result = -1;
974  goto rexit;
975  }
976  // Every member node should have at least 1 child!
977  int member_child_count = ts_node_named_child_count(child);
978  if (member_child_count < 1 || member_child_count > 2) {
979  parser_error(state, "ERROR: enum member AST cannot contain less than 1 or more than 2 items");
980  node_malformed_error(state, child, text, "enum field");
981  free(enum_pair);
982  result = -1;
983  goto rexit;
984  }
985  // Every member can be:
986  // - empty
987  // - atomic: "1"
988  // - expression: "1 << 2"
989  if (state->verbose) {
990  char *membertext = ts_node_sub_string(child, text);
991  char *nodeast = ts_node_string(child);
992  if (membertext && nodeast) {
993  parser_debug(state, "member text: %s\n", membertext);
994  parser_debug(state, "member ast: %s\n", nodeast);
995  }
996  free(nodeast);
997  free(membertext);
998  }
999  if (member_child_count == 1) {
1000  // It's an empty field, like just "A,"
1001  TSNode member_identifier = ts_node_child_by_field_name(child, "name", 4);
1002  if (ts_node_is_null(member_identifier)) {
1003  parser_error(state, "ERROR: Enum case identifier should not be NULL!\n");
1004  node_malformed_error(state, child, text, "enum case");
1005  free(enum_pair);
1006  result = -1;
1007  goto rexit;
1008  }
1009  char *real_identifier = ts_node_sub_string(member_identifier, text);
1010  parser_debug(state, "enum member: %s\n", real_identifier);
1011  // Add an enum case
1012  RzVector *cases = &enum_pair->btype->enum_data.cases;
1013  // In this case we just increment previous value by 1
1014  st64 derived_val = 0;
1015  if (!rz_vector_empty(cases)) {
1016  RzTypeEnumCase *lastcase = rz_vector_tail(cases);
1017  derived_val = lastcase->val + 1;
1018  }
1019  RzTypeEnumCase cas = {
1020  .name = real_identifier,
1021  .val = derived_val
1022  };
1023  void *element = rz_vector_push(cases, &cas); // returns null if no space available
1024  if (!element) {
1025  parser_error(state, "Error appending enum case to the base type\n");
1026  free(cas.name);
1027  free(enum_pair);
1028  result = -1;
1029  goto rexit;
1030  }
1031  } else {
1032  // It's a proper field, like "A = 1,"
1033  TSNode member_identifier = ts_node_child_by_field_name(child, "name", 4);
1034  TSNode member_value = ts_node_child_by_field_name(child, "value", 5);
1035  if (ts_node_is_null(member_identifier) || ts_node_is_null(member_value)) {
1036  parser_error(state, "ERROR: Enum case identifier and value should not be NULL!\n");
1037  node_malformed_error(state, child, text, "enum case");
1038  free(enum_pair);
1039  result = -1;
1040  goto rexit;
1041  }
1042  char *real_identifier = ts_node_sub_string(member_identifier, text);
1043  char *real_value = ts_node_sub_string(member_value, text);
1044  // FIXME: Use RzNum to calculate complex expressions
1045  parser_debug(state, "enum member: %s value: %s\n", real_identifier, real_value);
1046  // Add an enum case
1047  RzVector *cases = &enum_pair->btype->enum_data.cases;
1048  RzTypeEnumCase cas = {
1049  .name = real_identifier,
1050  .val = rz_num_get(NULL, real_value)
1051  };
1052  free(real_value);
1053  void *element = rz_vector_push(cases, &cas); // returns null if no space available
1054  if (!element) {
1055  parser_error(state, "Error appending enum case to the base type\n");
1056  free(cas.name);
1057  free(enum_pair);
1058  result = -1;
1059  goto rexit;
1060  }
1061  }
1062  }
1063  // If parsing successfull completed - we store the state
1064  if (enum_pair) {
1065  c_parser_base_type_store(state, name, enum_pair);
1066  // If it was a forward definition previously - remove it
1069  }
1070  }
1071  *tpair = enum_pair;
1072 rexit:
1073  free(name);
1074  return result;
1075 }
lzma_index ** i
Definition: index.h:629
RZ_API ut64 rz_num_get(RzNum *num, const char *str)
Definition: unum.c:172
#define st64
Definition: rz_types_base.h:10
static void * rz_vector_tail(RzVector *vec)
Definition: rz_vector.h:100
RZ_API void * rz_vector_push(RzVector *vec, void *x)
Definition: vector.c:197
static bool rz_vector_empty(const RzVector *vec)
Definition: rz_vector.h:74
RzBaseType * btype
Definition: types_parser.h:23
Definition: z80asm.h:102
RzVector cases
Definition: rz_type.h:108
RzBaseTypeEnum enum_data
Definition: rz_type.h:119
void parser_warning(CParserState *state, const char *fmt,...)
Definition: types_parser.c:55
bool c_parser_forward_definition_remove(CParserState *state, RZ_NONNULL const char *name)
Definition: types_storage.c:70
bool c_parser_base_type_is_forward_definition(CParserState *state, RZ_NONNULL const char *name)
Definition: types_storage.c:26
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.
bool c_parser_base_type_store(CParserState *state, RZ_NONNULL const char *name, ParserTypePair *tpair)
Definition: types_storage.c:36
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.
RZ_OWN char * c_parser_new_anonymous_enum_name(CParserState *state)
RZ_OWN ParserTypePair * c_parser_new_enum_forward_definition(CParserState *state, RZ_NONNULL const char *name)
Creates new enum forward definition.
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.

References ParserTypePair::btype, c_parser_base_type_is_forward_definition(), c_parser_base_type_store(), c_parser_forward_definition_remove(), c_parser_get_enum_type(), c_parser_new_anonymous_enum_name(), c_parser_new_enum_forward_definition(), c_parser_new_enum_naked_type(), c_parser_new_enum_type(), rz_base_type_enum_t::cases, rz_base_type_t::enum_data, free(), i, rz_type_enum_case_t::name, node_malformed_error(), NULL, parser_debug(), parser_error(), parser_warning(), rz_num_get(), rz_return_val_if_fail, rz_vector_empty(), rz_vector_push(), rz_vector_tail(), st64, 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_string(), ts_node_sub_string(), ts_node_type(), and rz_type_enum_case_t::val.

Referenced by parse_type_node_single(), and parse_type_nodes_save().

◆ parse_parameter_declaration_node()

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

Definition at line 226 of file types_parser.c.

226  {
227  rz_return_val_if_fail(state && text && tpair, -1);
230 
231  const char *param_type = ts_node_type(node);
232  parser_debug(state, "parameter type: %s\n", param_type);
233 
234  // Type descriptor has three fields:
235  // 0. type qualifier (optional)
236  // 1. type itself (optional)
237  // 2. declarator (can be concrete or an abstract one)
238 
239  // Parse the type qualifier first (if present)
240  // FIXME: There could be multiple different type qualifiers in one declaration
241  bool is_const = false;
242  TSNode first_leaf = ts_node_named_child(node, 0);
243  if (!ts_node_is_null(first_leaf)) {
244  const char *leaf_type = ts_node_type(first_leaf);
245  // If we have type qualifier in this position it is related to
246  // the type itself
247  if (!strcmp(leaf_type, "type_qualifier")) {
248  char *qualifier = ts_node_sub_string(first_leaf, text);
249  parser_debug(state, "has qualifier %s\n", qualifier);
250  if (!strcmp(qualifier, "const")) {
251  is_const = true;
252  }
253  free(qualifier);
254  }
255  }
256 
257  // Ever parameter should have at least type field
258  TSNode parameter_type = ts_node_child_by_field_name(node, "type", 4);
259  if (ts_node_is_null(parameter_type)) {
260  parser_error(state, "ERROR: Parameter AST should contain at least one node!\n");
261  node_malformed_error(state, node, text, "parameter type");
262  return -1;
263  }
264 
265  if (parse_type_node_single(state, parameter_type, text, tpair, is_const)) {
266  parser_error(state, "Cannot parse type_descriptor's type field");
267  return -1;
268  }
269  if (!*tpair) {
270  parser_error(state, "Failed to parse type_descriptor's type field");
271  return -1;
272  }
273 
274  // Ever parameter could have a declarator field but it's optional
275  TSNode parameter_declarator = ts_node_child_by_field_name(node, "declarator", 10);
276  if (ts_node_is_null(parameter_declarator)) {
277  // In the case it's null it means the sole type name which was
278  // already parsed in "parse_type_node_single()"
279  return 0;
280  }
281 
282  // Check if it's abstract or a concrete node
283  const char *declarator_type = ts_node_type(parameter_declarator);
284  if (!declarator_type) {
285  node_malformed_error(state, parameter_declarator, text, "parameter declarator");
286  return -1;
287  }
288  parser_debug(state, "declarator type: \"%s\"\n", declarator_type);
289  if (is_abstract_declarator(declarator_type)) {
290  return parse_type_abstract_declarator_node(state, parameter_declarator, text, tpair);
291  } else if (is_declarator(declarator_type)) {
292  return parse_type_declarator_node(state, parameter_declarator, text, tpair, identifier);
293  }
294  node_malformed_error(state, parameter_declarator, text, "parameter declarator");
295  return -1;
296 }
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)
static bool is_declarator(const char *declarator)
Definition: types_parser.c:69

References free(), is_abstract_declarator(), is_declarator(), node_malformed_error(), parse_type_abstract_declarator_node(), 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_sub_string(), and ts_node_type().

Referenced by parse_parameter_list().

◆ parse_parameter_list()

int parse_parameter_list ( CParserState state,
TSNode  paramlist,
const char *  text,
ParserTypePair **  tpair 
)

Definition at line 1228 of file types_parser.c.

1228  {
1229  rz_return_val_if_fail(state && text && tpair, -1);
1230  rz_return_val_if_fail(!ts_node_is_null(paramlist), -1);
1231  // We skip simple nodes (e.g. conditions and braces)
1232  if (!ts_node_is_named(paramlist)) {
1233  return 0;
1234  }
1235 
1236  if ((*tpair)->type->kind != RZ_TYPE_KIND_CALLABLE) {
1237  parser_error(state, "ERROR: Parameter description only acceptable as part of function definition!\n");
1238  return -1;
1239  }
1240  parser_debug(state, "parse_parameter_list()\n");
1241 
1242  const char *node_type = ts_node_type(paramlist);
1243  if (strcmp(node_type, "parameter_list")) {
1244  node_malformed_error(state, paramlist, text, "parameter_list");
1245  return -1;
1246  }
1247  int paramlist_child_count = ts_node_named_child_count(paramlist);
1248  if (paramlist_child_count < 1) {
1249  node_malformed_error(state, paramlist, text, "parameter_list");
1250  return -1;
1251  }
1252  int i;
1253  for (i = 0; i < paramlist_child_count; i++) {
1254  parser_debug(state, "parameter_list: processing %d field...\n", i);
1255  TSNode child = ts_node_named_child(paramlist, i);
1256  const char *node_type = ts_node_type(child);
1257  // Every field should have (parameter_declaration) AST clause
1258  if (strcmp(node_type, "parameter_declaration") && strcmp(node_type, "variadic_parameter")) {
1259  parser_error(state, "ERROR: Parameter field AST should contain (parameter_declaration|variadic_parameter) node!\n");
1260  node_malformed_error(state, child, text, "parameter_declaration|variadic_parameter");
1261  return -1;
1262  }
1263  if (!strcmp(node_type, "variadic_parameter")) {
1264  // This is a variadic parameter "...", let's ignore it for now
1265  parser_debug(state, "Processing variadic parameter, ignoring for now...\n", i);
1266  continue;
1267  }
1268  char *identifier = NULL;
1269  // Create new TypePair here
1270  ParserTypePair *argtpair = NULL;
1271  if (parse_parameter_declaration_node(state, child, text, &argtpair, &identifier)) {
1272  parser_error(state, "ERROR: Parsing parameter declarator!\n");
1273  return -1;
1274  }
1275  if (!argtpair || !argtpair->type) {
1276  return -1;
1277  }
1278  // Store the parameters if available
1279  // If the name is not available just name it as "argN" where N is argument index
1280  if (!identifier) {
1281  identifier = rz_str_newf("arg%d", i);
1282  }
1283  parser_debug(state, "Adding \"%s\" parameter\n", identifier);
1284  if (!c_parser_new_callable_argument(state, (*tpair)->type->callable, identifier, argtpair->type)) {
1285  parser_error(state, "ERROR: Cannot add the parameter to the function!\n");
1286  free(identifier);
1287  return -1;
1288  }
1289  free(identifier);
1290  }
1291  return 0;
1292 }
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
@ RZ_TYPE_KIND_CALLABLE
Definition: rz_type.h:131
RzType * type
Definition: types_parser.h:24
int parse_parameter_declaration_node(CParserState *state, TSNode node, const char *text, ParserTypePair **tpair, char **identifier)
Definition: types_parser.c:226
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.

References c_parser_new_callable_argument(), free(), i, node_malformed_error(), NULL, parse_parameter_declaration_node(), parser_debug(), parser_error(), rz_return_val_if_fail, rz_str_newf(), RZ_TYPE_KIND_CALLABLE, create_tags_rz::text, ts_node_is_named(), ts_node_is_null(), ts_node_named_child(), ts_node_named_child_count(), ts_node_type(), and ParserTypePair::type.

Referenced by parse_type_abstract_declarator_node(), and parse_type_declarator_node().

◆ parse_primitive_type()

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

Definition at line 83 of file types_parser.c.

83  {
84  rz_return_val_if_fail(state && text && tpair, -1);
87 
88  parser_debug(state, "parse_primitive_type(): %s\n", is_const ? "const" : "not const");
89  if (strcmp(ts_node_type(node), "primitive_type")) {
90  node_malformed_error(state, node, text, "not primitive type");
91  return -1;
92  }
93  char *real_type = ts_node_sub_string(node, text);
94  if (!real_type) {
95  node_malformed_error(state, node, text, "primitive type");
96  parser_error(state, "Primitive type name cannot be NULL\n");
97  return -1;
98  }
99  // At first we search if the type is already presented in the state
100  if ((*tpair = c_parser_get_primitive_type(state, real_type, is_const))) {
101  parser_debug(state, "Fetched primitive type: \"%s\"\n", real_type);
102  free(real_type);
103  return 0;
104  }
105  // If not - we form both RzType and RzBaseType to store in the Types database
106  ParserTypePair *type_pair = c_parser_new_primitive_type(state, real_type, is_const);
107  if (!type_pair) {
108  parser_error(state, "Error forming RzType and RzBaseType pair out of primitive type\n");
109  free(real_type);
110  return -1;
111  }
112  c_parser_base_type_store(state, real_type, type_pair);
113  *tpair = type_pair;
114  free(real_type);
115  return 0;
116 }
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.
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.

References c_parser_base_type_store(), c_parser_get_primitive_type(), c_parser_new_primitive_type(), free(), node_malformed_error(), parser_debug(), 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 parse_type_node_single().

◆ parse_sized_primitive_type()

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

Definition at line 119 of file types_parser.c.

119  {
120  rz_return_val_if_fail(state && text && tpair, -1);
123 
124  if (strcmp(ts_node_type(node), "sized_type_specifier")) {
125  node_malformed_error(state, node, text, "not sized primitive type");
126  return -1;
127  }
128  char *real_type = ts_node_sub_string(node, text);
129  if (!real_type) {
130  node_malformed_error(state, node, text, "primitive type");
131  parser_error(state, "Primitive type name cannot be NULL\n");
132  free(real_type);
133  return -1;
134  }
135  // At first we search if the type is already presented in the state
136  if ((*tpair = c_parser_get_primitive_type(state, real_type, is_const))) {
137  parser_debug(state, "Fetched primitive type: \"%s\"\n", real_type);
138  free(real_type);
139  return 0;
140  }
141  // If not - we form both RzType and RzBaseType to store in the Types database
142  ParserTypePair *type_pair = c_parser_new_primitive_type(state, real_type, is_const);
143  if (!type_pair) {
144  parser_error(state, "Error forming RzType and RzBaseType pair out of primitive type\n");
145  free(real_type);
146  return -1;
147  }
148  c_parser_base_type_store(state, real_type, type_pair);
149  *tpair = type_pair;
150  free(real_type);
151  return 0;
152 }

References c_parser_base_type_store(), c_parser_get_primitive_type(), c_parser_new_primitive_type(), free(), node_malformed_error(), parser_debug(), 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 parse_type_node_single().

◆ parse_sole_type_name()

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

Definition at line 155 of file types_parser.c.

155  {
156  rz_return_val_if_fail(state && text && tpair, -1);
159 
160  if (strcmp(ts_node_type(node), "type_identifier")) {
161  node_malformed_error(state, node, text, "just a type name");
162  return -1;
163  }
164  char *real_type = ts_node_sub_string(node, text);
165  // At first we search if the type is already presented in the state and is a primitive one
166  if ((*tpair = c_parser_get_primitive_type(state, real_type, is_const))) {
167  parser_debug(state, "Fetched type: \"%s\"\n", real_type);
168  free(real_type);
169  return 0;
170  }
171  // After that we search if the type is already presented in the state and is a type alias
172  if ((*tpair = c_parser_get_typedef(state, real_type))) {
173  parser_debug(state, "Fetched type: \"%s\"\n", real_type);
174  free(real_type);
175  return 0;
176  }
177  // Then we check if the type is already forward-defined
179  parser_debug(state, "Already has forward definition of type: \"%s\"\n", real_type);
180  *tpair = c_parser_new_unspecified_naked_type(state, real_type, is_const);
181  if (!*tpair) {
182  parser_error(state, "Error forming naked RzType pair out of simple forward-looking type: \"%s\"\n", real_type);
183  free(real_type);
184  return -1;
185  }
186  free(real_type);
187  return 0;
188  }
189  // Before resorting to create a new forward type, check if there is some union or struct with the same name already.
190  // This will e.g. catch cases like referring to `struct MyStruct` by just `MyStruct`.
191  if ((*tpair = c_parser_get_structure_type(state, real_type))) {
192  parser_debug(state, "Fetched type as struct: \"%s\"\n", real_type);
193  free(real_type);
194  return 0;
195  }
196  if ((*tpair = c_parser_get_union_type(state, real_type))) {
197  parser_debug(state, "Fetched type as union: \"%s\"\n", real_type);
198  free(real_type);
199  return 0;
200  }
201  // If not - we form both RzType and RzBaseType to store in the Types database
202  // as a forward-looking definition
203  *tpair = c_parser_new_primitive_type(state, real_type, is_const);
204  if (!*tpair) {
205  parser_error(state, "Error forming RzType and RzBaseType pair out of simple forward-looking type\n");
206  free(real_type);
207  return -1;
208  }
209  // Do allow forward-looking definitions we just add the type into the forward hashtable
210  if (c_parser_forward_definition_store(state, real_type)) {
211  parser_debug(state, "Added forward definition of type: \"%s\"\n", real_type);
212  rz_type_base_type_free((*tpair)->btype);
213  (*tpair)->btype = NULL;
214  free(real_type);
215  return 0;
216  }
217  rz_type_free((*tpair)->type);
218  rz_type_base_type_free((*tpair)->btype);
219  RZ_FREE(*tpair);
220  free(real_type);
221  return -1;
222 }
RZ_API void rz_type_base_type_free(RzBaseType *type)
Frees the RzBaseType instance and all of its members.
Definition: base.c:132
#define RZ_FREE(x)
Definition: rz_types.h:369
RZ_API void rz_type_free(RZ_NULLABLE RzType *type)
Frees the RzType.
Definition: type.c:1273
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.
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.
bool c_parser_forward_definition_store(CParserState *state, RZ_NONNULL const char *name)
Definition: types_storage.c:50
RZ_OWN ParserTypePair * c_parser_get_typedef(CParserState *state, RZ_NONNULL const char *name)
Returns the type if matching in the types hashtable.
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.

References c_parser_base_type_is_forward_definition(), c_parser_forward_definition_store(), c_parser_get_primitive_type(), c_parser_get_structure_type(), c_parser_get_typedef(), c_parser_get_union_type(), c_parser_new_primitive_type(), c_parser_new_unspecified_naked_type(), free(), node_malformed_error(), NULL, parser_debug(), parser_error(), RZ_FREE, rz_return_val_if_fail, rz_type_base_type_free(), rz_type_free(), create_tags_rz::text, ts_node_is_named(), ts_node_is_null(), ts_node_sub_string(), and ts_node_type().

Referenced by parse_type_node_single().

◆ parse_struct_node()

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

Definition at line 306 of file types_parser.c.

306  {
307  rz_return_val_if_fail(state && text && tpair, -1);
310 
311  parser_debug(state, "parse_struct_node()\n");
312 
313  int struct_node_child_count = ts_node_named_child_count(node);
314  if (struct_node_child_count < 1 || struct_node_child_count > 2) {
315  node_malformed_error(state, node, text, "struct");
316  return -1;
317  }
318  int result = 0;
319  // Name is optional, in abstract definitions or as the member of nested types
320  char *name = NULL;
321  TSNode struct_name = ts_node_child_by_field_name(node, "name", 4);
322  if (ts_node_is_null(struct_name)) {
323  parser_debug(state, "Anonymous struct\n");
325  } else {
326  name = ts_node_sub_string(struct_name, text);
327  if (!name) {
328  parser_error(state, "ERROR: Struct name should not be NULL!\n");
329  node_malformed_error(state, node, text, "struct");
330  return -1;
331  }
332  parser_debug(state, "struct name: %s\n", name);
333  }
334 
335  // Parsing the structure body
336  // If the structure doesn't have body but has a name
337  // it means that it uses the type predefined before
338  // e.g. "const struct tm* a;"
339  TSNode struct_body = ts_node_child_by_field_name(node, "body", 4);
340  if (ts_node_is_null(struct_body) && !ts_node_is_null(struct_name)) {
341  parser_debug(state, "Fetching predefined structure: \"%s\"\n", name);
342  if (!(*tpair = c_parser_get_structure_type(state, name))) {
343  parser_warning(state, "Cannot find \"%s\" structure in the context\n", name);
344  // At first we check if there is a forward definion already
346  parser_debug(state, "Structure \"%s\" was forward-defined before\n", name);
347  if (!(*tpair = c_parser_new_structure_naked_type(state, name))) {
348  parser_error(state, "Cannot create \"%s\" naked structure type in the context\n", name);
349  result = -1;
350  goto snexit;
351  }
352  goto snexit;
353  }
354  // We still could create the "forward looking struct declaration"
355  // The parser then can augment the definition
357  parser_error(state, "Cannot create \"%s\" forward structure definition in the context\n", name);
358  result = -1;
359  goto snexit;
360  }
361  goto snexit;
362  } else {
363  goto snexit;
364  }
365  }
366 
367  // If it's the type definition - we proceed further
368  int body_child_count = ts_node_named_child_count(struct_body);
369 
370  // Structures could lack BOTH name and body, e.g. as a member of another struct:
371  // struct a {
372  // struct {} b;
373  // }
374 
375  // Now we form both RzType and RzBaseType to store in the Types database
376  ParserTypePair *struct_pair = c_parser_new_structure_type(state, name, body_child_count);
377  if (!struct_pair) {
378  parser_error(state, "Error forming RzType and RzBaseType pair out of struct: \"%s\"\n", name);
379  result = -1;
380  goto snexit;
381  }
382 
383  char *real_type = NULL;
384  char *real_identifier = NULL;
385  int i;
386  for (i = 0; i < body_child_count; i++) {
387  parser_debug(state, "struct: processing %d field...\n", i);
388  TSNode child = ts_node_named_child(struct_body, i);
389  const char *node_type = ts_node_type(child);
390 
391  // Skip comments
392  if (!strcmp(node_type, "comment")) {
393  continue;
394  }
395 
396  // Parse the type qualifier first (if present)
397  // FIXME: There could be multiple different type qualifiers in one declaration
398  bool is_const = false;
399  TSNode first_leaf = ts_node_named_child(child, 0);
400  if (ts_node_is_null(first_leaf)) {
401  node_malformed_error(state, child, text, "field_declaration");
402  result = -1;
403  goto srnexit;
404  }
405  const char *leaf_type = ts_node_type(first_leaf);
406  // If we have type qualifier in this position it is related to
407  // the declarator itself, not the type, e.g. constant pointer,
408  // not pointer to the constant
409  if (!strcmp(leaf_type, "type_qualifier")) {
410  char *qualifier = ts_node_sub_string(first_leaf, text);
411  parser_debug(state, "has qualifier %s\n", qualifier);
412  if (!strcmp(qualifier, "const")) {
413  is_const = true;
414  }
415  free(qualifier);
416  }
417 
418  // Every field should have (field_declaration) AST clause
419  if (strcmp(node_type, "field_declaration")) {
420  parser_error(state, "ERROR: Struct field AST should contain (field_declaration) node!\n");
421  node_malformed_error(state, child, text, "struct field");
422  result = -1;
423  goto srnexit;
424  }
425 
426  // Every field node should have at least type and declarator:
427  TSNode field_type = ts_node_child_by_field_name(child, "type", 4);
428  TSNode field_declarator = ts_node_child_by_field_name(child, "declarator", 10);
430  parser_error(state, "ERROR: Struct field AST shoudl contain type and declarator items");
431  node_malformed_error(state, child, text, "struct field");
432  result = -1;
433  goto srnexit;
434  }
435 
436  // Every field can be:
437  // - atomic: "int a;" or "char b[20]"
438  // - bitfield: int a:7;"
439  // - nested: "struct { ... } a;" or "union { ... } a;"
440  if (state->verbose) {
441  char *fieldtext = ts_node_sub_string(child, text);
442  char *nodeast = ts_node_string(child);
443  if (fieldtext && nodeast) {
444  parser_debug(state, "field text: %s\n", fieldtext);
445  parser_debug(state, "field ast: %s\n", nodeast);
446  }
447  free(fieldtext);
448  free(nodeast);
449  }
450  // 1st case, bitfield
451  // AST looks like
452  // type: (primitive_type) declarator: (field_identifier) (bitfield_clause (number_literal))
453  // Thus it has the additional node after the declarator
455  if (!ts_node_is_null(bitfield_clause)) {
456  const char *bfnode_type = ts_node_type(field_type);
457  // As per C standard bitfields are defined only for atomic types, particularly "int"
458  if (strcmp(bfnode_type, "primitive_type") && strcmp(bfnode_type, "type_identifier")) {
459  parser_error(state, "ERROR: Struct bitfield cannot contain non-primitive bitfield!\n");
460  node_malformed_error(state, child, text, "struct field");
461  result = -1;
462  goto srnexit;
463  }
464  free(real_type);
465  real_type = ts_node_sub_string(field_type, text);
466  if (!real_type) {
467  parser_error(state, "ERROR: Struct bitfield type should not be NULL!\n");
468  node_malformed_error(state, child, text, "struct field");
469  result = -1;
470  goto srnexit;
471  }
472  free(real_identifier);
473  real_identifier = ts_node_sub_string(field_declarator, text);
474  if (!real_identifier) {
475  parser_error(state, "ERROR: Struct bitfield identifier should not be NULL!\n");
476  node_malformed_error(state, child, text, "struct field");
477  result = -1;
478  goto srnexit;
479  }
480  if (ts_node_named_child_count(bitfield_clause) != 1) {
481  node_malformed_error(state, child, text, "struct field");
482  result = -1;
483  goto srnexit;
484  }
485  TSNode field_bits = ts_node_named_child(bitfield_clause, 0);
486  if (ts_node_is_null(field_bits)) {
487  parser_error(state, "ERROR: Struct bitfield bits AST node should not be NULL!\n");
488  node_malformed_error(state, child, text, "struct field");
489  result = -1;
490  goto srnexit;
491  }
492  const char *bits_str = ts_node_sub_string(field_bits, text);
493  int bits = rz_num_get(NULL, bits_str);
494  parser_debug(state, "field type: %s field_identifier: %s bits: %d\n", real_type, real_identifier, bits);
495  ParserTypePair *membtpair = NULL;
496  if (parse_type_node_single(state, field_type, text, &membtpair, is_const)) {
497  parser_error(state, "ERROR: parsing bitfield struct member identifier\n");
498  node_malformed_error(state, child, text, "struct field");
499  result = -1;
500  goto srnexit;
501  }
502  // Then we augment resulting type field with the data from parsed declarator
503  char *membname = NULL;
504  if (parse_type_declarator_node(state, field_declarator, text, &membtpair, &membname)) {
505  parser_error(state, "ERROR: parsing bitfield struct member declarator\n");
506  node_malformed_error(state, child, text, "struct field");
507  result = -1;
508  goto srnexit;
509  }
510  // Add a struct member
511  RzVector *members = &struct_pair->btype->struct_data.members;
512  RzTypeStructMember memb = {
513  .name = membname,
514  .type = membtpair->type,
515  .offset = 0, // FIXME
516  .size = 0, // FIXME
517  };
518  void *element = rz_vector_push(members, &memb); // returns null if no space available
519  if (!element) {
520  parser_error(state, "Error appending bitfield struct member to the base type\n");
521  result = -1;
522  goto srnexit;
523  }
524  } else {
525  // 2nd case, normal structure
526  // AST looks like
527  // type: (primitive_type) declarator: (field_identifier)
528  free(real_type);
529  real_type = ts_node_sub_string(field_type, text);
530  if (!real_type) {
531  parser_error(state, "ERROR: Struct field type should not be NULL!\n");
532  node_malformed_error(state, child, text, "struct field");
533  result = -1;
534  goto srnexit;
535  }
536  free(real_identifier);
537  real_identifier = ts_node_sub_string(field_declarator, text);
538  if (!real_identifier) {
539  parser_error(state, "ERROR: Struct declarator should not be NULL!\n");
540  node_malformed_error(state, child, text, "struct field");
541  result = -1;
542  goto srnexit;
543  }
544  parser_debug(state, "field type: %s field_declarator: %s\n", real_type, real_identifier);
545  ParserTypePair *membtpair = NULL;
546  // At first, we parse the type field
547  if (parse_type_node_single(state, field_type, text, &membtpair, is_const)) {
548  parser_error(state, "ERROR: parsing struct member type\n");
549  node_malformed_error(state, child, text, "struct field");
550  result = -1;
551  goto srnexit;
552  }
553  // Then we augment resulting type field with the data from parsed declarator
554  char *membname = NULL;
555  if (parse_type_declarator_node(state, field_declarator, text, &membtpair, &membname)) {
556  parser_error(state, "ERROR: parsing struct member declarator\n");
557  node_malformed_error(state, child, text, "struct field");
558  result = -1;
559  goto srnexit;
560  }
561  // Add a struct member
562  RzVector *members = &struct_pair->btype->struct_data.members;
563  RzTypeStructMember memb = {
564  .name = membname,
565  .type = membtpair->type,
566  .offset = 0, // FIXME
567  .size = 0, // FIXME
568  };
569  void *element = rz_vector_push(members, &memb); // returns null if no space available
570  if (!element) {
571  parser_error(state, "Error appending struct member to the base type\n");
572  result = -1;
573  goto srnexit;
574  }
575  parser_debug(state, "Appended member \"%s\" into struct \"%s\"\n", membname, name);
576  }
577  }
578  // If parsing successfull completed - we store the state
579  if (struct_pair) {
580  c_parser_base_type_store(state, name, struct_pair);
581  // If it was a forward definition previously - remove it
584  }
585  }
586  *tpair = struct_pair;
587 
588 srnexit:
589  free(real_type);
590  free(real_identifier);
591 snexit:
592  free(name);
593  return result;
594 }
TSNode ts_node_next_named_sibling(TSNode)
Definition: node.c:624
int bits(struct state *s, int need)
Definition: blast.c:72
RzBaseTypeStruct struct_data
Definition: rz_type.h:118
@ field_type
Definition: parser.c:1970
@ field_declarator
Definition: parser.c:1954
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.
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.
RZ_OWN char * c_parser_new_anonymous_structure_name(CParserState *state)
RZ_OWN ParserTypePair * c_parser_new_structure_forward_definition(CParserState *state, RZ_NONNULL const char *name)
Creates new structure forward definition.

References bits(), ParserTypePair::btype, c_parser_base_type_is_forward_definition(), c_parser_base_type_store(), c_parser_forward_definition_remove(), c_parser_get_structure_type(), c_parser_new_anonymous_structure_name(), c_parser_new_structure_forward_definition(), c_parser_new_structure_naked_type(), c_parser_new_structure_type(), field_declarator, field_type, free(), i, rz_base_type_struct_t::members, rz_type_struct_member_t::name, node_malformed_error(), NULL, parse_type_declarator_node(), parse_type_node_single(), parser_debug(), parser_error(), parser_warning(), rz_num_get(), rz_return_val_if_fail, rz_vector_push(), rz_base_type_t::struct_data, 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_next_named_sibling(), ts_node_string(), ts_node_sub_string(), ts_node_type(), and ParserTypePair::type.

Referenced by parse_type_node_single(), and parse_type_nodes_save().

◆ 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_TYPE_KIND_ARRAY
Definition: rz_type.h:130
@ RZ_TYPE_KIND_POINTER
Definition: rz_type.h:129
#define RZ_NEW0(x)
Definition: rz_types.h:284
RzType * type
Definition: rz_type.h:163
int parse_parameter_list(CParserState *state, TSNode paramlist, 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 }
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_NULLABLE char * name
Definition: rz_type.h:147
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)
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().

◆ parse_typedef_node()

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

Definition at line 1078 of file types_parser.c.

1078  {
1079  rz_return_val_if_fail(state && text && tpair, -1);
1082 
1083  parser_debug(state, "parse_typedef_node()\n");
1084 
1085  int typedef_node_child_count = ts_node_named_child_count(node);
1086  if (typedef_node_child_count < 2) {
1087  node_malformed_error(state, node, text, "typedef");
1088  return -1;
1089  }
1090  // Parse the type qualifier first
1091  // FIXME: There could be multiple different type qualifiers in one declaration
1092  bool is_const = false;
1093 
1094  TSNode first_leaf = ts_node_named_child(node, 0);
1095  if (ts_node_is_null(first_leaf)) {
1096  node_malformed_error(state, node, text, "typedef");
1097  return -1;
1098  }
1099  const char *leaf_type = ts_node_type(first_leaf);
1100  if (!strcmp(leaf_type, "type_qualifier")) {
1101  char *qualifier = ts_node_sub_string(first_leaf, text);
1102  parser_debug(state, "has qualifier %s\n", qualifier);
1103  if (!strcmp(qualifier, "const")) {
1104  is_const = true;
1105  }
1106  free(qualifier);
1107  }
1108 
1109  TSNode typedef_type = ts_node_child_by_field_name(node, "type", 4);
1110  TSNode typedef_declarator = ts_node_child_by_field_name(node, "declarator", 10);
1111  if (ts_node_is_null(typedef_type) || ts_node_is_null(typedef_declarator)) {
1112  parser_error(state, "ERROR: Typedef type and declarator nodes should not be NULL!\n");
1113  node_malformed_error(state, node, text, "typedef");
1114  return -1;
1115  }
1116  // Every typedef type can be:
1117  // - atomic: "int", "uint64_t", etc
1118  // - some type name - any identificator
1119  // - complex type like struct, union, or enum
1120  if (state->verbose) {
1121  char *typetext = ts_node_sub_string(typedef_type, text);
1122  char *nodeast = ts_node_string(typedef_type);
1123  if (typetext && nodeast) {
1124  parser_debug(state, "type text: %s\n", typetext);
1125  parser_debug(state, "type ast: %s\n", nodeast);
1126  }
1127  free(typetext);
1128  free(nodeast);
1129  }
1130  ParserTypePair *type_pair = NULL;
1131  if (parse_type_node_single(state, typedef_type, text, &type_pair, is_const)) {
1132  parser_error(state, "ERROR: parsing typedef type identifier\n");
1133  node_malformed_error(state, typedef_type, text, "typedef type");
1134  return -1;
1135  }
1136  // Then we augment resulting type field with the data from parsed declarator
1137  char *typedef_name = NULL;
1138  if (parse_type_declarator_node(state, typedef_declarator, text, &type_pair, &typedef_name)) {
1139  parser_error(state, "ERROR: parsing typedef declarator\n");
1140  node_malformed_error(state, typedef_declarator, text, "typedef declarator");
1141  return -1;
1142  }
1143 
1144  // Now we form both RzType and RzBaseType to store in the Types database
1145  // Note, that if base type is NULL then it's forward definition and we should
1146  // use the RzType identifier instead;
1147  const char *base_type_name = rz_type_identifier(type_pair->type);
1148  parser_debug(state, "typedef \"%s\" -> \"%s\"\n", typedef_name, base_type_name);
1149  ParserTypePair *typedef_pair = c_parser_new_typedef(state, typedef_name, base_type_name);
1150  if (!typedef_pair) {
1151  parser_error(state, "Error forming RzType and RzBaseType pair out of typedef: \"%s\"\n", typedef_name);
1152  return -1;
1153  }
1154  // If parsing successfull completed - we store the state
1155  if (typedef_pair) {
1156  typedef_pair->btype->type = type_pair->type;
1157  parser_debug(state, "storing typedef \"%s\" -> \"%s\"\n", typedef_name, base_type_name);
1158  c_parser_base_type_store(state, typedef_name, typedef_pair);
1159  // If it was a forward definition previously - remove it
1160  if (c_parser_base_type_is_forward_definition(state, typedef_name)) {
1162  }
1163  }
1164 
1165  *tpair = typedef_pair;
1166  return 0;
1167 }
RzType * type
Definition: rz_type.h:113
RZ_API RZ_BORROW const char * rz_type_identifier(RZ_NONNULL const RzType *type)
Returns the type C identifier.
Definition: type.c:1155
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.

References ParserTypePair::btype, c_parser_base_type_is_forward_definition(), c_parser_base_type_store(), c_parser_forward_definition_remove(), c_parser_new_typedef(), free(), node_malformed_error(), NULL, parse_type_declarator_node(), parse_type_node_single(), parser_debug(), parser_error(), rz_return_val_if_fail, rz_type_identifier(), 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_string(), ts_node_sub_string(), ts_node_type(), rz_base_type_t::type, and ParserTypePair::type.

Referenced by parse_type_node_single(), and parse_type_nodes_save().

◆ parse_union_node()

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

Definition at line 598 of file types_parser.c.

598  {
599  rz_return_val_if_fail(state && text && tpair, -1);
602 
603  parser_debug(state, "parse_union_node()\n");
604 
605  int union_node_child_count = ts_node_named_child_count(node);
606  if (union_node_child_count < 1 || union_node_child_count > 2) {
607  node_malformed_error(state, node, text, "union");
608  return -1;
609  }
610  int result = 0;
611  // Name is optional, in abstract definitions or as the member of nested types
612  char *name = NULL;
613  TSNode union_name = ts_node_child_by_field_name(node, "name", 4);
614  if (ts_node_is_null(union_name)) {
615  parser_debug(state, "Anonymous union\n");
617  } else {
618  name = ts_node_sub_string(union_name, text);
619  if (!name) {
620  parser_error(state, "ERROR: Union name should not be NULL!\n");
621  node_malformed_error(state, node, text, "union");
622  return -1;
623  }
624  parser_debug(state, "union name: %s\n", name);
625  }
626 
627  // Parsing the union body
628  // If the union doesn't have body but has a name
629  // it means that it uses the type predefined before
630  // e.g. "const union tm* a;"
631  TSNode union_body = ts_node_child_by_field_name(node, "body", 4);
632  if (ts_node_is_null(union_body) && !ts_node_is_null(union_name)) {
633  parser_debug(state, "Fetching predefined union: \"%s\"\n", name);
634  if (!(*tpair = c_parser_get_union_type(state, name))) {
635  parser_warning(state, "Cannot find \"%s\" union in the context\n", name);
636  // At first we check if there is a forward definion already
638  parser_debug(state, "Union \"%s\" was forward-defined before\n", name);
639  if (!(*tpair = c_parser_new_union_naked_type(state, name))) {
640  parser_error(state, "Cannot create \"%s\" naked union type in the context\n", name);
641  result = -1;
642  goto unexit;
643  }
644  goto unexit;
645  }
646  // We still could create the "forward looking union declaration"
647  // The parser then can augment the definition
649  parser_error(state, "Cannot create \"%s\" forward union definition in the context\n", name);
650  result = -1;
651  goto unexit;
652  }
653  goto unexit;
654  } else {
655  goto unexit;
656  }
657  }
658 
659  // If it's the type definition - we proceed further
660  int body_child_count = ts_node_named_child_count(union_body);
661 
662  // Unions could lack BOTH name and body, e.g. as a member of another struct or union:
663  // struct a {
664  // union {} b;
665  // }
666 
667  // Now we form both RzType and RzBaseType to store in the Types database
668  ParserTypePair *union_pair = c_parser_new_union_type(state, name, body_child_count);
669  if (!union_pair) {
670  parser_error(state, "Error forming RzType and RzBaseType pair out of union\n");
671  return -1;
672  }
673 
674  char *real_type = NULL;
675  char *real_identifier = NULL;
676  int i;
677  for (i = 0; i < body_child_count; i++) {
678  parser_debug(state, "union: processing %d field...\n", i);
679  TSNode child = ts_node_named_child(union_body, i);
680  const char *node_type = ts_node_type(child);
681 
682  // Skip comments
683  if (!strcmp(node_type, "comment")) {
684  continue;
685  }
686 
687  // Parse the type qualifier first (if present)
688  // FIXME: There could be multiple different type qualifiers in one declaration
689  bool is_const = false;
690  TSNode first_leaf = ts_node_named_child(child, 0);
691  if (ts_node_is_null(first_leaf)) {
692  node_malformed_error(state, child, text, "field_declaration");
693  result = -1;
694  goto urnexit;
695  }
696  const char *leaf_type = ts_node_type(first_leaf);
697  // If we have type qualifier in this position it is related to
698  // the declarator itself, not the type, e.g. constant pointer,
699  // not pointer to the constant
700  if (!strcmp(leaf_type, "type_qualifier")) {
701  char *qualifier = ts_node_sub_string(first_leaf, text);
702  parser_debug(state, "has qualifier %s\n", qualifier);
703  if (!strcmp(qualifier, "const")) {
704  is_const = true;
705  }
706  free(qualifier);
707  }
708 
709  // Every field should have (field_declaration) AST clause
710  if (strcmp(node_type, "field_declaration")) {
711  parser_error(state, "ERROR: Union field AST should contain (field_declaration) node!\n");
712  node_malformed_error(state, child, text, "union field");
713  result = -1;
714  goto urnexit;
715  }
716 
717  // Every field node should have at least type and declarator:
718  TSNode field_type = ts_node_child_by_field_name(child, "type", 4);
719  TSNode field_declarator = ts_node_child_by_field_name(child, "declarator", 10);
721  parser_error(state, "ERROR: Union field AST shoudl contain type and declarator items");
722  node_malformed_error(state, child, text, "union field");
723  result = -1;
724  goto urnexit;
725  }
726  // Every field can be:
727  // - atomic: "int a;" or "char b[20]"
728  // - bitfield: int a:7;"
729  // - nested: "struct { ... } a;" or "union { ... } a;"
730  if (state->verbose) {
731  char *fieldtext = ts_node_sub_string(child, text);
732  char *nodeast = ts_node_string(child);
733  if (fieldtext && nodeast) {
734  parser_debug(state, "field text: %s\n", fieldtext);
735  parser_debug(state, "field ast: %s\n", nodeast);
736  }
737  free(fieldtext);
738  free(nodeast);
739  }
740  // 1st case, bitfield
741  // AST looks like
742  // type: (primitive_type) declarator: (field_identifier) (bitfield_clause (number_literal))
743  // Thus it has the additional node after the declarator
745  if (!ts_node_is_null(bitfield_clause)) {
746  const char *bfnode_type = ts_node_type(field_type);
747  // As per C standard bitfields are defined only for atomic types, particularly "int"
748  if (strcmp(bfnode_type, "primitive_type") && strcmp(bfnode_type, "type_identifier")) {
749  parser_error(state, "ERROR: Union bitfield cannot contain non-primitive bitfield!\n");
750  node_malformed_error(state, child, text, "union field");
751  result = -1;
752  goto urnexit;
753  }
754  free(real_type);
755  real_type = ts_node_sub_string(field_type, text);
756  if (!real_type) {
757  parser_error(state, "ERROR: Union bitfield type should not be NULL!\n");
758  node_malformed_error(state, child, text, "union field");
759  result = -1;
760  goto urnexit;
761  }
762  free(real_identifier);
763  real_identifier = ts_node_sub_string(field_declarator, text);
764  if (!real_identifier) {
765  parser_error(state, "ERROR: Union bitfield identifier should not be NULL!\n");
766  node_malformed_error(state, child, text, "union field");
767  result = -1;
768  goto urnexit;
769  }
770  if (ts_node_named_child_count(bitfield_clause) != 1) {
771  node_malformed_error(state, child, text, "union field");
772  result = -1;
773  goto urnexit;
774  }
775  TSNode field_bits = ts_node_named_child(bitfield_clause, 0);
776  if (ts_node_is_null(field_bits)) {
777  parser_error(state, "ERROR: Union bitfield bits AST node should not be NULL!\n");
778  node_malformed_error(state, child, text, "union field");
779  result = -1;
780  goto urnexit;
781  }
782  const char *bits_str = ts_node_sub_string(field_bits, text);
783  int bits = rz_num_get(NULL, bits_str);
784  parser_debug(state, "field type: %s field_identifier: %s bits: %d\n", real_type, real_identifier, bits);
785  ParserTypePair *membtpair = NULL;
786  if (parse_type_node_single(state, field_type, text, &membtpair, is_const)) {
787  parser_error(state, "ERROR: parsing union member identifier\n");
788  node_malformed_error(state, child, text, "union field");
789  result = -1;
790  goto urnexit;
791  }
792  // Then we augment resulting type field with the data from parsed declarator
793  char *membname = NULL;
794  if (parse_type_declarator_node(state, field_declarator, text, &membtpair, &membname)) {
795  parser_error(state, "ERROR: parsing union member declarator\n");
796  node_malformed_error(state, child, text, "union field");
797  result = -1;
798  goto urnexit;
799  }
800  // Add a union member
801  RzVector *members = &union_pair->btype->union_data.members;
802  RzTypeUnionMember memb = {
803  .name = membname,
804  .type = membtpair->type,
805  .offset = 0, // Always 0 for unions
806  .size = 0, // FIXME
807  };
808  void *element = rz_vector_push(members, &memb); // returns null if no space available
809  if (!element) {
810  parser_error(state, "Error appending union member to the base type\n");
811  result = -1;
812  goto urnexit;
813  }
814  } else {
815  // 2nd case, normal union
816  // AST looks like
817  // type: (primitive_type) declarator: (field_identifier)
818  free(real_type);
819  real_type = ts_node_sub_string(field_type, text);
820  if (!real_type) {
821  parser_error(state, "ERROR: Union field type should not be NULL!\n");
822  node_malformed_error(state, child, text, "union field");
823  result = -1;
824  goto urnexit;
825  }
826  free(real_identifier);
827  real_identifier = ts_node_sub_string(field_declarator, text);
828  if (!real_identifier) {
829  parser_error(state, "ERROR: Union declarator should not be NULL!\n");
830  node_malformed_error(state, child, text, "union field");
831  result = -1;
832  goto urnexit;
833  }
834  parser_debug(state, "field type: %s field_declarator: %s\n", real_type, real_identifier);
835  ParserTypePair *membtpair = NULL;
836  // At first, we parse the type field
837  if (parse_type_node_single(state, field_type, text, &membtpair, is_const)) {
838  parser_error(state, "ERROR: parsing union member type\n");
839  node_malformed_error(state, child, text, "union field");
840  result = -1;
841  goto urnexit;
842  }
843  // Then we augment resulting type field with the data from parsed declarator
844  char *membname = NULL;
845  if (parse_type_declarator_node(state, field_declarator, text, &membtpair, &membname)) {
846  parser_error(state, "ERROR: parsing union member declarator\n");
847  node_malformed_error(state, child, text, "union field");
848  result = -1;
849  goto urnexit;
850  }
851  // Add a union member
852  RzVector *members = &union_pair->btype->union_data.members;
853  RzTypeUnionMember memb = {
854  .name = membname,
855  .type = membtpair->type,
856  .offset = 0, // Always 0 for unions
857  .size = 0, // FIXME
858  };
859  void *element = rz_vector_push(members, &memb); // returns null if no space available
860  if (!element) {
861  parser_error(state, "Error appending union member to the base type\n");
862  result = -1;
863  goto urnexit;
864  }
865  }
866  }
867  // If parsing successfull completed - we store the state
868  if (union_pair) {
869  c_parser_base_type_store(state, name, union_pair);
870  // If it was a forward definition previously - remove it
873  }
874  }
875  *tpair = union_pair;
876 urnexit:
877  free(real_type);
878  free(real_identifier);
879 unexit:
880  free(name);
881  return result;
882 }
RzBaseTypeUnion union_data
Definition: rz_type.h:120
RzVector members
Definition: rz_type.h:104
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.
RZ_OWN char * c_parser_new_anonymous_union_name(CParserState *state)
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.
RZ_OWN ParserTypePair * c_parser_new_union_forward_definition(CParserState *state, RZ_NONNULL const char *name)
Creates new union forward definition.

References bits(), ParserTypePair::btype, c_parser_base_type_is_forward_definition(), c_parser_base_type_store(), c_parser_forward_definition_remove(), c_parser_get_union_type(), c_parser_new_anonymous_union_name(), c_parser_new_union_forward_definition(), c_parser_new_union_naked_type(), c_parser_new_union_type(), field_declarator, field_type, free(), i, rz_base_type_union_t::members, rz_type_union_member_t::name, node_malformed_error(), NULL, parse_type_declarator_node(), parse_type_node_single(), parser_debug(), parser_error(), parser_warning(), rz_num_get(), rz_return_val_if_fail, rz_vector_push(), 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_next_named_sibling(), ts_node_string(), ts_node_sub_string(), ts_node_type(), ParserTypePair::type, and rz_base_type_t::union_data.

Referenced by parse_type_node_single(), and parse_type_nodes_save().

◆ parser_debug()

◆ 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().

◆ ts_node_sub_string()

static char* ts_node_sub_string ( TSNode  node,
const char *  cstr 
)
static

Definition at line 21 of file types_parser.c.

21  {
22  ut32 start, end;
23  TS_START_END(node, start, end);
24  return rz_str_newf("%.*s", end - start, cstr + start);
25 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void start
Definition: sflib.h:133
uint32_t ut32
#define TS_START_END(node, start, end)
Definition: types_parser.c:15

References test_evm::end, rz_str_newf(), start, and TS_START_END.

Referenced by node_malformed_error(), parse_declaration_node(), parse_enum_node(), parse_parameter_declaration_node(), parse_primitive_type(), parse_sized_primitive_type(), parse_sole_type_name(), parse_struct_node(), parse_type_abstract_declarator_node(), parse_type_declarator_node(), parse_type_descriptor_single(), parse_type_nodes_save(), parse_typedef_node(), and parse_union_node().