ir_entity *gcji_get_rtti_entity(ir_type *type) { if (is_Pointer_type(type)) { ir_type *points_to = get_pointer_points_to_type(type); if (is_Class_type(points_to)) return oo_get_class_rtti_entity(points_to); return NULL; } else if (is_Primitive_type(type)) { if (type == type_boolean) return gcj_boolean_rtti_entity; if (type == type_byte) return gcj_byte_rtti_entity; if (type == type_char) return gcj_char_rtti_entity; if (type == type_short) return gcj_short_rtti_entity; if (type == type_int) return gcj_int_rtti_entity; if (type == type_long) return gcj_long_rtti_entity; if (type == type_float) return gcj_float_rtti_entity; if (type == type_double) return gcj_double_rtti_entity; panic("unexpected type"); } else { return oo_get_class_rtti_entity(type); } }
/** * Check if a argument of the ir graph with mode * reference is read, write or both. * * @param irg The ir graph to analyze. */ static void analyze_ent_args(ir_entity *ent) { ir_type *mtp = get_entity_type(ent); size_t nparams = get_method_n_params(mtp); ent->attr.mtd_attr.param_access = NEW_ARR_F(ptr_access_kind, nparams); /* If the method haven't parameters we have * nothing to do. */ if (nparams <= 0) return; /* we have not yet analyzed the graph, set ALL access for pointer args */ for (size_t i = nparams; i-- > 0; ) { ir_type *type = get_method_param_type(mtp, i); ent->attr.mtd_attr.param_access[i] = is_Pointer_type(type) ? ptr_access_all : ptr_access_none; } ir_graph *irg = get_entity_irg(ent); if (irg == NULL) { /* no graph, no better info */ return; } assure_irg_outs(irg); ir_node *irg_args = get_irg_args(irg); /* A array to save the information for each argument with mode reference.*/ ptr_access_kind *rw_info; NEW_ARR_A(ptr_access_kind, rw_info, nparams); /* We initialize the element with none state. */ for (size_t i = nparams; i-- > 0; ) rw_info[i] = ptr_access_none; /* search for arguments with mode reference to analyze them.*/ for (int i = get_irn_n_outs(irg_args); i-- > 0; ) { ir_node *arg = get_irn_out(irg_args, i); ir_mode *arg_mode = get_irn_mode(arg); long proj_nr = get_Proj_proj(arg); if (mode_is_reference(arg_mode)) rw_info[proj_nr] |= analyze_arg(arg, rw_info[proj_nr]); } /* copy the temporary info */ memcpy(ent->attr.mtd_attr.param_access, rw_info, nparams * sizeof(ent->attr.mtd_attr.param_access[0])); }
static ir_node *gcji_get_runtime_classinfo_(ir_node *block, ir_node **mem, ir_type *type) { ir_entity *rtti_entity = gcji_get_rtti_entity(type); ir_graph *irg = get_irn_irg(block); if (rtti_entity != NULL) return new_r_Address(irg, rtti_entity); /* Arrays are represented as pointer types. We extract the base type, * get its classinfo and let gcj give the array type for that. * * gcj emits the type signature to the class' constant pool. During * class linking, the reference to the utf8const is replaced by the * reference to the appropriate class object. */ assert(is_Pointer_type(type)); unsigned n_pointer_levels = 0; ir_type *eltype = type; while (is_Pointer_type(eltype)) { ++n_pointer_levels; eltype = get_pointer_points_to_type(eltype); } if (!is_Primitive_type(eltype)) --n_pointer_levels; ir_entity *elem_cdf = gcji_get_rtti_entity(eltype); assert(elem_cdf != NULL); ir_node *array_class_ref = new_r_Address(irg, elem_cdf); for (unsigned d = 0; d < n_pointer_levels; d++) { array_class_ref = gcji_get_arrayclass(block, mem, array_class_ref); } return array_class_ref; }
static ir_entity *emit_type_signature(ir_type *type) { ir_type *curtype = type; unsigned n_pointer_levels = 0; while (is_Pointer_type(curtype)) { n_pointer_levels++; curtype = get_pointer_points_to_type(curtype); } struct obstack obst; obstack_init(&obst); if (n_pointer_levels > 0) { for (unsigned i = 0; i < n_pointer_levels-1; i++) obstack_1grow(&obst, '['); if (is_Primitive_type(curtype)) obstack_1grow(&obst, '['); } if (is_Primitive_type(curtype)) { char c = get_prim_type_char(curtype); obstack_1grow(&obst, c); } else { assert(is_Class_type(curtype)); obstack_1grow(&obst, 'L'); obstack_printf(&obst, "%s", get_compound_name(curtype)); obstack_1grow(&obst, ';'); obstack_1grow(&obst, '\0'); } const char *sig_bytes = obstack_finish(&obst); ir_entity *res = do_emit_utf8_const(sig_bytes, strlen(sig_bytes)); obstack_free(&obst, NULL); return res; }
static ir_type *get_Sel_or_SymConst_type(ir_node *sos) { assert (is_Sel(sos) || is_SymConst_addr_ent(sos)); ir_entity *entity = get_irn_entity_attr(sos); ir_type *type = get_entity_type(entity); if (is_Method_type(type)) { size_t n_ress = get_method_n_ress(type); if (n_ress == 0) return NULL; assert (n_ress == 1); type = get_method_res_type(type, 0); } if (is_Pointer_type(type)) type = get_pointer_points_to_type(type); if (is_Class_type(type)) return type; return NULL; }
void init_predefined_types(void) { static const type_base_t error = { TYPE_ERROR, TYPE_QUALIFIER_NONE, NULL }; type_error_type = (type_t*)&error; type_bool = make_atomic_type(ATOMIC_TYPE_BOOL, TYPE_QUALIFIER_NONE); type_signed_char = make_atomic_type(ATOMIC_TYPE_SCHAR, TYPE_QUALIFIER_NONE); type_unsigned_char = make_atomic_type(ATOMIC_TYPE_UCHAR, TYPE_QUALIFIER_NONE); type_short = make_atomic_type(ATOMIC_TYPE_SHORT, TYPE_QUALIFIER_NONE); type_unsigned_short = make_atomic_type(ATOMIC_TYPE_USHORT, TYPE_QUALIFIER_NONE); type_int = make_atomic_type(ATOMIC_TYPE_INT, TYPE_QUALIFIER_NONE); type_unsigned_int = make_atomic_type(ATOMIC_TYPE_UINT, TYPE_QUALIFIER_NONE); type_long = make_atomic_type(ATOMIC_TYPE_LONG, TYPE_QUALIFIER_NONE); type_unsigned_long = make_atomic_type(ATOMIC_TYPE_ULONG, TYPE_QUALIFIER_NONE); type_long_long = make_atomic_type(ATOMIC_TYPE_LONGLONG, TYPE_QUALIFIER_NONE); type_unsigned_long_long = make_atomic_type(ATOMIC_TYPE_ULONGLONG, TYPE_QUALIFIER_NONE); type_long_double = make_atomic_type(ATOMIC_TYPE_LONG_DOUBLE, TYPE_QUALIFIER_NONE); type_double = make_atomic_type(ATOMIC_TYPE_DOUBLE, TYPE_QUALIFIER_NONE); type_float = make_atomic_type(ATOMIC_TYPE_FLOAT, TYPE_QUALIFIER_NONE); type_char = make_atomic_type(ATOMIC_TYPE_CHAR, TYPE_QUALIFIER_NONE); type_void = make_void_type(TYPE_QUALIFIER_NONE); type_const_void = make_void_type(TYPE_QUALIFIER_CONST); type_builtin_template = allocate_type_zero(TYPE_BUILTIN_TEMPLATE); type_builtin_template = identify_new_type(type_builtin_template); int8_type_kind = find_signed_int_atomic_type_kind_for_size(1); int16_type_kind = find_signed_int_atomic_type_kind_for_size(2); int32_type_kind = find_signed_int_atomic_type_kind_for_size(4); int64_type_kind = find_signed_int_atomic_type_kind_for_size(8); type_int32_t = make_atomic_type(int32_type_kind, TYPE_QUALIFIER_NONE); type_int64_t = make_atomic_type(int64_type_kind, TYPE_QUALIFIER_NONE); /* pointer types */ type_void_ptr = make_pointer_type(type_void, TYPE_QUALIFIER_NONE); type_const_void_ptr = make_pointer_type(type_const_void, TYPE_QUALIFIER_NONE); type_void_ptr_restrict = make_pointer_type(type_void, TYPE_QUALIFIER_RESTRICT); type_const_void_ptr_restrict = make_pointer_type(type_const_void, TYPE_QUALIFIER_RESTRICT); type_char_ptr = make_pointer_type(type_char, TYPE_QUALIFIER_NONE); type_char_ptr_restrict = make_pointer_type(type_char, TYPE_QUALIFIER_RESTRICT); type_signed_char_ptr = make_pointer_type(type_signed_char, TYPE_QUALIFIER_NONE); type_short_ptr = make_pointer_type(type_short, TYPE_QUALIFIER_NONE); type_int_ptr = make_pointer_type(type_int, TYPE_QUALIFIER_NONE); type_long_ptr = make_pointer_type(type_long, TYPE_QUALIFIER_NONE); type_unsigned_char_ptr = make_pointer_type(type_unsigned_char, TYPE_QUALIFIER_NONE); type_unsigned_short_ptr = make_pointer_type(type_unsigned_short, TYPE_QUALIFIER_NONE); type_unsigned_int_ptr = make_pointer_type(type_unsigned_int, TYPE_QUALIFIER_NONE); type_unsigned_long_ptr = make_pointer_type(type_unsigned_long, TYPE_QUALIFIER_NONE); type_unsigned_long_long_ptr = make_pointer_type(type_unsigned_long, TYPE_QUALIFIER_NONE); type_long_long_ptr = make_pointer_type(type_long_long, TYPE_QUALIFIER_NONE); type_long_double_ptr = make_pointer_type(type_long_double, TYPE_QUALIFIER_NONE); type_double_ptr = make_pointer_type(type_double, TYPE_QUALIFIER_NONE); type_float_ptr = make_pointer_type(type_float, TYPE_QUALIFIER_NONE); type_char_ptr_ptr = make_pointer_type(type_char_ptr, TYPE_QUALIFIER_NONE); type_builtin_template_ptr = make_pointer_type(type_builtin_template, TYPE_QUALIFIER_NONE); backend_params const *const be_params = be_get_backend_param(); ir_type *be_va_list_type = be_params->vararg.va_list_type; if (!be_va_list_type) { /* Backend has no vararg support. Just hope the the program will not be * using any. If it does, the parse_va_* functions will complain. */ type_valist = type_error_type; type_valist_arg = type_error_type; } else if (is_Pointer_type(be_va_list_type)) { type_valist = type_void_ptr; type_valist_arg = type_void_ptr; } else if (is_Struct_type(be_va_list_type)) { entity_t *ent = allocate_entity_zero(ENTITY_STRUCT, NAMESPACE_NORMAL, sym_anonymous, &builtin_position); ent->compound.alignment = get_type_alignment_bytes(be_va_list_type); ent->compound.size = get_type_size_bytes(be_va_list_type); ent->compound.complete = true; ent->compound.members = (scope_t){ .first_entity = NULL, .last_entity = NULL, .depth = 0 }; type_t *type_valist_struct = allocate_type_zero(TYPE_COMPOUND_STRUCT); type_valist_struct->base.firm_type = be_va_list_type; type_valist_struct->compound.compound = &ent->compound; type_valist = make_array_type(type_valist_struct, 1, TYPE_QUALIFIER_NONE); type_valist_arg = automatic_type_conversion(type_valist); } /* const character types */ type_const_char = make_atomic_type(ATOMIC_TYPE_CHAR, TYPE_QUALIFIER_CONST); type_const_char_ptr = make_pointer_type(type_const_char, TYPE_QUALIFIER_NONE); type_const_char_ptr_restrict = make_pointer_type(type_const_char, TYPE_QUALIFIER_RESTRICT); atomic_type_kind_t pointer_sized_int = dialect.pointer_sized_int; atomic_type_kind_t pointer_sized_uint = dialect.pointer_sized_uint; type_size_t = make_atomic_type(pointer_sized_uint, TYPE_QUALIFIER_NONE); type_ssize_t = make_atomic_type(pointer_sized_int, TYPE_QUALIFIER_NONE); type_uptrdiff_t = type_size_t; type_ptrdiff_t = type_ssize_t; type_intmax_t = type_long_long; type_uintmax_t = type_unsigned_long_long; type_wint_t = type_unsigned_int; type_intmax_t_ptr = make_pointer_type(type_intmax_t, TYPE_QUALIFIER_NONE); type_uintmax_t_ptr = make_pointer_type(type_uintmax_t, TYPE_QUALIFIER_NONE); type_ptrdiff_t_ptr = make_pointer_type(type_ptrdiff_t, TYPE_QUALIFIER_NONE); type_uptrdiff_t_ptr = make_pointer_type(type_uptrdiff_t, TYPE_QUALIFIER_NONE); type_ssize_t_ptr = make_pointer_type(type_ssize_t, TYPE_QUALIFIER_NONE); type_size_t_ptr = make_pointer_type(type_size_t, TYPE_QUALIFIER_NONE); atomic_type_kind_t akind = dialect.cpp ? ATOMIC_TYPE_WCHAR_T : dialect.wchar_atomic_kind; type_wchar_t = make_atomic_type(akind, TYPE_QUALIFIER_NONE); type_const_wchar_t = make_atomic_type(akind, TYPE_QUALIFIER_CONST); type_wchar_t_ptr = make_pointer_type(type_wchar_t, TYPE_QUALIFIER_NONE); type_const_wchar_t_ptr = make_pointer_type(type_const_wchar_t, TYPE_QUALIFIER_NONE); atomic_type_kind_t const u2 = find_unsigned_int_atomic_type_kind_for_size(2); type_char16_t = make_atomic_type(u2, TYPE_QUALIFIER_NONE); type_char16_t_const = make_atomic_type(u2, TYPE_QUALIFIER_CONST); type_char16_t_ptr = make_pointer_type(type_char16_t, TYPE_QUALIFIER_NONE); type_char16_t_const_ptr = make_pointer_type(type_char16_t_const, TYPE_QUALIFIER_NONE); atomic_type_kind_t const u4 = find_unsigned_int_atomic_type_kind_for_size(4); type_char32_t = make_atomic_type(u4, TYPE_QUALIFIER_NONE); type_char32_t_const = make_atomic_type(u4, TYPE_QUALIFIER_CONST); type_char32_t_ptr = make_pointer_type(type_char32_t, TYPE_QUALIFIER_NONE); type_char32_t_const_ptr = make_pointer_type(type_char32_t_const, TYPE_QUALIFIER_NONE); if (dialect.ms) init_ms_types(); }