/* Support routines for manipulating internal types for GDB.
- Copyright (C) 1992-2014 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};
/* Initialize the fields that might not be zero. */
TYPE_CODE (type) = TYPE_CODE_UNDEF;
- TYPE_VPTR_FIELDNO (type) = -1;
TYPE_CHAIN (type) = type; /* Chain back to itself. */
return type;
/* Allocate a new GDBARCH-associated type structure and fill it
with some defaults. Space for the type structure is allocated
- on the heap. */
+ on the obstack associated with GDBARCH. */
struct type *
alloc_type_arch (struct gdbarch *gdbarch)
/* Alloc the structure and start off with all fields zeroed. */
- type = XCNEW (struct type);
- TYPE_MAIN_TYPE (type) = XCNEW (struct main_type);
+ type = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct type);
+ TYPE_MAIN_TYPE (type) = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct main_type);
TYPE_OBJFILE_OWNED (type) = 0;
TYPE_OWNER (type).gdbarch = gdbarch;
/* Initialize the fields that might not be zero. */
TYPE_CODE (type) = TYPE_CODE_UNDEF;
- TYPE_VPTR_FIELDNO (type) = -1;
TYPE_CHAIN (type) = type; /* Chain back to itself. */
return type;
return type;
}
+/* See gdbtypes.h. */
+
+unsigned int
+type_length_units (struct type *type)
+{
+ struct gdbarch *arch = get_type_arch (type);
+ int unit_size = gdbarch_addressable_memory_unit_size (arch);
+
+ return TYPE_LENGTH (type) / unit_size;
+}
+
/* Alloc a new type instance structure, fill it with some defaults,
and point it at OLDTYPE. Allocate the new type instance from the
same place as OLDTYPE. */
/* Lookup a C++ `reference' to a type TYPE. TYPEPTR, if nonzero,
points to a pointer to memory where the reference type should be
stored. If *TYPEPTR is zero, update it to point to the reference
- type we return. We allocate new memory if needed. */
+ type we return. We allocate new memory if needed. REFCODE denotes
+ the kind of reference type to lookup (lvalue or rvalue reference). */
struct type *
-make_reference_type (struct type *type, struct type **typeptr)
+make_reference_type (struct type *type, struct type **typeptr,
+ enum type_code refcode)
{
struct type *ntype; /* New type */
+ struct type **reftype;
struct type *chain;
- ntype = TYPE_REFERENCE_TYPE (type);
+ gdb_assert (refcode == TYPE_CODE_REF || refcode == TYPE_CODE_RVALUE_REF);
+
+ ntype = (refcode == TYPE_CODE_REF ? TYPE_REFERENCE_TYPE (type)
+ : TYPE_RVALUE_REFERENCE_TYPE (type));
if (ntype)
{
}
TYPE_TARGET_TYPE (ntype) = type;
- TYPE_REFERENCE_TYPE (type) = ntype;
+ reftype = (refcode == TYPE_CODE_REF ? &TYPE_REFERENCE_TYPE (type)
+ : &TYPE_RVALUE_REFERENCE_TYPE (type));
+
+ *reftype = ntype;
/* FIXME! Assume the machine has only one representation for
references, and that it matches the (only) representation for
TYPE_LENGTH (ntype) =
gdbarch_ptr_bit (get_type_arch (type)) / TARGET_CHAR_BIT;
- TYPE_CODE (ntype) = TYPE_CODE_REF;
+ TYPE_CODE (ntype) = refcode;
- if (!TYPE_REFERENCE_TYPE (type)) /* Remember it, if don't have one. */
- TYPE_REFERENCE_TYPE (type) = ntype;
+ *reftype = ntype;
/* Update the length of all the other variants of this type. */
chain = TYPE_CHAIN (ntype);
details. */
struct type *
-lookup_reference_type (struct type *type)
+lookup_reference_type (struct type *type, enum type_code refcode)
+{
+ return make_reference_type (type, (struct type **) 0, refcode);
+}
+
+/* Lookup the lvalue reference type for the type TYPE. */
+
+struct type *
+lookup_lvalue_reference_type (struct type *type)
{
- return make_reference_type (type, (struct type **) 0);
+ return lookup_reference_type (type, TYPE_CODE_REF);
+}
+
+/* Lookup the rvalue reference type for the type TYPE. */
+
+struct type *
+lookup_rvalue_reference_type (struct type *type)
+{
+ return lookup_reference_type (type, TYPE_CODE_RVALUE_REF);
}
/* Lookup a function type that returns type TYPE. TYPEPTR, if
gdb_assert (nparams == 0);
TYPE_PROTOTYPED (fn) = 1;
}
+ else
+ TYPE_PROTOTYPED (fn) = 1;
}
TYPE_NFIELDS (fn) = nparams;
- TYPE_FIELDS (fn) = TYPE_ZALLOC (fn, nparams * sizeof (struct field));
+ TYPE_FIELDS (fn)
+ = (struct field *) TYPE_ZALLOC (fn, nparams * sizeof (struct field));
for (i = 0; i < nparams; ++i)
TYPE_FIELD_TYPE (fn, i) = param_types[i];
NULL);
}
+/* Make a '_Atomic'-qualified version of TYPE. */
+
+struct type *
+make_atomic_type (struct type *type)
+{
+ return make_qualified_type (type,
+ (TYPE_INSTANCE_FLAGS (type)
+ | TYPE_INSTANCE_FLAG_ATOMIC),
+ NULL);
+}
+
/* Replace the contents of ntype with the type *type. This changes the
contents, rather than the pointer for TYPE_MAIN_TYPE (ntype); thus
the changes are propogated to all types in the TYPE_CHAIN.
the assignment of one type's main type structure to the other
will produce a type with references to objects (names; field
lists; etc.) allocated on an objfile other than its own. */
- gdb_assert (TYPE_OBJFILE (ntype) == TYPE_OBJFILE (ntype));
+ gdb_assert (TYPE_OBJFILE (ntype) == TYPE_OBJFILE (type));
*TYPE_MAIN_TYPE (ntype) = *TYPE_MAIN_TYPE (type);
TYPE_LENGTH (mtype) = 1;
TYPE_STUB (mtype) = 1;
TYPE_TARGET_TYPE (mtype) = type;
- /* _DOMAIN_TYPE (mtype) = unknown yet */
+ /* TYPE_SELF_TYPE (mtype) = unknown yet */
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. */
int
get_discrete_bounds (struct type *type, LONGEST *lowp, LONGEST *highp)
{
- CHECK_TYPEDEF (type);
+ type = check_typedef (type);
switch (TYPE_CODE (type))
{
case TYPE_CODE_RANGE:
*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
return 1;
}
+/* Assuming that TYPE is a discrete type and VAL is a valid integer
+ representation of a value of this type, save the corresponding
+ position number in POS.
+
+ Its differs from VAL only in the case of enumeration types. In
+ this case, the position number of the value of the first listed
+ enumeration literal is zero; the position number of the value of
+ each subsequent enumeration literal is one more than that of its
+ predecessor in the list.
+
+ Return 1 if the operation was successful. Return zero otherwise,
+ in which case the value of POS is unmodified.
+*/
+
+int
+discrete_position (struct type *type, LONGEST val, LONGEST *pos)
+{
+ if (TYPE_CODE (type) == TYPE_CODE_ENUM)
+ {
+ int i;
+
+ for (i = 0; i < TYPE_NFIELDS (type); i += 1)
+ {
+ if (val == TYPE_FIELD_ENUMVAL (type, i))
+ {
+ *pos = i;
+ return 1;
+ }
+ }
+ /* Invalid enumeration value. */
+ return 0;
+ }
+ else
+ {
+ *pos = val;
+ return 1;
+ }
+}
+
/* Create an array type using either a blank type supplied in
RESULT_TYPE, or creating a new type, inheriting the objfile from
RANGE_TYPE.
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)))
{
LONGEST low_bound, high_bound;
if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
low_bound = high_bound = 0;
- CHECK_TYPEDEF (element_type);
+ element_type = check_typedef (element_type);
/* Be careful when setting the array length. Ada arrays can be
empty arrays with the high_bound being smaller than the low_bound.
In such cases, the array length should be zero. */
TYPE_FIELDS (result_type) =
(struct field *) TYPE_ZALLOC (result_type, sizeof (struct field));
TYPE_INDEX_TYPE (result_type) = range_type;
- TYPE_VPTR_FIELDNO (result_type) = -1;
- 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_FLAG_TARGET_STUB will take care of zero length arrays. */
+ /* TYPE_TARGET_STUB will take care of zero length arrays. */
if (TYPE_LENGTH (result_type) == 0)
TYPE_TARGET_STUB (result_type) = 1;
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);
}
TYPE_CODE (result_type) = TYPE_CODE_SET;
TYPE_NFIELDS (result_type) = 1;
- TYPE_FIELDS (result_type) = TYPE_ZALLOC (result_type, sizeof (struct field));
+ TYPE_FIELDS (result_type)
+ = (struct field *) TYPE_ZALLOC (result_type, sizeof (struct field));
if (!TYPE_STUB (domain_type))
{
return array_type;
}
-/* Smash TYPE to be a type of pointers to members of DOMAIN with type
+/* Internal routine called by TYPE_SELF_TYPE to return the type that TYPE
+ belongs to. In c++ this is the class of "this", but TYPE_THIS_TYPE is too
+ confusing. "self" is a common enough replacement for "this".
+ TYPE must be one of TYPE_CODE_METHODPTR, TYPE_CODE_MEMBERPTR, or
+ TYPE_CODE_METHOD. */
+
+struct type *
+internal_type_self_type (struct type *type)
+{
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_METHODPTR:
+ case TYPE_CODE_MEMBERPTR:
+ if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NONE)
+ return NULL;
+ gdb_assert (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_SELF_TYPE);
+ return TYPE_MAIN_TYPE (type)->type_specific.self_type;
+ case TYPE_CODE_METHOD:
+ if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NONE)
+ return NULL;
+ gdb_assert (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_FUNC);
+ return TYPE_MAIN_TYPE (type)->type_specific.func_stuff->self_type;
+ default:
+ gdb_assert_not_reached ("bad type");
+ }
+}
+
+/* Set the type of the class that TYPE belongs to.
+ In c++ this is the class of "this".
+ TYPE must be one of TYPE_CODE_METHODPTR, TYPE_CODE_MEMBERPTR, or
+ TYPE_CODE_METHOD. */
+
+void
+set_type_self_type (struct type *type, struct type *self_type)
+{
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_METHODPTR:
+ case TYPE_CODE_MEMBERPTR:
+ if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NONE)
+ TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_SELF_TYPE;
+ gdb_assert (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_SELF_TYPE);
+ TYPE_MAIN_TYPE (type)->type_specific.self_type = self_type;
+ break;
+ case TYPE_CODE_METHOD:
+ if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NONE)
+ INIT_FUNC_SPECIFIC (type);
+ gdb_assert (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_FUNC);
+ TYPE_MAIN_TYPE (type)->type_specific.func_stuff->self_type = self_type;
+ break;
+ default:
+ gdb_assert_not_reached ("bad type");
+ }
+}
+
+/* Smash TYPE to be a type of pointers to members of SELF_TYPE with type
TO_TYPE. A member pointer is a wierd thing -- it amounts to a
typed offset into a struct, e.g. "an int at offset 8". A MEMBER
TYPE doesn't include the offset (that's the value of the MEMBER
allocated. */
void
-smash_to_memberptr_type (struct type *type, struct type *domain,
+smash_to_memberptr_type (struct type *type, struct type *self_type,
struct type *to_type)
{
smash_type (type);
+ TYPE_CODE (type) = TYPE_CODE_MEMBERPTR;
TYPE_TARGET_TYPE (type) = to_type;
- TYPE_DOMAIN_TYPE (type) = domain;
+ set_type_self_type (type, self_type);
/* Assume that a data member pointer is the same size as a normal
pointer. */
TYPE_LENGTH (type)
= gdbarch_ptr_bit (get_type_arch (to_type)) / TARGET_CHAR_BIT;
- TYPE_CODE (type) = TYPE_CODE_MEMBERPTR;
}
/* Smash TYPE to be a type of pointer to methods type TO_TYPE.
smash_to_methodptr_type (struct type *type, struct type *to_type)
{
smash_type (type);
+ TYPE_CODE (type) = TYPE_CODE_METHODPTR;
TYPE_TARGET_TYPE (type) = to_type;
- TYPE_DOMAIN_TYPE (type) = TYPE_DOMAIN_TYPE (to_type);
+ set_type_self_type (type, TYPE_SELF_TYPE (to_type));
TYPE_LENGTH (type) = cplus_method_ptr_size (to_type);
- TYPE_CODE (type) = TYPE_CODE_METHODPTR;
}
-/* Smash TYPE to be a type of method of DOMAIN with type TO_TYPE.
+/* Smash TYPE to be a type of method of SELF_TYPE with type TO_TYPE.
METHOD just means `function that gets an extra "this" argument'.
When "smashing" the type, we preserve the objfile that the old type
allocated. */
void
-smash_to_method_type (struct type *type, struct type *domain,
+smash_to_method_type (struct type *type, struct type *self_type,
struct type *to_type, struct field *args,
int nargs, int varargs)
{
smash_type (type);
+ TYPE_CODE (type) = TYPE_CODE_METHOD;
TYPE_TARGET_TYPE (type) = to_type;
- TYPE_DOMAIN_TYPE (type) = domain;
+ set_type_self_type (type, self_type);
TYPE_FIELDS (type) = args;
TYPE_NFIELDS (type) = nargs;
if (varargs)
TYPE_VARARGS (type) = 1;
TYPE_LENGTH (type) = 1; /* In practice, this is never needed. */
- TYPE_CODE (type) = TYPE_CODE_METHOD;
}
-/* Return a typename for a struct/union/enum type without "struct ",
- "union ", or "enum ". If the type has a NULL name, return NULL. */
-
-const char *
-type_name_no_tag (const struct type *type)
-{
- if (TYPE_TAG_NAME (type) != NULL)
- return TYPE_TAG_NAME (type);
-
- /* Is there code which expects this to return the name if there is
- no tag name? My guess is that this is mainly used for C++ in
- cases where the two will always be the same. */
- return TYPE_NAME (type);
-}
-
-/* A wrapper of type_name_no_tag which calls error if the type is anonymous.
+/* A wrapper of TYPE_NAME which calls error if the type is anonymous.
Since GCC PR debug/47510 DWARF provides associated information to detect the
anonymous class linkage name from its typedef.
apply it itself. */
const char *
-type_name_no_tag_or_error (struct type *type)
+type_name_or_error (struct type *type)
{
struct type *saved_type = type;
const char *name;
struct objfile *objfile;
- CHECK_TYPEDEF (type);
+ type = check_typedef (type);
- name = type_name_no_tag (type);
+ name = TYPE_NAME (type);
if (name != NULL)
return name;
- name = type_name_no_tag (saved_type);
+ name = TYPE_NAME (saved_type);
objfile = TYPE_OBJFILE (saved_type);
error (_("Invalid anonymous type %s [in module %s], GCC PR debug/47510 bug?"),
name ? name : "<anonymous>",
const struct block *block, int noerr)
{
struct symbol *sym;
- struct type *type;
- sym = lookup_symbol (name, block, VAR_DOMAIN, 0);
+ sym = lookup_symbol_in_language (name, block, VAR_DOMAIN,
+ language->la_language, NULL).symbol;
if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
return SYMBOL_TYPE (sym);
- type = language_lookup_primitive_type_by_name (language, gdbarch, name);
- if (type)
- return type;
-
if (noerr)
return NULL;
error (_("No type named %s."), name);
lookup_unsigned_typename (const struct language_defn *language,
struct gdbarch *gdbarch, const char *name)
{
- char *uns = alloca (strlen (name) + 10);
+ char *uns = (char *) alloca (strlen (name) + 10);
strcpy (uns, "unsigned ");
strcpy (uns + 9, name);
struct gdbarch *gdbarch, const char *name)
{
struct type *t;
- char *uns = alloca (strlen (name) + 8);
+ char *uns = (char *) alloca (strlen (name) + 8);
strcpy (uns, "signed ");
strcpy (uns + 7, name);
{
struct symbol *sym;
- sym = lookup_symbol (name, block, STRUCT_DOMAIN, 0);
+ sym = lookup_symbol (name, block, STRUCT_DOMAIN, 0).symbol;
if (sym == NULL)
{
struct symbol *sym;
struct type *t;
- sym = lookup_symbol (name, block, STRUCT_DOMAIN, 0);
+ sym = lookup_symbol (name, block, STRUCT_DOMAIN, 0).symbol;
if (sym == NULL)
error (_("No union type named %s."), name);
{
struct symbol *sym;
- sym = lookup_symbol (name, block, STRUCT_DOMAIN, 0);
+ sym = lookup_symbol (name, block, STRUCT_DOMAIN, 0).symbol;
if (sym == NULL)
{
error (_("No enum type named %s."), name);
strcat (nam, TYPE_NAME (type));
strcat (nam, " >"); /* FIXME, extra space still introduced in gcc? */
- sym = lookup_symbol (nam, block, VAR_DOMAIN, 0);
+ sym = lookup_symbol (nam, block, VAR_DOMAIN, 0).symbol;
if (sym == NULL)
{
lookup_struct_elt_type (struct type *type, const char *name, int noerr)
{
int i;
- char *typename;
for (;;)
{
- CHECK_TYPEDEF (type);
+ type = check_typedef (type);
if (TYPE_CODE (type) != TYPE_CODE_PTR
&& TYPE_CODE (type) != TYPE_CODE_REF)
break;
if (TYPE_CODE (type) != TYPE_CODE_STRUCT
&& TYPE_CODE (type) != TYPE_CODE_UNION)
{
- typename = type_to_string (type);
- make_cleanup (xfree, typename);
- error (_("Type %s is not a structure or union type."), typename);
+ std::string type_name = type_to_string (type);
+ error (_("Type %s is not a structure or union type."),
+ type_name.c_str ());
}
#if 0
I.e. when doing "ptype bell->bar" for "struct foo { int bar; int
foo; } bell;" Disabled by fnf. */
{
- char *typename;
+ char *type_name;
- typename = type_name_no_tag (type);
- if (typename != NULL && strcmp (typename, name) == 0)
+ type_name = TYPE_NAME (type);
+ if (type_name != NULL && strcmp (type_name, name) == 0)
return type;
}
#endif
return NULL;
}
- typename = type_to_string (type);
- make_cleanup (xfree, typename);
- error (_("Type %s has no component named %s."), typename, name);
+ std::string type_name = type_to_string (type);
+ error (_("Type %s has no component named %s."), type_name.c_str (), name);
}
/* Store in *MAX the largest number representable by unsigned integer type
{
unsigned int n;
- CHECK_TYPEDEF (type);
+ type = check_typedef (type);
gdb_assert (TYPE_CODE (type) == TYPE_CODE_INT && TYPE_UNSIGNED (type));
gdb_assert (TYPE_LENGTH (type) <= sizeof (ULONGEST));
{
unsigned int n;
- CHECK_TYPEDEF (type);
+ type = check_typedef (type);
gdb_assert (TYPE_CODE (type) == TYPE_CODE_INT && !TYPE_UNSIGNED (type));
gdb_assert (TYPE_LENGTH (type) <= sizeof (LONGEST));
*max = ((ULONGEST) 1 << (n - 1)) - 1;
}
+/* Internal routine called by TYPE_VPTR_FIELDNO to return the value of
+ cplus_stuff.vptr_fieldno.
+
+ cplus_stuff is initialized to cplus_struct_default which does not
+ set vptr_fieldno to -1 for portability reasons (IWBN to use C99
+ designated initializers). We cope with that here. */
+
+int
+internal_type_vptr_fieldno (struct type *type)
+{
+ type = check_typedef (type);
+ gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT
+ || TYPE_CODE (type) == TYPE_CODE_UNION);
+ if (!HAVE_CPLUS_STRUCT (type))
+ return -1;
+ return TYPE_RAW_CPLUS_SPECIFIC (type)->vptr_fieldno;
+}
+
+/* Set the value of cplus_stuff.vptr_fieldno. */
+
+void
+set_type_vptr_fieldno (struct type *type, int fieldno)
+{
+ type = check_typedef (type);
+ gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT
+ || TYPE_CODE (type) == TYPE_CODE_UNION);
+ if (!HAVE_CPLUS_STRUCT (type))
+ ALLOCATE_CPLUS_STRUCT_TYPE (type);
+ TYPE_RAW_CPLUS_SPECIFIC (type)->vptr_fieldno = fieldno;
+}
+
+/* Internal routine called by TYPE_VPTR_BASETYPE to return the value of
+ cplus_stuff.vptr_basetype. */
+
+struct type *
+internal_type_vptr_basetype (struct type *type)
+{
+ type = check_typedef (type);
+ gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT
+ || TYPE_CODE (type) == TYPE_CODE_UNION);
+ gdb_assert (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_CPLUS_STUFF);
+ return TYPE_RAW_CPLUS_SPECIFIC (type)->vptr_basetype;
+}
+
+/* Set the value of cplus_stuff.vptr_basetype. */
+
+void
+set_type_vptr_basetype (struct type *type, struct type *basetype)
+{
+ type = check_typedef (type);
+ gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT
+ || TYPE_CODE (type) == TYPE_CODE_UNION);
+ if (!HAVE_CPLUS_STRUCT (type))
+ ALLOCATE_CPLUS_STRUCT_TYPE (type);
+ TYPE_RAW_CPLUS_SPECIFIC (type)->vptr_basetype = basetype;
+}
+
/* Lookup the vptr basetype/fieldno values for TYPE.
If found store vptr_basetype in *BASETYPEP if non-NULL, and return
vptr_fieldno. Also, if found and basetype is from the same objfile,
int
get_vptr_fieldno (struct type *type, struct type **basetypep)
{
- CHECK_TYPEDEF (type);
+ type = check_typedef (type);
if (TYPE_VPTR_FIELDNO (type) < 0)
{
it, it may have a different lifetime. PR 2384 */
if (TYPE_OBJFILE (type) == TYPE_OBJFILE (basetype))
{
- TYPE_VPTR_FIELDNO (type) = fieldno;
- TYPE_VPTR_BASETYPE (type) = basetype;
+ set_type_vptr_fieldno (type, fieldno);
+ set_type_vptr_basetype (type, basetype);
}
if (basetypep)
*basetypep = basetype;
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
+ 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. */
|| TYPE_DATA_LOCATION_KIND (type) == PROP_LOCLIST))
return 1;
+ if (TYPE_ASSOCIATED_PROP (type))
+ return 1;
+
+ if (TYPE_ALLOCATED_PROP (type))
+ return 1;
+
switch (TYPE_CODE (type))
{
case TYPE_CODE_RANGE:
- return !has_static_range (TYPE_RANGE_DATA (type));
+ {
+ /* A range type is obviously dynamic if it has at least one
+ dynamic bound. But also consider the range type to be
+ dynamic when its subtype is dynamic, even if the bounds
+ of the range type are static. It allows us to assume that
+ the subtype of a static range type is also static. */
+ return (!has_static_range (TYPE_RANGE_DATA (type))
+ || is_dynamic_type_internal (TYPE_TARGET_TYPE (type), 0));
+ }
case TYPE_CODE_ARRAY:
{
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:
return is_dynamic_type_internal (type, 1);
}
-static struct type *resolve_dynamic_type_internal (struct type *type,
- CORE_ADDR addr,
- int top_level);
+static struct type *resolve_dynamic_type_internal
+ (struct type *type, struct property_addr_info *addr_stack, int top_level);
-/* Given a dynamic range type (dyn_range_type) and address,
- return a static version of that type. */
+/* Given a dynamic range type (dyn_range_type) and a stack of
+ struct property_addr_info elements, return a static version
+ of that type. */
static struct type *
-resolve_dynamic_range (struct type *dyn_range_type, CORE_ADDR addr)
+resolve_dynamic_range (struct type *dyn_range_type,
+ struct property_addr_info *addr_stack)
{
CORE_ADDR value;
- struct type *static_range_type;
+ struct type *static_range_type, *static_target_type;
const struct dynamic_prop *prop;
- const struct dwarf2_locexpr_baton *baton;
struct dynamic_prop low_bound, high_bound;
gdb_assert (TYPE_CODE (dyn_range_type) == TYPE_CODE_RANGE);
prop = &TYPE_RANGE_DATA (dyn_range_type)->low;
- if (dwarf2_evaluate_property (prop, addr, &value))
+ if (dwarf2_evaluate_property (prop, NULL, addr_stack, &value))
{
low_bound.kind = PROP_CONST;
low_bound.data.const_val = value;
}
prop = &TYPE_RANGE_DATA (dyn_range_type)->high;
- if (dwarf2_evaluate_property (prop, addr, &value))
+ if (dwarf2_evaluate_property (prop, NULL, addr_stack, &value))
{
high_bound.kind = PROP_CONST;
high_bound.data.const_val = value;
high_bound.data.const_val = 0;
}
+ static_target_type
+ = resolve_dynamic_type_internal (TYPE_TARGET_TYPE (dyn_range_type),
+ addr_stack, 0);
static_range_type = create_range_type (copy_type (dyn_range_type),
- TYPE_TARGET_TYPE (dyn_range_type),
+ static_target_type,
&low_bound, &high_bound);
TYPE_RANGE_DATA (static_range_type)->flag_bound_evaluated = 1;
return static_range_type;
}
/* Resolves dynamic bound values of an array type TYPE to static ones.
- ADDRESS might be needed to resolve the subrange bounds, it is the location
- of the associated array. */
+ ADDR_STACK is a stack of struct property_addr_info to be used
+ if needed during the dynamic resolution. */
static struct type *
-resolve_dynamic_array (struct type *type, CORE_ADDR addr)
+resolve_dynamic_array (struct type *type,
+ struct property_addr_info *addr_stack)
{
CORE_ADDR value;
struct type *elt_type;
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);
+ type = copy_type (type);
+
elt_type = type;
range_type = check_typedef (TYPE_INDEX_TYPE (elt_type));
- range_type = resolve_dynamic_range (range_type, addr);
+ range_type = resolve_dynamic_range (range_type, addr_stack);
+
+ /* Resolve allocated/associated here before creating a new array type, which
+ will update the length of the array accordingly. */
+ prop = TYPE_ALLOCATED_PROP (type);
+ if (prop != NULL && dwarf2_evaluate_property (prop, NULL, addr_stack, &value))
+ {
+ TYPE_DYN_PROP_ADDR (prop) = value;
+ TYPE_DYN_PROP_KIND (prop) = PROP_CONST;
+ }
+ prop = TYPE_ASSOCIATED_PROP (type);
+ if (prop != NULL && dwarf2_evaluate_property (prop, NULL, addr_stack, &value))
+ {
+ TYPE_DYN_PROP_ADDR (prop) = value;
+ TYPE_DYN_PROP_KIND (prop) = PROP_CONST;
+ }
ary_dim = check_typedef (TYPE_TARGET_TYPE (elt_type));
if (ary_dim != NULL && TYPE_CODE (ary_dim) == TYPE_CODE_ARRAY)
- elt_type = resolve_dynamic_array (TYPE_TARGET_TYPE (type), addr);
+ elt_type = resolve_dynamic_array (ary_dim, addr_stack);
else
elt_type = TYPE_TARGET_TYPE (type);
- return create_array_type (copy_type (type),
- elt_type,
- range_type);
+ 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
- bounds. */
+ bounds. ADDR_STACK is a stack of struct property_addr_info
+ to be used if needed during the dynamic resolution. */
static struct type *
-resolve_dynamic_union (struct type *type, CORE_ADDR addr)
+resolve_dynamic_union (struct type *type,
+ struct property_addr_info *addr_stack)
{
struct type *resolved_type;
int i;
resolved_type = copy_type (type);
TYPE_FIELDS (resolved_type)
- = TYPE_ALLOC (resolved_type,
- TYPE_NFIELDS (resolved_type) * sizeof (struct field));
+ = (struct field *) TYPE_ALLOC (resolved_type,
+ TYPE_NFIELDS (resolved_type)
+ * sizeof (struct field));
memcpy (TYPE_FIELDS (resolved_type),
TYPE_FIELDS (type),
TYPE_NFIELDS (resolved_type) * sizeof (struct field));
continue;
t = resolve_dynamic_type_internal (TYPE_FIELD_TYPE (resolved_type, i),
- addr, 0);
+ addr_stack, 0);
TYPE_FIELD_TYPE (resolved_type, i) = t;
if (TYPE_LENGTH (t) > max_len)
max_len = TYPE_LENGTH (t);
}
/* Resolve dynamic bounds of members of the struct TYPE to static
- bounds. */
+ bounds. ADDR_STACK is a stack of struct property_addr_info to
+ be used if needed during the dynamic resolution. */
static struct type *
-resolve_dynamic_struct (struct type *type, CORE_ADDR addr)
+resolve_dynamic_struct (struct type *type,
+ struct property_addr_info *addr_stack)
{
struct type *resolved_type;
int i;
resolved_type = copy_type (type);
TYPE_FIELDS (resolved_type)
- = TYPE_ALLOC (resolved_type,
- TYPE_NFIELDS (resolved_type) * sizeof (struct field));
+ = (struct field *) TYPE_ALLOC (resolved_type,
+ TYPE_NFIELDS (resolved_type)
+ * sizeof (struct field));
memcpy (TYPE_FIELDS (resolved_type),
TYPE_FIELDS (type),
TYPE_NFIELDS (resolved_type) * sizeof (struct field));
for (i = 0; i < TYPE_NFIELDS (resolved_type); ++i)
{
unsigned new_bit_length;
+ struct property_addr_info pinfo;
if (field_is_static (&TYPE_FIELD (type, i)))
continue;
- TYPE_FIELD_TYPE (resolved_type, i)
- = resolve_dynamic_type_internal (TYPE_FIELD_TYPE (resolved_type, i),
- addr, 0);
-
/* As we know this field is not a static field, the field's
field_loc_kind should be FIELD_LOC_KIND_BITPOS. Verify
this is the case, but only trigger a simple error rather
that verification indicates a bug in our code, the error
is not severe enough to suggest to the user he stops
his debugging session because of it. */
- if (TYPE_FIELD_LOC_KIND (resolved_type, i) != FIELD_LOC_KIND_BITPOS)
+ if (TYPE_FIELD_LOC_KIND (type, i) != FIELD_LOC_KIND_BITPOS)
error (_("Cannot determine struct field location"
" (invalid location kind)"));
+
+ pinfo.type = check_typedef (TYPE_FIELD_TYPE (type, i));
+ pinfo.valaddr = addr_stack->valaddr;
+ pinfo.addr
+ = (addr_stack->addr
+ + (TYPE_FIELD_BITPOS (resolved_type, i) / TARGET_CHAR_BIT));
+ pinfo.next = addr_stack;
+
+ TYPE_FIELD_TYPE (resolved_type, i)
+ = resolve_dynamic_type_internal (TYPE_FIELD_TYPE (resolved_type, i),
+ &pinfo, 0);
+ gdb_assert (TYPE_FIELD_LOC_KIND (resolved_type, i)
+ == FIELD_LOC_KIND_BITPOS);
+
new_bit_length = TYPE_FIELD_BITPOS (resolved_type, i);
if (TYPE_FIELD_BITSIZE (resolved_type, i) != 0)
new_bit_length += TYPE_FIELD_BITSIZE (resolved_type, i);
resolved_type_bit_length = new_bit_length;
}
- TYPE_LENGTH (resolved_type)
- = (resolved_type_bit_length + TARGET_CHAR_BIT - 1) / TARGET_CHAR_BIT;
+ /* The length of a type won't change for fortran, but it does for C and Ada.
+ For fortran the size of dynamic fields might change over time but not the
+ type length of the structure. If we adapt it, we run into problems
+ when calculating the element offset for arrays of structs. */
+ if (current_language->la_language != language_fortran)
+ TYPE_LENGTH (resolved_type)
+ = (resolved_type_bit_length + TARGET_CHAR_BIT - 1) / TARGET_CHAR_BIT;
+
+ /* The Ada language uses this field as a cache for static fixed types: reset
+ it as RESOLVED_TYPE must have its own static fixed type. */
+ TYPE_TARGET_TYPE (resolved_type) = NULL;
return resolved_type;
}
/* Worker for resolved_dynamic_type. */
static struct type *
-resolve_dynamic_type_internal (struct type *type, CORE_ADDR addr,
+resolve_dynamic_type_internal (struct type *type,
+ struct property_addr_info *addr_stack,
int top_level)
{
struct type *real_type = check_typedef (type);
struct type *resolved_type = type;
- const struct dynamic_prop *prop;
+ struct dynamic_prop *prop;
CORE_ADDR value;
if (!is_dynamic_type_internal (real_type, top_level))
{
resolved_type = copy_type (type);
TYPE_TARGET_TYPE (resolved_type)
- = resolve_dynamic_type_internal (TYPE_TARGET_TYPE (type), addr,
+ = resolve_dynamic_type_internal (TYPE_TARGET_TYPE (type), addr_stack,
top_level);
}
else
{
case TYPE_CODE_REF:
{
- CORE_ADDR target_addr = read_memory_typed_address (addr, type);
+ struct property_addr_info pinfo;
+
+ pinfo.type = check_typedef (TYPE_TARGET_TYPE (type));
+ pinfo.valaddr = NULL;
+ if (addr_stack->valaddr != NULL)
+ pinfo.addr = extract_typed_address (addr_stack->valaddr, type);
+ else
+ pinfo.addr = read_memory_typed_address (addr_stack->addr, type);
+ pinfo.next = addr_stack;
resolved_type = copy_type (type);
TYPE_TARGET_TYPE (resolved_type)
= resolve_dynamic_type_internal (TYPE_TARGET_TYPE (type),
- target_addr, top_level);
+ &pinfo, top_level);
break;
}
case TYPE_CODE_ARRAY:
- resolved_type = resolve_dynamic_array (type, addr);
+ resolved_type = resolve_dynamic_array (type, addr_stack);
break;
case TYPE_CODE_RANGE:
- resolved_type = resolve_dynamic_range (type, addr);
+ resolved_type = resolve_dynamic_range (type, addr_stack);
break;
case TYPE_CODE_UNION:
- resolved_type = resolve_dynamic_union (type, addr);
+ resolved_type = resolve_dynamic_union (type, addr_stack);
break;
case TYPE_CODE_STRUCT:
- resolved_type = resolve_dynamic_struct (type, addr);
+ resolved_type = resolve_dynamic_struct (type, addr_stack);
break;
}
}
/* Resolve data_location attribute. */
prop = TYPE_DATA_LOCATION (resolved_type);
- if (dwarf2_evaluate_property (prop, addr, &value))
+ if (prop != NULL
+ && dwarf2_evaluate_property (prop, NULL, addr_stack, &value))
{
- TYPE_DATA_LOCATION_ADDR (resolved_type) = value;
- TYPE_DATA_LOCATION_KIND (resolved_type) = PROP_CONST;
+ TYPE_DYN_PROP_ADDR (prop) = value;
+ TYPE_DYN_PROP_KIND (prop) = PROP_CONST;
}
- else
- TYPE_DATA_LOCATION (resolved_type) = NULL;
return resolved_type;
}
/* See gdbtypes.h */
struct type *
-resolve_dynamic_type (struct type *type, CORE_ADDR addr)
+resolve_dynamic_type (struct type *type, const gdb_byte *valaddr,
+ CORE_ADDR addr)
+{
+ struct property_addr_info pinfo
+ = {check_typedef (type), valaddr, addr, NULL};
+
+ return resolve_dynamic_type_internal (type, &pinfo, 1);
+}
+
+/* See gdbtypes.h */
+
+struct dynamic_prop *
+get_dyn_prop (enum dynamic_prop_node_kind prop_kind, const struct type *type)
+{
+ struct dynamic_prop_list *node = TYPE_DYN_PROP_LIST (type);
+
+ while (node != NULL)
+ {
+ if (node->prop_kind == prop_kind)
+ return &node->prop;
+ node = node->next;
+ }
+ return NULL;
+}
+
+/* See gdbtypes.h */
+
+void
+add_dyn_prop (enum dynamic_prop_node_kind prop_kind, struct dynamic_prop prop,
+ struct type *type)
{
- return resolve_dynamic_type_internal (type, addr, 1);
+ struct dynamic_prop_list *temp;
+
+ gdb_assert (TYPE_OBJFILE_OWNED (type));
+
+ 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);
+
+ TYPE_DYN_PROP_LIST (type) = temp;
+}
+
+/* Remove dynamic property from TYPE in case it exists. */
+
+void
+remove_dyn_prop (enum dynamic_prop_node_kind prop_kind,
+ struct type *type)
+{
+ struct dynamic_prop_list *prev_node, *curr_node;
+
+ curr_node = TYPE_DYN_PROP_LIST (type);
+ prev_node = NULL;
+
+ while (NULL != curr_node)
+ {
+ if (curr_node->prop_kind == prop_kind)
+ {
+ /* Update the linked list but don't free anything.
+ The property was allocated on objstack and it is not known
+ if we are on top of it. Nevertheless, everything is released
+ when the complete objstack is freed. */
+ if (NULL == prev_node)
+ TYPE_DYN_PROP_LIST (type) = curr_node->next;
+ else
+ prev_node->next = curr_node->next;
+
+ return;
+ }
+
+ prev_node = curr_node;
+ curr_node = curr_node->next;
+ }
}
/* Find the real type of TYPE. This function returns the real type,
if (currently_reading_symtab)
return make_qualified_type (type, instance_flags, NULL);
- name = type_name_no_tag (type);
- /* FIXME: shouldn't we separately check the TYPE_NAME and
- the TYPE_TAG_NAME, and look in STRUCT_DOMAIN and/or
- VAR_DOMAIN as appropriate? (this code was written before
- TYPE_NAME and TYPE_TAG_NAME were separate). */
+ name = TYPE_NAME (type);
+ /* FIXME: shouldn't we look in STRUCT_DOMAIN and/or
+ VAR_DOMAIN as appropriate? */
if (name == NULL)
{
stub_noname_complaint ();
return make_qualified_type (type, instance_flags, NULL);
}
- sym = lookup_symbol (name, 0, STRUCT_DOMAIN, 0);
+ sym = lookup_symbol (name, 0, STRUCT_DOMAIN, 0).symbol;
if (sym)
TYPE_TARGET_TYPE (type) = SYMBOL_TYPE (sym);
else /* TYPE_CODE_UNDEF */
&& opaque_type_resolution
&& !currently_reading_symtab)
{
- const char *name = type_name_no_tag (type);
+ const char *name = TYPE_NAME (type);
struct type *newtype;
if (name == NULL)
types. */
else if (TYPE_STUB (type) && !currently_reading_symtab)
{
- const char *name = type_name_no_tag (type);
- /* FIXME: shouldn't we separately check the TYPE_NAME and the
- TYPE_TAG_NAME, and look in STRUCT_DOMAIN and/or VAR_DOMAIN
- as appropriate? (this code was written before TYPE_NAME and
- TYPE_TAG_NAME were separate). */
+ const char *name = TYPE_NAME (type);
+ /* FIXME: shouldn't we look in STRUCT_DOMAIN and/or VAR_DOMAIN
+ as appropriate? */
struct symbol *sym;
if (name == NULL)
stub_noname_complaint ();
return make_qualified_type (type, instance_flags, NULL);
}
- sym = lookup_symbol (name, 0, STRUCT_DOMAIN, 0);
+ sym = lookup_symbol (name, 0, STRUCT_DOMAIN, 0).symbol;
if (sym)
{
/* Same as above for opaque types, we can replace the stub
if (TYPE_TARGET_STUB (type))
{
- struct type *range_type;
struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type));
if (TYPE_STUB (target_type) || TYPE_TARGET_STUB (target_type))
{
struct ui_file *saved_gdb_stderr;
struct type *type = NULL; /* Initialize to keep gcc happy. */
- volatile struct gdb_exception except;
/* Suppress error messages. */
saved_gdb_stderr = gdb_stderr;
- gdb_stderr = ui_file_new ();
+ gdb_stderr = &null_stream;
/* Call parse_and_eval_type() without fear of longjmp()s. */
- TRY_CATCH (except, RETURN_MASK_ERROR)
+ TRY
{
type = parse_and_eval_type (p, length);
}
-
- if (except.reason < 0)
- type = builtin_type (gdbarch)->builtin_void;
+ CATCH (except, RETURN_MASK_ERROR)
+ {
+ type = builtin_type (gdbarch)->builtin_void;
+ }
+ END_CATCH
/* Stop suppressing error messages. */
- ui_file_delete (gdb_stderr);
gdb_stderr = saved_gdb_stderr;
return type;
}
/* If we read one argument and it was ``void'', don't count it. */
- if (strncmp (argtypetext, "(void)", 6) == 0)
+ if (startswith (argtypetext, "(void)"))
argcount -= 1;
/* We need one extra slot, for the THIS pointer. */
/* Now update the old "stub" type into a real type. */
mtype = TYPE_FN_FIELD_TYPE (f, signature_id);
- TYPE_DOMAIN_TYPE (mtype) = type;
- TYPE_FIELDS (mtype) = argtypes;
- TYPE_NFIELDS (mtype) = argcount;
+ /* MTYPE may currently be a function (TYPE_CODE_FUNC).
+ We want a method (TYPE_CODE_METHOD). */
+ smash_to_method_type (mtype, type, TYPE_TARGET_TYPE (mtype),
+ argtypes, argcount, p[-2] == '.');
TYPE_STUB (mtype) = 0;
TYPE_FN_FIELD_STUB (f, signature_id) = 0;
- if (p[-2] == '.')
- TYPE_VARARGS (mtype) = 1;
xfree (demangled_name);
}
Therefore the only thing we need to handle here are v2 operator
names. */
- if (found_stub && strncmp (TYPE_FN_FIELD_PHYSNAME (f, 0), "_Z", 2) != 0)
+ if (found_stub && !startswith (TYPE_FN_FIELD_PHYSNAME (f, 0), "_Z"))
{
int ret;
char dem_opname[256];
TYPE_RAW_CPLUS_SPECIFIC (type) = (struct cplus_struct_type *)
TYPE_ALLOC (type, sizeof (struct cplus_struct_type));
*(TYPE_RAW_CPLUS_SPECIFIC (type)) = cplus_struct_default;
+ set_type_vptr_fieldno (type, -1);
}
const struct gnat_aux_type gnat_aux_default =
*(TYPE_GNAT_SPECIFIC (type)) = gnat_aux_default;
}
-/* Helper function to initialize the standard scalar types.
+/* Helper function to initialize a newly allocated type. Set type code
+ to CODE and initialize the type-specific fields accordingly. */
+
+static void
+set_type_code (struct type *type, enum type_code code)
+{
+ TYPE_CODE (type) = code;
+
+ switch (code)
+ {
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ case TYPE_CODE_NAMESPACE:
+ INIT_CPLUS_SPECIFIC (type);
+ break;
+ case TYPE_CODE_FLT:
+ TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_FLOATFORMAT;
+ break;
+ case TYPE_CODE_FUNC:
+ INIT_FUNC_SPECIFIC (type);
+ break;
+ }
+}
+
+/* Helper function to verify floating-point format and size.
+ BIT is the type size in bits; if BIT equals -1, the size is
+ determined by the floatformat. Returns size to be used. */
+
+static int
+verify_floatformat (int bit, const struct floatformat *floatformat)
+{
+ gdb_assert (floatformat != NULL);
+
+ if (bit == -1)
+ bit = floatformat->totalsize;
+
+ 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.
+ Note that NAME is not copied; it is required to have a lifetime at
+ least as long as OBJFILE. */
+
+struct type *
+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);
+ 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 *
+init_integer_type (struct objfile *objfile,
+ int bit, int unsigned_p, const char *name)
+{
+ struct type *t;
+
+ t = init_type (objfile, TYPE_CODE_INT, bit, name);
+ if (unsigned_p)
+ TYPE_UNSIGNED (t) = 1;
+
+ return t;
+}
+
+/* Allocate a TYPE_CODE_CHAR 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 *
+init_character_type (struct objfile *objfile,
+ int bit, int unsigned_p, const char *name)
+{
+ struct type *t;
+
+ t = init_type (objfile, TYPE_CODE_CHAR, bit, name);
+ if (unsigned_p)
+ TYPE_UNSIGNED (t) = 1;
+
+ return t;
+}
+
+/* Allocate a TYPE_CODE_BOOL 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 *
+init_boolean_type (struct objfile *objfile,
+ int bit, int unsigned_p, const char *name)
+{
+ struct type *t;
+
+ t = init_type (objfile, TYPE_CODE_BOOL, bit, name);
+ if (unsigned_p)
+ TYPE_UNSIGNED (t) = 1;
+
+ return t;
+}
+
+/* Allocate a TYPE_CODE_FLT type structure associated with OBJFILE.
+ BIT is the type size in bits; if BIT equals -1, the size is
+ determined by the floatformat. NAME is the type name. Set the
+ TYPE_FLOATFORMAT from FLOATFORMATS. */
+
+struct type *
+init_float_type (struct objfile *objfile,
+ 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, fmt);
+ t = init_type (objfile, TYPE_CODE_FLT, bit, name);
+ TYPE_FLOATFORMAT (t) = fmt;
+
+ return t;
+}
+
+/* Allocate a TYPE_CODE_DECFLOAT type structure associated with OBJFILE.
+ BIT is the type size in bits. NAME is the type name. */
+
+struct type *
+init_decfloat_type (struct objfile *objfile, int bit, const char *name)
+{
+ struct type *t;
+
+ t = init_type (objfile, TYPE_CODE_DECFLOAT, bit, name);
+ return t;
+}
+
+/* Allocate a TYPE_CODE_COMPLEX type structure associated with OBJFILE.
+ NAME is the type name. TARGET_TYPE is the component float type. */
+
+struct type *
+init_complex_type (struct objfile *objfile,
+ const char *name, struct type *target_type)
+{
+ struct type *t;
+
+ t = init_type (objfile, TYPE_CODE_COMPLEX,
+ 2 * TYPE_LENGTH (target_type) * TARGET_CHAR_BIT, name);
+ TYPE_TARGET_TYPE (t) = target_type;
+ return t;
+}
+
+/* Allocate a TYPE_CODE_PTR type structure associated with OBJFILE.
+ BIT is the pointer type size in bits. NAME is the type name.
+ TARGET_TYPE is the pointer target type. Always sets the pointer type's
+ TYPE_UNSIGNED flag. */
+
+struct type *
+init_pointer_type (struct objfile *objfile,
+ int bit, const char *name, struct type *target_type)
+{
+ struct type *t;
+
+ 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;
- If NAME is non-NULL, then it is used to initialize the type name.
- Note that NAME is not copied; it is required to have a lifetime at
- least as long as OBJFILE. */
+ case TYPE_CODE_METHODPTR:
+ case TYPE_CODE_MEMBERPTR:
+ align = type_length_units (type);
+ break;
-struct type *
-init_type (enum type_code code, int length, int flags,
- const char *name, struct objfile *objfile)
-{
- struct type *type;
+ case TYPE_CODE_VOID:
+ align = 1;
+ break;
- type = alloc_type (objfile);
- TYPE_CODE (type) = code;
- TYPE_LENGTH (type) = length;
-
- gdb_assert (!(flags & (TYPE_FLAG_MIN - 1)));
- if (flags & TYPE_FLAG_UNSIGNED)
- TYPE_UNSIGNED (type) = 1;
- if (flags & TYPE_FLAG_NOSIGN)
- TYPE_NOSIGN (type) = 1;
- if (flags & TYPE_FLAG_STUB)
- TYPE_STUB (type) = 1;
- if (flags & TYPE_FLAG_TARGET_STUB)
- TYPE_TARGET_STUB (type) = 1;
- if (flags & TYPE_FLAG_STATIC)
- TYPE_STATIC (type) = 1;
- if (flags & TYPE_FLAG_PROTOTYPED)
- TYPE_PROTOTYPED (type) = 1;
- if (flags & TYPE_FLAG_INCOMPLETE)
- TYPE_INCOMPLETE (type) = 1;
- if (flags & TYPE_FLAG_VARARGS)
- TYPE_VARARGS (type) = 1;
- if (flags & TYPE_FLAG_VECTOR)
- TYPE_VECTOR (type) = 1;
- if (flags & TYPE_FLAG_STUB_SUPPORTED)
- TYPE_STUB_SUPPORTED (type) = 1;
- if (flags & TYPE_FLAG_FIXED_INSTANCE)
- TYPE_FIXED_INSTANCE (type) = 1;
- if (flags & TYPE_FLAG_GNU_IFUNC)
- TYPE_GNU_IFUNC (type) = 1;
+ case TYPE_CODE_ERROR:
+ case TYPE_CODE_METHOD:
+ default:
+ break;
+ }
- TYPE_NAME (type) = name;
+ if ((align & (align - 1)) != 0)
+ {
+ /* Not a power of 2, so pass. */
+ align = 0;
+ }
- /* C++ fancies. */
+ return align;
+}
- if (name && strcmp (name, "char") == 0)
- TYPE_NOSIGN (type) = 1;
+/* See gdbtypes.h. */
- switch (code)
+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)
{
- case TYPE_CODE_STRUCT:
- case TYPE_CODE_UNION:
- case TYPE_CODE_NAMESPACE:
- INIT_CPLUS_SPECIFIC (type);
- break;
- case TYPE_CODE_FLT:
- TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_FLOATFORMAT;
- break;
- case TYPE_CODE_FUNC:
- INIT_FUNC_SPECIFIC (type);
- break;
+ ++result;
+ align >>= 1;
}
- return type;
+
+ if (result >= (1 << TYPE_ALIGN_BITS))
+ return false;
+
+ type->align_log2 = result;
+ return true;
}
+
\f
/* Queries on types. */
{
/* FIXME: Should we return true for references as well as
pointers? */
- CHECK_TYPEDEF (t);
+ t = check_typedef (t);
return
(t != NULL
&& TYPE_CODE (t) == TYPE_CODE_PTR
int
is_integral_type (struct type *t)
{
- CHECK_TYPEDEF (t);
+ t = check_typedef (t);
return
((t != NULL)
&& ((TYPE_CODE (t) == TYPE_CODE_INT)
|| (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. */
-static int
+int
is_scalar_type (struct type *type)
{
- CHECK_TYPEDEF (type);
+ type = check_typedef (type);
switch (TYPE_CODE (type))
{
int
is_scalar_type_recursive (struct type *t)
{
- CHECK_TYPEDEF (t);
+ t = check_typedef (t);
if (is_scalar_type (t))
return 1;
distance_to_ancestor (A, D, 1) = -1. */
static int
-distance_to_ancestor (struct type *base, struct type *dclass, int public)
+distance_to_ancestor (struct type *base, struct type *dclass, int is_public)
{
int i;
int d;
- CHECK_TYPEDEF (base);
- CHECK_TYPEDEF (dclass);
+ base = check_typedef (base);
+ dclass = check_typedef (dclass);
if (class_types_same_p (base, dclass))
return 0;
for (i = 0; i < TYPE_N_BASECLASSES (dclass); i++)
{
- if (public && ! BASETYPE_VIA_PUBLIC (dclass, i))
+ if (is_public && ! BASETYPE_VIA_PUBLIC (dclass, i))
continue;
- d = distance_to_ancestor (base, TYPE_BASECLASS (dclass, i), public);
+ d = distance_to_ancestor (base, TYPE_BASECLASS (dclass, i), is_public);
if (d >= 0)
return 1 + d;
}
{
int i, count = 0;
- CHECK_TYPEDEF (base);
- CHECK_TYPEDEF (dclass);
+ base = check_typedef (base);
+ dclass = check_typedef (dclass);
for (i = 0; i < TYPE_N_BASECLASSES (dclass) && count < 2; ++i)
{
struct value **args, int nargs)
{
int i;
- struct badness_vector *bv;
+ struct badness_vector *bv = XNEW (struct badness_vector);
int min_len = nparms < nargs ? nparms : nargs;
- bv = xmalloc (sizeof (struct badness_vector));
bv->length = nargs + 1; /* add 1 for the length-match rank. */
bv->rank = XNEWVEC (struct rank, nargs + 1);
return 1;
}
-/* Compares type A to type B returns 1 if the represent the same type
- 0 otherwise. */
+/* Compares type A to type B. Returns true if they represent the same
+ type, false otherwise. */
-int
+bool
types_equal (struct type *a, struct type *b)
{
/* Identical type pointers. */
and a. The reason is that builtin types are different from
the same ones constructed from the object. */
if (a == b)
- return 1;
+ return true;
/* Resolve typedefs */
if (TYPE_CODE (a) == TYPE_CODE_TYPEDEF)
/* If after resolving typedefs a and b are not of the same type
code then they are not equal. */
if (TYPE_CODE (a) != TYPE_CODE (b))
- return 0;
+ return false;
/* If a and b are both pointers types or both reference types then
they are equal of the same type iff the objects they refer to are
if (TYPE_NAME (a) && TYPE_NAME (b)
&& strcmp (TYPE_NAME (a), TYPE_NAME (b)) == 0)
- return 1;
+ return true;
/* Check if identical after resolving typedefs. */
if (a == b)
- return 1;
+ return true;
/* Two function types are equal if their argument and return types
are equal. */
int i;
if (TYPE_NFIELDS (a) != TYPE_NFIELDS (b))
- return 0;
+ return false;
if (!types_equal (TYPE_TARGET_TYPE (a), TYPE_TARGET_TYPE (b)))
- return 0;
+ return false;
for (i = 0; i < TYPE_NFIELDS (a); ++i)
if (!types_equal (TYPE_FIELD_TYPE (a, i), TYPE_FIELD_TYPE (b, i)))
- return 0;
+ return false;
- return 1;
+ return true;
}
- return 0;
+ return false;
}
\f
/* Deep comparison of types. */
/* An entry in the type-equality bcache. */
-typedef struct type_equality_entry
+struct type_equality_entry
{
- struct type *type1, *type2;
-} type_equality_entry_d;
+ type_equality_entry (struct type *t1, struct type *t2)
+ : type1 (t1),
+ type2 (t2)
+ {
+ }
-DEF_VEC_O (type_equality_entry_d);
+ struct type *type1, *type2;
+};
-/* A helper function to compare two strings. Returns 1 if they are
- the same, 0 otherwise. Handles NULLs properly. */
+/* A helper function to compare two strings. Returns true if they are
+ the same, false otherwise. Handles NULLs properly. */
-static int
+static bool
compare_maybe_null_strings (const char *s, const char *t)
{
- if (s == NULL && t != NULL)
- return 0;
- else if (s != NULL && t == NULL)
- return 0;
- else if (s == NULL && t== NULL)
- return 1;
+ if (s == NULL || t == NULL)
+ return s == t;
return strcmp (s, t) == 0;
}
/* A helper function for check_types_worklist that checks two types for
- "deep" equality. Returns non-zero if the types are considered the
- same, zero otherwise. */
+ "deep" equality. Returns true if the types are considered the
+ same, false otherwise. */
-static int
+static bool
check_types_equal (struct type *type1, struct type *type2,
- VEC (type_equality_entry_d) **worklist)
+ std::vector<type_equality_entry> *worklist)
{
- CHECK_TYPEDEF (type1);
- CHECK_TYPEDEF (type2);
+ type1 = check_typedef (type1);
+ type2 = check_typedef (type2);
if (type1 == type2)
- return 1;
+ return true;
if (TYPE_CODE (type1) != TYPE_CODE (type2)
|| TYPE_LENGTH (type1) != TYPE_LENGTH (type2)
|| TYPE_NOTTEXT (type1) != TYPE_NOTTEXT (type2)
|| TYPE_INSTANCE_FLAGS (type1) != TYPE_INSTANCE_FLAGS (type2)
|| TYPE_NFIELDS (type1) != TYPE_NFIELDS (type2))
- return 0;
+ return false;
- if (!compare_maybe_null_strings (TYPE_TAG_NAME (type1),
- TYPE_TAG_NAME (type2)))
- return 0;
if (!compare_maybe_null_strings (TYPE_NAME (type1), TYPE_NAME (type2)))
- return 0;
+ return false;
+ if (!compare_maybe_null_strings (TYPE_NAME (type1), TYPE_NAME (type2)))
+ return false;
if (TYPE_CODE (type1) == TYPE_CODE_RANGE)
{
- if (memcmp (TYPE_RANGE_DATA (type1), TYPE_RANGE_DATA (type2),
- sizeof (*TYPE_RANGE_DATA (type1))) != 0)
- return 0;
+ if (*TYPE_RANGE_DATA (type1) != *TYPE_RANGE_DATA (type2))
+ return false;
}
else
{
{
const struct field *field1 = &TYPE_FIELD (type1, i);
const struct field *field2 = &TYPE_FIELD (type2, i);
- struct type_equality_entry entry;
if (FIELD_ARTIFICIAL (*field1) != FIELD_ARTIFICIAL (*field2)
|| FIELD_BITSIZE (*field1) != FIELD_BITSIZE (*field2)
|| FIELD_LOC_KIND (*field1) != FIELD_LOC_KIND (*field2))
- return 0;
+ return false;
if (!compare_maybe_null_strings (FIELD_NAME (*field1),
FIELD_NAME (*field2)))
- return 0;
+ return false;
switch (FIELD_LOC_KIND (*field1))
{
case FIELD_LOC_KIND_BITPOS:
if (FIELD_BITPOS (*field1) != FIELD_BITPOS (*field2))
- return 0;
+ return false;
break;
case FIELD_LOC_KIND_ENUMVAL:
if (FIELD_ENUMVAL (*field1) != FIELD_ENUMVAL (*field2))
- return 0;
+ return false;
break;
case FIELD_LOC_KIND_PHYSADDR:
if (FIELD_STATIC_PHYSADDR (*field1)
!= FIELD_STATIC_PHYSADDR (*field2))
- return 0;
+ return false;
break;
case FIELD_LOC_KIND_PHYSNAME:
if (!compare_maybe_null_strings (FIELD_STATIC_PHYSNAME (*field1),
FIELD_STATIC_PHYSNAME (*field2)))
- return 0;
+ return false;
break;
case FIELD_LOC_KIND_DWARF_BLOCK:
{
if (block1->per_cu != block2->per_cu
|| block1->size != block2->size
|| memcmp (block1->data, block2->data, block1->size) != 0)
- return 0;
+ return false;
}
break;
default:
FIELD_LOC_KIND (*field1));
}
- entry.type1 = FIELD_TYPE (*field1);
- entry.type2 = FIELD_TYPE (*field2);
- VEC_safe_push (type_equality_entry_d, *worklist, &entry);
+ worklist->emplace_back (FIELD_TYPE (*field1), FIELD_TYPE (*field2));
}
}
if (TYPE_TARGET_TYPE (type1) != NULL)
{
- struct type_equality_entry entry;
-
if (TYPE_TARGET_TYPE (type2) == NULL)
- return 0;
+ return false;
- entry.type1 = TYPE_TARGET_TYPE (type1);
- entry.type2 = TYPE_TARGET_TYPE (type2);
- VEC_safe_push (type_equality_entry_d, *worklist, &entry);
+ worklist->emplace_back (TYPE_TARGET_TYPE (type1),
+ TYPE_TARGET_TYPE (type2));
}
else if (TYPE_TARGET_TYPE (type2) != NULL)
- return 0;
+ return false;
- return 1;
+ return true;
}
-/* Check types on a worklist for equality. Returns zero if any pair
- is not equal, non-zero if they are all considered equal. */
+/* Check types on a worklist for equality. Returns false if any pair
+ is not equal, true if they are all considered equal. */
-static int
-check_types_worklist (VEC (type_equality_entry_d) **worklist,
+static bool
+check_types_worklist (std::vector<type_equality_entry> *worklist,
struct bcache *cache)
{
- while (!VEC_empty (type_equality_entry_d, *worklist))
+ while (!worklist->empty ())
{
- struct type_equality_entry entry;
int added;
- entry = *VEC_last (type_equality_entry_d, *worklist);
- VEC_pop (type_equality_entry_d, *worklist);
+ struct type_equality_entry entry = std::move (worklist->back ());
+ worklist->pop_back ();
/* If the type pair has already been visited, we know it is
ok. */
if (!added)
continue;
- if (check_types_equal (entry.type1, entry.type2, worklist) == 0)
- return 0;
+ if (!check_types_equal (entry.type1, entry.type2, worklist))
+ return false;
}
- return 1;
+ return true;
}
-/* Return non-zero if types TYPE1 and TYPE2 are equal, as determined by a
- "deep comparison". Otherwise return zero. */
+/* Return true if types TYPE1 and TYPE2 are equal, as determined by a
+ "deep comparison". Otherwise return false. */
-int
+bool
types_deeply_equal (struct type *type1, struct type *type2)
{
- volatile struct gdb_exception except;
- int result = 0;
+ struct gdb_exception except = exception_none;
+ bool result = false;
struct bcache *cache;
- VEC (type_equality_entry_d) *worklist = NULL;
- struct type_equality_entry entry;
+ std::vector<type_equality_entry> worklist;
gdb_assert (type1 != NULL && type2 != NULL);
/* Early exit for the simple case. */
if (type1 == type2)
- return 1;
+ return true;
cache = bcache_xmalloc (NULL, NULL);
- entry.type1 = type1;
- entry.type2 = type2;
- VEC_safe_push (type_equality_entry_d, worklist, &entry);
+ worklist.emplace_back (type1, type2);
- TRY_CATCH (except, RETURN_MASK_ALL)
+ /* check_types_worklist calls several nested helper functions, some
+ of which can raise a GDB exception, so we just check and rethrow
+ here. If there is a GDB exception, a comparison is not capable
+ (or trusted), so exit. */
+ TRY
{
result = check_types_worklist (&worklist, cache);
}
- /* check_types_worklist calls several nested helper functions,
- some of which can raise a GDB Exception, so we just check
- and rethrow here. If there is a GDB exception, a comparison
- is not capable (or trusted), so exit. */
+ CATCH (ex, RETURN_MASK_ALL)
+ {
+ except = ex;
+ }
+ END_CATCH
+
bcache_xfree (cache);
- VEC_free (type_equality_entry_d, worklist);
+
/* Rethrow if there was a problem. */
if (except.reason < 0)
throw_exception (except);
return result;
}
+
+/* Allocated status of type TYPE. Return zero if type TYPE is allocated.
+ Otherwise return one. */
+
+int
+type_not_allocated (const struct type *type)
+{
+ struct dynamic_prop *prop = TYPE_ALLOCATED_PROP (type);
+
+ return (prop && TYPE_DYN_PROP_KIND (prop) == PROP_CONST
+ && !TYPE_DYN_PROP_ADDR (prop));
+}
+
+/* Associated status of type TYPE. Return zero if type TYPE is associated.
+ Otherwise return one. */
+
+int
+type_not_associated (const struct type *type)
+{
+ struct dynamic_prop *prop = TYPE_ASSOCIATED_PROP (type);
+
+ return (prop && TYPE_DYN_PROP_KIND (prop) == PROP_CONST
+ && !TYPE_DYN_PROP_ADDR (prop));
+}
\f
/* Compare one type (PARM) for compatibility with another (ARG).
* PARM is intended to be the parameter type of a function; and
{
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. */
- if (TYPE_CODE (arg) == TYPE_CODE_REF)
+
+ if (TYPE_IS_REFERENCE (arg))
return (sum_ranks (rank_one_type (parm, TYPE_TARGET_TYPE (arg), NULL),
REFERENCE_CONVERSION_BADNESS));
- if (TYPE_CODE (parm) == TYPE_CODE_REF)
+ if (TYPE_IS_REFERENCE (parm))
return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL),
REFERENCE_CONVERSION_BADNESS));
if (overload_debug)
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;
}
static void
print_cplus_stuff (struct type *type, int spaces)
{
+ printfi_filtered (spaces, "vptr_fieldno %d\n", TYPE_VPTR_FIELDNO (type));
+ printfi_filtered (spaces, "vptr_basetype ");
+ gdb_print_host_address (TYPE_VPTR_BASETYPE (type), gdb_stdout);
+ puts_filtered ("\n");
+ if (TYPE_VPTR_BASETYPE (type) != NULL)
+ recursive_dump_type (TYPE_VPTR_BASETYPE (type), spaces + 2);
+
printfi_filtered (spaces, "n_baseclasses %d\n",
TYPE_N_BASECLASSES (type));
printfi_filtered (spaces, "nfn_fields %d\n",
{
struct type *descriptive_type = TYPE_DESCRIPTIVE_TYPE (type);
- recursive_dump_type (descriptive_type, spaces + 2);
+ if (descriptive_type == NULL)
+ printfi_filtered (spaces + 2, "no descriptive type\n");
+ else
+ {
+ printfi_filtered (spaces + 2, "descriptive type\n");
+ recursive_dump_type (descriptive_type, spaces + 4);
+ }
}
static struct obstack dont_print_type_obstack;
TYPE_NAME (type) ? TYPE_NAME (type) : "<NULL>");
gdb_print_host_address (TYPE_NAME (type), gdb_stdout);
printf_filtered (")\n");
- printfi_filtered (spaces, "tagname '%s' (",
- TYPE_TAG_NAME (type) ? TYPE_TAG_NAME (type) : "<NULL>");
- gdb_print_host_address (TYPE_TAG_NAME (type), gdb_stdout);
- printf_filtered (")\n");
printfi_filtered (spaces, "code 0x%x ", TYPE_CODE (type));
switch (TYPE_CODE (type))
{
TYPE_INSTANCE_FLAGS (type));
if (TYPE_CONST (type))
{
- puts_filtered (" TYPE_FLAG_CONST");
+ puts_filtered (" TYPE_CONST");
}
if (TYPE_VOLATILE (type))
{
- puts_filtered (" TYPE_FLAG_VOLATILE");
+ puts_filtered (" TYPE_VOLATILE");
}
if (TYPE_CODE_SPACE (type))
{
- puts_filtered (" TYPE_FLAG_CODE_SPACE");
+ puts_filtered (" TYPE_CODE_SPACE");
}
if (TYPE_DATA_SPACE (type))
{
- puts_filtered (" TYPE_FLAG_DATA_SPACE");
+ puts_filtered (" TYPE_DATA_SPACE");
}
if (TYPE_ADDRESS_CLASS_1 (type))
{
- puts_filtered (" TYPE_FLAG_ADDRESS_CLASS_1");
+ puts_filtered (" TYPE_ADDRESS_CLASS_1");
}
if (TYPE_ADDRESS_CLASS_2 (type))
{
- puts_filtered (" TYPE_FLAG_ADDRESS_CLASS_2");
+ puts_filtered (" TYPE_ADDRESS_CLASS_2");
}
if (TYPE_RESTRICT (type))
{
- puts_filtered (" TYPE_FLAG_RESTRICT");
+ puts_filtered (" TYPE_RESTRICT");
+ }
+ if (TYPE_ATOMIC (type))
+ {
+ puts_filtered (" TYPE_ATOMIC");
}
puts_filtered ("\n");
printfi_filtered (spaces, "flags");
if (TYPE_UNSIGNED (type))
{
- puts_filtered (" TYPE_FLAG_UNSIGNED");
+ puts_filtered (" TYPE_UNSIGNED");
}
if (TYPE_NOSIGN (type))
{
- puts_filtered (" TYPE_FLAG_NOSIGN");
+ puts_filtered (" TYPE_NOSIGN");
}
if (TYPE_STUB (type))
{
- puts_filtered (" TYPE_FLAG_STUB");
+ puts_filtered (" TYPE_STUB");
}
if (TYPE_TARGET_STUB (type))
{
- puts_filtered (" TYPE_FLAG_TARGET_STUB");
- }
- if (TYPE_STATIC (type))
- {
- puts_filtered (" TYPE_FLAG_STATIC");
+ puts_filtered (" TYPE_TARGET_STUB");
}
if (TYPE_PROTOTYPED (type))
{
- puts_filtered (" TYPE_FLAG_PROTOTYPED");
+ puts_filtered (" TYPE_PROTOTYPED");
}
if (TYPE_INCOMPLETE (type))
{
- puts_filtered (" TYPE_FLAG_INCOMPLETE");
+ puts_filtered (" TYPE_INCOMPLETE");
}
if (TYPE_VARARGS (type))
{
- puts_filtered (" TYPE_FLAG_VARARGS");
+ puts_filtered (" TYPE_VARARGS");
}
/* This is used for things like AltiVec registers on ppc. Gcc emits
an attribute for the array type, which tells whether or not we
have a vector, instead of a regular array. */
if (TYPE_VECTOR (type))
{
- puts_filtered (" TYPE_FLAG_VECTOR");
+ puts_filtered (" TYPE_VECTOR");
}
if (TYPE_FIXED_INSTANCE (type))
{
idx, plongest (TYPE_FIELD_ENUMVAL (type, idx)));
else
printfi_filtered (spaces + 2,
- "[%d] bitpos %d bitsize %d type ",
- idx, TYPE_FIELD_BITPOS (type, idx),
+ "[%d] bitpos %s bitsize %d type ",
+ idx, plongest (TYPE_FIELD_BITPOS (type, idx)),
TYPE_FIELD_BITSIZE (type, idx));
gdb_print_host_address (TYPE_FIELD_TYPE (type, idx), gdb_stdout);
printf_filtered (" name '%s' (",
TYPE_HIGH_BOUND_UNDEFINED (type)
? " (undefined)" : "");
}
- printfi_filtered (spaces, "vptr_basetype ");
- gdb_print_host_address (TYPE_VPTR_BASETYPE (type), gdb_stdout);
- puts_filtered ("\n");
- if (TYPE_VPTR_BASETYPE (type) != NULL)
- {
- recursive_dump_type (TYPE_VPTR_BASETYPE (type), spaces + 2);
- }
- printfi_filtered (spaces, "vptr_fieldno %d\n",
- TYPE_VPTR_FIELDNO (type));
switch (TYPE_SPECIFIC_FIELD (type))
{
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;
TYPE_CALLING_CONVENTION (type));
/* tail_call_list is not printed. */
break;
+
+ case TYPE_SPECIFIC_SELF_TYPE:
+ printfi_filtered (spaces, "self_type ");
+ gdb_print_host_address (TYPE_SELF_TYPE (type), gdb_stdout);
+ puts_filtered ("\n");
+ break;
}
if (spaces == 0)
/* 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, *new;
+ type_pair (struct type *old_, struct type *newobj_)
+ : old (old_), newobj (newobj_)
+ {}
+
+ struct type * const old, * const newobj;
};
static hashval_t
type_pair_hash (const void *item)
{
- const struct type_pair *pair = item;
+ const struct type_pair *pair = (const struct type_pair *) item;
return htab_hash_pointer (pair->old);
}
static int
type_pair_eq (const void *item_lhs, const void *item_rhs)
{
- const struct type_pair *lhs = item_lhs, *rhs = item_rhs;
+ const struct type_pair *lhs = (const struct type_pair *) item_lhs;
+ const struct type_pair *rhs = (const struct type_pair *) item_rhs;
return lhs->old == rhs->old;
}
dummy_obstack_deallocate);
}
+/* Recursively copy (deep copy) a dynamic attribute list of a type. */
+
+static struct dynamic_prop_list *
+copy_dynamic_prop_list (struct obstack *objfile_obstack,
+ struct dynamic_prop_list *list)
+{
+ struct dynamic_prop_list *copy = list;
+ struct dynamic_prop_list **node_ptr = ©
+
+ while (*node_ptr != NULL)
+ {
+ struct dynamic_prop_list *node_copy;
+
+ node_copy = ((struct dynamic_prop_list *)
+ obstack_copy (objfile_obstack, *node_ptr,
+ sizeof (struct dynamic_prop_list)));
+ node_copy->prop = (*node_ptr)->prop;
+ *node_ptr = node_copy;
+
+ node_ptr = &node_copy->next;
+ }
+
+ return copy;
+}
+
/* Recursively copy (deep copy) TYPE, if it is associated with
- OBJFILE. Return a new type allocated using malloc, a saved type if
- we have already visited TYPE (using COPIED_TYPES), or TYPE if it is
- not associated with OBJFILE. */
+ OBJFILE. Return a new type owned by the gdbarch associated with the type, a
+ saved type if we have already visited TYPE (using COPIED_TYPES), or TYPE if
+ it is not associated with OBJFILE. */
struct type *
copy_type_recursive (struct objfile *objfile,
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)->new;
+ return ((struct type_pair *) *slot)->newobj;
new_type = alloc_type_arch (get_type_arch (type));
/* We must add the new type to the hash table immediately, in case
we encounter this type again during a recursive call below. */
- stored
- = obstack_alloc (&objfile->objfile_obstack, sizeof (struct type_pair));
- stored->old = type;
- stored->new = 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
if (TYPE_NAME (type))
TYPE_NAME (new_type) = xstrdup (TYPE_NAME (type));
- if (TYPE_TAG_NAME (type))
- TYPE_TAG_NAME (new_type) = xstrdup (TYPE_TAG_NAME (type));
TYPE_INSTANCE_FLAGS (new_type) = TYPE_INSTANCE_FLAGS (type);
TYPE_LENGTH (new_type) = TYPE_LENGTH (type);
/* For range types, copy the bounds information. */
if (TYPE_CODE (type) == TYPE_CODE_RANGE)
{
- TYPE_RANGE_DATA (new_type) = xmalloc (sizeof (struct range_bounds));
+ TYPE_RANGE_DATA (new_type) = XNEW (struct range_bounds);
*TYPE_RANGE_DATA (new_type) = *TYPE_RANGE_DATA (type);
}
- /* Copy the data location information. */
- if (TYPE_DATA_LOCATION (type) != NULL)
- {
- TYPE_DATA_LOCATION (new_type)
- = TYPE_ALLOC (new_type, sizeof (struct dynamic_prop));
- memcpy (TYPE_DATA_LOCATION (new_type), TYPE_DATA_LOCATION (type),
- sizeof (struct dynamic_prop));
- }
+ if (TYPE_DYN_PROP_LIST (type) != NULL)
+ TYPE_DYN_PROP_LIST (new_type)
+ = copy_dynamic_prop_list (&objfile->objfile_obstack,
+ TYPE_DYN_PROP_LIST (type));
+
/* Copy pointers to other types. */
if (TYPE_TARGET_TYPE (type))
copy_type_recursive (objfile,
TYPE_TARGET_TYPE (type),
copied_types);
- if (TYPE_VPTR_BASETYPE (type))
- TYPE_VPTR_BASETYPE (new_type) =
- copy_type_recursive (objfile,
- TYPE_VPTR_BASETYPE (type),
- copied_types);
+
/* Maybe copy the type_specific bits.
NOTE drow/2005-12-09: We do not copy the C++-specific bits like
base classes and methods. There's no fundamental reason why we
can't, but at the moment it is not needed. */
- if (TYPE_CODE (type) == TYPE_CODE_FLT)
- TYPE_FLOATFORMAT (new_type) = TYPE_FLOATFORMAT (type);
- else if (TYPE_CODE (type) == TYPE_CODE_STRUCT
- || TYPE_CODE (type) == TYPE_CODE_UNION
- || TYPE_CODE (type) == TYPE_CODE_NAMESPACE)
- INIT_CPLUS_SPECIFIC (new_type);
+ switch (TYPE_SPECIFIC_FIELD (type))
+ {
+ case TYPE_SPECIFIC_NONE:
+ break;
+ case TYPE_SPECIFIC_FUNC:
+ INIT_FUNC_SPECIFIC (new_type);
+ TYPE_CALLING_CONVENTION (new_type) = TYPE_CALLING_CONVENTION (type);
+ TYPE_NO_RETURN (new_type) = TYPE_NO_RETURN (type);
+ TYPE_TAIL_CALL_LIST (new_type) = NULL;
+ break;
+ case TYPE_SPECIFIC_FLOATFORMAT:
+ TYPE_FLOATFORMAT (new_type) = TYPE_FLOATFORMAT (type);
+ break;
+ case TYPE_SPECIFIC_CPLUS_STUFF:
+ INIT_CPLUS_SPECIFIC (new_type);
+ break;
+ case TYPE_SPECIFIC_GNAT_STUFF:
+ INIT_GNAT_SPECIFIC (new_type);
+ break;
+ case TYPE_SPECIFIC_SELF_TYPE:
+ set_type_self_type (new_type,
+ copy_type_recursive (objfile, TYPE_SELF_TYPE (type),
+ copied_types));
+ break;
+ default:
+ gdb_assert_not_reached ("bad type_specific_kind");
+ }
return new_type;
}
TYPE_LENGTH (new_type) = TYPE_LENGTH (type);
memcpy (TYPE_MAIN_TYPE (new_type), TYPE_MAIN_TYPE (type),
sizeof (struct main_type));
- if (TYPE_DATA_LOCATION (type) != NULL)
- {
- TYPE_DATA_LOCATION (new_type)
- = TYPE_ALLOC (new_type, sizeof (struct dynamic_prop));
- memcpy (TYPE_DATA_LOCATION (new_type), TYPE_DATA_LOCATION (type),
- sizeof (struct dynamic_prop));
- }
+ if (TYPE_DYN_PROP_LIST (type) != NULL)
+ TYPE_DYN_PROP_LIST (new_type)
+ = copy_dynamic_prop_list (&TYPE_OBJFILE (type) -> objfile_obstack,
+ TYPE_DYN_PROP_LIST (type));
return new_type;
}
struct type *
arch_type (struct gdbarch *gdbarch,
- enum type_code code, int length, char *name)
+ enum type_code code, int bit, const char *name)
{
struct type *type;
type = alloc_type_arch (gdbarch);
- TYPE_CODE (type) = code;
- TYPE_LENGTH (type) = length;
+ set_type_code (type, code);
+ gdb_assert ((bit % TARGET_CHAR_BIT) == 0);
+ TYPE_LENGTH (type) = bit / TARGET_CHAR_BIT;
if (name)
- TYPE_NAME (type) = xstrdup (name);
+ TYPE_NAME (type) = gdbarch_obstack_strdup (gdbarch, name);
return type;
}
struct type *
arch_integer_type (struct gdbarch *gdbarch,
- int bit, int unsigned_p, char *name)
+ int bit, int unsigned_p, const char *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;
- if (name && strcmp (name, "char") == 0)
- TYPE_NOSIGN (t) = 1;
return t;
}
struct type *
arch_character_type (struct gdbarch *gdbarch,
- int bit, int unsigned_p, char *name)
+ int bit, int unsigned_p, const char *name)
{
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 *
arch_boolean_type (struct gdbarch *gdbarch,
- int bit, int unsigned_p, char *name)
+ int bit, int unsigned_p, const char *name)
{
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;
struct type *
arch_float_type (struct gdbarch *gdbarch,
- int bit, char *name, const struct floatformat **floatformats)
+ int bit, const char *name,
+ const struct floatformat **floatformats)
{
+ const struct floatformat *fmt = floatformats[gdbarch_byte_order (gdbarch)];
struct type *t;
- if (bit == -1)
- {
- gdb_assert (floatformats != NULL);
- gdb_assert (floatformats[0] != NULL && floatformats[1] != NULL);
- bit = floatformats[0]->totalsize;
- }
- gdb_assert (bit >= 0);
+ bit = verify_floatformat (bit, fmt);
+ t = arch_type (gdbarch, TYPE_CODE_FLT, bit, name);
+ TYPE_FLOATFORMAT (t) = fmt;
+
+ return t;
+}
+
+/* Allocate a TYPE_CODE_DECFLOAT type structure associated with GDBARCH.
+ BIT is the type size in bits. NAME is the type name. */
+
+struct type *
+arch_decfloat_type (struct gdbarch *gdbarch, int bit, const char *name)
+{
+ struct type *t;
- t = arch_type (gdbarch, TYPE_CODE_FLT, bit / TARGET_CHAR_BIT, name);
- TYPE_FLOATFORMAT (t) = floatformats;
+ t = arch_type (gdbarch, TYPE_CODE_DECFLOAT, bit, name);
return t;
}
struct type *
arch_complex_type (struct gdbarch *gdbarch,
- char *name, struct type *target_type)
+ const char *name, struct type *target_type)
{
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;
+}
+
+/* Allocate a TYPE_CODE_PTR type structure associated with GDBARCH.
+ BIT is the pointer type size in bits. NAME is the type name.
+ TARGET_TYPE is the pointer target type. Always sets the pointer type's
+ TYPE_UNSIGNED flag. */
+
+struct type *
+arch_pointer_type (struct gdbarch *gdbarch,
+ int bit, const char *name, struct type *target_type)
+{
+ struct type *t;
+
+ 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, char *name, int length)
+arch_flags_type (struct gdbarch *gdbarch, const char *name, int bit)
{
- int 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) = nfields;
- TYPE_FIELDS (type) = TYPE_ZALLOC (type, nfields * sizeof (struct field));
+ TYPE_NFIELDS (type) = 0;
+ /* Pre-allocate enough space assuming every field is one bit. */
+ TYPE_FIELDS (type)
+ = (struct field *) TYPE_ZALLOC (type, bit * sizeof (struct field));
return type;
}
/* Add field to TYPE_CODE_FLAGS type TYPE to indicate the bit at
- position BITPOS is called NAME. */
+ position BITPOS is called NAME. Pass NAME as "" for fields that
+ should not be printed. */
void
-append_flags_type_flag (struct type *type, int bitpos, char *name)
+append_flags_type_field (struct type *type, int start_bitpos, int nr_bits,
+ struct type *field_type, const char *name)
{
+ int type_bitsize = TYPE_LENGTH (type) * TARGET_CHAR_BIT;
+ int field_nr = TYPE_NFIELDS (type);
+
gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLAGS);
- gdb_assert (bitpos < TYPE_NFIELDS (type));
- gdb_assert (bitpos >= 0);
+ gdb_assert (TYPE_NFIELDS (type) + 1 <= type_bitsize);
+ gdb_assert (start_bitpos >= 0 && start_bitpos < type_bitsize);
+ gdb_assert (nr_bits >= 1 && nr_bits <= type_bitsize);
+ gdb_assert (name != NULL);
+
+ TYPE_FIELD_NAME (type, field_nr) = xstrdup (name);
+ TYPE_FIELD_TYPE (type, field_nr) = field_type;
+ SET_FIELD_BITPOS (TYPE_FIELD (type, field_nr), start_bitpos);
+ TYPE_FIELD_BITSIZE (type, field_nr) = nr_bits;
+ ++TYPE_NFIELDS (type);
+}
- if (name)
- {
- TYPE_FIELD_NAME (type, bitpos) = xstrdup (name);
- SET_FIELD_BITPOS (TYPE_FIELD (type, bitpos), bitpos);
- }
- else
- {
- /* Don't show this field to the user. */
- SET_FIELD_BITPOS (TYPE_FIELD (type, bitpos), -1);
- }
+/* Special version of append_flags_type_field to add a flag field.
+ Add field to TYPE_CODE_FLAGS type TYPE to indicate the bit at
+ position BITPOS is called NAME. */
+
+void
+append_flags_type_flag (struct type *type, int bitpos, const char *name)
+{
+ struct gdbarch *gdbarch = get_type_arch (type);
+
+ append_flags_type_field (type, bitpos, 1,
+ builtin_type (gdbarch)->builtin_bool,
+ name);
}
/* Allocate a TYPE_CODE_STRUCT or TYPE_CODE_UNION type structure (as
specified by CODE) associated with GDBARCH. NAME is the type name. */
struct type *
-arch_composite_type (struct gdbarch *gdbarch, char *name, enum type_code code)
+arch_composite_type (struct gdbarch *gdbarch, const char *name,
+ enum type_code code)
{
struct type *t;
gdb_assert (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION);
t = arch_type (gdbarch, code, 0, NULL);
- TYPE_TAG_NAME (t) = name;
+ TYPE_NAME (t) = name;
INIT_CPLUS_SPECIFIC (t);
return t;
}
the caller should do so. Return the new field. */
struct field *
-append_composite_type_field_raw (struct type *t, char *name,
+append_composite_type_field_raw (struct type *t, const char *name,
struct type *field)
{
struct field *f;
TYPE_NFIELDS (t) = TYPE_NFIELDS (t) + 1;
- TYPE_FIELDS (t) = xrealloc (TYPE_FIELDS (t),
- sizeof (struct field) * TYPE_NFIELDS (t));
+ TYPE_FIELDS (t) = XRESIZEVEC (struct field, TYPE_FIELDS (t),
+ TYPE_NFIELDS (t));
f = &(TYPE_FIELDS (t)[TYPE_NFIELDS (t) - 1]);
memset (f, 0, sizeof f[0]);
FIELD_TYPE (f[0]) = field;
ALIGNMENT (if non-zero) specifies the minimum field alignment. */
void
-append_composite_type_field_aligned (struct type *t, char *name,
+append_composite_type_field_aligned (struct type *t, const char *name,
struct type *field, int alignment)
{
struct field *f = append_composite_type_field_raw (t, name, field);
/* Add new field with name NAME and type FIELD to composite type T. */
void
-append_composite_type_field (struct type *t, char *name,
+append_composite_type_field (struct type *t, const char *name,
struct type *field)
{
append_composite_type_field_aligned (t, name, field, 0);
const struct builtin_type *
builtin_type (struct gdbarch *gdbarch)
{
- return gdbarch_data (gdbarch, gdbtypes_data);
+ return (const struct builtin_type *) gdbarch_data (gdbarch, gdbtypes_data);
}
static void *
/* 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");
+ TYPE_NOSIGN (builtin_type->builtin_char) = 1;
builtin_type->builtin_signed_char
= arch_integer_type (gdbarch, TARGET_CHAR_BIT,
0, "signed 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. */
builtin_type->builtin_decfloat
- = arch_type (gdbarch, TYPE_CODE_DECFLOAT, 32 / 8, "_Decimal32");
+ = arch_decfloat_type (gdbarch, 32, "_Decimal32");
builtin_type->builtin_decdouble
- = arch_type (gdbarch, TYPE_CODE_DECFLOAT, 64 / 8, "_Decimal64");
+ = arch_decfloat_type (gdbarch, 64, "_Decimal64");
builtin_type->builtin_declong
- = arch_type (gdbarch, TYPE_CODE_DECFLOAT, 128 / 8, "_Decimal128");
+ = arch_decfloat_type (gdbarch, 128, "_Decimal128");
/* "True" character types. */
builtin_type->builtin_true_char
= arch_integer_type (gdbarch, 16, 0, "int16_t");
builtin_type->builtin_uint16
= arch_integer_type (gdbarch, 16, 1, "uint16_t");
+ builtin_type->builtin_int24
+ = arch_integer_type (gdbarch, 24, 0, "int24_t");
+ builtin_type->builtin_uint24
+ = arch_integer_type (gdbarch, 24, 1, "uint24_t");
builtin_type->builtin_int32
= arch_integer_type (gdbarch, 32, 0, "int32_t");
builtin_type->builtin_uint32
/* 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
{
struct gdbarch *gdbarch;
struct objfile_type *objfile_type
- = objfile_data (objfile, objfile_type_data);
+ = (struct objfile_type *) objfile_data (objfile, objfile_type_data);
if (objfile_type)
return objfile_type;
/* Basic types. */
objfile_type->builtin_void
- = init_type (TYPE_CODE_VOID, 1,
- 0,
- "void", objfile);
-
+ = init_type (objfile, TYPE_CODE_VOID, TARGET_CHAR_BIT, "void");
objfile_type->builtin_char
- = init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
- (TYPE_FLAG_NOSIGN
- | (gdbarch_char_signed (gdbarch) ? 0 : TYPE_FLAG_UNSIGNED)),
- "char", objfile);
+ = init_integer_type (objfile, TARGET_CHAR_BIT,
+ !gdbarch_char_signed (gdbarch), "char");
+ TYPE_NOSIGN (objfile_type->builtin_char) = 1;
objfile_type->builtin_signed_char
- = init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
- 0,
- "signed char", objfile);
+ = init_integer_type (objfile, TARGET_CHAR_BIT,
+ 0, "signed char");
objfile_type->builtin_unsigned_char
- = init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
- TYPE_FLAG_UNSIGNED,
- "unsigned char", objfile);
+ = init_integer_type (objfile, TARGET_CHAR_BIT,
+ 1, "unsigned char");
objfile_type->builtin_short
- = init_type (TYPE_CODE_INT,
- gdbarch_short_bit (gdbarch) / TARGET_CHAR_BIT,
- 0, "short", objfile);
+ = init_integer_type (objfile, gdbarch_short_bit (gdbarch),
+ 0, "short");
objfile_type->builtin_unsigned_short
- = init_type (TYPE_CODE_INT,
- gdbarch_short_bit (gdbarch) / TARGET_CHAR_BIT,
- TYPE_FLAG_UNSIGNED, "unsigned short", objfile);
+ = init_integer_type (objfile, gdbarch_short_bit (gdbarch),
+ 1, "unsigned short");
objfile_type->builtin_int
- = init_type (TYPE_CODE_INT,
- gdbarch_int_bit (gdbarch) / TARGET_CHAR_BIT,
- 0, "int", objfile);
+ = init_integer_type (objfile, gdbarch_int_bit (gdbarch),
+ 0, "int");
objfile_type->builtin_unsigned_int
- = init_type (TYPE_CODE_INT,
- gdbarch_int_bit (gdbarch) / TARGET_CHAR_BIT,
- TYPE_FLAG_UNSIGNED, "unsigned int", objfile);
+ = init_integer_type (objfile, gdbarch_int_bit (gdbarch),
+ 1, "unsigned int");
objfile_type->builtin_long
- = init_type (TYPE_CODE_INT,
- gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT,
- 0, "long", objfile);
+ = init_integer_type (objfile, gdbarch_long_bit (gdbarch),
+ 0, "long");
objfile_type->builtin_unsigned_long
- = init_type (TYPE_CODE_INT,
- gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT,
- TYPE_FLAG_UNSIGNED, "unsigned long", objfile);
+ = init_integer_type (objfile, gdbarch_long_bit (gdbarch),
+ 1, "unsigned long");
objfile_type->builtin_long_long
- = init_type (TYPE_CODE_INT,
- gdbarch_long_long_bit (gdbarch) / TARGET_CHAR_BIT,
- 0, "long long", objfile);
+ = init_integer_type (objfile, gdbarch_long_long_bit (gdbarch),
+ 0, "long long");
objfile_type->builtin_unsigned_long_long
- = init_type (TYPE_CODE_INT,
- gdbarch_long_long_bit (gdbarch) / TARGET_CHAR_BIT,
- TYPE_FLAG_UNSIGNED, "unsigned long long", objfile);
-
+ = init_integer_type (objfile, gdbarch_long_long_bit (gdbarch),
+ 1, "unsigned long long");
objfile_type->builtin_float
- = init_type (TYPE_CODE_FLT,
- gdbarch_float_bit (gdbarch) / TARGET_CHAR_BIT,
- 0, "float", objfile);
- TYPE_FLOATFORMAT (objfile_type->builtin_float)
- = gdbarch_float_format (gdbarch);
+ = init_float_type (objfile, gdbarch_float_bit (gdbarch),
+ "float", gdbarch_float_format (gdbarch));
objfile_type->builtin_double
- = init_type (TYPE_CODE_FLT,
- gdbarch_double_bit (gdbarch) / TARGET_CHAR_BIT,
- 0, "double", objfile);
- TYPE_FLOATFORMAT (objfile_type->builtin_double)
- = gdbarch_double_format (gdbarch);
+ = init_float_type (objfile, gdbarch_double_bit (gdbarch),
+ "double", gdbarch_double_format (gdbarch));
objfile_type->builtin_long_double
- = init_type (TYPE_CODE_FLT,
- gdbarch_long_double_bit (gdbarch) / TARGET_CHAR_BIT,
- 0, "long double", objfile);
- TYPE_FLOATFORMAT (objfile_type->builtin_long_double)
- = gdbarch_long_double_format (gdbarch);
+ = init_float_type (objfile, gdbarch_long_double_bit (gdbarch),
+ "long double", gdbarch_long_double_format (gdbarch));
/* This type represents a type that was unrecognized in symbol read-in. */
objfile_type->builtin_error
- = init_type (TYPE_CODE_ERROR, 0, 0, "<unknown type>", objfile);
+ = init_type (objfile, TYPE_CODE_ERROR, 0, "<unknown type>");
/* The following set of types is used for symbols with no
debug information. */
objfile_type->nodebug_text_symbol
- = init_type (TYPE_CODE_FUNC, 1, 0,
- "<text variable, no debug info>", objfile);
- TYPE_TARGET_TYPE (objfile_type->nodebug_text_symbol)
- = objfile_type->builtin_int;
+ = init_type (objfile, TYPE_CODE_FUNC, TARGET_CHAR_BIT,
+ "<text variable, no debug info>");
objfile_type->nodebug_text_gnu_ifunc_symbol
- = init_type (TYPE_CODE_FUNC, 1, TYPE_FLAG_GNU_IFUNC,
- "<text gnu-indirect-function variable, no debug info>",
- objfile);
- TYPE_TARGET_TYPE (objfile_type->nodebug_text_gnu_ifunc_symbol)
- = objfile_type->nodebug_text_symbol;
+ = init_type (objfile, TYPE_CODE_FUNC, TARGET_CHAR_BIT,
+ "<text gnu-indirect-function variable, no debug info>");
+ TYPE_GNU_IFUNC (objfile_type->nodebug_text_gnu_ifunc_symbol) = 1;
objfile_type->nodebug_got_plt_symbol
- = init_type (TYPE_CODE_PTR, gdbarch_addr_bit (gdbarch) / 8, 0,
- "<text from jump slot in .got.plt, no debug info>",
- objfile);
- TYPE_TARGET_TYPE (objfile_type->nodebug_got_plt_symbol)
- = objfile_type->nodebug_text_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_type (TYPE_CODE_INT,
- gdbarch_int_bit (gdbarch) / HOST_CHAR_BIT, 0,
- "<data variable, no debug info>", objfile);
+ = init_nodebug_var_type (objfile, "<data variable, no debug info>");
objfile_type->nodebug_unknown_symbol
- = init_type (TYPE_CODE_INT, 1, 0,
- "<variable (not text or data), no debug info>", objfile);
+ = init_nodebug_var_type (objfile, "<variable (not text or data), no debug info>");
objfile_type->nodebug_tls_symbol
- = init_type (TYPE_CODE_INT,
- gdbarch_int_bit (gdbarch) / HOST_CHAR_BIT, 0,
- "<thread local variable, no debug info>", objfile);
+ = init_nodebug_var_type (objfile, "<thread local variable, no debug info>");
/* NOTE: on some targets, addresses and pointers are not necessarily
the same.
are indeed in the unified virtual address space. */
objfile_type->builtin_core_addr
- = init_type (TYPE_CODE_INT,
- gdbarch_addr_bit (gdbarch) / 8,
- TYPE_FLAG_UNSIGNED, "__CORE_ADDR", objfile);
+ = init_integer_type (objfile, gdbarch_addr_bit (gdbarch), 1,
+ "__CORE_ADDR");
set_objfile_data (objfile, objfile_type_data, objfile_type);
return objfile_type;
}
-extern initialize_file_ftype _initialize_gdbtypes;
-
void
_initialize_gdbtypes (void)
{