/* Support routines for manipulating internal types for GDB.
- Copyright (C) 1992-2019 Free Software Foundation, Inc.
+ Copyright (C) 1992-2020 Free Software Foundation, Inc.
Contributed by Cygnus Support, using pieces from other GDB modules.
#include "hashtab.h"
#include "cp-support.h"
#include "bcache.h"
-#include "dwarf2loc.h"
+#include "dwarf2/loc.h"
#include "gdbcore.h"
#include "floatformat.h"
+#include <algorithm>
/* Initialize BADNESS constants. */
const struct rank BOOL_CONVERSION_BADNESS = {3,0};
const struct rank BASE_CONVERSION_BADNESS = {2,0};
const struct rank REFERENCE_CONVERSION_BADNESS = {2,0};
+const struct rank REFERENCE_SEE_THROUGH_BADNESS = {0,1};
const struct rank NULL_POINTER_CONVERSION_BADNESS = {2,0};
const struct rank NS_POINTER_CONVERSION_BADNESS = {10,0};
const struct rank NS_INTEGER_POINTER_CONVERSION_BADNESS = {3,0};
struct gdbarch *arch;
if (TYPE_OBJFILE_OWNED (type))
- arch = get_objfile_arch (TYPE_OWNER (type).objfile);
+ arch = TYPE_OWNER (type).objfile->arch ();
else
arch = TYPE_OWNER (type).gdbarch;
case PROP_LOCEXPR:
case PROP_LOCLIST:
return l.data.baton == r.data.baton;
+ case PROP_VARIANT_PARTS:
+ return l.data.variant_parts == r.data.variant_parts;
+ case PROP_TYPE:
+ return l.data.original_type == r.data.original_type;
}
gdb_assert_not_reached ("unhandled dynamic_prop kind");
TYPE_RANGE_DATA (result_type)->high = *high_bound;
TYPE_RANGE_DATA (result_type)->bias = bias;
+ /* Initialize the stride to be a constant, the value will already be zero
+ thanks to the use of TYPE_ZALLOC above. */
+ TYPE_RANGE_DATA (result_type)->stride.kind = PROP_CONST;
+
if (low_bound->kind == PROP_CONST && low_bound->data.const_val >= 0)
TYPE_UNSIGNED (result_type) = 1;
if (high_bound->kind == PROP_CONST && high_bound->data.const_val < 0)
TYPE_UNSIGNED (result_type) = 0;
+ TYPE_ENDIANITY_NOT_DEFAULT (result_type)
+ = TYPE_ENDIANITY_NOT_DEFAULT (index_type);
+
+ return result_type;
+}
+
+/* See gdbtypes.h. */
+
+struct type *
+create_range_type_with_stride (struct type *result_type,
+ struct type *index_type,
+ const struct dynamic_prop *low_bound,
+ const struct dynamic_prop *high_bound,
+ LONGEST bias,
+ const struct dynamic_prop *stride,
+ bool byte_stride_p)
+{
+ result_type = create_range_type (result_type, index_type, low_bound,
+ high_bound, bias);
+
+ gdb_assert (stride != nullptr);
+ TYPE_RANGE_DATA (result_type)->stride = *stride;
+ TYPE_RANGE_DATA (result_type)->flag_is_byte_stride = byte_stride_p;
+
return result_type;
}
+
+
/* Create a range type using either a blank type supplied in
RESULT_TYPE, or creating a new type, inheriting the objfile from
INDEX_TYPE.
/* Predicate tests whether BOUNDS are static. Returns 1 if all bounds values
are static, otherwise returns 0. */
-static int
+static bool
has_static_range (const struct range_bounds *bounds)
{
+ /* If the range doesn't have a defined stride then its stride field will
+ be initialized to the constant 0. */
return (bounds->low.kind == PROP_CONST
- && bounds->high.kind == PROP_CONST);
+ && bounds->high.kind == PROP_CONST
+ && bounds->stride.kind == PROP_CONST);
}
}
}
+/* If the array TYPE has static bounds calculate and update its
+ size, then return true. Otherwise return false and leave TYPE
+ unchanged. */
+
+static bool
+update_static_array_size (struct type *type)
+{
+ gdb_assert (TYPE_CODE (type) == TYPE_CODE_ARRAY);
+
+ struct type *range_type = TYPE_INDEX_TYPE (type);
+
+ if (get_dyn_prop (DYN_PROP_BYTE_STRIDE, type) == nullptr
+ && has_static_range (TYPE_RANGE_DATA (range_type))
+ && (!type_not_associated (type)
+ && !type_not_allocated (type)))
+ {
+ LONGEST low_bound, high_bound;
+ int stride;
+ struct type *element_type;
+
+ /* If the array itself doesn't provide a stride value then take
+ whatever stride the range provides. Don't update BIT_STRIDE as
+ we don't want to place the stride value from the range into this
+ arrays bit size field. */
+ stride = TYPE_FIELD_BITSIZE (type, 0);
+ if (stride == 0)
+ stride = TYPE_BIT_STRIDE (range_type);
+
+ if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
+ low_bound = high_bound = 0;
+ element_type = check_typedef (TYPE_TARGET_TYPE (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. */
+ if (high_bound < low_bound)
+ TYPE_LENGTH (type) = 0;
+ else if (stride != 0)
+ {
+ /* Ensure that the type length is always positive, even in the
+ case where (for example in Fortran) we have a negative
+ stride. It is possible to have a single element array with a
+ negative stride in Fortran (this doesn't mean anything
+ special, it's still just a single element array) so do
+ consider that case when touching this code. */
+ LONGEST element_count = std::abs (high_bound - low_bound + 1);
+ TYPE_LENGTH (type)
+ = ((std::abs (stride) * element_count) + 7) / 8;
+ }
+ else
+ TYPE_LENGTH (type) =
+ TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
+
+ return true;
+ }
+
+ return false;
+}
+
/* Create an array type using either a blank type supplied in
RESULT_TYPE, or creating a new type, inheriting the objfile from
RANGE_TYPE.
TYPE_CODE (result_type) = TYPE_CODE_ARRAY;
TYPE_TARGET_TYPE (result_type) = element_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;
- 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. */
- if (high_bound < low_bound)
- TYPE_LENGTH (result_type) = 0;
- else if (bit_stride > 0)
- TYPE_LENGTH (result_type) =
- (bit_stride * (high_bound - low_bound + 1) + 7) / 8;
- else
- TYPE_LENGTH (result_type) =
- TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
- }
- else
+ TYPE_NFIELDS (result_type) = 1;
+ TYPE_FIELDS (result_type) =
+ (struct field *) TYPE_ZALLOC (result_type, sizeof (struct field));
+ TYPE_INDEX_TYPE (result_type) = range_type;
+ 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;
+
+ if (!update_static_array_size (result_type))
{
/* This type is dynamic and its length needs to be computed
on demand. In the meantime, avoid leaving the TYPE_LENGTH
TYPE_LENGTH (result_type) = 0;
}
- TYPE_NFIELDS (result_type) = 1;
- TYPE_FIELDS (result_type) =
- (struct field *) TYPE_ZALLOC (result_type, sizeof (struct field));
- TYPE_INDEX_TYPE (result_type) = range_type;
- if (byte_stride_prop != NULL)
- add_dyn_prop (DYN_PROP_BYTE_STRIDE, *byte_stride_prop, result_type);
- else if (bit_stride > 0)
- TYPE_FIELD_BITSIZE (result_type, 0) = bit_stride;
-
/* TYPE_TARGET_STUB will take care of zero length arrays. */
if (TYPE_LENGTH (result_type) == 0)
TYPE_TARGET_STUB (result_type) = 1;
struct type *
lookup_typename (const struct language_defn *language,
- struct gdbarch *gdbarch, const char *name,
+ const char *name,
const struct block *block, int noerr)
{
struct symbol *sym;
struct type *
lookup_unsigned_typename (const struct language_defn *language,
- struct gdbarch *gdbarch, const char *name)
+ const char *name)
{
char *uns = (char *) alloca (strlen (name) + 10);
strcpy (uns, "unsigned ");
strcpy (uns + 9, name);
- return lookup_typename (language, gdbarch, uns, NULL, 0);
+ return lookup_typename (language, uns, NULL, 0);
}
struct type *
-lookup_signed_typename (const struct language_defn *language,
- struct gdbarch *gdbarch, const char *name)
+lookup_signed_typename (const struct language_defn *language, const char *name)
{
struct type *t;
char *uns = (char *) alloca (strlen (name) + 8);
strcpy (uns, "signed ");
strcpy (uns + 7, name);
- t = lookup_typename (language, gdbarch, uns, NULL, 1);
+ t = lookup_typename (language, uns, NULL, 1);
/* If we don't find "signed FOO" just try again with plain "FOO". */
if (t != NULL)
return t;
- return lookup_typename (language, gdbarch, name, NULL, 0);
+ return lookup_typename (language, name, NULL, 0);
}
/* Lookup a structure type named "struct NAME",
if (TYPE_ALLOCATED_PROP (type))
return 1;
+ struct dynamic_prop *prop = get_dyn_prop (DYN_PROP_VARIANT_PARTS, type);
+ if (prop != nullptr && prop->kind != PROP_TYPE)
+ return 1;
+
+ if (TYPE_HAS_DYNAMIC_LENGTH (type))
+ return 1;
+
switch (TYPE_CODE (type))
{
case TYPE_CODE_RANGE:
|| is_dynamic_type_internal (TYPE_TARGET_TYPE (type), 0));
}
+ case TYPE_CODE_STRING:
+ /* Strings are very much like an array of characters, and can be
+ treated as one here. */
case TYPE_CODE_ARRAY:
{
gdb_assert (TYPE_NFIELDS (type) == 1);
{
int i;
+ bool is_cplus = HAVE_CPLUS_STRUCT (type);
+
for (i = 0; i < TYPE_NFIELDS (type); ++i)
- if (!field_is_static (&TYPE_FIELD (type, i))
- && is_dynamic_type_internal (TYPE_FIELD_TYPE (type, i), 0))
+ {
+ /* Static fields can be ignored here. */
+ if (field_is_static (&TYPE_FIELD (type, i)))
+ continue;
+ /* If the field has dynamic type, then so does TYPE. */
+ if (is_dynamic_type_internal (TYPE_FIELD_TYPE (type, i), 0))
+ return 1;
+ /* If the field is at a fixed offset, then it is not
+ dynamic. */
+ if (TYPE_FIELD_LOC_KIND (type, i) != FIELD_LOC_KIND_DWARF_BLOCK)
+ continue;
+ /* Do not consider C++ virtual base types to be dynamic
+ due to the field's offset being dynamic; these are
+ handled via other means. */
+ if (is_cplus && BASETYPE_VIA_VIRTUAL (type, i))
+ continue;
return 1;
+ }
}
break;
}
CORE_ADDR value;
struct type *static_range_type, *static_target_type;
const struct dynamic_prop *prop;
- struct dynamic_prop low_bound, high_bound;
+ struct dynamic_prop low_bound, high_bound, stride;
gdb_assert (TYPE_CODE (dyn_range_type) == TYPE_CODE_RANGE);
high_bound.data.const_val = 0;
}
+ bool byte_stride_p = TYPE_RANGE_DATA (dyn_range_type)->flag_is_byte_stride;
+ prop = &TYPE_RANGE_DATA (dyn_range_type)->stride;
+ if (dwarf2_evaluate_property (prop, NULL, addr_stack, &value))
+ {
+ stride.kind = PROP_CONST;
+ stride.data.const_val = value;
+
+ /* If we have a bit stride that is not an exact number of bytes then
+ I really don't think this is going to work with current GDB, the
+ array indexing code in GDB seems to be pretty heavily tied to byte
+ offsets right now. Assuming 8 bits in a byte. */
+ struct gdbarch *gdbarch = get_type_arch (dyn_range_type);
+ int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);
+ if (!byte_stride_p && (value % (unit_size * 8)) != 0)
+ error (_("bit strides that are not a multiple of the byte size "
+ "are currently not supported"));
+ }
+ else
+ {
+ stride.kind = PROP_UNDEFINED;
+ stride.data.const_val = 0;
+ byte_stride_p = true;
+ }
+
static_target_type
= resolve_dynamic_type_internal (TYPE_TARGET_TYPE (dyn_range_type),
addr_stack, 0);
LONGEST bias = TYPE_RANGE_DATA (dyn_range_type)->bias;
- static_range_type = create_range_type (copy_type (dyn_range_type),
- static_target_type,
- &low_bound, &high_bound, bias);
+ static_range_type = create_range_type_with_stride
+ (copy_type (dyn_range_type), static_target_type,
+ &low_bound, &high_bound, bias, &stride, byte_stride_p);
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.
- ADDR_STACK is a stack of struct property_addr_info to be used
- if needed during the dynamic resolution. */
+/* Resolves dynamic bound values of an array or string type TYPE to static
+ ones. 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,
- struct property_addr_info *addr_stack)
+resolve_dynamic_array_or_string (struct type *type,
+ struct property_addr_info *addr_stack)
{
CORE_ADDR value;
struct type *elt_type;
struct dynamic_prop *prop;
unsigned int bit_stride = 0;
- gdb_assert (TYPE_CODE (type) == TYPE_CODE_ARRAY);
+ /* For dynamic type resolution strings can be treated like arrays of
+ characters. */
+ gdb_assert (TYPE_CODE (type) == TYPE_CODE_ARRAY
+ || TYPE_CODE (type) == TYPE_CODE_STRING);
type = copy_type (type);
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 (ary_dim, addr_stack);
+ elt_type = resolve_dynamic_array_or_string (ary_dim, addr_stack);
else
elt_type = TYPE_TARGET_TYPE (type);
return resolved_type;
}
+/* See gdbtypes.h. */
+
+bool
+variant::matches (ULONGEST value, bool is_unsigned) const
+{
+ for (const discriminant_range &range : discriminants)
+ if (range.contains (value, is_unsigned))
+ return true;
+ return false;
+}
+
+static void
+compute_variant_fields_inner (struct type *type,
+ struct property_addr_info *addr_stack,
+ const variant_part &part,
+ std::vector<bool> &flags);
+
+/* A helper function to determine which variant fields will be active.
+ This handles both the variant's direct fields, and any variant
+ parts embedded in this variant. TYPE is the type we're examining.
+ ADDR_STACK holds information about the concrete object. VARIANT is
+ the current variant to be handled. FLAGS is where the results are
+ stored -- this function sets the Nth element in FLAGS if the
+ corresponding field is enabled. ENABLED is whether this variant is
+ enabled or not. */
+
+static void
+compute_variant_fields_recurse (struct type *type,
+ struct property_addr_info *addr_stack,
+ const variant &variant,
+ std::vector<bool> &flags,
+ bool enabled)
+{
+ for (int field = variant.first_field; field < variant.last_field; ++field)
+ flags[field] = enabled;
+
+ for (const variant_part &new_part : variant.parts)
+ {
+ if (enabled)
+ compute_variant_fields_inner (type, addr_stack, new_part, flags);
+ else
+ {
+ for (const auto &sub_variant : new_part.variants)
+ compute_variant_fields_recurse (type, addr_stack, sub_variant,
+ flags, enabled);
+ }
+ }
+}
+
+/* A helper function to determine which variant fields will be active.
+ This evaluates the discriminant, decides which variant (if any) is
+ active, and then updates FLAGS to reflect which fields should be
+ available. TYPE is the type we're examining. ADDR_STACK holds
+ information about the concrete object. VARIANT is the current
+ variant to be handled. FLAGS is where the results are stored --
+ this function sets the Nth element in FLAGS if the corresponding
+ field is enabled. */
+
+static void
+compute_variant_fields_inner (struct type *type,
+ struct property_addr_info *addr_stack,
+ const variant_part &part,
+ std::vector<bool> &flags)
+{
+ /* Evaluate the discriminant. */
+ gdb::optional<ULONGEST> discr_value;
+ if (part.discriminant_index != -1)
+ {
+ int idx = part.discriminant_index;
+
+ if (TYPE_FIELD_LOC_KIND (type, idx) != FIELD_LOC_KIND_BITPOS)
+ error (_("Cannot determine struct field location"
+ " (invalid location kind)"));
+
+ if (addr_stack->valaddr.data () != NULL)
+ discr_value = unpack_field_as_long (type, addr_stack->valaddr.data (),
+ idx);
+ else
+ {
+ CORE_ADDR addr = (addr_stack->addr
+ + (TYPE_FIELD_BITPOS (type, idx)
+ / TARGET_CHAR_BIT));
+
+ LONGEST bitsize = TYPE_FIELD_BITSIZE (type, idx);
+ LONGEST size = bitsize / 8;
+ if (size == 0)
+ size = TYPE_LENGTH (TYPE_FIELD_TYPE (type, idx));
+
+ gdb_byte bits[sizeof (ULONGEST)];
+ read_memory (addr, bits, size);
+
+ LONGEST bitpos = (TYPE_FIELD_BITPOS (type, idx)
+ % TARGET_CHAR_BIT);
+
+ discr_value = unpack_bits_as_long (TYPE_FIELD_TYPE (type, idx),
+ bits, bitpos, bitsize);
+ }
+ }
+
+ /* Go through each variant and see which applies. */
+ const variant *default_variant = nullptr;
+ const variant *applied_variant = nullptr;
+ for (const auto &variant : part.variants)
+ {
+ if (variant.is_default ())
+ default_variant = &variant;
+ else if (discr_value.has_value ()
+ && variant.matches (*discr_value, part.is_unsigned))
+ {
+ applied_variant = &variant;
+ break;
+ }
+ }
+ if (applied_variant == nullptr)
+ applied_variant = default_variant;
+
+ for (const auto &variant : part.variants)
+ compute_variant_fields_recurse (type, addr_stack, variant,
+ flags, applied_variant == &variant);
+}
+
+/* Determine which variant fields are available in TYPE. The enabled
+ fields are stored in RESOLVED_TYPE. ADDR_STACK holds information
+ about the concrete object. PARTS describes the top-level variant
+ parts for this type. */
+
+static void
+compute_variant_fields (struct type *type,
+ struct type *resolved_type,
+ struct property_addr_info *addr_stack,
+ const gdb::array_view<variant_part> &parts)
+{
+ /* Assume all fields are included by default. */
+ std::vector<bool> flags (TYPE_NFIELDS (resolved_type), true);
+
+ /* Now disable fields based on the variants that control them. */
+ for (const auto &part : parts)
+ compute_variant_fields_inner (type, addr_stack, part, flags);
+
+ TYPE_NFIELDS (resolved_type) = std::count (flags.begin (), flags.end (),
+ true);
+ TYPE_FIELDS (resolved_type)
+ = (struct field *) TYPE_ALLOC (resolved_type,
+ TYPE_NFIELDS (resolved_type)
+ * sizeof (struct field));
+ int out = 0;
+ for (int i = 0; i < TYPE_NFIELDS (type); ++i)
+ {
+ if (!flags[i])
+ continue;
+
+ TYPE_FIELD (resolved_type, out) = TYPE_FIELD (type, i);
+ ++out;
+ }
+}
+
/* Resolve dynamic bounds of members of the struct TYPE to static
bounds. ADDR_STACK is a stack of struct property_addr_info to
be used if needed during the dynamic resolution. */
gdb_assert (TYPE_NFIELDS (type) > 0);
resolved_type = copy_type (type);
- TYPE_FIELDS (resolved_type)
- = (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));
+
+ struct dynamic_prop *variant_prop = get_dyn_prop (DYN_PROP_VARIANT_PARTS,
+ resolved_type);
+ if (variant_prop != nullptr && variant_prop->kind == PROP_VARIANT_PARTS)
+ {
+ compute_variant_fields (type, resolved_type, addr_stack,
+ *variant_prop->data.variant_parts);
+ /* We want to leave the property attached, so that the Rust code
+ can tell whether the type was originally an enum. */
+ variant_prop->kind = PROP_TYPE;
+ variant_prop->data.original_type = type;
+ }
+ else
+ {
+ TYPE_FIELDS (resolved_type)
+ = (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)))
+ if (field_is_static (&TYPE_FIELD (resolved_type, i)))
continue;
+ if (TYPE_FIELD_LOC_KIND (resolved_type, i) == FIELD_LOC_KIND_DWARF_BLOCK)
+ {
+ struct dwarf2_property_baton baton;
+ baton.property_type
+ = lookup_pointer_type (TYPE_FIELD_TYPE (resolved_type, i));
+ baton.locexpr = *TYPE_FIELD_DWARF_BLOCK (resolved_type, i);
+
+ struct dynamic_prop prop;
+ prop.kind = PROP_LOCEXPR;
+ prop.data.baton = &baton;
+
+ CORE_ADDR addr;
+ if (dwarf2_evaluate_property (&prop, nullptr, addr_stack, &addr,
+ true))
+ SET_FIELD_BITPOS (TYPE_FIELD (resolved_type, i),
+ TARGET_CHAR_BIT * (addr - addr_stack->addr));
+ }
+
/* 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 (type, i) != FIELD_LOC_KIND_BITPOS)
+ if (TYPE_FIELD_LOC_KIND (resolved_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.type = check_typedef (TYPE_FIELD_TYPE (resolved_type, i));
pinfo.valaddr = addr_stack->valaddr;
pinfo.addr
= (addr_stack->addr
int top_level)
{
struct type *real_type = check_typedef (type);
- struct type *resolved_type = type;
+ struct type *resolved_type = nullptr;
struct dynamic_prop *prop;
CORE_ADDR value;
if (!is_dynamic_type_internal (real_type, top_level))
return type;
+ gdb::optional<CORE_ADDR> type_length;
+ prop = TYPE_DYNAMIC_LENGTH (type);
+ if (prop != NULL
+ && dwarf2_evaluate_property (prop, NULL, addr_stack, &value))
+ type_length = value;
+
if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
{
resolved_type = copy_type (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);
+ pinfo.valaddr = {};
+ if (addr_stack->valaddr.data () != NULL)
+ pinfo.addr = extract_typed_address (addr_stack->valaddr.data (),
+ type);
else
pinfo.addr = read_memory_typed_address (addr_stack->addr, type);
pinfo.next = addr_stack;
break;
}
+ case TYPE_CODE_STRING:
+ /* Strings are very much like an array of characters, and can be
+ treated as one here. */
case TYPE_CODE_ARRAY:
- resolved_type = resolve_dynamic_array (type, addr_stack);
+ resolved_type = resolve_dynamic_array_or_string (type, addr_stack);
break;
case TYPE_CODE_RANGE:
}
}
+ if (resolved_type == nullptr)
+ return type;
+
+ if (type_length.has_value ())
+ {
+ TYPE_LENGTH (resolved_type) = *type_length;
+ remove_dyn_prop (DYN_PROP_BYTE_SIZE, resolved_type);
+ }
+
/* Resolve data_location attribute. */
prop = TYPE_DATA_LOCATION (resolved_type);
if (prop != NULL
/* See gdbtypes.h */
struct type *
-resolve_dynamic_type (struct type *type, const gdb_byte *valaddr,
+resolve_dynamic_type (struct type *type,
+ gdb::array_view<const gdb_byte> valaddr,
CORE_ADDR addr)
{
struct property_addr_info pinfo
TYPE_LENGTH (type) = TYPE_LENGTH (target_type);
TYPE_TARGET_STUB (type) = 0;
}
+ else if (TYPE_CODE (type) == TYPE_CODE_ARRAY
+ && update_static_array_size (type))
+ TYPE_TARGET_STUB (type) = 0;
}
type = make_qualified_type (type, instance_flags, NULL);
/* 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. */
+ TYPE_FLOATFORMAT from FLOATFORMATS. BYTE_ORDER is the byte order
+ to use. If it is BFD_ENDIAN_UNKNOWN (the default), then the byte
+ order of the objfile's architecture is used. */
struct type *
init_float_type (struct objfile *objfile,
int bit, const char *name,
- const struct floatformat **floatformats)
+ const struct floatformat **floatformats,
+ enum bfd_endian byte_order)
{
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
- const struct floatformat *fmt = floatformats[gdbarch_byte_order (gdbarch)];
+ if (byte_order == BFD_ENDIAN_UNKNOWN)
+ {
+ struct gdbarch *gdbarch = objfile->arch ();
+ byte_order = gdbarch_byte_order (gdbarch);
+ }
+ const struct floatformat *fmt = floatformats[byte_order];
struct type *t;
bit = verify_floatformat (bit, fmt);
return t;
}
-/* Allocate a TYPE_CODE_COMPLEX type structure associated with OBJFILE.
- NAME is the type name. TARGET_TYPE is the component float type. */
+/* Allocate a TYPE_CODE_COMPLEX type structure. NAME is the type
+ name. TARGET_TYPE is the component type. */
struct type *
-init_complex_type (struct objfile *objfile,
- const char *name, struct type *target_type)
+init_complex_type (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;
+ gdb_assert (TYPE_CODE (target_type) == TYPE_CODE_INT
+ || TYPE_CODE (target_type) == TYPE_CODE_FLT);
+
+ if (TYPE_MAIN_TYPE (target_type)->flds_bnds.complex_type == nullptr)
+ {
+ if (name == nullptr)
+ {
+ char *new_name
+ = (char *) TYPE_ALLOC (target_type,
+ strlen (TYPE_NAME (target_type))
+ + strlen ("_Complex ") + 1);
+ strcpy (new_name, "_Complex ");
+ strcat (new_name, TYPE_NAME (target_type));
+ name = new_name;
+ }
+
+ t = alloc_type_copy (target_type);
+ set_type_code (t, TYPE_CODE_COMPLEX);
+ TYPE_LENGTH (t) = 2 * TYPE_LENGTH (target_type);
+ TYPE_NAME (t) = name;
+
+ TYPE_TARGET_TYPE (t) = target_type;
+ TYPE_MAIN_TYPE (target_type)->flds_bnds.complex_type = t;
+ }
+
+ return TYPE_MAIN_TYPE (target_type)->flds_bnds.complex_type;
}
/* Allocate a TYPE_CODE_PTR type structure associated with OBJFILE.
value_address (val), val) == 1;
}
+/* See gdbtypes.h. */
+
+enum bfd_endian
+type_byte_order (const struct type *type)
+{
+ bfd_endian byteorder = gdbarch_byte_order (get_type_arch (type));
+ if (TYPE_ENDIANITY_NOT_DEFAULT (type))
+ {
+ if (byteorder == BFD_ENDIAN_BIG)
+ return BFD_ENDIAN_LITTLE;
+ else
+ {
+ gdb_assert (byteorder == BFD_ENDIAN_LITTLE);
+ return BFD_ENDIAN_BIG;
+ }
+ }
+
+ return byteorder;
+}
+
\f
/* Overload resolution. */
static bool
check_types_worklist (std::vector<type_equality_entry> *worklist,
- struct bcache *cache)
+ gdb::bcache *cache)
{
while (!worklist->empty ())
{
if (type1 == type2)
return true;
- struct bcache cache (nullptr, nullptr);
+ gdb::bcache cache (nullptr, nullptr);
worklist.emplace_back (type1, type2);
return check_types_worklist (&worklist, &cache);
}
}
else
{
- /* Lvalues should prefer lvalue overloads. */
+ /* It's illegal to pass an lvalue as an rvalue. */
if (TYPE_CODE (parm) == TYPE_CODE_RVALUE_REF)
- {
- rank.subrank = REFERENCE_CONVERSION_RVALUE;
- return sum_ranks (rank, REFERENCE_CONVERSION_BADNESS);
- }
+ return INCOMPATIBLE_TYPE_BADNESS;
}
}
if (TYPE_IS_REFERENCE (arg))
return (sum_ranks (rank_one_type (parm, TYPE_TARGET_TYPE (arg), NULL),
- REFERENCE_CONVERSION_BADNESS));
+ REFERENCE_SEE_THROUGH_BADNESS));
if (TYPE_IS_REFERENCE (parm))
return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL),
- REFERENCE_CONVERSION_BADNESS));
+ REFERENCE_SEE_THROUGH_BADNESS));
if (overload_debug)
/* Debugging only. */
fprintf_filtered (gdb_stderr,
TYPE_FN_FIELD_PROTECTED (f, overload_idx));
printfi_filtered (spaces + 8, "is_stub %d\n",
TYPE_FN_FIELD_STUB (f, overload_idx));
+ printfi_filtered (spaces + 8, "defaulted %d\n",
+ TYPE_FN_FIELD_DEFAULTED (f, overload_idx));
+ printfi_filtered (spaces + 8, "is_deleted %d\n",
+ TYPE_FN_FIELD_DELETED (f, overload_idx));
printfi_filtered (spaces + 8, "voffset %u\n",
TYPE_FN_FIELD_VOFFSET (f, overload_idx));
}
{
dump_fn_fieldlists (type, spaces);
}
+
+ printfi_filtered (spaces, "calling_convention %d\n",
+ TYPE_CPLUS_CALLING_CONVENTION (type));
}
/* Print the contents of the TYPE's type_specific union, assuming that
{
puts_filtered (" TYPE_PROTOTYPED");
}
- if (TYPE_INCOMPLETE (type))
- {
- puts_filtered (" TYPE_INCOMPLETE");
- }
if (TYPE_VARARGS (type))
{
puts_filtered (" TYPE_VARARGS");
return t;
}
-/* Allocate a TYPE_CODE_COMPLEX type structure associated with GDBARCH.
- NAME is the type name. TARGET_TYPE is the component float type. */
-
-struct type *
-arch_complex_type (struct gdbarch *gdbarch,
- const char *name, struct type *target_type)
-{
- struct type *t;
-
- t = arch_type (gdbarch, 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 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
= arch_float_type (gdbarch, gdbarch_long_double_bit (gdbarch),
"long double", gdbarch_long_double_format (gdbarch));
builtin_type->builtin_complex
- = arch_complex_type (gdbarch, "complex",
- builtin_type->builtin_float);
+ = init_complex_type ("complex", builtin_type->builtin_float);
builtin_type->builtin_double_complex
- = arch_complex_type (gdbarch, "double complex",
- builtin_type->builtin_double);
+ = init_complex_type ("double complex", builtin_type->builtin_double);
builtin_type->builtin_string
= arch_type (gdbarch, TYPE_CODE_STRING, TARGET_CHAR_BIT, "string");
builtin_type->builtin_bool
1, struct objfile_type);
/* Use the objfile architecture to determine basic type properties. */
- gdbarch = get_objfile_arch (objfile);
+ gdbarch = objfile->arch ();
/* Basic types. */
objfile_type->builtin_void
return objfile_type;
}
+void _initialize_gdbtypes ();
void
-_initialize_gdbtypes (void)
+_initialize_gdbtypes ()
{
gdbtypes_data = gdbarch_data_register_post_init (gdbtypes_post_init);
show_strict_type_checking,
&setchecklist, &showchecklist);
}
-
-/* See gdbtypes.h. */
-enum bfd_endian
-type_byte_order (const struct type *type)
-{
- bfd_endian byteorder = gdbarch_byte_order (get_type_arch (type));
- if (TYPE_ENDIANITY_NOT_DEFAULT (type))
- {
- if (byteorder == BFD_ENDIAN_BIG)
- return BFD_ENDIAN_LITTLE;
- else if (byteorder == BFD_ENDIAN_LITTLE)
- return BFD_ENDIAN_BIG;
- else
- return BFD_ENDIAN_UNKNOWN;
- }
-
- return byteorder;
-}