/* Low level packing and unpacking of values for GDB, the GNU Debugger.
- Copyright (C) 1986-2016 Free Software Foundation, Inc.
+ Copyright (C) 1986-2017 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 "cp-abi.h"
#include "user-regs.h"
#include <algorithm>
-
-/* Prototypes for exported functions. */
-
-void _initialize_values (void);
+#include "completer.h"
/* Definition of a user function. */
struct internal_function
/* If the value has been released. */
unsigned int released : 1;
- /* Register number if the value is from a register. */
- short regnum;
-
/* Location of value (if lval). */
union
{
- /* If lval == lval_memory, this is the address in the inferior.
- If lval == lval_register, this is the byte offset into the
- registers structure. */
+ /* If lval == lval_memory, this is the address in the inferior */
CORE_ADDR address;
+ /*If lval == lval_register, the value is from a register. */
+ struct
+ {
+ /* Register number. */
+ int regnum;
+ /* Frame ID of "next" frame to which a register value is relative.
+ If the register value is found relative to frame F, then the
+ frame id of F->next will be stored in next_frame_id. */
+ struct frame_id next_frame_id;
+ } reg;
+
/* Pointer to internal variable. */
struct internalvar *internalvar;
} location;
/* Describes offset of a value within lval of a structure in target
- addressable memory units. If lval == lval_memory, this is an offset to
- the address. If lval == lval_register, this is a further offset from
- location.address within the registers structure. Note also the member
- embedded_offset below. */
+ addressable memory units. Note also the member embedded_offset
+ below. */
LONGEST offset;
/* Only used for bitfields; number of bits contained in them. */
bitfields. */
struct value *parent;
- /* Frame ID of "next" frame to which a register value is relative. A
- register value is indicated when the lval enum (above) is set to
- lval_register. So, if the register value is found relative to frame F,
- then the frame id of F->next will be stored in next_frame_id. */
- struct frame_id next_frame_id;
-
/* Type of the value. */
struct type *type;
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
val->enclosing_type = type;
VALUE_LVAL (val) = not_lval;
val->location.address = 0;
- VALUE_NEXT_FRAME_ID (val) = null_frame_id;
val->offset = 0;
val->bitpos = 0;
val->bitsize = 0;
- VALUE_REGNUM (val) = -1;
val->lazy = 1;
val->embedded_offset = 0;
val->pointed_to_offset = 0;
{
/* If result's target type is TYPE_CODE_STRUCT, proceed to
fetch its rtti type. */
- if ((TYPE_CODE (result) == TYPE_CODE_PTR
- || TYPE_CODE (result) == TYPE_CODE_REF)
+ if ((TYPE_CODE (result) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (result))
&& TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (result)))
== TYPE_CODE_STRUCT
&& !value_optimized_out (value))
CORE_ADDR
value_address (const struct value *value)
{
- if (value->lval == lval_internalvar
- || value->lval == lval_internalvar_component
- || value->lval == lval_xcallable)
+ if (value->lval != lval_memory)
return 0;
if (value->parent != NULL)
return value_address (value->parent) + value->offset;
CORE_ADDR
value_raw_address (const struct value *value)
{
- if (value->lval == lval_internalvar
- || value->lval == lval_internalvar_component
- || value->lval == lval_xcallable)
+ if (value->lval != lval_memory)
return 0;
return value->location.address;
}
void
set_value_address (struct value *value, CORE_ADDR addr)
{
- gdb_assert (value->lval != lval_internalvar
- && value->lval != lval_internalvar_component
- && value->lval != lval_xcallable);
+ gdb_assert (value->lval == lval_memory);
value->location.address = addr;
}
struct frame_id *
deprecated_value_next_frame_id_hack (struct value *value)
{
- return &value->next_frame_id;
+ gdb_assert (value->lval == lval_register);
+ return &value->location.reg.next_frame_id;
}
-short *
+int *
deprecated_value_regnum_hack (struct value *value)
{
- return &value->regnum;
+ gdb_assert (value->lval == lval_register);
+ return &value->location.reg.regnum;
}
int
val->offset = arg->offset;
val->bitpos = arg->bitpos;
val->bitsize = arg->bitsize;
- VALUE_NEXT_FRAME_ID (val) = VALUE_NEXT_FRAME_ID (arg);
- VALUE_REGNUM (val) = VALUE_REGNUM (arg);
val->lazy = arg->lazy;
val->embedded_offset = value_embedded_offset (arg);
val->pointed_to_offset = arg->pointed_to_offset;
"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;
return NULL;
}
-/* Complete NAME by comparing it to the names of internal variables.
- Returns a vector of newly allocated strings, or NULL if no matches
- were found. */
+/* Complete NAME by comparing it to the names of internal
+ variables. */
-VEC (char_ptr) *
-complete_internalvar (const char *name)
+void
+complete_internalvar (completion_tracker &tracker, const char *name)
{
- VEC (char_ptr) *result = NULL;
struct internalvar *var;
int len;
for (var = internalvars; var; var = var->next)
if (strncmp (var->name, name, len) == 0)
{
- char *r = xstrdup (var->name);
+ gdb::unique_xmalloc_ptr<char> copy (xstrdup (var->name));
- VEC_safe_push (char_ptr, result, r);
+ tracker.add_completion (std::move (copy));
}
-
- return result;
}
/* Create an internal variable with name NAME and with a void value.
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;
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. */
ABI-specific code is a more reasonable place to handle it. */
if (TYPE_CODE (value_type (val)) != TYPE_CODE_PTR
- && TYPE_CODE (value_type (val)) != TYPE_CODE_REF
+ && !TYPE_IS_REFERENCE (value_type (val))
&& gdbarch_integer_to_address_p (gdbarch))
return gdbarch_integer_to_address (gdbarch, value_type (val),
value_contents (val));
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:
+ case TYPE_CODE_RVALUE_REF:
/* Assume a CORE_ADDR can fit in a LONGEST (for now). Not sure
whether we want this to be true eventually. */
return extract_typed_address (valaddr, type);
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. */
+ value_embedded_offset (arg1));
}
set_value_component_location (v, arg1);
- VALUE_REGNUM (v) = VALUE_REGNUM (arg1);
- VALUE_NEXT_FRAME_ID (v) = VALUE_NEXT_FRAME_ID (arg1);
return v;
}
}
v = allocate_value (ftype);
+ VALUE_LVAL (v) = lval_memory;
if (sym)
{
set_value_address (v, BLOCK_START (SYMBOL_BLOCK_VALUE (sym)));
break;
case TYPE_CODE_REF:
+ case TYPE_CODE_RVALUE_REF:
case TYPE_CODE_PTR:
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));
break;
case TYPE_CODE_REF:
+ case TYPE_CODE_RVALUE_REF:
case TYPE_CODE_PTR:
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."),
v = allocate_value_lazy (type);
else
v = value_from_contents (type, valaddr);
- set_value_address (v, address);
VALUE_LVAL (v) = lval_memory;
+ set_value_address (v, address);
return v;
}
if (TYPE_DATA_LOCATION (resolved_type_no_typedef) != NULL
&& TYPE_DATA_LOCATION_KIND (resolved_type_no_typedef) == PROP_CONST)
address = TYPE_DATA_LOCATION_ADDR (resolved_type_no_typedef);
- set_value_address (v, address);
VALUE_LVAL (v) = lval_memory;
+ set_value_address (v, address);
return v;
}
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. */
}
v->offset = value_offset (whole) + offset + value_embedded_offset (whole);
set_value_component_location (v, whole);
- VALUE_REGNUM (v) = VALUE_REGNUM (whole);
- VALUE_FRAME_ID (v) = VALUE_FRAME_ID (whole);
return v;
}
{
const struct lval_funcs *funcs;
- if (TYPE_CODE (check_typedef (value_type (arg))) != TYPE_CODE_REF)
+ if (!TYPE_IS_REFERENCE (check_typedef (value_type (arg))))
return NULL;
if (value_lval_const (arg) != lval_computed)
if (retval)
return retval;
- if (TYPE_CODE (value_type_arg_tmp) != TYPE_CODE_REF)
+ if (!TYPE_IS_REFERENCE (value_type_arg_tmp))
return arg;
enc_type = check_typedef (value_enclosing_type (arg));