/* Perform non-arithmetic operations on values, for GDB.
- Copyright (C) 1986-2020 Free Software Foundation, Inc.
+ Copyright (C) 1986-2021 Free Software Foundation, Inc.
This file is part of GDB.
return arg2;
}
+/* See value.h. */
+
+gdb_mpq
+value_to_gdb_mpq (struct value *value)
+{
+ struct type *type = check_typedef (value_type (value));
+
+ gdb_mpq result;
+ if (is_floating_type (type))
+ {
+ double d = target_float_to_host_double (value_contents (value),
+ type);
+ mpq_set_d (result.val, d);
+ }
+ else
+ {
+ gdb_assert (is_integral_type (type)
+ || is_fixed_point_type (type));
+
+ gdb_mpz vz;
+ vz.read (gdb::make_array_view (value_contents (value),
+ TYPE_LENGTH (type)),
+ type_byte_order (type), type->is_unsigned ());
+ mpq_set_z (result.val, vz.val);
+
+ if (is_fixed_point_type (type))
+ mpq_mul (result.val, result.val,
+ type->fixed_point_scaling_factor ().val);
+ }
+
+ return result;
+}
+
+/* Assuming that TO_TYPE is a fixed point type, return a value
+ corresponding to the cast of FROM_VAL to that type. */
+
+static struct value *
+value_cast_to_fixed_point (struct type *to_type, struct value *from_val)
+{
+ struct type *from_type = value_type (from_val);
+
+ if (from_type == to_type)
+ return from_val;
+
+ if (!is_floating_type (from_type)
+ && !is_integral_type (from_type)
+ && !is_fixed_point_type (from_type))
+ error (_("Invalid conversion from type %s to fixed point type %s"),
+ from_type->name (), to_type->name ());
+
+ gdb_mpq vq = value_to_gdb_mpq (from_val);
+
+ /* Divide that value by the scaling factor to obtain the unscaled
+ value, first in rational form, and then in integer form. */
+
+ mpq_div (vq.val, vq.val, to_type->fixed_point_scaling_factor ().val);
+ gdb_mpz unscaled = vq.get_rounded ();
+
+ /* Finally, create the result value, and pack the unscaled value
+ in it. */
+ struct value *result = allocate_value (to_type);
+ unscaled.write (gdb::make_array_view (value_contents_raw (result),
+ TYPE_LENGTH (to_type)),
+ type_byte_order (to_type),
+ to_type->is_unsigned ());
+
+ return result;
+}
+
/* Cast value ARG2 to type TYPE and return as a value.
More general than a C cast: accepts any two types of the same length,
and if ARG2 is an lvalue it can be cast into anything at all. */
int convert_to_boolean = 0;
- if (value_type (arg2) == type)
- return arg2;
+ /* TYPE might be equal in meaning to the existing type of ARG2, but for
+ many reasons, might be a different type object (e.g. TYPE might be a
+ gdbarch owned type, while VALUE_TYPE (ARG2) could be an objfile owned
+ type).
+
+ In this case we want to preserve the LVAL of ARG2 as this allows the
+ resulting value to be used in more places. We do this by calling
+ VALUE_COPY if appropriate. */
+ if (types_deeply_equal (value_type (arg2), type))
+ {
+ /* If the types are exactly equal then we can avoid creating a new
+ value completely. */
+ if (value_type (arg2) != type)
+ {
+ arg2 = value_copy (arg2);
+ deprecated_set_value_type (arg2, type);
+ }
+ return arg2;
+ }
+
+ if (is_fixed_point_type (type))
+ return value_cast_to_fixed_point (type, arg2);
/* Check if we are casting struct reference to struct reference. */
if (TYPE_IS_REFERENCE (check_typedef (type)))
{
/* We dereference type; then we recurse and finally
- we generate value of the given reference. Nothing wrong with
+ we generate value of the given reference. Nothing wrong with
that. */
struct type *t1 = check_typedef (type);
struct type *dereftype = check_typedef (TYPE_TARGET_TYPE (t1));
int val_length = TYPE_LENGTH (type2);
LONGEST low_bound, high_bound, new_length;
- if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
+ if (!get_discrete_bounds (range_type, &low_bound, &high_bound))
low_bound = 0, high_bound = 0;
new_length = val_length / element_length;
if (val_length % element_length != 0)
scalar = (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_FLT
|| code2 == TYPE_CODE_DECFLOAT || code2 == TYPE_CODE_ENUM
- || code2 == TYPE_CODE_RANGE);
+ || code2 == TYPE_CODE_RANGE
+ || is_fixed_point_type (type2));
if ((code1 == TYPE_CODE_STRUCT || code1 == TYPE_CODE_UNION)
&& (code2 == TYPE_CODE_STRUCT || code2 == TYPE_CODE_UNION)
value_contents_raw (v), type);
return v;
}
+ else if (is_fixed_point_type (type2))
+ {
+ gdb_mpq fp_val;
+
+ fp_val.read_fixed_point
+ (gdb::make_array_view (value_contents (arg2), TYPE_LENGTH (type2)),
+ type_byte_order (type2), type2->is_unsigned (),
+ type2->fixed_point_scaling_factor ());
+
+ struct value *v = allocate_value (to_type);
+ target_float_from_host_double (value_contents_raw (v),
+ to_type, mpq_get_d (fp_val.val));
+ return v;
+ }
/* The only option left is an integral type. */
if (type2->is_unsigned ())
LONGEST longest;
/* When we cast pointers to integers, we mustn't use
- gdbarch_pointer_to_address to find the address the pointer
- represents, as value_as_long would. GDB should evaluate
- expressions just as the compiler would --- and the compiler
- sees a cast as a simple reinterpretation of the pointer's
- bits. */
+ gdbarch_pointer_to_address to find the address the pointer
+ represents, as value_as_long would. GDB should evaluate
+ expressions just as the compiler would --- and the compiler
+ sees a cast as a simple reinterpretation of the pointer's
+ bits. */
if (code2 == TYPE_CODE_PTR)
- longest = extract_unsigned_integer
+ longest = extract_unsigned_integer
(value_contents (arg2), TYPE_LENGTH (type2),
type_byte_order (type2));
else
- longest = value_as_long (arg2);
+ longest = value_as_long (arg2);
return value_from_longest (to_type, convert_to_boolean ?
(LONGEST) (longest ? 1 : 0) : longest);
}
otherwise occur when dealing with a target having two byte
pointers and four byte addresses. */
- int addr_bit = gdbarch_addr_bit (get_type_arch (type2));
+ int addr_bit = gdbarch_addr_bit (type2->arch ());
LONGEST longest = value_as_long (arg2);
if (addr_bit < sizeof (LONGEST) * HOST_CHAR_BIT)
if (is_ref)
result = value_cast (type, value_ref (value_ind (result),
- type->code ()));
+ type->code ()));
return result;
}
enum target_xfer_status status;
ULONGEST xfered_partial;
- status = target_xfer_partial (current_top_target (),
+ status = target_xfer_partial (current_inferior ()->top_target (),
object, NULL,
buffer + xfered_total * unit_size, NULL,
memaddr + xfered_total,
{
case lval_internalvar:
set_internalvar (VALUE_INTERNALVAR (toval), fromval);
- return value_of_internalvar (get_type_arch (type),
+ return value_of_internalvar (type->arch (),
VALUE_INTERNALVAR (toval));
case lval_internalvar_component:
const gdb_byte *dest_buffer;
CORE_ADDR changed_addr;
int changed_len;
- gdb_byte buffer[sizeof (LONGEST)];
+ gdb_byte buffer[sizeof (LONGEST)];
if (value_bitsize (toval))
{
{
struct value *parent = value_parent (toval);
LONGEST offset = value_offset (parent) + value_offset (toval);
- int changed_len;
+ size_t changed_len;
gdb_byte buffer[sizeof (LONGEST)];
int optim, unavail;
+ HOST_CHAR_BIT - 1)
/ HOST_CHAR_BIT;
- if (changed_len > (int) sizeof (LONGEST))
+ if (changed_len > sizeof (LONGEST))
error (_("Can't handle bitfields which "
"don't fit in a %d bit word."),
(int) sizeof (LONGEST) * HOST_CHAR_BIT);
if (!get_frame_register_bytes (frame, value_reg, offset,
- changed_len, buffer,
+ {buffer, changed_len},
&optim, &unavail))
{
if (optim)
value_bitpos (toval), value_bitsize (toval));
put_frame_register_bytes (frame, value_reg, offset,
- changed_len, buffer);
+ {buffer, changed_len});
}
else
{
}
else
{
+ gdb::array_view<const gdb_byte> contents
+ = gdb::make_array_view (value_contents (fromval),
+ TYPE_LENGTH (type));
put_frame_register_bytes (frame, value_reg,
value_offset (toval),
- TYPE_LENGTH (type),
- value_contents (fromval));
+ contents);
}
}
case lval_register:
case lval_computed:
- gdb::observers::target_changed.notify (current_top_target ());
+ gdb::observers::target_changed.notify
+ (current_inferior ()->top_target ());
/* Having destroyed the frame cache, restore the selected
frame. */
struct type *enc_type;
/* We may be pointing to something embedded in a larger object.
- Get the real type of the enclosing object. */
+ Get the real type of the enclosing object. */
enc_type = check_typedef (value_enclosing_type (arg1));
enc_type = TYPE_TARGET_TYPE (enc_type);
ARM. */
/* We should be doing much hairier argument matching (see
- section 13.2 of the ARM), but as a quick kludge, just check
- for the same type code. */
+ section 13.2 of the ARM), but as a quick kludge, just check
+ for the same type code. */
if (t1[i].type ()->code () != value_type (t2[i])->code ())
return i + 1;
}
struct value *v = NULL;
struct type *basetype = check_typedef (TYPE_BASECLASS (type, i));
/* If we are looking for baseclasses, this is what we get when
- we hit them. But it could happen that the base part's member
- name is not yet filled in. */
+ we hit them. But it could happen that the base part's member
+ name is not yet filled in. */
int found_baseclass = (m_looking_for_baseclass
&& TYPE_BASECLASS_NAME (type, i) != NULL
&& (strcmp_iw (m_name,
/* if there are no arguments ...do this... */
/* Try as a field first, because if we succeed, there is less
- work to be done. */
+ work to be done. */
v = search_struct_field (name, *argp, t, 0);
if (v)
return v;
/* C++: If it was not found as a data field, then try to
- return it as a pointer to a method. */
+ return it as a pointer to a method. */
v = search_struct_method (name, argp, args, 0,
static_memfuncp, t);
else if (v == 0)
{
/* See if user tried to invoke data as function. If so, hand it
- back. If it's not callable (i.e., a pointer to function),
- gdb should give an error. */
+ back. If it's not callable (i.e., a pointer to function),
+ gdb should give an error. */
v = search_struct_field (name, *argp, t, 0);
/* If we found an ordinary field, then it is not a method call.
So, treat it as if it were a static member function. */
if (!v)
throw_error (NOT_FOUND_ERROR,
- _("Structure has no component named %s."), name);
+ _("Structure has no component named %s."), name);
return v;
}
value_find_oload_method_list (&temp, name, 0, &methods,
&xmethods, &basetype, &boffset);
/* If this is a method only search, and no methods were found
- the search has failed. */
+ the search has failed. */
if (method == METHOD && methods.empty () && xmethods.empty ())
error (_("Couldn't find method %s%s%s"),
obj_type_name,
const char *qualified_name = NULL;
/* If the overload match is being search for both as a method
- and non member function, the first argument must now be
- dereferenced. */
+ and non member function, the first argument must now be
+ dereferenced. */
if (method == BOTH)
args[0] = value_ind (args[0]);
if (fsym)
- {
- qualified_name = fsym->natural_name ();
+ {
+ qualified_name = fsym->natural_name ();
- /* If we have a function with a C++ name, try to extract just
+ /* If we have a function with a C++ name, try to extract just
the function part. Do not try this for non-functions (e.g.
function pointers). */
- if (qualified_name
- && (check_typedef (SYMBOL_TYPE (fsym))->code ()
+ if (qualified_name
+ && (check_typedef (SYMBOL_TYPE (fsym))->code ()
== TYPE_CODE_FUNC))
- {
+ {
temp_func = cp_func_name (qualified_name);
/* If cp_func_name did not remove anything, the name of the
- symbol did not include scope or argument types - it was
- probably a C-style function. */
+ symbol did not include scope or argument types - it was
+ probably a C-style function. */
if (temp_func != nullptr)
{
if (strcmp (temp_func.get (), qualified_name) == 0)
else
func_name = temp_func.get ();
}
- }
- }
+ }
+ }
else
{
func_name = name;
not a function at all. Just return the same symbol. Do the
same if cp_func_name fails for some reason. */
if (func_name == NULL)
- {
+ {
*symp = fsym;
- return 0;
- }
+ return 0;
+ }
func_oload_champ = find_oload_champ_namespace (args,
- func_name,
- qualified_name,
- &functions,
- &func_badness,
- no_adl);
+ func_name,
+ qualified_name,
+ &functions,
+ &func_badness,
+ no_adl);
if (func_oload_champ >= 0)
func_match_quality = classify_oload_match (func_badness,
/* Did we find a match ? */
if (method_oload_champ == -1 && func_oload_champ == -1)
throw_error (NOT_FOUND_ERROR,
- _("No symbol \"%s\" in current context."),
- name);
+ _("No symbol \"%s\" in current context."),
+ name);
/* If we have found both a method match and a function
match, find out which one is better, and calculate match
if (method_oload_champ >= 0 && func_oload_champ >= 0)
{
switch (compare_badness (func_badness, method_badness))
- {
+ {
case 0: /* Top two contenders are equally good. */
/* FIXME: GDB does not support the general ambiguous case.
All candidates should be collected and presented the
default:
error (_("Internal error: unexpected overload comparison result"));
break;
- }
+ }
}
else
{
}
/* Compare parameter types to supplied argument types. Skip
- THIS for static methods. */
+ THIS for static methods. */
bv = rank_function (parm_types,
args.slice (static_offset));
for (ix = 1; ix <= nargs - static_offset; ix++)
{
/* If this conversion is as bad as INCOMPATIBLE_TYPE_BADNESS
- or worse return INCOMPATIBLE. */
+ or worse return INCOMPATIBLE. */
if (compare_ranks (oload_champ_bv[ix],
- INCOMPATIBLE_TYPE_BADNESS) <= 0)
+ INCOMPATIBLE_TYPE_BADNESS) <= 0)
return INCOMPATIBLE; /* Truly mismatched types. */
/* Otherwise If this conversion is as bad as
- NS_POINTER_CONVERSION_BADNESS or worse return NON_STANDARD. */
+ NS_POINTER_CONVERSION_BADNESS or worse return NON_STANDARD. */
else if (compare_ranks (oload_champ_bv[ix],
- NS_POINTER_CONVERSION_BADNESS) <= 0)
+ NS_POINTER_CONVERSION_BADNESS) <= 0)
worst = NON_STANDARD; /* Non-standard type conversions
needed. */
}
int name_len = strlen (name);
gdb_assert (type->code () == TYPE_CODE_ENUM
- && TYPE_DECLARED_CLASS (type));
+ && type->is_declared_class ());
for (i = TYPE_N_BASECLASSES (type); i < type->num_fields (); ++i)
{
{
if (compare_ranks (rank_one_type (t1->field (start + i).type (),
t2->field (i).type (), NULL),
- EXACT_MATCH_BADNESS) != 0)
+ EXACT_MATCH_BADNESS) != 0)
return 0;
}
{
struct type *t = vt->field (i).type ();
if (types_equal (t, cls))
- {
- if (BASETYPE_VIA_VIRTUAL (vt, i))
- {
+ {
+ if (BASETYPE_VIA_VIRTUAL (vt, i))
+ {
const gdb_byte *adr = value_contents_for_printing (v);
*boffs = baseclass_offset (vt, i, adr, value_offset (v),
value_as_long (v), v);
*isvirt = true;
- }
- else
+ }
+ else
*isvirt = false;
- return true;
- }
+ return true;
+ }
if (get_baseclass_offset (check_typedef (t), cls, v, boffs, isvirt))
- {
+ {
if (*isvirt == false) /* Add non-virtual base offset. */
{
const gdb_byte *adr = value_contents_for_printing (v);
bool isvirt = false;
if (get_baseclass_offset (domain, curtype, v, &boff,
&isvirt))
- mem_offset += boff;
+ mem_offset += boff;
else
- {
- struct type *p = check_typedef (value_type (this_v));
- p = check_typedef (TYPE_TARGET_TYPE (p));
- if (get_baseclass_offset (p, curtype, this_v,
+ {
+ struct type *p = check_typedef (value_type (this_v));
+ p = check_typedef (TYPE_TARGET_TYPE (p));
+ if (get_baseclass_offset (p, curtype, this_v,
&boff, &isvirt))
- mem_offset += boff;
- }
+ mem_offset += boff;
+ }
}
tmp = lookup_pointer_type (TYPE_TARGET_TYPE (type));
result = value_from_pointer (tmp,
{
try
- {
+ {
target = value_ind (v);
- }
+ }
catch (const gdb_exception_error &except)
{
if (except.error == MEMORY_ERROR)
{
/* value_ind threw a memory error. The pointer is NULL or
- contains an uninitialized value: we can't determine any
- type. */
+ contains an uninitialized value: we can't determine any
+ type. */
return NULL;
}
throw;
real_type = make_cv_type (TYPE_CONST (target_type),
TYPE_VOLATILE (target_type), real_type, NULL);
if (TYPE_IS_REFERENCE (type))
- real_type = lookup_reference_type (real_type, type->code ());
+ real_type = lookup_reference_type (real_type, type->code ());
else if (type->code () == TYPE_CODE_PTR)
- real_type = lookup_pointer_type (real_type);
+ real_type = lookup_pointer_type (real_type);
else
- internal_error (__FILE__, __LINE__, _("Unexpected value type."));
+ internal_error (__FILE__, __LINE__, _("Unexpected value type."));
/* Copy qualifiers to the pointer/reference. */
real_type = make_cv_type (TYPE_CONST (type), TYPE_VOLATILE (type),
error (_("array not associated"));
range_type = array_type->index_type ();
- if (get_discrete_bounds (range_type, &lowerbound, &upperbound) < 0)
+ if (!get_discrete_bounds (range_type, &lowerbound, &upperbound))
error (_("slice from bad array or bitstring"));
if (lowbound < lowerbound || length < 0