+
+/* Construct, if necessary, and return the GDB type implementing target
+ type TDESC_TYPE for architecture GDBARCH. */
+
+static struct type *
+tdesc_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *tdesc_type)
+{
+ struct type *type;
+
+ switch (tdesc_type->kind)
+ {
+ /* Predefined types. */
+ case TDESC_TYPE_INT8:
+ return builtin_type (gdbarch)->builtin_int8;
+
+ case TDESC_TYPE_INT16:
+ return builtin_type (gdbarch)->builtin_int16;
+
+ case TDESC_TYPE_INT32:
+ return builtin_type (gdbarch)->builtin_int32;
+
+ case TDESC_TYPE_INT64:
+ return builtin_type (gdbarch)->builtin_int64;
+
+ case TDESC_TYPE_INT128:
+ return builtin_type (gdbarch)->builtin_int128;
+
+ case TDESC_TYPE_UINT8:
+ return builtin_type (gdbarch)->builtin_uint8;
+
+ case TDESC_TYPE_UINT16:
+ return builtin_type (gdbarch)->builtin_uint16;
+
+ case TDESC_TYPE_UINT32:
+ return builtin_type (gdbarch)->builtin_uint32;
+
+ case TDESC_TYPE_UINT64:
+ return builtin_type (gdbarch)->builtin_uint64;
+
+ case TDESC_TYPE_UINT128:
+ return builtin_type (gdbarch)->builtin_uint128;
+
+ case TDESC_TYPE_CODE_PTR:
+ return builtin_type (gdbarch)->builtin_func_ptr;
+
+ case TDESC_TYPE_DATA_PTR:
+ return builtin_type (gdbarch)->builtin_data_ptr;
+
+ default:
+ break;
+ }
+
+ type = tdesc_find_type (gdbarch, tdesc_type->name);
+ if (type)
+ return type;
+
+ switch (tdesc_type->kind)
+ {
+ case TDESC_TYPE_IEEE_SINGLE:
+ return arch_float_type (gdbarch, -1, "builtin_type_ieee_single",
+ floatformats_ieee_single);
+
+ case TDESC_TYPE_IEEE_DOUBLE:
+ return arch_float_type (gdbarch, -1, "builtin_type_ieee_double",
+ floatformats_ieee_double);
+
+ case TDESC_TYPE_ARM_FPA_EXT:
+ return arch_float_type (gdbarch, -1, "builtin_type_arm_ext",
+ floatformats_arm_ext);
+
+ case TDESC_TYPE_I387_EXT:
+ return arch_float_type (gdbarch, -1, "builtin_type_i387_ext",
+ floatformats_i387_ext);
+
+ /* Types defined by a target feature. */
+ case TDESC_TYPE_VECTOR:
+ {
+ struct type *type, *field_type;
+
+ field_type = tdesc_gdb_type (gdbarch, tdesc_type->u.v.type);
+ type = init_vector_type (field_type, tdesc_type->u.v.count);
+ TYPE_NAME (type) = xstrdup (tdesc_type->name);
+
+ return type;
+ }
+
+ case TDESC_TYPE_STRUCT:
+ {
+ struct type *type, *field_type;
+ struct tdesc_type_field *f;
+ int ix;
+
+ type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+ TYPE_NAME (type) = xstrdup (tdesc_type->name);
+ TYPE_TAG_NAME (type) = TYPE_NAME (type);
+
+ for (ix = 0;
+ VEC_iterate (tdesc_type_field, tdesc_type->u.u.fields, ix, f);
+ ix++)
+ {
+ if (f->type == NULL)
+ {
+ /* Bitfield. */
+ struct field *fld;
+ struct type *field_type;
+ int bitsize, total_size;
+
+ /* This invariant should be preserved while creating
+ types. */
+ gdb_assert (tdesc_type->u.u.size != 0);
+ if (tdesc_type->u.u.size > 4)
+ field_type = builtin_type (gdbarch)->builtin_uint64;
+ else
+ field_type = builtin_type (gdbarch)->builtin_uint32;
+
+ fld = append_composite_type_field_raw (type, xstrdup (f->name),
+ field_type);
+
+ /* For little-endian, BITPOS counts from the LSB of
+ the structure and marks the LSB of the field. For
+ big-endian, BITPOS counts from the MSB of the
+ structure and marks the MSB of the field. Either
+ way, it is the number of bits to the "left" of the
+ field. To calculate this in big-endian, we need
+ the total size of the structure. */
+ bitsize = f->end - f->start + 1;
+ total_size = tdesc_type->u.u.size * TARGET_CHAR_BIT;
+ if (gdbarch_bits_big_endian (gdbarch))
+ FIELD_BITPOS (fld[0]) = total_size - f->start - bitsize;
+ else
+ FIELD_BITPOS (fld[0]) = f->start;
+ FIELD_BITSIZE (fld[0]) = bitsize;
+ }
+ else
+ {
+ field_type = tdesc_gdb_type (gdbarch, f->type);
+ append_composite_type_field (type, xstrdup (f->name),
+ field_type);
+ }
+ }
+
+ if (tdesc_type->u.u.size != 0)
+ TYPE_LENGTH (type) = tdesc_type->u.u.size;
+ return type;
+ }
+
+ case TDESC_TYPE_UNION:
+ {
+ struct type *type, *field_type;
+ struct tdesc_type_field *f;
+ int ix;
+
+ type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
+ TYPE_NAME (type) = xstrdup (tdesc_type->name);
+
+ for (ix = 0;
+ VEC_iterate (tdesc_type_field, tdesc_type->u.u.fields, ix, f);
+ ix++)
+ {
+ field_type = tdesc_gdb_type (gdbarch, f->type);
+ append_composite_type_field (type, xstrdup (f->name), field_type);
+
+ /* If any of the children of a union are vectors, flag the
+ union as a vector also. This allows e.g. a union of two
+ vector types to show up automatically in "info vector". */
+ if (TYPE_VECTOR (field_type))
+ TYPE_VECTOR (type) = 1;
+ }
+ return type;
+ }
+
+ case TDESC_TYPE_FLAGS:
+ {
+ struct type *type, *field_type;
+ struct tdesc_type_flag *f;
+ int ix;
+
+ type = arch_flags_type (gdbarch, xstrdup (tdesc_type->name),
+ tdesc_type->u.f.size);
+ for (ix = 0;
+ VEC_iterate (tdesc_type_flag, tdesc_type->u.f.flags, ix, f);
+ ix++)
+ /* Note that contrary to the function name, this call will
+ just set the properties of an already-allocated
+ field. */
+ append_flags_type_flag (type, f->start,
+ *f->name ? f->name : NULL);
+
+ return type;
+ }
+ }
+
+ internal_error (__FILE__, __LINE__,
+ "Type \"%s\" has an unknown kind %d",
+ tdesc_type->name, tdesc_type->kind);
+}