+2020-04-24 Tom Tromey <tromey@adacore.com>
+
+ * ada-lang.c (ada_discrete_type_high_bound, ada_discrete_type_low)
+ (ada_value_primitive_packed_val): Update.
+ * ada-valprint.c (ada_value_print_1): Update.
+ * dwarf2/loc.c (evaluate_for_locexpr_baton): New struct.
+ (dwarf2_locexpr_baton_eval): Take a property_addr_info rather than
+ just an address. Use evaluate_for_locexpr_baton.
+ (dwarf2_evaluate_property): Update.
+ * dwarf2/loc.h (struct property_addr_info) <valaddr>: Now an
+ array_view.
+ * findvar.c (default_read_var_value): Update.
+ * gdbtypes.c (compute_variant_fields_inner)
+ (resolve_dynamic_type_internal): Update.
+ (resolve_dynamic_type): Change type of valaddr parameter.
+ * gdbtypes.h (resolve_dynamic_type): Update.
+ * valarith.c (value_subscripted_rvalue): Update.
+ * value.c (value_from_contents_and_address): Update.
+
2020-04-24 Tom Tromey <tromey@adacore.com>
* dwarf2/loc.c (dwarf2_locexpr_baton_eval): Add
LONGEST
ada_discrete_type_high_bound (struct type *type)
{
- type = resolve_dynamic_type (type, NULL, 0);
+ type = resolve_dynamic_type (type, {}, 0);
switch (TYPE_CODE (type))
{
case TYPE_CODE_RANGE:
LONGEST
ada_discrete_type_low_bound (struct type *type)
{
- type = resolve_dynamic_type (type, NULL, 0);
+ type = resolve_dynamic_type (type, {}, 0);
switch (TYPE_CODE (type))
{
case TYPE_CODE_RANGE:
staging.data (), staging.size (),
is_big_endian, has_negatives (type),
is_scalar);
- type = resolve_dynamic_type (type, staging.data (), 0);
+ type = resolve_dynamic_type (type, staging, 0);
if (TYPE_LENGTH (type) < (bit_size + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT)
{
/* This happens when the length of the object is dynamic,
const gdb_byte *valaddr = value_contents_for_printing (val);
CORE_ADDR address = value_address (val);
- type = ada_check_typedef (resolve_dynamic_type (type, valaddr, address));
+ gdb::array_view<const gdb_byte> view
+ = gdb::make_array_view (valaddr, TYPE_LENGTH (type));
+ type = ada_check_typedef (resolve_dynamic_type (type, view, address));
if (type != saved_type)
{
val = value_copy (val);
NULL, 0);
}
-/* Evaluates a dwarf expression and stores the result in VAL, expecting
- that the dwarf expression only produces a single CORE_ADDR. FRAME is the
- frame in which the expression is evaluated. ADDR is a context (location of
- a variable) and might be needed to evaluate the location expression.
- PUSH_INITIAL_VALUE is true if ADDR should be pushed on the stack
- before evaluating the expression; this is required by certain
- forms of DWARF expression. Returns 1 on success, 0 otherwise. */
+/* A specialization of dwarf_evaluate_loc_desc that is used by
+ dwarf2_locexpr_baton_eval. This subclass exists to handle the case
+ where a caller of dwarf2_locexpr_baton_eval passes in some data,
+ but with the address being 0. In this situation, we arrange for
+ memory reads to come from the passed-in buffer. */
+
+struct evaluate_for_locexpr_baton : public dwarf_evaluate_loc_desc
+{
+ /* The data that was passed in. */
+ gdb::array_view<const gdb_byte> data_view;
+
+ CORE_ADDR get_object_address () override
+ {
+ if (data_view.data () == nullptr && obj_address == 0)
+ error (_("Location address is not set."));
+ return obj_address;
+ }
+
+ void read_mem (gdb_byte *buf, CORE_ADDR addr, size_t len) override
+ {
+ if (len == 0)
+ return;
+
+ /* Prefer the passed-in memory, if it exists. */
+ CORE_ADDR offset = addr - obj_address;
+ if (offset < data_view.size () && offset + len <= data_view.size ())
+ {
+ memcpy (buf, data_view.data (), len);
+ return;
+ }
+
+ read_memory (addr, buf, len);
+ }
+};
+
+/* Evaluates a dwarf expression and stores the result in VAL,
+ expecting that the dwarf expression only produces a single
+ CORE_ADDR. FRAME is the frame in which the expression is
+ evaluated. ADDR_STACK is a context (location of a variable) and
+ might be needed to evaluate the location expression.
+ PUSH_INITIAL_VALUE is true if the address (either from ADDR_STACK,
+ or the default of 0) should be pushed on the DWARF expression
+ evaluation stack before evaluating the expression; this is required
+ by certain forms of DWARF expression. Returns 1 on success, 0
+ otherwise. */
static int
dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
struct frame_info *frame,
- CORE_ADDR addr,
+ const struct property_addr_info *addr_stack,
CORE_ADDR *valp,
bool push_initial_value)
{
if (dlbaton == NULL || dlbaton->size == 0)
return 0;
- dwarf_evaluate_loc_desc ctx;
+ evaluate_for_locexpr_baton ctx;
ctx.frame = frame;
ctx.per_cu = dlbaton->per_cu;
- ctx.obj_address = addr;
+ if (addr_stack == nullptr)
+ ctx.obj_address = 0;
+ else
+ {
+ ctx.obj_address = addr_stack->addr;
+ ctx.data_view = addr_stack->valaddr;
+ }
objfile = dlbaton->per_cu->objfile ();
ctx.offset = dlbaton->per_cu->text_offset ();
if (push_initial_value)
- ctx.push_address (addr, false);
+ ctx.push_address (ctx.obj_address, false);
try
{
= (const struct dwarf2_property_baton *) prop->data.baton;
gdb_assert (baton->property_type != NULL);
- if (dwarf2_locexpr_baton_eval (&baton->locexpr, frame,
- addr_stack ? addr_stack->addr : 0,
+ if (dwarf2_locexpr_baton_eval (&baton->locexpr, frame, addr_stack,
value, push_initial_value))
{
if (baton->locexpr.is_reference)
}
if (pinfo == NULL)
error (_("cannot find reference address for offset property"));
- if (pinfo->valaddr != NULL)
+ if (pinfo->valaddr.data () != NULL)
val = value_from_contents
(baton->offset_info.type,
- pinfo->valaddr + baton->offset_info.offset);
+ pinfo->valaddr.data () + baton->offset_info.offset);
else
val = value_at (baton->offset_info.type,
pinfo->addr + baton->offset_info.offset);
struct type *type;
/* If not NULL, a buffer containing the object's value. */
- const gdb_byte *valaddr;
+ gdb::array_view<const gdb_byte> valaddr;
/* The address of that object. */
CORE_ADDR addr;
if (is_dynamic_type (type))
{
/* Value is a constant byte-sequence and needs no memory access. */
- type = resolve_dynamic_type (type, NULL, /* Unused address. */ 0);
+ type = resolve_dynamic_type (type, {}, /* Unused address. */ 0);
}
/* Put the constant back in target format. */
v = allocate_value (type);
if (is_dynamic_type (type))
{
/* Value is a constant byte-sequence and needs no memory access. */
- type = resolve_dynamic_type (type, NULL, /* Unused address. */ 0);
+ type = resolve_dynamic_type (type, {}, /* Unused address. */ 0);
}
v = allocate_value (type);
memcpy (value_contents_raw (v), SYMBOL_VALUE_BYTES (var),
case LOC_OPTIMIZED_OUT:
if (is_dynamic_type (type))
- type = resolve_dynamic_type (type, NULL, /* Unused address. */ 0);
+ type = resolve_dynamic_type (type, {}, /* Unused address. */ 0);
return allocate_optimized_out_value (type);
default:
error (_("Cannot determine struct field location"
" (invalid location kind)"));
- if (addr_stack->valaddr != NULL)
- discr_value = unpack_field_as_long (type, addr_stack->valaddr, idx);
+ 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
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;
/* 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
ADDR specifies the location of the variable the type is bound to.
If TYPE has no dynamic properties return TYPE; otherwise a new type with
static properties is returned. */
-extern struct type *resolve_dynamic_type (struct type *type,
- const gdb_byte *valaddr,
- CORE_ADDR addr);
+extern struct type *resolve_dynamic_type
+ (struct type *type, gdb::array_view<const gdb_byte> valaddr,
+ CORE_ADDR addr);
/* * Predicate if the type has dynamic values, which are not resolved yet. */
extern int is_dynamic_type (struct type *type);
CORE_ADDR address;
address = value_address (array) + elt_offs;
- elt_type = resolve_dynamic_type (elt_type, NULL, address);
+ elt_type = resolve_dynamic_type (elt_type, {}, address);
}
return value_from_component (array, elt_type, elt_offs);
const gdb_byte *valaddr,
CORE_ADDR address)
{
- struct type *resolved_type = resolve_dynamic_type (type, valaddr, address);
+ gdb::array_view<const gdb_byte> view;
+ if (valaddr != nullptr)
+ view = gdb::make_array_view (valaddr, TYPE_LENGTH (type));
+ struct type *resolved_type = resolve_dynamic_type (type, view, address);
struct type *resolved_type_no_typedef = check_typedef (resolved_type);
struct value *v;