*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
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);
}
static void
stub_noname_complaint (void)
{
- complaint (&symfile_complaints, _("stub type has NULL name"));
+ complaint (_("stub type has NULL name"));
}
/* Return nonzero if TYPE has a DYN_PROP_BYTE_STRIDE dynamic property
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. */
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;
}
/* 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
objfile_type->nodebug_text_gnu_ifunc_symbol
= init_type (objfile, TYPE_CODE_FUNC, TARGET_CHAR_BIT,
"<text gnu-indirect-function variable, no debug info>");
- /* Ifunc resolvers return a function address. */
- TYPE_TARGET_TYPE (objfile_type->nodebug_text_gnu_ifunc_symbol)
- = init_integer_type (objfile, gdbarch_addr_bit (gdbarch), 1,
- "__IFUNC_RESOLVER_RET");
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),