/* Low level packing and unpacking of values for GDB, the GNU Debugger.
- Copyright (C) 1986-2017 Free Software Foundation, Inc.
+ Copyright (C) 1986-2018 Free Software Foundation, Inc.
This file is part of GDB.
#include "target.h"
#include "language.h"
#include "demangle.h"
-#include "doublest.h"
#include "regcache.h"
#include "block.h"
-#include "dfp.h"
+#include "target-float.h"
#include "objfiles.h"
#include "valprint.h"
#include "cli/cli-decode.h"
#include <algorithm>
#include "completer.h"
-/* Prototypes for exported functions. */
-
-void _initialize_values (void);
-
/* Definition of a user function. */
struct internal_function
{
with LENGTH bits of VAL2's contents starting at OFFSET2 bits.
Return true if the available bits match. */
-static int
+static bool
value_contents_bits_eq (const struct value *val1, int offset1,
const struct value *val2, int offset2,
int length)
if (!find_first_range_overlap_and_match (&rp1[i], &rp2[i],
offset1, offset2, length,
&l_tmp, &h_tmp))
- return 0;
+ return false;
/* We're interested in the lowest/first range found. */
if (i == 0 || l_tmp < l)
/* Compare the available/valid contents. */
if (memcmp_with_bit_offsets (val1->contents, offset1,
val2->contents, offset2, l) != 0)
- return 0;
+ return false;
length -= h;
offset1 += h;
offset2 += h;
}
- return 1;
+ return true;
}
-int
+bool
value_contents_eq (const struct value *val1, LONGEST offset1,
const struct value *val2, LONGEST offset2,
LONGEST length)
length * TARGET_CHAR_BIT);
}
-/* Prototypes for local functions. */
-
-static void show_values (char *, int);
-
-static void show_convenience (char *, int);
-
/* The value-history records all the values printed
by print commands during this session. Each chunk
/* Implement the "set max-value-size" command. */
static void
-set_max_value_size (char *args, int from_tty,
+set_max_value_size (const char *args, int from_tty,
struct cmd_list_element *c)
{
gdb_assert (max_value_size == -1 || max_value_size >= 0);
funcs->free_closure (val);
}
else if (VALUE_LVAL (val) == lval_xcallable)
- free_xmethod_worker (val->location.xm_worker);
+ delete val->location.xm_worker;
xfree (val->contents);
VEC_free (range_s, val->unavailable);
}
static void
-show_values (char *num_exp, int from_tty)
+show_values (const char *num_exp, int from_tty)
{
int i;
struct value *val;
"show values +". If num_exp is null, this is unnecessary, since
"show values +" is not useful after "show values". */
if (from_tty && num_exp)
- {
- num_exp[0] = '+';
- num_exp[1] = '\0';
- }
+ set_repeat_arguments ("+");
}
\f
enum internalvar_kind
/* If the variable does not already exist create it and give it the
value given. If no value is given then the default is zero. */
static void
-init_if_undefined_command (char* args, int from_tty)
+init_if_undefined_command (const char* args, int from_tty)
{
struct internalvar* intvar;
the implementation of the sub-command that is created when
registering an internal function. */
static void
-function_command (char *command, int from_tty)
+function_command (const char *command, int from_tty)
{
/* Do nothing. */
}
}
static void
-show_convenience (char *ignore, int from_tty)
+show_convenience (const char *ignore, int from_tty)
{
struct gdbarch *gdbarch = get_current_arch ();
struct internalvar *var;
}
}
\f
-/* Return the TYPE_CODE_XMETHOD value corresponding to WORKER. */
+
+/* See value.h. */
struct value *
-value_of_xmethod (struct xmethod_worker *worker)
+value_from_xmethod (xmethod_worker_up &&worker)
{
- if (worker->value == NULL)
- {
- struct value *v;
+ struct value *v;
- v = allocate_value (builtin_type (target_gdbarch ())->xmethod);
- v->lval = lval_xcallable;
- v->location.xm_worker = worker;
- v->modifiable = 0;
- worker->value = v;
- }
+ v = allocate_value (builtin_type (target_gdbarch ())->xmethod);
+ v->lval = lval_xcallable;
+ v->location.xm_worker = worker.release ();
+ v->modifiable = 0;
- return worker->value;
+ return v;
}
/* Return the type of the result of TYPE_CODE_XMETHOD value METHOD. */
gdb_assert (TYPE_CODE (value_type (method)) == TYPE_CODE_XMETHOD
&& method->lval == lval_xcallable && argc > 0);
- return get_xmethod_result_type (method->location.xm_worker,
- argv[0], argv + 1, argc - 1);
+ return method->location.xm_worker->get_result_type
+ (argv[0], argv + 1, argc - 1);
}
/* Call the xmethod corresponding to the TYPE_CODE_XMETHOD value METHOD. */
gdb_assert (TYPE_CODE (value_type (method)) == TYPE_CODE_XMETHOD
&& method->lval == lval_xcallable && argc > 0);
- return invoke_xmethod (method->location.xm_worker,
- argv[0], argv + 1, argc - 1);
+ return method->location.xm_worker->invoke (argv[0], argv + 1, argc - 1);
}
\f
/* Extract a value as a C number (either long or double).
return unpack_long (value_type (val), value_contents (val));
}
-DOUBLEST
-value_as_double (struct value *val)
-{
- DOUBLEST foo;
- int inv;
-
- foo = unpack_double (value_type (val), value_contents (val), &inv);
- if (inv)
- error (_("Invalid floating value found in program."));
- return foo;
-}
-
/* Extract a value as a C pointer. Does not deallocate the value.
Note that val's type may not actually be a pointer; value_as_long
handles all the cases. */
return extract_signed_integer (valaddr, len, byte_order);
case TYPE_CODE_FLT:
- return (LONGEST) extract_typed_floating (valaddr, type);
-
case TYPE_CODE_DECFLOAT:
- /* libdecnumber has a function to convert from decimal to integer, but
- it doesn't work when the decimal number has a fractional part. */
- return (LONGEST) decimal_to_doublest (valaddr, len, byte_order);
+ return target_float_to_longest (valaddr, type);
case TYPE_CODE_PTR:
case TYPE_CODE_REF:
return 0; /* Placate lint. */
}
-/* Return a double value from the specified type and address.
- INVP points to an int which is set to 0 for valid value,
- 1 for invalid value (bad float format). In either case,
- the returned double is OK to use. Argument is in target
- format, result is in host format. */
-
-DOUBLEST
-unpack_double (struct type *type, const gdb_byte *valaddr, int *invp)
-{
- enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
- enum type_code code;
- int len;
- int nosign;
-
- *invp = 0; /* Assume valid. */
- type = check_typedef (type);
- code = TYPE_CODE (type);
- len = TYPE_LENGTH (type);
- nosign = TYPE_UNSIGNED (type);
- if (code == TYPE_CODE_FLT)
- {
- /* NOTE: cagney/2002-02-19: There was a test here to see if the
- floating-point value was valid (using the macro
- INVALID_FLOAT). That test/macro have been removed.
-
- It turns out that only the VAX defined this macro and then
- only in a non-portable way. Fixing the portability problem
- wouldn't help since the VAX floating-point code is also badly
- bit-rotten. The target needs to add definitions for the
- methods gdbarch_float_format and gdbarch_double_format - these
- exactly describe the target floating-point format. The
- problem here is that the corresponding floatformat_vax_f and
- floatformat_vax_d values these methods should be set to are
- also not defined either. Oops!
-
- Hopefully someone will add both the missing floatformat
- definitions and the new cases for floatformat_is_valid (). */
-
- if (!floatformat_is_valid (floatformat_from_type (type), valaddr))
- {
- *invp = 1;
- return 0.0;
- }
-
- return extract_typed_floating (valaddr, type);
- }
- else if (code == TYPE_CODE_DECFLOAT)
- return decimal_to_doublest (valaddr, len, byte_order);
- else if (nosign)
- {
- /* Unsigned -- be sure we compensate for signed LONGEST. */
- return (ULONGEST) unpack_long (type, valaddr);
- }
- else
- {
- /* Signed -- we are OK with unpack_long. */
- return unpack_long (type, valaddr);
- }
-}
-
/* Unpack raw data (copied from debugee, target byte order) at VALADDR
as a CORE_ADDR, assuming the raw data is described by type TYPE.
We don't assume any alignment for the raw data. Return value is in
return unpack_long (type, valaddr);
}
+bool
+is_floating_value (struct value *val)
+{
+ struct type *type = check_typedef (value_type (val));
+
+ if (is_floating_type (type))
+ {
+ if (!target_float_is_valid (value_contents (val), type))
+ error (_("Invalid floating value found in program."));
+ return true;
+ }
+
+ return false;
+}
+
\f
/* Get the value of the FIELDNO'th field (which must be static) of
TYPE. */
store_typed_address (buf, type, (CORE_ADDR) num);
break;
+ case TYPE_CODE_FLT:
+ case TYPE_CODE_DECFLOAT:
+ target_float_from_longest (buf, type, num);
+ break;
+
default:
error (_("Unexpected type (%d) encountered for integer constant."),
TYPE_CODE (type));
store_typed_address (buf, type, (CORE_ADDR) num);
break;
+ case TYPE_CODE_FLT:
+ case TYPE_CODE_DECFLOAT:
+ target_float_from_ulongest (buf, type, num);
+ break;
+
default:
error (_("Unexpected type (%d) encountered "
"for unsigned integer constant."),
return result;
}
-struct value *
-value_from_double (struct type *type, DOUBLEST num)
-{
- struct value *val = allocate_value (type);
- struct type *base_type = check_typedef (type);
- enum type_code code = TYPE_CODE (base_type);
-
- if (code == TYPE_CODE_FLT)
- {
- store_typed_floating (value_contents_raw (val), base_type, num);
- }
- else
- error (_("Unexpected type encountered for floating constant."));
-
- return val;
-}
-
-struct value *
-value_from_decfloat (struct type *type, const gdb_byte *dec)
-{
- struct value *val = allocate_value (type);
-
- memcpy (value_contents_raw (val), dec, TYPE_LENGTH (type));
- return val;
-}
-
/* Extract a value from the history file. Input will be of the form
$digits or $$digits. See block comment above 'write_dollar_variable'
for details. */