/* 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.
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};
/* Should opaque types be resolved? */
-static int opaque_type_resolution = 1;
+static bool opaque_type_resolution = true;
-/* A flag to enable printing of debugging information of C++
- overloading. */
+/* See gdbtypes.h. */
unsigned int overload_debug = 0;
/* A flag to enable strict type checking. */
-static int strict_type_checking = 1;
+static bool strict_type_checking = true;
/* A function to show whether opaque types are resolved. */
return the integer flag defined in gdbtypes.h. */
int
-address_space_name_to_int (struct gdbarch *gdbarch, char *space_identifier)
+address_space_name_to_int (struct gdbarch *gdbarch,
+ const char *space_identifier)
{
int type_flags;
return (FIELD_EQ (low)
&& FIELD_EQ (high)
&& FIELD_EQ (flag_upper_bound_is_count)
- && FIELD_EQ (flag_bound_evaluated));
+ && FIELD_EQ (flag_bound_evaluated)
+ && FIELD_EQ (bias));
#undef FIELD_EQ
}
struct type *
create_range_type (struct type *result_type, struct type *index_type,
const struct dynamic_prop *low_bound,
- const struct dynamic_prop *high_bound)
+ const struct dynamic_prop *high_bound,
+ LONGEST bias)
{
+ /* The INDEX_TYPE should be a type capable of holding the upper and lower
+ bounds, as such a zero sized, or void type makes no sense. */
+ gdb_assert (TYPE_CODE (index_type) != TYPE_CODE_VOID);
+ gdb_assert (TYPE_LENGTH (index_type) > 0);
+
if (result_type == NULL)
result_type = alloc_type_copy (index_type);
TYPE_CODE (result_type) = TYPE_CODE_RANGE;
TYPE_ZALLOC (result_type, sizeof (struct range_bounds));
TYPE_RANGE_DATA (result_type)->low = *low_bound;
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.
high.kind = PROP_CONST;
high.data.const_val = high_bound;
- result_type = create_range_type (result_type, index_type, &low, &high);
+ result_type = create_range_type (result_type, index_type, &low, &high, 0);
return result_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);
}
&& !type_not_allocated (result_type)))
{
LONGEST low_bound, high_bound;
+ unsigned int stride;
+
+ /* 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 = bit_stride;
+ 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;
In such cases, the array length should be zero. */
if (high_bound < low_bound)
TYPE_LENGTH (result_type) = 0;
- else if (bit_stride > 0)
+ else if (stride > 0)
TYPE_LENGTH (result_type) =
- (bit_stride * (high_bound - low_bound + 1) + 7) / 8;
+ (stride * (high_bound - low_bound + 1) + 7) / 8;
else
TYPE_LENGTH (result_type) =
TYPE_LENGTH (element_type) * (high_bound - low_bound + 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",
visible in lexical block BLOCK. */
struct type *
-lookup_template_type (char *name, struct type *type,
+lookup_template_type (const char *name, struct type *type,
const struct block *block)
{
struct symbol *sym;
|| 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);
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);
- static_range_type = create_range_type (copy_type (dyn_range_type),
- static_target_type,
- &low_bound, &high_bound);
+ LONGEST bias = TYPE_RANGE_DATA (dyn_range_type)->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);
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)
+ if (dwarf2_evaluate_property (prop, NULL, addr_stack, &value))
{
remove_dyn_prop (DYN_PROP_BYTE_STRIDE, type);
bit_stride = (unsigned int) (value * 8);
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:
gdb_stderr = &null_stream;
/* Call parse_and_eval_type() without fear of longjmp()s. */
- TRY
+ try
{
type = parse_and_eval_type (p, length);
}
- CATCH (except, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &except)
{
type = builtin_type (gdbarch)->builtin_void;
}
- END_CATCH
/* Stop suppressing error messages. */
gdb_stderr = saved_gdb_stderr;
}
}
-/* Ensure it is in .rodata (if available) by workarounding GCC PR 44690. */
+/* Ensure it is in .rodata (if available) by working around GCC PR 44690. */
const struct cplus_struct_type cplus_struct_default = { };
void
/* 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 = get_objfile_arch (objfile);
+ byte_order = gdbarch_byte_order (gdbarch);
+ }
+ const struct floatformat *fmt = floatformats[byte_order];
struct type *t;
bit = verify_floatformat (bit, fmt);
case TYPE_CODE_STRUCT:
case TYPE_CODE_UNION:
{
- if (TYPE_NFIELDS (type) == 0)
- {
- /* An empty struct has alignment 1. */
- align = 1;
- break;
- }
+ int number_of_non_static_fields = 0;
for (unsigned i = 0; i < TYPE_NFIELDS (type); ++i)
{
if (!field_is_static (&TYPE_FIELD (type, i)))
{
+ number_of_non_static_fields++;
ULONGEST f_align = type_align (TYPE_FIELD_TYPE (type, i));
if (f_align == 0)
{
align = f_align;
}
}
+ /* A struct with no fields, or with only static fields has an
+ alignment of 1. */
+ if (number_of_non_static_fields == 0)
+ align = 1;
}
break;
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. */
|| TYPE_LENGTH (type1) != TYPE_LENGTH (type2)
|| TYPE_UNSIGNED (type1) != TYPE_UNSIGNED (type2)
|| TYPE_NOSIGN (type1) != TYPE_NOSIGN (type2)
+ || TYPE_ENDIANITY_NOT_DEFAULT (type1) != TYPE_ENDIANITY_NOT_DEFAULT (type2)
|| TYPE_VARARGS (type1) != TYPE_VARARGS (type2)
|| TYPE_VECTOR (type1) != TYPE_VECTOR (type2)
|| TYPE_NOTTEXT (type1) != TYPE_NOTTEXT (type2)
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_NOSIGN");
}
+ if (TYPE_ENDIANITY_NOT_DEFAULT (type))
+ {
+ puts_filtered (" TYPE_ENDIANITY_NOT_DEFAULT");
+ }
if (TYPE_STUB (type))
{
puts_filtered (" TYPE_STUB");
builtin_type->builtin_unsigned_long_long
= arch_integer_type (gdbarch, gdbarch_long_long_bit (gdbarch),
1, "unsigned long long");
+ builtin_type->builtin_half
+ = arch_float_type (gdbarch, gdbarch_half_bit (gdbarch),
+ "half", gdbarch_half_format (gdbarch));
builtin_type->builtin_float
= arch_float_type (gdbarch, gdbarch_float_bit (gdbarch),
"float", gdbarch_float_format (gdbarch));
/* This set of objfile-based types is intended to be used by symbol
readers as basic types. */
-static const struct objfile_data *objfile_type_data;
+static const struct objfile_key<struct objfile_type,
+ gdb::noop_deleter<struct objfile_type>>
+ objfile_type_data;
const struct objfile_type *
objfile_type (struct objfile *objfile)
{
struct gdbarch *gdbarch;
- struct objfile_type *objfile_type
- = (struct objfile_type *) objfile_data (objfile, objfile_type_data);
+ struct objfile_type *objfile_type = objfile_type_data.get (objfile);
if (objfile_type)
return objfile_type;
= init_integer_type (objfile, gdbarch_addr_bit (gdbarch), 1,
"__CORE_ADDR");
- set_objfile_data (objfile, objfile_type_data, objfile_type);
+ objfile_type_data.set (objfile, objfile_type);
return objfile_type;
}
_initialize_gdbtypes (void)
{
gdbtypes_data = gdbarch_data_register_post_init (gdbtypes_post_init);
- objfile_type_data = register_objfile_data ();
add_setshow_zuinteger_cmd ("overload", no_class, &overload_debug,
_("Set debugging of C++ overloading."),