/* Support routines for manipulating internal types for GDB.
- Copyright (C) 1992-2017 Free Software Foundation, Inc.
+ Copyright (C) 1992-2018 Free Software Foundation, Inc.
Contributed by Cygnus Support, using pieces from other GDB modules.
#include "bcache.h"
#include "dwarf2loc.h"
#include "gdbcore.h"
+#include "floatformat.h"
/* Initialize BADNESS constants. */
const struct rank INTEGER_PROMOTION_BADNESS = {1,0};
const struct rank FLOAT_PROMOTION_BADNESS = {1,0};
const struct rank BASE_PTR_CONVERSION_BADNESS = {1,0};
+const struct rank CV_CONVERSION_BADNESS = {1, 0};
const struct rank INTEGER_CONVERSION_BADNESS = {2,0};
const struct rank FLOAT_CONVERSION_BADNESS = {2,0};
const struct rank INT_FLOAT_CONVERSION_BADNESS = {2,0};
gdb_assert (nparams == 0);
TYPE_PROTOTYPED (fn) = 1;
}
+ else
+ TYPE_PROTOTYPED (fn) = 1;
}
TYPE_NFIELDS (fn) = nparams;
return mtype;
}
+/* See gdbtypes.h. */
+
+bool
+operator== (const dynamic_prop &l, const dynamic_prop &r)
+{
+ if (l.kind != r.kind)
+ return false;
+
+ switch (l.kind)
+ {
+ case PROP_UNDEFINED:
+ return true;
+ case PROP_CONST:
+ return l.data.const_val == r.data.const_val;
+ case PROP_ADDR_OFFSET:
+ case PROP_LOCEXPR:
+ case PROP_LOCLIST:
+ return l.data.baton == r.data.baton;
+ }
+
+ gdb_assert_not_reached ("unhandled dynamic_prop kind");
+}
+
+/* See gdbtypes.h. */
+
+bool
+operator== (const range_bounds &l, const range_bounds &r)
+{
+#define FIELD_EQ(FIELD) (l.FIELD == r.FIELD)
+
+ return (FIELD_EQ (low)
+ && FIELD_EQ (high)
+ && FIELD_EQ (flag_upper_bound_is_count)
+ && FIELD_EQ (flag_bound_evaluated));
+
+#undef FIELD_EQ
+}
+
/* Create a range type with a dynamic range from LOW_BOUND to
HIGH_BOUND, inclusive. See create_range_type for further details. */
*highp = -*lowp - 1;
return 0;
}
- /* ... fall through for unsigned ints ... */
+ /* fall through */
case TYPE_CODE_CHAR:
*lowp = 0;
/* This round-about calculation is to avoid shifting by
Elements will be of type ELEMENT_TYPE, the indices will be of type
RANGE_TYPE.
+ BYTE_STRIDE_PROP, when not NULL, provides the array's byte stride.
+ This byte stride property is added to the resulting array type
+ as a DYN_PROP_BYTE_STRIDE. As a consequence, the BYTE_STRIDE_PROP
+ argument can only be used to create types that are objfile-owned
+ (see add_dyn_prop), meaning that either this function must be called
+ with an objfile-owned RESULT_TYPE, or an objfile-owned RANGE_TYPE.
+
+ BIT_STRIDE is taken into account only when BYTE_STRIDE_PROP is NULL.
If BIT_STRIDE is not zero, build a packed array type whose element
size is BIT_STRIDE. Otherwise, ignore this parameter.
create_array_type_with_stride (struct type *result_type,
struct type *element_type,
struct type *range_type,
+ struct dynamic_prop *byte_stride_prop,
unsigned int bit_stride)
{
+ if (byte_stride_prop != NULL
+ && byte_stride_prop->kind == PROP_CONST)
+ {
+ /* The byte stride is actually not dynamic. Pretend we were
+ called with bit_stride set instead of byte_stride_prop.
+ This will give us the same result type, while avoiding
+ the need to handle this as a special case. */
+ bit_stride = byte_stride_prop->data.const_val * 8;
+ byte_stride_prop = NULL;
+ }
+
if (result_type == NULL)
result_type = alloc_type_copy (range_type);
TYPE_CODE (result_type) = TYPE_CODE_ARRAY;
TYPE_TARGET_TYPE (result_type) = element_type;
- if (has_static_range (TYPE_RANGE_DATA (range_type))
+ if (byte_stride_prop == NULL
+ && has_static_range (TYPE_RANGE_DATA (range_type))
&& (!type_not_associated (result_type)
&& !type_not_allocated (result_type)))
{
TYPE_FIELDS (result_type) =
(struct field *) TYPE_ZALLOC (result_type, sizeof (struct field));
TYPE_INDEX_TYPE (result_type) = range_type;
- if (bit_stride > 0)
+ if (byte_stride_prop != NULL)
+ add_dyn_prop (DYN_PROP_BYTE_STRIDE, *byte_stride_prop, result_type);
+ else if (bit_stride > 0)
TYPE_FIELD_BITSIZE (result_type, 0) = bit_stride;
/* TYPE_TARGET_STUB will take care of zero length arrays. */
struct type *range_type)
{
return create_array_type_with_stride (result_type, element_type,
- range_type, 0);
+ range_type, NULL, 0);
}
struct type *
lookup_array_range_type (struct type *element_type,
LONGEST low_bound, LONGEST high_bound)
{
- struct gdbarch *gdbarch = get_type_arch (element_type);
- struct type *index_type = builtin_type (gdbarch)->builtin_int;
- struct type *range_type
- = create_static_range_type (NULL, index_type, low_bound, high_bound);
+ struct type *index_type;
+ struct type *range_type;
+
+ if (TYPE_OBJFILE_OWNED (element_type))
+ index_type = objfile_type (TYPE_OWNER (element_type).objfile)->builtin_int;
+ else
+ index_type = builtin_type (get_type_arch (element_type))->builtin_int;
+ range_type = create_static_range_type (NULL, index_type,
+ low_bound, high_bound);
return create_array_type (NULL, element_type, range_type);
}
complaint (&symfile_complaints, _("stub type has NULL name"));
}
+/* Return nonzero if TYPE has a DYN_PROP_BYTE_STRIDE dynamic property
+ attached to it, and that property has a non-constant value. */
+
+static int
+array_type_has_dynamic_stride (struct type *type)
+{
+ struct dynamic_prop *prop = get_dyn_prop (DYN_PROP_BYTE_STRIDE, type);
+
+ return (prop != NULL && prop->kind != PROP_CONST);
+}
+
/* Worker for is_dynamic_type. */
static int
{
gdb_assert (TYPE_NFIELDS (type) == 1);
- /* The array is dynamic if either the bounds are dynamic,
- or the elements it contains have a dynamic contents. */
+ /* The array is dynamic if either the bounds are dynamic... */
if (is_dynamic_type_internal (TYPE_INDEX_TYPE (type), 0))
return 1;
- return is_dynamic_type_internal (TYPE_TARGET_TYPE (type), 0);
+ /* ... or the elements it contains have a dynamic contents... */
+ if (is_dynamic_type_internal (TYPE_TARGET_TYPE (type), 0))
+ return 1;
+ /* ... or if it has a dynamic stride... */
+ if (array_type_has_dynamic_stride (type))
+ return 1;
+ return 0;
}
case TYPE_CODE_STRUCT:
struct type *range_type;
struct type *ary_dim;
struct dynamic_prop *prop;
+ unsigned int bit_stride = 0;
gdb_assert (TYPE_CODE (type) == TYPE_CODE_ARRAY);
else
elt_type = TYPE_TARGET_TYPE (type);
- return create_array_type_with_stride (type, elt_type, range_type,
- TYPE_FIELD_BITSIZE (type, 0));
+ prop = get_dyn_prop (DYN_PROP_BYTE_STRIDE, type);
+ if (prop != NULL)
+ {
+ int prop_eval_ok
+ = dwarf2_evaluate_property (prop, NULL, addr_stack, &value);
+
+ if (prop_eval_ok)
+ {
+ remove_dyn_prop (DYN_PROP_BYTE_STRIDE, type);
+ bit_stride = (unsigned int) (value * 8);
+ }
+ else
+ {
+ /* Could be a bug in our code, but it could also happen
+ if the DWARF info is not correct. Issue a warning,
+ and assume no byte/bit stride (leave bit_stride = 0). */
+ warning (_("cannot determine array stride for type %s"),
+ TYPE_NAME (type) ? TYPE_NAME (type) : "<no name>");
+ }
+ }
+ else
+ bit_stride = TYPE_FIELD_BITSIZE (type, 0);
+
+ return create_array_type_with_stride (type, elt_type, range_type, NULL,
+ bit_stride);
}
/* Resolve dynamic bounds of members of the union TYPE to static
void
add_dyn_prop (enum dynamic_prop_node_kind prop_kind, struct dynamic_prop prop,
- struct type *type, struct objfile *objfile)
+ struct type *type)
{
struct dynamic_prop_list *temp;
gdb_assert (TYPE_OBJFILE_OWNED (type));
- temp = XOBNEW (&objfile->objfile_obstack, struct dynamic_prop_list);
+ temp = XOBNEW (&TYPE_OBJFILE (type)->objfile_obstack,
+ struct dynamic_prop_list);
temp->prop_kind = prop_kind;
temp->prop = prop;
temp->next = TYPE_DYN_PROP_LIST (type);
determined by the floatformat. Returns size to be used. */
static int
-verify_floatformat (int bit, const struct floatformat **floatformats)
+verify_floatformat (int bit, const struct floatformat *floatformat)
{
- gdb_assert (floatformats != NULL);
- gdb_assert (floatformats[0] != NULL && floatformats[1] != NULL);
+ gdb_assert (floatformat != NULL);
if (bit == -1)
- bit = floatformats[0]->totalsize;
- gdb_assert (bit >= 0);
+ bit = floatformat->totalsize;
- size_t len = bit / TARGET_CHAR_BIT;
- gdb_assert (len >= floatformat_totalsize_bytes (floatformats[0]));
- gdb_assert (len >= floatformat_totalsize_bytes (floatformats[1]));
+ gdb_assert (bit >= 0);
+ gdb_assert (bit >= floatformat->totalsize);
return bit;
}
+/* Return the floating-point format for a floating-point variable of
+ type TYPE. */
+
+const struct floatformat *
+floatformat_from_type (const struct type *type)
+{
+ gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);
+ gdb_assert (TYPE_FLOATFORMAT (type));
+ return TYPE_FLOATFORMAT (type);
+}
+
/* Helper function to initialize the standard scalar types.
If NAME is non-NULL, then it is used to initialize the type name.
least as long as OBJFILE. */
struct type *
-init_type (struct objfile *objfile, enum type_code code, int length,
+init_type (struct objfile *objfile, enum type_code code, int bit,
const char *name)
{
struct type *type;
type = alloc_type (objfile);
set_type_code (type, code);
- TYPE_LENGTH (type) = length;
+ gdb_assert ((bit % TARGET_CHAR_BIT) == 0);
+ TYPE_LENGTH (type) = bit / TARGET_CHAR_BIT;
TYPE_NAME (type) = name;
return type;
}
+/* Allocate a TYPE_CODE_ERROR type structure associated with OBJFILE,
+ to use with variables that have no debug info. NAME is the type
+ name. */
+
+static struct type *
+init_nodebug_var_type (struct objfile *objfile, const char *name)
+{
+ return init_type (objfile, TYPE_CODE_ERROR, 0, name);
+}
+
/* Allocate a TYPE_CODE_INT type structure associated with OBJFILE.
BIT is the type size in bits. If UNSIGNED_P is non-zero, set
the type's TYPE_UNSIGNED flag. NAME is the type name. */
{
struct type *t;
- t = init_type (objfile, TYPE_CODE_INT, bit / TARGET_CHAR_BIT, name);
+ t = init_type (objfile, TYPE_CODE_INT, bit, name);
if (unsigned_p)
TYPE_UNSIGNED (t) = 1;
{
struct type *t;
- t = init_type (objfile, TYPE_CODE_CHAR, bit / TARGET_CHAR_BIT, name);
+ t = init_type (objfile, TYPE_CODE_CHAR, bit, name);
if (unsigned_p)
TYPE_UNSIGNED (t) = 1;
{
struct type *t;
- t = init_type (objfile, TYPE_CODE_BOOL, bit / TARGET_CHAR_BIT, name);
+ t = init_type (objfile, TYPE_CODE_BOOL, bit, name);
if (unsigned_p)
TYPE_UNSIGNED (t) = 1;
int bit, const char *name,
const struct floatformat **floatformats)
{
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ const struct floatformat *fmt = floatformats[gdbarch_byte_order (gdbarch)];
struct type *t;
- bit = verify_floatformat (bit, floatformats);
- t = init_type (objfile, TYPE_CODE_FLT, bit / TARGET_CHAR_BIT, name);
- TYPE_FLOATFORMAT (t) = floatformats;
+ bit = verify_floatformat (bit, fmt);
+ t = init_type (objfile, TYPE_CODE_FLT, bit, name);
+ TYPE_FLOATFORMAT (t) = fmt;
return t;
}
{
struct type *t;
- t = init_type (objfile, TYPE_CODE_DECFLOAT, bit / TARGET_CHAR_BIT, name);
+ t = init_type (objfile, TYPE_CODE_DECFLOAT, bit, name);
return t;
}
struct type *t;
t = init_type (objfile, TYPE_CODE_COMPLEX,
- 2 * TYPE_LENGTH (target_type), name);
+ 2 * TYPE_LENGTH (target_type) * TARGET_CHAR_BIT, name);
TYPE_TARGET_TYPE (t) = target_type;
return t;
}
{
struct type *t;
- t = init_type (objfile, TYPE_CODE_PTR, bit / TARGET_CHAR_BIT, name);
+ t = init_type (objfile, TYPE_CODE_PTR, bit, name);
TYPE_TARGET_TYPE (t) = target_type;
TYPE_UNSIGNED (t) = 1;
return t;
}
+/* See gdbtypes.h. */
+
+unsigned
+type_raw_align (struct type *type)
+{
+ if (type->align_log2 != 0)
+ return 1 << (type->align_log2 - 1);
+ return 0;
+}
+
+/* See gdbtypes.h. */
+
+unsigned
+type_align (struct type *type)
+{
+ unsigned raw_align = type_raw_align (type);
+ if (raw_align != 0)
+ return raw_align;
+
+ ULONGEST align = 0;
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_PTR:
+ case TYPE_CODE_FUNC:
+ case TYPE_CODE_FLAGS:
+ case TYPE_CODE_INT:
+ case TYPE_CODE_FLT:
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_REF:
+ case TYPE_CODE_RVALUE_REF:
+ case TYPE_CODE_CHAR:
+ case TYPE_CODE_BOOL:
+ case TYPE_CODE_DECFLOAT:
+ {
+ struct gdbarch *arch = get_type_arch (type);
+ align = gdbarch_type_align (arch, type);
+ }
+ break;
+
+ case TYPE_CODE_ARRAY:
+ case TYPE_CODE_COMPLEX:
+ case TYPE_CODE_TYPEDEF:
+ align = type_align (TYPE_TARGET_TYPE (type));
+ break;
+
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ {
+ if (TYPE_NFIELDS (type) == 0)
+ {
+ /* An empty struct has alignment 1. */
+ align = 1;
+ break;
+ }
+ for (unsigned i = 0; i < TYPE_NFIELDS (type); ++i)
+ {
+ ULONGEST f_align = type_align (TYPE_FIELD_TYPE (type, i));
+ if (f_align == 0)
+ {
+ /* Don't pretend we know something we don't. */
+ align = 0;
+ break;
+ }
+ if (f_align > align)
+ align = f_align;
+ }
+ }
+ break;
+
+ case TYPE_CODE_SET:
+ case TYPE_CODE_RANGE:
+ case TYPE_CODE_STRING:
+ /* Not sure what to do here, and these can't appear in C or C++
+ anyway. */
+ break;
+
+ case TYPE_CODE_METHODPTR:
+ case TYPE_CODE_MEMBERPTR:
+ align = TYPE_LENGTH (type);
+ break;
+
+ case TYPE_CODE_VOID:
+ align = 1;
+ break;
+
+ case TYPE_CODE_ERROR:
+ case TYPE_CODE_METHOD:
+ default:
+ break;
+ }
+
+ if ((align & (align - 1)) != 0)
+ {
+ /* Not a power of 2, so pass. */
+ align = 0;
+ }
+
+ return align;
+}
+
+/* See gdbtypes.h. */
+
+bool
+set_type_align (struct type *type, ULONGEST align)
+{
+ /* Must be a power of 2. Zero is ok. */
+ gdb_assert ((align & (align - 1)) == 0);
+
+ unsigned result = 0;
+ while (align != 0)
+ {
+ ++result;
+ align >>= 1;
+ }
+
+ if (result >= (1 << TYPE_ALIGN_BITS))
+ return false;
+
+ type->align_log2 = result;
+ return true;
+}
+
\f
/* Queries on types. */
|| (TYPE_CODE (t) == TYPE_CODE_BOOL)));
}
+int
+is_floating_type (struct type *t)
+{
+ t = check_typedef (t);
+ return
+ ((t != NULL)
+ && ((TYPE_CODE (t) == TYPE_CODE_FLT)
+ || (TYPE_CODE (t) == TYPE_CODE_DECFLOAT)));
+}
+
/* Return true if TYPE is scalar. */
int
if (TYPE_CODE (type1) == TYPE_CODE_RANGE)
{
- if (memcmp (TYPE_RANGE_DATA (type1), TYPE_RANGE_DATA (type2),
- sizeof (*TYPE_RANGE_DATA (type1))) != 0)
+ if (*TYPE_RANGE_DATA (type1) != *TYPE_RANGE_DATA (type2))
return 0;
}
else
{
struct rank rank = {0,0};
- if (types_equal (parm, arg))
- return EXACT_MATCH_BADNESS;
-
/* Resolve typedefs */
if (TYPE_CODE (parm) == TYPE_CODE_TYPEDEF)
parm = check_typedef (parm);
if (TYPE_CODE (arg) == TYPE_CODE_TYPEDEF)
arg = check_typedef (arg);
+ if (TYPE_IS_REFERENCE (parm) && value != NULL)
+ {
+ if (VALUE_LVAL (value) == not_lval)
+ {
+ /* Rvalues should preferably bind to rvalue references or const
+ lvalue references. */
+ if (TYPE_CODE (parm) == TYPE_CODE_RVALUE_REF)
+ rank.subrank = REFERENCE_CONVERSION_RVALUE;
+ else if (TYPE_CONST (TYPE_TARGET_TYPE (parm)))
+ rank.subrank = REFERENCE_CONVERSION_CONST_LVALUE;
+ else
+ return INCOMPATIBLE_TYPE_BADNESS;
+ return sum_ranks (rank, REFERENCE_CONVERSION_BADNESS);
+ }
+ else
+ {
+ /* Lvalues should prefer lvalue overloads. */
+ if (TYPE_CODE (parm) == TYPE_CODE_RVALUE_REF)
+ {
+ rank.subrank = REFERENCE_CONVERSION_RVALUE;
+ return sum_ranks (rank, REFERENCE_CONVERSION_BADNESS);
+ }
+ }
+ }
+
+ if (types_equal (parm, arg))
+ {
+ struct type *t1 = parm;
+ struct type *t2 = arg;
+
+ /* For pointers and references, compare target type. */
+ if (TYPE_CODE (parm) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (parm))
+ {
+ t1 = TYPE_TARGET_TYPE (parm);
+ t2 = TYPE_TARGET_TYPE (arg);
+ }
+
+ /* Make sure they are CV equal, too. */
+ if (TYPE_CONST (t1) != TYPE_CONST (t2))
+ rank.subrank |= CV_CONVERSION_CONST;
+ if (TYPE_VOLATILE (t1) != TYPE_VOLATILE (t2))
+ rank.subrank |= CV_CONVERSION_VOLATILE;
+ if (rank.subrank != 0)
+ return sum_ranks (CV_CONVERSION_BADNESS, rank);
+ return EXACT_MATCH_BADNESS;
+ }
+
/* See through references, since we can almost make non-references
references. */
return INCOMPATIBLE_TYPE_BADNESS;
case TYPE_CODE_ARRAY:
- if (types_equal (TYPE_TARGET_TYPE (parm),
- TYPE_TARGET_TYPE (arg)))
- return EXACT_MATCH_BADNESS;
- return INCOMPATIBLE_TYPE_BADNESS;
+ {
+ struct type *t1 = TYPE_TARGET_TYPE (parm);
+ struct type *t2 = TYPE_TARGET_TYPE (arg);
+
+ if (types_equal (t1, t2))
+ {
+ /* Make sure they are CV equal. */
+ if (TYPE_CONST (t1) != TYPE_CONST (t2))
+ rank.subrank |= CV_CONVERSION_CONST;
+ if (TYPE_VOLATILE (t1) != TYPE_VOLATILE (t2))
+ rank.subrank |= CV_CONVERSION_VOLATILE;
+ if (rank.subrank != 0)
+ return sum_ranks (CV_CONVERSION_BADNESS, rank);
+ return EXACT_MATCH_BADNESS;
+ }
+ return INCOMPATIBLE_TYPE_BADNESS;
+ }
case TYPE_CODE_FUNC:
return rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL);
case TYPE_CODE_INT:
return INTEGER_CONVERSION_BADNESS;
else if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm))
return INTEGER_PROMOTION_BADNESS;
- /* >>> !! else fall through !! <<< */
+ /* fall through */
case TYPE_CODE_CHAR:
/* Deal with signed, unsigned, and plain chars for C++ and
with int cases falling through from previous case. */
rank.subrank = distance_to_ancestor (parm, arg, 0);
if (rank.subrank >= 0)
return sum_ranks (BASE_CONVERSION_BADNESS, rank);
- /* else fall through */
+ /* fall through */
default:
return INCOMPATIBLE_TYPE_BADNESS;
}
{
puts_filtered (" TYPE_TARGET_STUB");
}
- if (TYPE_STATIC (type))
- {
- puts_filtered (" TYPE_STATIC");
- }
if (TYPE_PROTOTYPED (type))
{
puts_filtered (" TYPE_PROTOTYPED");
case TYPE_SPECIFIC_FLOATFORMAT:
printfi_filtered (spaces, "floatformat ");
- if (TYPE_FLOATFORMAT (type) == NULL)
+ if (TYPE_FLOATFORMAT (type) == NULL
+ || TYPE_FLOATFORMAT (type)->name == NULL)
puts_filtered ("(null)");
else
- {
- puts_filtered ("{ ");
- if (TYPE_FLOATFORMAT (type)[0] == NULL
- || TYPE_FLOATFORMAT (type)[0]->name == NULL)
- puts_filtered ("(null)");
- else
- puts_filtered (TYPE_FLOATFORMAT (type)[0]->name);
-
- puts_filtered (", ");
- if (TYPE_FLOATFORMAT (type)[1] == NULL
- || TYPE_FLOATFORMAT (type)[1]->name == NULL)
- puts_filtered ("(null)");
- else
- puts_filtered (TYPE_FLOATFORMAT (type)[1]->name);
-
- puts_filtered (" }");
- }
+ puts_filtered (TYPE_FLOATFORMAT (type)->name);
puts_filtered ("\n");
break;
/* Trivial helpers for the libiberty hash table, for mapping one
type to another. */
-struct type_pair
+struct type_pair : public allocate_on_obstack
{
- struct type *old, *newobj;
+ type_pair (struct type *old_, struct type *newobj_)
+ : old (old_), newobj (newobj_)
+ {}
+
+ struct type * const old, * const newobj;
};
static hashval_t
struct type *type,
htab_t copied_types)
{
- struct type_pair *stored, pair;
void **slot;
struct type *new_type;
if it did, the type might disappear unexpectedly. */
gdb_assert (TYPE_OBJFILE (type) == objfile);
- pair.old = type;
+ struct type_pair pair (type, nullptr);
+
slot = htab_find_slot (copied_types, &pair, INSERT);
if (*slot != NULL)
return ((struct type_pair *) *slot)->newobj;
/* We must add the new type to the hash table immediately, in case
we encounter this type again during a recursive call below. */
- stored = XOBNEW (&objfile->objfile_obstack, struct type_pair);
- stored->old = type;
- stored->newobj = new_type;
+ struct type_pair *stored
+ = new (&objfile->objfile_obstack) struct type_pair (type, new_type);
+
*slot = stored;
/* Copy the common fields of types. For the main type, we simply
struct type *
arch_type (struct gdbarch *gdbarch,
- enum type_code code, int length, const char *name)
+ enum type_code code, int bit, const char *name)
{
struct type *type;
type = alloc_type_arch (gdbarch);
set_type_code (type, code);
- TYPE_LENGTH (type) = length;
+ gdb_assert ((bit % TARGET_CHAR_BIT) == 0);
+ TYPE_LENGTH (type) = bit / TARGET_CHAR_BIT;
if (name)
TYPE_NAME (type) = gdbarch_obstack_strdup (gdbarch, name);
{
struct type *t;
- t = arch_type (gdbarch, TYPE_CODE_INT, bit / TARGET_CHAR_BIT, name);
+ t = arch_type (gdbarch, TYPE_CODE_INT, bit, name);
if (unsigned_p)
TYPE_UNSIGNED (t) = 1;
{
struct type *t;
- t = arch_type (gdbarch, TYPE_CODE_CHAR, bit / TARGET_CHAR_BIT, name);
+ t = arch_type (gdbarch, TYPE_CODE_CHAR, bit, name);
if (unsigned_p)
TYPE_UNSIGNED (t) = 1;
{
struct type *t;
- t = arch_type (gdbarch, TYPE_CODE_BOOL, bit / TARGET_CHAR_BIT, name);
+ t = arch_type (gdbarch, TYPE_CODE_BOOL, bit, name);
if (unsigned_p)
TYPE_UNSIGNED (t) = 1;
int bit, const char *name,
const struct floatformat **floatformats)
{
+ const struct floatformat *fmt = floatformats[gdbarch_byte_order (gdbarch)];
struct type *t;
- bit = verify_floatformat (bit, floatformats);
- t = arch_type (gdbarch, TYPE_CODE_FLT, bit / TARGET_CHAR_BIT, name);
- TYPE_FLOATFORMAT (t) = floatformats;
+ bit = verify_floatformat (bit, fmt);
+ t = arch_type (gdbarch, TYPE_CODE_FLT, bit, name);
+ TYPE_FLOATFORMAT (t) = fmt;
return t;
}
{
struct type *t;
- t = arch_type (gdbarch, TYPE_CODE_DECFLOAT, bit / TARGET_CHAR_BIT, name);
+ t = arch_type (gdbarch, TYPE_CODE_DECFLOAT, bit, name);
return t;
}
struct type *t;
t = arch_type (gdbarch, TYPE_CODE_COMPLEX,
- 2 * TYPE_LENGTH (target_type), name);
+ 2 * TYPE_LENGTH (target_type) * TARGET_CHAR_BIT, name);
TYPE_TARGET_TYPE (t) = target_type;
return t;
}
{
struct type *t;
- t = arch_type (gdbarch, TYPE_CODE_PTR, bit / TARGET_CHAR_BIT, name);
+ t = arch_type (gdbarch, TYPE_CODE_PTR, bit, name);
TYPE_TARGET_TYPE (t) = target_type;
TYPE_UNSIGNED (t) = 1;
return t;
}
/* Allocate a TYPE_CODE_FLAGS type structure associated with GDBARCH.
- NAME is the type name. LENGTH is the size of the flag word in bytes. */
+ NAME is the type name. BIT is the size of the flag word in bits. */
struct type *
-arch_flags_type (struct gdbarch *gdbarch, const char *name, int length)
+arch_flags_type (struct gdbarch *gdbarch, const char *name, int bit)
{
- int max_nfields = length * TARGET_CHAR_BIT;
struct type *type;
- type = arch_type (gdbarch, TYPE_CODE_FLAGS, length, name);
+ type = arch_type (gdbarch, TYPE_CODE_FLAGS, bit, name);
TYPE_UNSIGNED (type) = 1;
TYPE_NFIELDS (type) = 0;
/* Pre-allocate enough space assuming every field is one bit. */
TYPE_FIELDS (type)
- = (struct field *) TYPE_ZALLOC (type, max_nfields * sizeof (struct field));
+ = (struct field *) TYPE_ZALLOC (type, bit * sizeof (struct field));
return type;
}
/* Basic types. */
builtin_type->builtin_void
- = arch_type (gdbarch, TYPE_CODE_VOID, 1, "void");
+ = arch_type (gdbarch, TYPE_CODE_VOID, TARGET_CHAR_BIT, "void");
builtin_type->builtin_char
= arch_integer_type (gdbarch, TARGET_CHAR_BIT,
!gdbarch_char_signed (gdbarch), "char");
= arch_complex_type (gdbarch, "double complex",
builtin_type->builtin_double);
builtin_type->builtin_string
- = arch_type (gdbarch, TYPE_CODE_STRING, 1, "string");
+ = arch_type (gdbarch, TYPE_CODE_STRING, TARGET_CHAR_BIT, "string");
builtin_type->builtin_bool
- = arch_type (gdbarch, TYPE_CODE_BOOL, 1, "bool");
+ = arch_type (gdbarch, TYPE_CODE_BOOL, TARGET_CHAR_BIT, "bool");
/* The following three are about decimal floating point types, which
are 32-bits, 64-bits and 128-bits respectively. */
/* Wide character types. */
builtin_type->builtin_char16
- = arch_integer_type (gdbarch, 16, 0, "char16_t");
+ = arch_integer_type (gdbarch, 16, 1, "char16_t");
builtin_type->builtin_char32
- = arch_integer_type (gdbarch, 32, 0, "char32_t");
-
+ = arch_integer_type (gdbarch, 32, 1, "char32_t");
+ builtin_type->builtin_wchar
+ = arch_integer_type (gdbarch, gdbarch_wchar_bit (gdbarch),
+ !gdbarch_wchar_signed (gdbarch), "wchar_t");
/* Default data/code pointer types. */
builtin_type->builtin_data_ptr
/* Basic types. */
objfile_type->builtin_void
- = init_type (objfile, TYPE_CODE_VOID, 1, "void");
+ = init_type (objfile, TYPE_CODE_VOID, TARGET_CHAR_BIT, "void");
objfile_type->builtin_char
= init_integer_type (objfile, TARGET_CHAR_BIT,
!gdbarch_char_signed (gdbarch), "char");
/* The following set of types is used for symbols with no
debug information. */
objfile_type->nodebug_text_symbol
- = init_type (objfile, TYPE_CODE_FUNC, 1,
+ = init_type (objfile, TYPE_CODE_FUNC, TARGET_CHAR_BIT,
"<text variable, no debug info>");
- TYPE_TARGET_TYPE (objfile_type->nodebug_text_symbol)
- = objfile_type->builtin_int;
objfile_type->nodebug_text_gnu_ifunc_symbol
- = init_type (objfile, TYPE_CODE_FUNC, 1,
+ = init_type (objfile, TYPE_CODE_FUNC, TARGET_CHAR_BIT,
"<text gnu-indirect-function variable, no debug info>");
- TYPE_TARGET_TYPE (objfile_type->nodebug_text_gnu_ifunc_symbol)
- = objfile_type->nodebug_text_symbol;
TYPE_GNU_IFUNC (objfile_type->nodebug_text_gnu_ifunc_symbol) = 1;
objfile_type->nodebug_got_plt_symbol
= init_pointer_type (objfile, gdbarch_addr_bit (gdbarch),
"<text from jump slot in .got.plt, no debug info>",
objfile_type->nodebug_text_symbol);
objfile_type->nodebug_data_symbol
- = init_integer_type (objfile, gdbarch_int_bit (gdbarch), 0,
- "<data variable, no debug info>");
+ = init_nodebug_var_type (objfile, "<data variable, no debug info>");
objfile_type->nodebug_unknown_symbol
- = init_integer_type (objfile, TARGET_CHAR_BIT, 0,
- "<variable (not text or data), no debug info>");
+ = init_nodebug_var_type (objfile, "<variable (not text or data), no debug info>");
objfile_type->nodebug_tls_symbol
- = init_integer_type (objfile, gdbarch_int_bit (gdbarch), 0,
- "<thread local variable, no debug info>");
+ = init_nodebug_var_type (objfile, "<thread local variable, no debug info>");
/* NOTE: on some targets, addresses and pointers are not necessarily
the same.
return objfile_type;
}
-extern initialize_file_ftype _initialize_gdbtypes;
-
void
_initialize_gdbtypes (void)
{