type default_conversion(expression e) { type from = e->type; if (type_enum(from)) from = type_tag(from)->reptype; if (type_smallerthanint(from)) { /* Traditionally, unsignedness is preserved in default promotions. */ if (flag_traditional && type_unsigned(from)) return unsigned_int_type; else return int_type; } if (flag_traditional && !flag_allow_single_precision && type_float(from)) return double_type; if (type_void(from)) { error("void value not ignored as it ought to be"); return error_type; } if (type_function(from)) { assert(!e->cst); e->cst = e->static_address; return make_pointer_type(from); } if (type_array(from)) { if (!e->lvalue) { error("invalid use of non-lvalue array"); return error_type; } assert(!e->cst); e->cst = e->static_address; /* It's being used as a pointer, so is not an lvalue */ e->lvalue = FALSE; return make_pointer_type(type_array_of(from)); } return from; }
void init_types(unsigned int_size, unsigned long_size, unsigned pointer_size, atomic_type_kind_t wchar_atomic_kind, atomic_type_kind_t pointer_sized_int, atomic_type_kind_t pointer_sized_uint) { obstack_init(&type_obst); atomic_type_properties_t *props = atomic_type_properties; props[ATOMIC_TYPE_INT].size = int_size; props[ATOMIC_TYPE_INT].alignment = int_size; props[ATOMIC_TYPE_UINT].size = int_size; props[ATOMIC_TYPE_UINT].alignment = int_size; props[ATOMIC_TYPE_LONG].size = long_size; props[ATOMIC_TYPE_LONG].alignment = long_size; props[ATOMIC_TYPE_ULONG].size = long_size; props[ATOMIC_TYPE_ULONG].alignment = long_size; pointer_properties.size = pointer_size; pointer_properties.alignment = pointer_size; props[ATOMIC_TYPE_LONG_DOUBLE] = props[ATOMIC_TYPE_DOUBLE]; /* set struct alignments to the same value as alignment */ for (size_t i = 0; i != ARRAY_SIZE(atomic_type_properties); ++i) { props[i].struct_alignment = props[i].alignment; } pointer_properties.struct_alignment = pointer_size; 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; atomic_type_kind_t akind = dialect.cpp ? ATOMIC_TYPE_WCHAR_T : 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); props[ATOMIC_TYPE_WCHAR_T] = props[wchar_atomic_kind]; }
static void init_ms_types(void) { type_int8 = make_atomic_type(int8_type_kind, TYPE_QUALIFIER_NONE); type_int16 = make_atomic_type(int16_type_kind, TYPE_QUALIFIER_NONE); type_int32 = make_atomic_type(int32_type_kind, TYPE_QUALIFIER_NONE); type_int64 = make_atomic_type(int64_type_kind, TYPE_QUALIFIER_NONE); unsigned_int8_type_kind = find_unsigned_int_atomic_type_kind_for_size(1); type_unsigned_int8 = make_atomic_type(unsigned_int8_type_kind, TYPE_QUALIFIER_NONE); unsigned_int16_type_kind = find_unsigned_int_atomic_type_kind_for_size(2); type_unsigned_int16 = make_atomic_type(unsigned_int16_type_kind, TYPE_QUALIFIER_NONE); unsigned_int32_type_kind = find_unsigned_int_atomic_type_kind_for_size(4); type_unsigned_int32 = make_atomic_type(unsigned_int32_type_kind, TYPE_QUALIFIER_NONE); unsigned_int64_type_kind = find_unsigned_int_atomic_type_kind_for_size(8); type_unsigned_int64 = make_atomic_type(unsigned_int64_type_kind, TYPE_QUALIFIER_NONE); /* pointer types */ type_int32_ptr = make_pointer_type(type_int32, TYPE_QUALIFIER_NONE); type_int64_ptr = make_pointer_type(type_int64, TYPE_QUALIFIER_NONE); type_unsigned_int32_ptr = make_pointer_type(type_unsigned_int32, TYPE_QUALIFIER_NONE); type_unsigned_int64_ptr = make_pointer_type(type_unsigned_int64, TYPE_QUALIFIER_NONE); }
/* Declare a new temporary that can be assigned a value of type t. Place the declaration at the start of block. XXX: See discussion in types.c:tag2ast about the (lack of) correctness of this approach. Return it's declaration */ data_decl build_declaration(region r, struct environment *e, type t, const char *name, expression init, data_declaration *oddecl) { struct data_declaration tempdecl; identifier_declarator id; variable_decl vd; data_decl dd; declarator tdeclarator; type_element tmodifiers; /* Compute real type, name */ if (type_array(t)) t = make_pointer_type(type_array_of(t)); else if (type_function(t)) t = make_pointer_type(t); /* Qualifiers must not be present on the temp (the qualifiers of t apply to the original location we are building a temp) */ t = make_qualified_type(t, no_qualifiers); /* Build AST for the declaration */ id = new_identifier_declarator(r, dummy_location, str2cstring(r, name)); type2ast(r, dummy_location, t, CAST(declarator, id), &tdeclarator, &tmodifiers); vd = new_variable_decl(r, dummy_location, tdeclarator, NULL, init, NULL, NULL); vd->declared_type = t; dd = new_data_decl(r, dummy_location, tmodifiers, CAST(declaration, vd)); if (e) /* Declare the variable */ { init_data_declaration(&tempdecl, CAST(declaration, vd), id->cstring.data, t); tempdecl.kind = decl_variable; tempdecl.vtype = variable_normal; tempdecl.islocal = TRUE; *oddecl = vd->ddecl = declare(e, &tempdecl, FALSE); } return dd; }
expression make_address_of(location loc, expression e) { expression result = CAST(expression, new_address_of(parse_region, loc, e)); result->type = error_type; if (e->type == error_type) ; else if (e->bitfield) error("attempt to take address of a bit-field structure member"); else { if (e->isregister) pedwarn("address of a register variable requested"); if (!(type_function(e->type) || e->lvalue)) error("invalid lvalue in unary `&'"); result->type = make_pointer_type(e->type); result->cst = e->static_address; } return result; }
static int ada_val_print_1 (struct type *type, char *valaddr0, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int format, int deref_ref, int recurse, enum val_prettyprint pretty) { unsigned int len; int i; struct type *elttype; unsigned int eltlen; LONGEST val; char *valaddr = valaddr0 + embedded_offset; CHECK_TYPEDEF (type); if (ada_is_array_descriptor_type (type) || ada_is_packed_array_type (type)) { int retn; struct value *mark = value_mark (); struct value *val; val = value_from_contents_and_address (type, valaddr, address); val = ada_coerce_to_simple_array_ptr (val); if (val == NULL) { fprintf_filtered (stream, "(null)"); retn = 0; } else retn = ada_val_print_1 (VALUE_TYPE (val), VALUE_CONTENTS (val), 0, VALUE_ADDRESS (val), stream, format, deref_ref, recurse, pretty); value_free_to_mark (mark); return retn; } valaddr = ada_aligned_value_addr (type, valaddr); embedded_offset -= valaddr - valaddr0 - embedded_offset; type = printable_val_type (type, valaddr); switch (TYPE_CODE (type)) { default: return c_val_print (type, valaddr0, embedded_offset, address, stream, format, deref_ref, recurse, pretty); case TYPE_CODE_PTR: { int ret = c_val_print (type, valaddr0, embedded_offset, address, stream, format, deref_ref, recurse, pretty); if (ada_is_tag_type (type)) { struct value *val = value_from_contents_and_address (type, valaddr, address); const char *name = ada_tag_name (val); if (name != NULL) fprintf_filtered (stream, " (%s)", name); return 0; } return ret; } case TYPE_CODE_INT: case TYPE_CODE_RANGE: if (ada_is_fixed_point_type (type)) { LONGEST v = unpack_long (type, valaddr); int len = TYPE_LENGTH (type); fprintf_filtered (stream, len < 4 ? "%.11g" : "%.17g", (double) ada_fixed_to_float (type, v)); return 0; } else if (ada_is_vax_floating_type (type)) { struct value *val = value_from_contents_and_address (type, valaddr, address); struct value *func = ada_vax_float_print_function (type); if (func != 0) { static struct type *parray_of_char = NULL; struct value *printable_val; if (parray_of_char == NULL) parray_of_char = make_pointer_type (create_array_type (NULL, builtin_type_char, create_range_type (NULL, builtin_type_int, 0, 32)), NULL); printable_val = value_ind (value_cast (parray_of_char, call_function_by_hand (func, 1, &val))); fprintf_filtered (stream, "%s", VALUE_CONTENTS (printable_val)); return 0; } /* No special printing function. Do as best we can. */ } else if (TYPE_CODE (type) == TYPE_CODE_RANGE) { struct type *target_type = TYPE_TARGET_TYPE (type); if (TYPE_LENGTH (type) != TYPE_LENGTH (target_type)) { /* Obscure case of range type that has different length from its base type. Perform a conversion, or we will get a nonsense value. Actually, we could use the same code regardless of lengths; I'm just avoiding a cast. */ struct value *v = value_cast (target_type, value_from_contents_and_address (type, valaddr, 0)); return ada_val_print_1 (target_type, VALUE_CONTENTS (v), 0, 0, stream, format, 0, recurse + 1, pretty); } else return ada_val_print_1 (TYPE_TARGET_TYPE (type), valaddr0, embedded_offset, address, stream, format, deref_ref, recurse, pretty); } else { format = format ? format : output_format; if (format) { print_scalar_formatted (valaddr, type, format, 0, stream); } else if (ada_is_system_address_type (type)) { /* FIXME: We want to print System.Address variables using the same format as for any access type. But for some reason GNAT encodes the System.Address type as an int, so we have to work-around this deficiency by handling System.Address values as a special case. */ fprintf_filtered (stream, "("); type_print (type, "", stream, -1); fprintf_filtered (stream, ") "); print_address_numeric (extract_typed_address (valaddr, builtin_type_void_data_ptr), 1, stream); } else { val_print_type_code_int (type, valaddr, stream); if (ada_is_character_type (type)) { fputs_filtered (" ", stream); ada_printchar ((unsigned char) unpack_long (type, valaddr), stream); } } return 0; } case TYPE_CODE_ENUM: if (format) { print_scalar_formatted (valaddr, type, format, 0, stream); break; } len = TYPE_NFIELDS (type); val = unpack_long (type, valaddr); for (i = 0; i < len; i++) { QUIT; if (val == TYPE_FIELD_BITPOS (type, i)) { break; } } if (i < len) { const char *name = ada_enum_name (TYPE_FIELD_NAME (type, i)); if (name[0] == '\'') fprintf_filtered (stream, "%ld %s", (long) val, name); else fputs_filtered (name, stream); } else { print_longest (stream, 'd', 0, val); } break; case TYPE_CODE_FLT: if (format) return c_val_print (type, valaddr0, embedded_offset, address, stream, format, deref_ref, recurse, pretty); else ada_print_floating (valaddr0 + embedded_offset, type, stream); break; case TYPE_CODE_UNION: case TYPE_CODE_STRUCT: if (ada_is_bogus_array_descriptor (type)) { fprintf_filtered (stream, "(...?)"); return 0; } else { print_record (type, valaddr, stream, format, recurse, pretty); return 0; } case TYPE_CODE_ARRAY: elttype = TYPE_TARGET_TYPE (type); if (elttype == NULL) eltlen = 0; else eltlen = TYPE_LENGTH (elttype); /* FIXME: This doesn't deal with non-empty arrays of 0-length items (not a typical case!) */ if (eltlen == 0) len = 0; else len = TYPE_LENGTH (type) / eltlen; /* For an array of chars, print with string syntax. */ if (ada_is_string_type (type) && (format == 0 || format == 's')) { if (prettyprint_arrays) { print_spaces_filtered (2 + 2 * recurse, stream); } /* If requested, look for the first null char and only print elements up to it. */ if (stop_print_at_null) { int temp_len; /* Look for a NULL char. */ for (temp_len = 0; temp_len < len && temp_len < print_max && char_at (valaddr, temp_len, eltlen) != 0; temp_len += 1); len = temp_len; } printstr (stream, valaddr, len, 0, eltlen); } else { len = 0; fprintf_filtered (stream, "("); print_optional_low_bound (stream, type); if (TYPE_FIELD_BITSIZE (type, 0) > 0) val_print_packed_array_elements (type, valaddr, 0, stream, format, recurse, pretty); else val_print_array_elements (type, valaddr, address, stream, format, deref_ref, recurse, pretty, 0); fprintf_filtered (stream, ")"); } gdb_flush (stream); return len; case TYPE_CODE_REF: elttype = check_typedef (TYPE_TARGET_TYPE (type)); /* De-reference the reference */ if (deref_ref) { if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) { LONGEST deref_val_int = (LONGEST) unpack_pointer (lookup_pointer_type (builtin_type_void), valaddr); if (deref_val_int != 0) { struct value *deref_val = ada_value_ind (value_from_longest (lookup_pointer_type (elttype), deref_val_int)); val_print (VALUE_TYPE (deref_val), VALUE_CONTENTS (deref_val), 0, VALUE_ADDRESS (deref_val), stream, format, deref_ref, recurse + 1, pretty); } else fputs_filtered ("(null)", stream); } else fputs_filtered ("???", stream); } break; } gdb_flush (stream); return 0; }
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(); }
Type& Parser::on_pointer_type(Type& t) { return make_pointer_type(cxt, t); }