/* * Functions to generate anonymous Ada types */ #include #include "ansi.h" #include "host.h" #include "files.h" #include "hash.h" #include "il.h" #include "nodeop.h" #include "allocate.h" #include "types.h" #include "stab.h" #include "ada_name.h" #include "anonymous.h" #include "config.h" #include "type_util.h" extern int auto_package; extern file_pos_t yypos; #undef TYPE_HASH_MAX #define TYPE_HASH_MAX 256 /* Anonymous type hash table size */ #undef NULL #define NULL 0 static typeinfo_t *anonymous_types[TYPE_HASH_MAX]; static int anonymous_ord[MAX_UNIQ_FNAMES]; symbol_t *anonymous_function_pointer; /* * Use ordinal for anonymous type names */ int next_anonymous_ord() { int file_ord; if (auto_package) { file_ord = FILE_ORD(yypos); assert(file_ord < num_files()); return anonymous_ord[file_ord]++; } return anonymous_ord[0]++; } /* * don't generate names ending in _t_t */ static int ends_in(str,postfix) char *str, *postfix; { for (; *str; str++) { if (*str == *postfix && strcmp(str+1,postfix+1) == 0) { return 1; } } return 0; } /* * look for type to Anonymous type hash table */ static typeinfo_t* find_anonymous_type(typ) typeinfo_t *typ; { typeinfo_t *t; assert(typ != NULL); assert(typ->type_hash != 0); t = anonymous_types[typ->type_hash & (TYPE_HASH_MAX-1)]; for (; t; t = t->type_anonymous_list) { if (equal_types(t, typ)) { return t; } } return NULL; } /* * add type to Anonymous type hash table */ static void store_anonymous_type(typ) typeinfo_t *typ; { int index; index = typ->type_hash & (TYPE_HASH_MAX-1); assert(typ->type_anonymous_list == NULL); typ->type_anonymous_list = anonymous_types[index]; anonymous_types[index] = typ; } static symbol_t* add_anonymous_builtin(typ, c_name, ada_name) typeinfo_t *typ; char *c_name, *ada_name; { symbol_t *basetype; typ->_anonymous = 1; basetype = new_sym(); basetype->intrinsic = 1; typ->type_base = basetype; store_anonymous_type(typ); basetype->sym_kind = type_symbol; basetype->sym_type = typ; basetype->sym_ident = new_node(_Ident, c_name); basetype->sym_ada_name = ada_name; basetype->gened = 1; return basetype; } static typeinfo_t* create_type(typ, n, mod1, mod2, mod3) typeinfo_t *typ; int n; int mod1, mod2, mod3; { switch (n) { case 3: typ = concat_types(typ, typeof_typemod(mod3)); case 2: typ = concat_types(typ, typeof_typemod(mod2)); case 1: typ = concat_types(typ, typeof_typemod(mod1)); } return typeof_typespec(typ); } static typeinfo_t* typeof_long_long(want_unsigned) int want_unsigned; { typeinfo_t *typ; typ = (want_unsigned) ? typeof_typemod(TYPEMOD_UNSIGNED) : NULL; return create_type(typ, 2, TYPEMOD_LONG, TYPEMOD_LONG, 0); } static typeinfo_t* typeof_long(want_unsigned) int want_unsigned; { typeinfo_t *typ; typ = (want_unsigned) ? typeof_typemod(TYPEMOD_UNSIGNED) : NULL; return create_type(typ, 1, TYPEMOD_LONG, 0, 0); } static typeinfo_t* typeof_short(want_unsigned) int want_unsigned; { typeinfo_t *typ; typ = (want_unsigned) ? typeof_typemod(TYPEMOD_UNSIGNED) : NULL; return create_type(typ, 1, TYPEMOD_SHORT, 0, 0); } /* * Define some builtin/intrinsic anonymous types */ void init_anonymous_types() { static int initialized = 0; if (initialized) return; initialized = 1; /* Builin: signed char* */ add_anonymous_builtin(add_pointer_type(set_signed_type(typeof_char())), "%% builin *signed char %%", TYPE_NAMEOF_CHAR_POINTER); /* Builin: unsigned char* */ add_anonymous_builtin(add_pointer_type(set_unsigned_type(typeof_char())), "%% builin *unsigned char %%", TYPE_NAMEOF_UCHAR_POINTER); /* Builin: void* */ add_anonymous_builtin(add_pointer_type(typeof_void()), "%% builin *void %%", TYPE_NAMEOF_VOID_POINTER); /* Builin: int (*)() */ anonymous_function_pointer = add_anonymous_builtin(add_function_type(typeof_int(0)), "%% int (*)() %%", TYPE_NAMEOF_FUNCTION_POINTER); #ifdef SIZEOF_LONG_LONG add_anonymous_builtin(add_pointer_type(typeof_long_long(0)), "%% long long int * %%", TYPE_NAMEOF_SIGNED_LONG_LONG_POINTER); add_anonymous_builtin(add_pointer_type(typeof_long_long(1)), "%% unsigned long long int * %%", TYPE_NAMEOF_UNSIGNED_LONG_LONG_POINTER); #endif /* builtin: long int* */ add_anonymous_builtin(add_pointer_type(typeof_long(0)), "%% long int * %%", TYPE_NAMEOF_SIGNED_LONG_POINTER); /* builtin: unsigned long int* */ add_anonymous_builtin(add_pointer_type(typeof_long(1)), "%% long unsigned int * %%", TYPE_NAMEOF_UNSIGNED_LONG_POINTER); /* builtin: int* */ add_anonymous_builtin(add_pointer_type(typeof_int(0)), "%% int * %%", TYPE_NAMEOF_SIGNED_INT_POINTER); /* builtin: int* */ add_anonymous_builtin(add_pointer_type(typeof_int(1)), "%% unsigned int * %%", TYPE_NAMEOF_UNSIGNED_INT_POINTER); /* builtin: short* */ add_anonymous_builtin(add_pointer_type(typeof_short(0)), "%% short int * %%", TYPE_NAMEOF_SIGNED_SHORT_POINTER); /* builtin: unsigned short* */ add_anonymous_builtin(add_pointer_type(typeof_short(1)), "%% short unsigned int * %%", TYPE_NAMEOF_UNSIGNED_SHORT_POINTER); /* builtin: float* */ add_anonymous_builtin(add_pointer_type(typeof_float()), "%% int * %%", TYPE_NAMEOF_FLOAT_POINTER); /* builtin: double* */ add_anonymous_builtin(add_pointer_type(typeof_double()), "%% int * %%", TYPE_NAMEOF_DOUBLE_POINTER); /* builtin: string */ add_anonymous_builtin(add_array_type(set_signed_type(typeof_char()), 1), "%% builin char[] %%", TYPE_NAMEOF_STRING); /* builtin: ustring */ add_anonymous_builtin(add_array_type(set_unsigned_type(typeof_char()), 1), "%% builin char[] %%", TYPE_NAMEOF_USTRING); } /* * Given "vector_of_c.signed_int" produce "vector_of_c_signed_int" */ rm_selectors(s) char *s; { for (; *s; s++) { if (*s == '.') *s = '_'; } } static int is_matrix(typ) typeinfo_t *typ; { int count; if (! is_array(typ)) return 0; count = 1; for (typ = typ->type_next; is_array(typ); typ = typ->type_next) { count++; } /* if even number of indices then assume matrix */ return (count & 1) == 0; } static void force_ada_name(sym) symbol_t *sym; { if (sym->sym_ada_name == NULL) { assert(sym->sym_ident != NULL); assert(sym->sym_ident->node_kind == _Ident); assert(sym->sym_ident->node.id.name != NULL); sym->sym_ada_name = ada_name(sym->sym_ident->node.id.name, FILE_ORD(sym->sym_def)); } } /* * Here we go. We may need to generate an anonymous type * for the input type. An example is when "struct foo *a;" is * encountered we'll need to gen "type a_sruct_foo_t is ...". */ symbol_t* get_anonymous_type(typ) typeinfo_t *typ; { typeinfo_t *anonymous_type; symbol_t *basetype; ident_case_t icase; char buf[1024]; assert(typ != NULL); if (typ->type_next != NULL && typ->type_next->type_base == NULL) { if (is_function_pointer(typ)) { typ->type_base = anonymous_function_pointer; return typ->type_base; } } assert(typ->type_next == NULL || typ->type_next->type_base != NULL); assert(typ->type_hash != 0); assert(typ->type_anonymous_list == NULL); anonymous_type = find_anonymous_type(typ); if (anonymous_type != NULL) { basetype = anonymous_type->type_base; assert(basetype != NULL); typ->type_base = basetype; return basetype; } if (is_access(typ)) { typeinfo_t *ptype; ptype = typ->type_next; assert(ptype != NULL); basetype = ptype->type_base; assert(basetype != NULL); assert(basetype->gened); force_ada_name(basetype); strcpy(buf, ACCESS_TYPE_PREFIX); if (ptype->_unsigned != basetype->sym_type->_unsigned) { if (ptype->_unsigned) { strcat(buf, "unsigned_"); } else { strcat(buf, "signed_"); } } strcat(buf, basetype->sym_ada_name); icase = id_case(basetype->sym_ada_name); } else if (is_array(typ)) { typeinfo_t *elem_typ; char *prefix = VECTOR_TYPE_PREFIX; elem_typ = typ->type_next; assert(elem_typ != NULL); if (is_array(elem_typ) && !is_matrix(elem_typ)) { /* matrix */ prefix = MATRIX_TYPE_PREFIX; elem_typ = elem_typ->type_next; assert(elem_typ != NULL); } basetype = elem_typ->type_base; assert(basetype != NULL); assert(basetype->gened); force_ada_name(basetype); sprintf(buf, "%s%s", prefix, basetype->sym_ada_name); icase = id_case(basetype->sym_ada_name); } else { sprintf(buf, "%s%d", OTHER_TYPE_PREFIX, next_anonymous_ord()); icase = Lower; } rm_selectors(buf); if (! ends_in(basetype->sym_ada_name, TYPE_POSTFIX)) { strcat(buf, TYPE_POSTFIX); } id_format(buf, icase); basetype = new_sym(); typ->type_base = basetype; typ = copy_type(typ); typ->_anonymous = 1; store_anonymous_type(typ); basetype->sym_kind = type_symbol; basetype->sym_type = typ; basetype->sym_def = yypos; basetype->sym_ident = new_node(_Ident, new_string(buf)); basetype->sym_ada_name = ada_name(basetype->sym_ident->node.id.name, FILE_ORD(yypos)); return basetype; }