2010-06-11 Tom Tromey <tromey@redhat.com>
+ PR gdb/9977, PR exp/11636:
+ * value.h (value_offset): Update.
+ (struct lval_funcs) <check_validity>: New field.
+ <copy_closure>: Make argument const.
+ (value_computed_closure): Update.
+ (value_contents_for_printing): Declare.
+ (value_bits_valid): Likewise.
+ (val_print): Likewise.
+ (set_value_component_location): Update.
+ (value_entirely_optimized_out): Declare.
+ * value.c (value_offset): Argument now const.
+ (require_not_optimized_out): New function.
+ (value_contents_for_printing): New function.
+ (value_contents_all): Call require_not_optimized_out.
+ (value_contents): Likewise.
+ (value_bits_valid): New function.
+ (value_computed_closure): Argument now const.
+ (set_value_component_location): Make 'whole' argument const.
+ (value_entirely_optimized_out): New function.
+ (value_bitsize): Argument now 'const'.
+ (value_bitpos): Likewise.
+ (value_type): Likewise.
+ * valprint.h (val_print_array_elements): Update.
+ * valprint.c (val_print): Add 'val' argument. Use
+ valprint_check_validity.
+ (valprint_check_validity): New function.
+ (value_check_printable): Use value_entirely_optimized_out.
+ (common_val_print): Update.
+ (value_print): Likewise.
+ (val_print_array_elements): Add 'val' argument.
+ * valops.c (value_fetch_lazy): Use value_contents_for_printing,
+ value_bits_valid. Reinit frame cache for lval_computed.
+ * sh64-tdep.c (sh64_do_register): Update.
+ * scm-valprint.c (scm_val_print): Add 'val' argument.
+ * scm-lang.h (scm_val_print): Update.
+ * python/python.h (apply_val_pretty_printer): Update.
+ * python/py-prettyprint.c (apply_val_pretty_printer): Add 'val'
+ argument. Call set_value_component_location.
+ * printcmd.c (print_scalar_formatted): Update.
+ * p-valprint.c (pascal_val_print): Add 'val' argument.
+ (pascal_object_print_value_fields): Likewise.
+ (pascal_object_print_value): Likewise.
+ (pascal_object_print_static_field): Update.
+ * p-lang.h (pascal_val_print): Update.
+ (pascal_object_print_value_fields): Update.
+ * mt-tdep.c (mt_registers_info): Update.
+ * mi/mi-main.c (get_register): Update.
+ (mi_cmd_data_evaluate_expression): Use common_val_print.
+ * m2-valprint.c (m2_print_array_contents): Add 'val' argument.
+ (m2_print_unbounded_array): Likewise.
+ (m2_val_print): Likewise.
+ * m2-lang.h (m2_val_print): Update.
+ * language.h (struct language_defn) <la_val_print>: Add 'val'
+ argument.
+ (LA_VAL_PRINT): Likewise.
+ * language.c (unk_lang_val_print): Add 'val' argument.
+ * jv-valprint.c (java_print_value_fields): Add 'val' argument.
+ (java_val_print): Likewise.
+ * jv-lang.h (java_val_print): Add 'val' argument.
+ * infcmd.c (default_print_registers_info): Update.
+ * f-valprint.c (f77_print_array_1): Add 'val' argument.
+ (f77_print_array): Likewise.
+ (f_val_print): Likewise.
+ * f-lang.h (f_val_print): Add 'val' argument.
+ * dwarf2loc.c (read_pieced_value): Use value_bitsize and
+ value_bitpos.
+ <DWARF_VALUE_OPTIMIZED_OUT>: Don't print warning. Call
+ set_value_optimized_out.
+ (write_pieced_value): Use value_bitsize and value_bitpos.
+ <default>: Don't exit loop.
+ (check_pieced_value_validity): New function.
+ (pieced_value_funcs): Reference check_pieced_value_validity,
+ check_pieced_value_invalid.
+ (copy_pieced_value_closure): Update.
+ (check_pieced_value_bits): New function.
+ (check_pieced_value_invalid): New function.
+ * d-valprint.c (dynamic_array_type): Add 'val' argument.
+ (d_val_print): Likewise.
+ * d-lang.h (d_val_print): Update.
+ * cp-valprint.c (cp_print_value_fields): Add 'val' argument.
+ (cp_print_value_fields_rtti): Likewise.
+ (cp_print_value): Likewise.
+ (cp_print_static_field): Update.
+ * c-valprint.c (c_val_print): Add 'val' argument.
+ (c_value_print): Update.
+ * c-lang.h (c_val_print): Update.
+ (cp_print_value_fields): Likewise.
+ (cp_print_value_fields_rtti): Likewise.
+ * ada-valprint.c (struct ada_val_print_args): Remove.
+ (val_print_packed_array_elements): Add 'val' argument.
+ (ada_val_print): Likewise. Rewrite.
+ (ada_val_print_stub): Remove.
+ (ada_val_print_array): Add 'val' argument.
+ (ada_val_print_1): Likewise.
+ (print_variant_part): Likewise.
+ (ada_value_print): Update.
+ (print_record): Add 'val' argument.
+ (print_field_values): Likewise.
+ * ada-lang.h (ada_val_print): Update.
+
+2010-06-11 Tom Tromey <tromey@redhat.com>
+
* vec.h (VEC_cleanup): New macro.
(DEF_VEC_ALLOC_FUNC_I): Update.
(DEF_VEC_ALLOC_FUNC_P): Likewise.
extern int ada_val_print (struct type *, const gdb_byte *, int, CORE_ADDR,
struct ui_file *, int,
+ const struct value *,
const struct value_print_options *);
extern int ada_value_print (struct value *, struct ui_file *,
#include "exceptions.h"
#include "objfiles.h"
-/* Encapsulates arguments to ada_val_print. */
-struct ada_val_print_args
-{
- struct type *type;
- const gdb_byte *valaddr0;
- int embedded_offset;
- CORE_ADDR address;
- struct ui_file *stream;
- int recurse;
- const struct value_print_options *options;
-};
-
static void print_record (struct type *, const gdb_byte *, struct ui_file *,
- int, const struct value_print_options *);
+ int,
+ const struct value *,
+ const struct value_print_options *);
static int print_field_values (struct type *, const gdb_byte *,
struct ui_file *, int,
+ const struct value *,
const struct value_print_options *,
int, struct type *,
const gdb_byte *);
static void adjust_type_signedness (struct type *);
-static int ada_val_print_stub (void *args0);
-
static int ada_val_print_1 (struct type *, const gdb_byte *, int, CORE_ADDR,
struct ui_file *, int,
+ const struct value *,
const struct value_print_options *);
\f
val_print_packed_array_elements (struct type *type, const gdb_byte *valaddr,
int bitoffset, struct ui_file *stream,
int recurse,
+ const struct value *val,
const struct value_print_options *options)
{
unsigned int i;
opts.deref_ref = 0;
val_print (elttype, value_contents (v0), 0, 0, stream,
- recurse + 1, &opts, current_language);
+ recurse + 1, val, &opts, current_language);
annotate_elt_rep (i - i0);
fprintf_filtered (stream, _(" <repeats %u times>"), i - i0);
annotate_elt_rep_end ();
stream, options);
}
val_print (elttype, value_contents (v0), 0, 0, stream,
- recurse + 1, &opts, current_language);
+ recurse + 1, val, &opts, current_language);
annotate_elt ();
}
}
ada_val_print (struct type *type, const gdb_byte *valaddr0,
int embedded_offset, CORE_ADDR address,
struct ui_file *stream, int recurse,
+ const struct value *val,
const struct value_print_options *options)
{
- struct ada_val_print_args args;
- args.type = type;
- args.valaddr0 = valaddr0;
- args.embedded_offset = embedded_offset;
- args.address = address;
- args.stream = stream;
- args.recurse = recurse;
- args.options = options;
-
- return catch_errors (ada_val_print_stub, &args, NULL, RETURN_MASK_ALL);
-}
+ volatile struct gdb_exception except;
+ int result = 0;
-/* Helper for ada_val_print; used as argument to catch_errors to
- unmarshal the arguments to ada_val_print_1, which does the work. */
-static int
-ada_val_print_stub (void *args0)
-{
- struct ada_val_print_args *argsp = (struct ada_val_print_args *) args0;
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ result = ada_val_print_1 (type, valaddr0, embedded_offset, address,
+ stream, recurse, val, options);
+ }
- return ada_val_print_1 (argsp->type, argsp->valaddr0,
- argsp->embedded_offset, argsp->address,
- argsp->stream, argsp->recurse, argsp->options);
+ if (except.reason < 0)
+ result = 0;
+
+ return result;
}
/* Assuming TYPE is a simple array, print the value of this array located
static int
ada_val_print_array (struct type *type, const gdb_byte *valaddr,
CORE_ADDR address, struct ui_file *stream, int recurse,
+ const struct value *val,
const struct value_print_options *options)
{
enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
print_optional_low_bound (stream, type, options);
if (TYPE_FIELD_BITSIZE (type, 0) > 0)
val_print_packed_array_elements (type, valaddr, 0, stream,
- recurse, options);
+ recurse, val, options);
else
val_print_array_elements (type, valaddr, address, stream,
- recurse, options, 0);
+ recurse, val, options, 0);
fprintf_filtered (stream, ")");
}
ada_val_print_1 (struct type *type, const gdb_byte *valaddr0,
int embedded_offset, CORE_ADDR address,
struct ui_file *stream, int recurse,
+ const struct value *original_value,
const struct value_print_options *options)
{
unsigned int len;
}
else
retn = ada_val_print_1 (value_type (val), value_contents (val), 0,
- value_address (val), stream, recurse, options);
+ value_address (val), stream, recurse,
+ NULL, options);
value_free_to_mark (mark);
return retn;
}
{
default:
return c_val_print (type, valaddr0, embedded_offset, address, stream,
- recurse, options);
+ recurse, original_value, options);
case TYPE_CODE_PTR:
{
int ret = c_val_print (type, valaddr0, embedded_offset, address,
- stream, recurse, options);
+ stream, recurse, original_value, options);
if (ada_is_tag_type (type))
{
(type, valaddr, 0));
return ada_val_print_1 (target_type, value_contents (v), 0, 0,
- stream, recurse + 1, options);
+ stream, recurse + 1, NULL, options);
}
else
return ada_val_print_1 (TYPE_TARGET_TYPE (type),
valaddr0, embedded_offset,
- address, stream, recurse, options);
+ address, stream, recurse, original_value, options);
}
else
{
case TYPE_CODE_FLT:
if (options->format)
return c_val_print (type, valaddr0, embedded_offset, address, stream,
- recurse, options);
+ recurse, original_value, options);
else
ada_print_floating (valaddr0 + embedded_offset, type, stream);
break;
}
else
{
- print_record (type, valaddr, stream, recurse, options);
+ print_record (type, valaddr, stream, recurse, original_value,
+ options);
return 0;
}
case TYPE_CODE_ARRAY:
return ada_val_print_array (type, valaddr, address, stream,
- recurse, options);
+ recurse, original_value, options);
case TYPE_CODE_REF:
/* For references, the debugger is expected to print the value as
val_print (value_type (deref_val),
value_contents (deref_val), 0,
value_address (deref_val), stream, recurse + 1,
- options, current_language);
+ original_value, options, current_language);
}
else
fputs_filtered ("(null)", stream);
static int
print_variant_part (struct type *type, int field_num, const gdb_byte *valaddr,
struct ui_file *stream, int recurse,
+ const struct value *val,
const struct value_print_options *options, int comma_needed,
struct type *outer_type, const gdb_byte *outer_valaddr)
{
(TYPE_FIELD_TYPE (var_type, which),
valaddr + TYPE_FIELD_BITPOS (type, field_num) / HOST_CHAR_BIT
+ TYPE_FIELD_BITPOS (var_type, which) / HOST_CHAR_BIT,
- stream, recurse, options,
+ stream, recurse, val, options,
comma_needed, outer_type, outer_valaddr);
}
opts = *options;
opts.deref_ref = 1;
return (val_print (type, value_contents (val), 0, address,
- stream, 0, &opts, current_language));
+ stream, 0, val, &opts, current_language));
}
static void
print_record (struct type *type, const gdb_byte *valaddr,
struct ui_file *stream, int recurse,
+ const struct value *val,
const struct value_print_options *options)
{
type = ada_check_typedef (type);
fprintf_filtered (stream, "(");
- if (print_field_values (type, valaddr, stream, recurse, options,
+ if (print_field_values (type, valaddr, stream, recurse, val, options,
0, type, valaddr) != 0 && options->pretty)
{
fprintf_filtered (stream, "\n");
static int
print_field_values (struct type *type, const gdb_byte *valaddr,
struct ui_file *stream, int recurse,
+ const struct value *val,
const struct value_print_options *options,
int comma_needed,
struct type *outer_type, const gdb_byte *outer_valaddr)
print_field_values (TYPE_FIELD_TYPE (type, i),
valaddr
+ TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT,
- stream, recurse, options,
+ stream, recurse, val, options,
comma_needed, type, valaddr);
continue;
}
{
comma_needed =
print_variant_part (type, i, valaddr,
- stream, recurse, options, comma_needed,
+ stream, recurse, val, options, comma_needed,
outer_type, outer_valaddr);
continue;
}
opts = *options;
opts.deref_ref = 0;
val_print (TYPE_FIELD_TYPE (type, i), value_contents (v), 0, 0,
- stream, recurse + 1, &opts, current_language);
+ stream, recurse + 1, v,
+ &opts, current_language);
}
}
else
opts.deref_ref = 0;
ada_val_print (TYPE_FIELD_TYPE (type, i),
valaddr + TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT,
- 0, 0, stream, recurse + 1, &opts);
+ 0, 0, stream, recurse + 1, val, &opts);
}
annotate_field_end ();
}
extern int c_val_print (struct type *, const gdb_byte *, int, CORE_ADDR,
struct ui_file *, int,
+ const struct value *,
const struct value_print_options *);
extern int c_value_print (struct value *, struct ui_file *,
extern void cp_print_value_fields (struct type *, struct type *,
const gdb_byte *, int, CORE_ADDR,
struct ui_file *, int,
+ const struct value *,
const struct value_print_options *,
struct type **, int);
extern void cp_print_value_fields_rtti (struct type *,
const gdb_byte *, int, CORE_ADDR,
struct ui_file *, int,
+ const struct value *,
const struct value_print_options *,
struct type **, int);
int
c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
CORE_ADDR address, struct ui_file *stream, int recurse,
+ const struct value *original_value,
const struct value_print_options *options)
{
struct gdbarch *gdbarch = get_type_arch (type);
print_spaces_filtered (2 + 2 * recurse, stream);
}
- /* Print arrays of textual chars with a string syntax. */
- if (c_textual_element_type (unresolved_elttype, options->format))
+ /* Print arrays of textual chars with a string syntax, as
+ long as the entire array is valid. */
+ if (c_textual_element_type (unresolved_elttype, options->format)
+ && value_bits_valid (original_value,
+ TARGET_CHAR_BIT * embedded_offset,
+ TARGET_CHAR_BIT * TYPE_LENGTH (type)))
{
/* If requested, look for the first null char and only print
elements up to it. */
i = 0;
}
val_print_array_elements (type, valaddr + embedded_offset, address, stream,
- recurse, options, i);
+ recurse, original_value, options, i);
fprintf_filtered (stream, "}");
}
break;
else
cp_print_value_fields_rtti (type, valaddr,
embedded_offset, address, stream,
- recurse, options, NULL, 0);
+ recurse, original_value, options, NULL, 0);
break;
case TYPE_CODE_ENUM:
full ? "" : _(" [incomplete object]"));
/* Print out object: enclosing type is same as real_type if full */
return val_print (value_enclosing_type (val),
- value_contents_all (val), 0,
+ value_contents_for_printing (val), 0,
value_address (val), stream, 0,
- &opts, current_language);
+ val, &opts, current_language);
/* Note: When we look up RTTI entries, we don't get any information on
const or volatile attributes */
}
fprintf_filtered (stream, "(%s ?) ",
TYPE_NAME (value_enclosing_type (val)));
return val_print (value_enclosing_type (val),
- value_contents_all (val), 0,
+ value_contents_for_printing (val), 0,
value_address (val), stream, 0,
- &opts, current_language);
+ val, &opts, current_language);
}
/* Otherwise, we end up at the return outside this "if" */
}
- return val_print (val_type, value_contents_all (val),
+ return val_print (val_type, value_contents_for_printing (val),
value_embedded_offset (val),
value_address (val),
- stream, 0, &opts, current_language);
+ stream, 0,
+ val, &opts, current_language);
}
static void cp_print_value (struct type *, struct type *, const gdb_byte *,
int, CORE_ADDR, struct ui_file *, int,
+ const struct value *,
const struct value_print_options *, struct type **);
cp_print_value_fields (struct type *type, struct type *real_type,
const gdb_byte *valaddr, int offset, CORE_ADDR address,
struct ui_file *stream, int recurse,
+ const struct value *val,
const struct value_print_options *options,
struct type **dont_print_vb, int dont_print_statmem)
{
if (n_baseclasses > 0)
cp_print_value (type, real_type, valaddr, offset, address, stream,
- recurse + 1, options, dont_print_vb);
+ recurse + 1, val, options, dont_print_vb);
/* Second, print out data fields */
{
fputs_filtered ("<optimized out or zero length>", stream);
}
+ else if (!value_bits_valid (val, TYPE_FIELD_BITPOS (type, i),
+ TYPE_FIELD_BITSIZE (type, i)))
+ {
+ fputs_filtered (_("<value optimized out>"), stream);
+ }
else
{
struct value_print_options opts = *options;
val_print (TYPE_FIELD_TYPE (type, i),
valaddr, offset + TYPE_FIELD_BITPOS (type, i) / 8,
address,
- stream, recurse + 1, &opts,
+ stream, recurse + 1, val, &opts,
current_language);
}
}
const gdb_byte *valaddr, int offset,
CORE_ADDR address,
struct ui_file *stream, int recurse,
+ const struct value *val,
const struct value_print_options *options,
struct type **dont_print_vb,
int dont_print_statmem)
{
- struct value *value;
- int full, top, using_enc;
- struct type *real_type;
-
- /* Ugh, we have to convert back to a value here. */
- value = value_from_contents_and_address (type, valaddr + offset,
- address + offset);
- /* We don't actually care about most of the result here -- just the
- type. We already have the correct offset, due to how val_print
- was initially called. */
- real_type = value_rtti_type (value, &full, &top, &using_enc);
+ struct type *real_type = NULL;
+
+ /* We require all bits to be valid in order to attempt a
+ conversion. */
+ if (value_bits_valid (val, TARGET_CHAR_BIT * offset,
+ TARGET_CHAR_BIT * TYPE_LENGTH (type)))
+ {
+ struct value *value;
+ int full, top, using_enc;
+
+ /* Ugh, we have to convert back to a value here. */
+ value = value_from_contents_and_address (type, valaddr + offset,
+ address + offset);
+ /* We don't actually care about most of the result here -- just the
+ type. We already have the correct offset, due to how val_print
+ was initially called. */
+ real_type = value_rtti_type (value, &full, &top, &using_enc);
+ }
+
if (!real_type)
real_type = type;
cp_print_value_fields (type, real_type, valaddr, offset,
- address, stream, recurse, options,
+ address, stream, recurse, val, options,
dont_print_vb, dont_print_statmem);
}
cp_print_value (struct type *type, struct type *real_type,
const gdb_byte *valaddr, int offset, CORE_ADDR address,
struct ui_file *stream, int recurse,
+ const struct value *val,
const struct value_print_options *options,
struct type **dont_print_vb)
{
result = apply_val_pretty_printer (baseclass, base_valaddr,
thisoffset + boffset,
address,
- stream, recurse,
+ stream, recurse, val,
options,
current_language);
if (!result)
cp_print_value_fields (baseclass, thistype, base_valaddr,
thisoffset + boffset, address,
- stream, recurse, options,
+ stream, recurse, val, options,
((struct type **)
obstack_base (&dont_print_vb_obstack)),
0);
sizeof (CORE_ADDR));
CHECK_TYPEDEF (type);
cp_print_value_fields (type, value_enclosing_type (val),
- value_contents_all (val),
+ value_contents_for_printing (val),
value_embedded_offset (val), addr,
- stream, recurse, options, NULL, 1);
+ stream, recurse,
+ val, options, NULL, 1);
return;
}
opts = *options;
opts.deref_ref = 0;
- val_print (type, value_contents_all (val),
+ val_print (type, value_contents_for_printing (val),
value_embedded_offset (val), value_address (val),
- stream, recurse, &opts, current_language);
+ stream, recurse,
+ val, &opts, current_language);
}
extern int d_val_print (struct type *type, const gdb_byte *valaddr,
int embedded_offset, CORE_ADDR address,
struct ui_file *stream, int recurse,
+ const struct value *val,
const struct value_print_options *options);
#endif /* !defined (D_LANG_H) */
dynamic_array_type (struct type *type, const gdb_byte *valaddr,
int embedded_offset, CORE_ADDR address,
struct ui_file *stream, int recurse,
+ const struct value *val,
const struct value_print_options *options)
{
if (TYPE_NFIELDS (type) == 2
&& TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_INT
&& strcmp (TYPE_FIELD_NAME (type, 0), "length") == 0
- && strcmp (TYPE_FIELD_NAME (type, 1), "ptr") == 0)
+ && strcmp (TYPE_FIELD_NAME (type, 1), "ptr") == 0
+ && value_bits_valid (val, TARGET_CHAR_BIT * embedded_offset,
+ TARGET_CHAR_BIT * TYPE_LENGTH (type)))
{
CORE_ADDR addr;
struct type *elttype;
ptraddr = value_contents (val);
return d_val_print (true_type, ptraddr, 0, addr, stream, recurse + 1,
- options);
+ NULL, options);
}
return -1;
}
int
d_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
CORE_ADDR address, struct ui_file *stream, int recurse,
+ const struct value *val,
const struct value_print_options *options)
{
int ret;
{
case TYPE_CODE_STRUCT:
ret = dynamic_array_type (type, valaddr, embedded_offset, address,
- stream, recurse, options);
+ stream, recurse, val, options);
if (ret != -1)
break;
default:
ret = c_val_print (type, valaddr, embedded_offset, address, stream,
- recurse, options);
+ recurse, val, options);
}
return ret;
contents = value_contents_raw (v);
bits_to_skip = 8 * value_offset (v);
- type_len = 8 * TYPE_LENGTH (value_type (v));
+ if (value_bitsize (v))
+ {
+ bits_to_skip += value_bitpos (v);
+ type_len = value_bitsize (v);
+ }
+ else
+ type_len = 8 * TYPE_LENGTH (value_type (v));
for (i = 0; i < c->n_pieces && offset < type_len; i++)
{
break;
case DWARF_VALUE_OPTIMIZED_OUT:
- /* We just leave the bits empty for now. This is not ideal
- but gdb currently does not have a nice way to represent
- optimized-out pieces. */
- warning (_("bits %ld-%ld in computed object were optimized out; "
- "replacing with zeroes"),
- offset,
- offset + (long) this_size_bits);
+ set_value_optimized_out (v, 1);
break;
default:
contents = value_contents (from);
bits_to_skip = 8 * value_offset (to);
- type_len = 8 * TYPE_LENGTH (value_type (to));
+ if (value_bitsize (to))
+ {
+ bits_to_skip += value_bitpos (to);
+ type_len = value_bitsize (to);
+ }
+ else
+ type_len = 8 * TYPE_LENGTH (value_type (to));
+
for (i = 0; i < c->n_pieces && offset < type_len; i++)
{
struct dwarf_expr_piece *p = &c->pieces[i];
break;
default:
set_value_optimized_out (to, 1);
- goto done;
+ break;
}
offset += this_size_bits;
}
- done:
do_cleanups (cleanup);
}
+static int
+check_pieced_value_bits (const struct value *value, int bit_offset,
+ int bit_length, int validity)
+{
+ struct piece_closure *c
+ = (struct piece_closure *) value_computed_closure (value);
+ int i;
+
+ bit_offset += 8 * value_offset (value);
+ if (value_bitsize (value))
+ bit_offset += value_bitpos (value);
+
+ for (i = 0; i < c->n_pieces && bit_length > 0; i++)
+ {
+ struct dwarf_expr_piece *p = &c->pieces[i];
+ size_t this_size_bits = p->size;
+
+ if (bit_offset > 0)
+ {
+ if (bit_offset >= this_size_bits)
+ {
+ bit_offset -= this_size_bits;
+ continue;
+ }
+
+ bit_length -= this_size_bits - bit_offset;
+ bit_offset = 0;
+ }
+ else
+ bit_length -= this_size_bits;
+
+ if (p->location == DWARF_VALUE_OPTIMIZED_OUT)
+ {
+ if (validity)
+ return 0;
+ }
+ else
+ {
+ if (!validity)
+ return 1;
+ }
+ }
+
+ return validity;
+}
+
+static int
+check_pieced_value_validity (const struct value *value, int bit_offset,
+ int bit_length)
+{
+ return check_pieced_value_bits (value, bit_offset, bit_length, 1);
+}
+
+static int
+check_pieced_value_invalid (const struct value *value)
+{
+ return check_pieced_value_bits (value, 0,
+ 8 * TYPE_LENGTH (value_type (value)), 0);
+}
+
static void *
-copy_pieced_value_closure (struct value *v)
+copy_pieced_value_closure (const struct value *v)
{
struct piece_closure *c = (struct piece_closure *) value_computed_closure (v);
static struct lval_funcs pieced_value_funcs = {
read_pieced_value,
write_pieced_value,
+ check_pieced_value_validity,
+ check_pieced_value_invalid,
copy_pieced_value_closure,
free_pieced_value_closure
};
extern int f_val_print (struct type *, const gdb_byte *, int, CORE_ADDR,
struct ui_file *, int,
+ const struct value *,
const struct value_print_options *);
/* Language-specific data structures */
f77_print_array_1 (int nss, int ndimensions, struct type *type,
const gdb_byte *valaddr, CORE_ADDR address,
struct ui_file *stream, int recurse,
+ const struct value *val,
const struct value_print_options *options,
int *elts)
{
f77_print_array_1 (nss + 1, ndimensions, TYPE_TARGET_TYPE (type),
valaddr + i * F77_DIM_OFFSET (nss),
address + i * F77_DIM_OFFSET (nss),
- stream, recurse, options, elts);
+ stream, recurse, val, options, elts);
fprintf_filtered (stream, ") ");
}
if (*elts >= options->print_max && i < F77_DIM_SIZE (nss))
valaddr + i * F77_DIM_OFFSET (ndimensions),
0,
address + i * F77_DIM_OFFSET (ndimensions),
- stream, recurse, options, current_language);
+ stream, recurse, val, options, current_language);
if (i != (F77_DIM_SIZE (nss) - 1))
fprintf_filtered (stream, ", ");
static void
f77_print_array (struct type *type, const gdb_byte *valaddr,
CORE_ADDR address, struct ui_file *stream,
- int recurse, const struct value_print_options *options)
+ int recurse,
+ const struct value *val,
+ const struct value_print_options *options)
{
int ndimensions;
int elts = 0;
f77_create_arrayprint_offset_tbl (type, stream);
f77_print_array_1 (1, ndimensions, type, valaddr, address, stream,
- recurse, options, &elts);
+ recurse, val, options, &elts);
}
\f
int
f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
CORE_ADDR address, struct ui_file *stream, int recurse,
+ const struct value *original_value,
const struct value_print_options *options)
{
struct gdbarch *gdbarch = get_type_arch (type);
case TYPE_CODE_ARRAY:
fprintf_filtered (stream, "(");
- f77_print_array (type, valaddr, address, stream, recurse, options);
+ f77_print_array (type, valaddr, address, stream, recurse, original_value, options);
fprintf_filtered (stream, ")");
break;
{
/* Bash the type code temporarily. */
TYPE_CODE (type) = TYPE_CODE_INT;
- f_val_print (type, valaddr, 0, address, stream, recurse, options);
+ val_print (type, valaddr, 0, address, stream, recurse,
+ original_value, options, current_language);
/* Restore the type code so later uses work as intended. */
TYPE_CODE (type) = TYPE_CODE_BOOL;
}
{
int offset = TYPE_FIELD_BITPOS (type, index) / 8;
- f_val_print (TYPE_FIELD_TYPE (type, index), valaddr + offset,
- embedded_offset, address, stream, recurse, options);
+ val_print (TYPE_FIELD_TYPE (type, index), valaddr + offset,
+ embedded_offset, address, stream, recurse + 1,
+ original_value, options, current_language);
if (index != TYPE_NFIELDS (type) - 1)
fputs_filtered (", ", stream);
}
get_user_print_options (&opts);
opts.deref_ref = 1;
val_print (register_type (gdbarch, i), buffer, 0, 0,
- file, 0, &opts, current_language);
+ file, 0, NULL, &opts, current_language);
fprintf_filtered (file, "\t(raw 0x");
for (j = 0; j < register_size (gdbarch, i); j++)
get_formatted_print_options (&opts, 'x');
opts.deref_ref = 1;
val_print (register_type (gdbarch, i), buffer, 0, 0,
- file, 0, &opts,
- current_language);
+ file, 0, NULL, &opts, current_language);
/* If not a vector register, print it also according to its
natural format. */
if (TYPE_VECTOR (register_type (gdbarch, i)) == 0)
opts.deref_ref = 1;
fprintf_filtered (file, "\t");
val_print (register_type (gdbarch, i), buffer, 0, 0,
- file, 0, &opts, current_language);
+ file, 0, NULL, &opts, current_language);
}
}
extern int java_val_print (struct type *, const gdb_byte *, int, CORE_ADDR,
struct ui_file *, int,
+ const struct value *,
const struct value_print_options *);
extern int java_value_print (struct value *, struct ui_file *,
java_print_value_fields (struct type *type, const gdb_byte *valaddr,
CORE_ADDR address, struct ui_file *stream,
int recurse,
+ const struct value *val,
const struct value_print_options *options)
{
int i, len, n_baseclasses;
base_valaddr = valaddr;
java_print_value_fields (baseclass, base_valaddr, address + boffset,
- stream, recurse + 1, options);
+ stream, recurse + 1, val, options);
fputs_filtered (", ", stream);
}
{
fputs_filtered ("<optimized out or zero length>", stream);
}
+ else if (!value_bits_valid (val, TYPE_FIELD_BITPOS (type, i),
+ TYPE_FIELD_BITSIZE (type, i)))
+ {
+ fputs_filtered (_("<value optimized out>"), stream);
+ }
else
{
struct value_print_options opts;
val_print (TYPE_FIELD_TYPE (type, i),
valaddr + TYPE_FIELD_BITPOS (type, i) / 8, 0,
address + TYPE_FIELD_BITPOS (type, i) / 8,
- stream, recurse + 1, &opts,
+ stream, recurse + 1, val, &opts,
current_language);
}
}
java_val_print (struct type *type, const gdb_byte *valaddr,
int embedded_offset, CORE_ADDR address,
struct ui_file *stream, int recurse,
+ const struct value *val,
const struct value_print_options *options)
{
struct gdbarch *gdbarch = get_type_arch (type);
case TYPE_CODE_STRUCT:
java_print_value_fields (type, valaddr, address, stream, recurse,
- options);
+ val, options);
break;
default:
return c_val_print (type, valaddr, embedded_offset, address, stream,
- recurse, options);
+ recurse, val, options);
}
return 0;
unk_lang_val_print (struct type *type, const gdb_byte *valaddr,
int embedded_offset, CORE_ADDR address,
struct ui_file *stream, int recurse,
+ const struct value *val,
const struct value_print_options *options)
{
error (_("internal error - unimplemented function unk_lang_val_print called."));
const gdb_byte *contents,
int embedded_offset, CORE_ADDR address,
struct ui_file *stream, int recurse,
+ const struct value *val,
const struct value_print_options *options);
/* Print a top-level value using syntax appropriate for this language. */
#define LA_PRINT_TYPEDEF(type,new_symbol,stream) \
(current_language->la_print_typedef(type,new_symbol,stream))
-#define LA_VAL_PRINT(type,valaddr,offset,addr,stream,recurse,options) \
+#define LA_VAL_PRINT(type,valaddr,offset,addr,stream,val,recurse,options) \
(current_language->la_val_print(type,valaddr,offset,addr,stream, \
- recurse,options))
+ val,recurse,options))
#define LA_VALUE_PRINT(val,stream,options) \
(current_language->la_value_print(val,stream,options))
extern int m2_val_print (struct type *, const gdb_byte *, int, CORE_ADDR,
struct ui_file *, int,
+ const struct value *,
const struct value_print_options *);
extern int get_long_set_bounds (struct type *type, LONGEST *low,
m2_print_array_contents (struct type *type, const gdb_byte *valaddr,
int embedded_offset, CORE_ADDR address,
struct ui_file *stream, int recurse,
+ const struct value *val,
const struct value_print_options *options,
int len);
fprintf_filtered (stream, "{");
m2_print_array_contents (value_type (val), value_contents(val),
value_embedded_offset (val), addr, stream,
- recurse, options, len);
+ recurse, NULL, options, len);
fprintf_filtered (stream, ", HIGH = %d}", (int) len);
}
m2_print_array_contents (struct type *type, const gdb_byte *valaddr,
int embedded_offset, CORE_ADDR address,
struct ui_file *stream, int recurse,
+ const struct value *val,
const struct value_print_options *options,
int len)
{
{
fprintf_filtered (stream, "{");
val_print_array_elements (type, valaddr + embedded_offset,
- address, stream, recurse, options, 0);
+ address, stream, recurse, val,
+ options, 0);
fprintf_filtered (stream, "}");
}
}
int
m2_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
CORE_ADDR address, struct ui_file *stream, int recurse,
+ const struct value *original_value,
const struct value_print_options *options)
{
struct gdbarch *gdbarch = get_type_arch (type);
{
fprintf_filtered (stream, "{");
val_print_array_elements (type, valaddr + embedded_offset,
- address, stream, recurse, options, 0);
+ address, stream, recurse, original_value,
+ options, 0);
fprintf_filtered (stream, "}");
}
break;
address, stream, recurse, options);
else
cp_print_value_fields (type, type, valaddr, embedded_offset,
- address, stream, recurse, options, NULL, 0);
+ address, stream, recurse, original_value,
+ options, NULL, 0);
break;
case TYPE_CODE_ENUM:
if (TYPE_LENGTH (type) == TYPE_LENGTH (TYPE_TARGET_TYPE (type)))
{
m2_val_print (TYPE_TARGET_TYPE (type), valaddr, embedded_offset,
- address, stream, recurse, options);
+ address, stream, recurse, original_value, options);
break;
}
/* FIXME: create_range_type does not set the unsigned bit in a
get_formatted_print_options (&opts, format);
opts.deref_ref = 1;
val_print (register_type (gdbarch, regnum), buffer, 0, 0,
- stb->stream, 0, &opts, current_language);
+ stb->stream, 0, NULL, &opts, current_language);
ui_out_field_stream (uiout, "value", stb);
ui_out_stream_delete (stb);
}
/* Print the result of the expression evaluation. */
get_user_print_options (&opts);
opts.deref_ref = 0;
- val_print (value_type (val), value_contents (val),
- value_embedded_offset (val), value_address (val),
- stb->stream, 0, &opts, current_language);
+ common_val_print (val, stb->stream, 0, &opts, current_language);
ui_out_field_stream (uiout, "value", stb);
ui_out_stream_delete (stb);
get_raw_print_options (&opts);
opts.deref_ref = 1;
val_print (register_type (gdbarch, regnum), buf,
- 0, 0, file, 0, &opts,
- current_language);
+ 0, 0, file, 0, NULL,
+ &opts, current_language);
fputs_filtered ("\n", file);
}
else if (regnum == MT_MAC_REGNUM || regnum == MT_MAC_PSEUDOREG_REGNUM)
extern int pascal_val_print (struct type *, const gdb_byte *, int,
CORE_ADDR, struct ui_file *, int,
+ const struct value *,
const struct value_print_options *);
extern int pascal_value_print (struct value *, struct ui_file *,
extern void pascal_object_print_value_fields (struct type *, const gdb_byte *,
CORE_ADDR, struct ui_file *,
int,
+ const struct value *,
const struct value_print_options *,
struct type **, int);
pascal_val_print (struct type *type, const gdb_byte *valaddr,
int embedded_offset, CORE_ADDR address,
struct ui_file *stream, int recurse,
+ const struct value *original_value,
const struct value_print_options *options)
{
struct gdbarch *gdbarch = get_type_arch (type);
i = 0;
}
val_print_array_elements (type, valaddr + embedded_offset, address, stream,
- recurse, options, i);
+ recurse, original_value, options, i);
fprintf_filtered (stream, "}");
}
break;
}
else
pascal_object_print_value_fields (type, valaddr + embedded_offset, address, stream,
- recurse, options, NULL, 0);
+ recurse, original_value, options, NULL, 0);
}
break;
static void pascal_object_print_value (struct type *, const gdb_byte *,
CORE_ADDR, struct ui_file *, int,
+ const struct value *,
const struct value_print_options *,
struct type **);
pascal_object_print_value_fields (struct type *type, const gdb_byte *valaddr,
CORE_ADDR address, struct ui_file *stream,
int recurse,
+ const struct value *val,
const struct value_print_options *options,
struct type **dont_print_vb,
int dont_print_statmem)
duplicates of virtual baseclasses. */
if (n_baseclasses > 0)
pascal_object_print_value (type, valaddr, address, stream,
- recurse + 1, options, dont_print_vb);
+ recurse + 1, val, options, dont_print_vb);
if (!len && n_baseclasses == 1)
fprintf_filtered (stream, "<No data fields>");
{
fputs_filtered ("<optimized out or zero length>", stream);
}
+ else if (!value_bits_valid (val, TYPE_FIELD_BITPOS (type, i),
+ TYPE_FIELD_BITSIZE (type, i)))
+ {
+ fputs_filtered (_("<value optimized out>"), stream);
+ }
else
{
struct value_print_options opts = *options;
val_print (TYPE_FIELD_TYPE (type, i),
valaddr, TYPE_FIELD_BITPOS (type, i) / 8,
address + TYPE_FIELD_BITPOS (type, i) / 8,
- stream, recurse + 1, &opts,
+ stream, recurse + 1, val, &opts,
current_language);
}
}
pascal_object_print_value (struct type *type, const gdb_byte *valaddr,
CORE_ADDR address, struct ui_file *stream,
int recurse,
+ const struct value *val,
const struct value_print_options *options,
struct type **dont_print_vb)
{
fprintf_filtered (stream, "<invalid address>");
else
pascal_object_print_value_fields (baseclass, base_valaddr, address + boffset,
- stream, recurse, options,
+ stream, recurse, val, options,
(struct type **) obstack_base (&dont_print_vb_obstack),
0);
fputs_filtered (", ", stream);
CHECK_TYPEDEF (type);
pascal_object_print_value_fields (type, value_contents (val), addr,
- stream, recurse, options, NULL, 1);
+ stream, recurse, NULL, options,
+ NULL, 1);
return;
}
struct value_print_options opts = *options;
opts.format = 0;
opts.deref_ref = 0;
- val_print (type, valaddr, 0, 0, stream, 0, &opts,
+ val_print (type, valaddr, 0, 0, stream, 0, NULL, &opts,
current_language);
return;
}
apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
int embedded_offset, CORE_ADDR address,
struct ui_file *stream, int recurse,
+ const struct value *val,
const struct value_print_options *options,
const struct language_defn *language)
{
valaddr += embedded_offset;
value = value_from_contents_and_address (type, valaddr,
address + embedded_offset);
+ if (val != NULL)
+ {
+ set_value_component_location (value, val);
+ /* set_value_component_location resets the address, so we may
+ need to set it again. */
+ if (VALUE_LVAL (value) != lval_internalvar
+ && VALUE_LVAL (value) != lval_internalvar_component
+ && VALUE_LVAL (value) != lval_computed)
+ set_value_address (value, address + embedded_offset);
+ }
val_obj = value_to_value_object (value);
if (! val_obj)
apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
int embedded_offset, CORE_ADDR address,
struct ui_file *stream, int recurse,
+ const struct value *val,
const struct value_print_options *options,
const struct language_defn *language)
{
int apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
int embedded_offset, CORE_ADDR address,
struct ui_file *stream, int recurse,
+ const struct value *val,
const struct value_print_options *options,
const struct language_defn *language);
extern int scm_val_print (struct type *, const gdb_byte *, int, CORE_ADDR,
struct ui_file *, int,
+ const struct value *,
const struct value_print_options *);
extern LONGEST scm_get_field (LONGEST, int, int, enum bfd_endian);
scm_val_print (struct type *type, const gdb_byte *valaddr,
int embedded_offset, CORE_ADDR address,
struct ui_file *stream, int recurse,
+ const struct value *val,
const struct value_print_options *options)
{
- if (is_scmvalue_type (type))
+ if (is_scmvalue_type (type)
+ && value_bits_valid (val, TARGET_CHAR_BIT * embedded_offset,
+ TARGET_CHAR_BIT * TYPE_LENGTH (type)))
{
enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
LONGEST svalue
}
else
{
- return c_val_print (type, valaddr, 0, address, stream, recurse, options);
+ return c_val_print (type, valaddr, 0, address, stream, recurse,
+ val, options);
}
}
get_formatted_print_options (&opts, 'x');
opts.deref_ref = 1;
val_print (register_type (gdbarch, regnum), raw_buffer, 0, 0,
- file, 0, &opts, current_language);
+ file, 0, NULL, &opts, current_language);
fprintf_filtered (file, "\t");
get_formatted_print_options (&opts, 0);
opts.deref_ref = 1;
val_print (register_type (gdbarch, regnum), raw_buffer, 0, 0,
- file, 0, &opts, current_language);
+ file, 0, NULL, &opts, current_language);
fprintf_filtered (file, "\n");
}
+2010-06-11 Tom Tromey <tromey@redhat.com>
+
+ PR gdb/9977, PR exp/11636::
+ * gdb.dwarf2/pieces.exp (pieces_test_f3): Remove kfail.
+ (pieces_test_f6): Update expected output.
+
2010-06-11 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.base/moribund-step.exp: New.
gdb_continue_to_breakpoint "continue to f3 breakpoint for pieces"
gdb_test "print a.i" " = 4" "print a.i in pieces:f3"
gdb_test "print a.j" " = 14" "print a.j in pieces:f3"
- # Right now gdb says "value optimized out" here, but that is wrong.
- setup_kfail "exp/11636" *-*-*
gdb_test "print a.i = 7" " = 7" "set a.i in pieces:f3"
gdb_test "print a.i" " = 7" "print new a.i in pieces:f3"
}
"set f6 breakpoint for pieces"
gdb_continue_to_breakpoint "continue to f6 breakpoint for pieces"
gdb_test "print a" \
- "warning: bits .* in computed object were.* = {i = 7, j = 8, q = 0}" \
+ " = {i = 7, j = 8, q = .value optimized out.}" \
"print a with optimized out piece"
# Note: no warning for this case.
gdb_test_multiple "print a.i" \
struct value *parent = value_parent (val);
LONGEST offset = value_offset (val);
LONGEST num = unpack_bits_as_long (value_type (val),
- value_contents (parent) + offset,
+ (value_contents_for_printing (parent)
+ + offset),
value_bitpos (val),
value_bitsize (val));
int length = TYPE_LENGTH (type);
+ if (!value_bits_valid (val,
+ TARGET_CHAR_BIT * offset + value_bitpos (val),
+ value_bitsize (val)))
+ error (_("value has been optimized out"));
+
store_signed_integer (value_contents_raw (val), length, byte_order, num);
}
else if (VALUE_LVAL (val) == lval_memory)
{
case lval_memory:
case lval_register:
+ case lval_computed:
reinit_frame_cache ();
}
}
+/* Helper function to check the validity of some bits of a value.
+
+ If TYPE represents some aggregate type (e.g., a structure), return 1.
+
+ Otherwise, any of the bytes starting at OFFSET and extending for
+ TYPE_LENGTH(TYPE) bytes are invalid, print a message to STREAM and
+ return 0. The checking is done using FUNCS.
+
+ Otherwise, return 1. */
+
+static int
+valprint_check_validity (struct ui_file *stream,
+ struct type *type,
+ int offset,
+ const struct value *val)
+{
+ CHECK_TYPEDEF (type);
+
+ if (TYPE_CODE (type) != TYPE_CODE_UNION
+ && TYPE_CODE (type) != TYPE_CODE_STRUCT
+ && TYPE_CODE (type) != TYPE_CODE_ARRAY)
+ {
+ if (! value_bits_valid (val, TARGET_CHAR_BIT * offset,
+ TARGET_CHAR_BIT * TYPE_LENGTH (type)))
+ {
+ fprintf_filtered (stream, _("<value optimized out>"));
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
/* Print using the given LANGUAGE the data of type TYPE located at VALADDR
(within GDB), which came from the inferior at address ADDRESS, onto
stdio stream STREAM according to OPTIONS.
int
val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
CORE_ADDR address, struct ui_file *stream, int recurse,
+ const struct value *val,
const struct value_print_options *options,
const struct language_defn *language)
{
if (TYPE_STUB (real_type))
{
- fprintf_filtered (stream, "<incomplete type>");
+ fprintf_filtered (stream, _("<incomplete type>"));
gdb_flush (stream);
return (0);
}
+ if (!valprint_check_validity (stream, real_type, embedded_offset, val))
+ return 0;
+
if (!options->raw)
{
ret = apply_val_pretty_printer (type, valaddr, embedded_offset,
- address, stream, recurse, options,
- language);
+ address, stream, recurse,
+ val, options, language);
if (ret)
return ret;
}
TRY_CATCH (except, RETURN_MASK_ERROR)
{
ret = language->la_val_print (type, valaddr, embedded_offset, address,
- stream, recurse, &local_opts);
+ stream, recurse, val,
+ &local_opts);
}
if (except.reason < 0)
fprintf_filtered (stream, _("<error reading variable>"));
return 0;
}
- if (value_optimized_out (val))
+ if (value_entirely_optimized_out (val))
{
fprintf_filtered (stream, _("<value optimized out>"));
return 0;
get a fixed representation of our value. */
val = ada_to_fixed_value (val);
- return val_print (value_type (val), value_contents_all (val),
+ return val_print (value_type (val), value_contents_for_printing (val),
value_embedded_offset (val), value_address (val),
- stream, recurse, options, language);
+ stream, recurse,
+ val, options, language);
}
/* Print on stream STREAM the value VAL according to OPTIONS. The value
if (!options->raw)
{
int r = apply_val_pretty_printer (value_type (val),
- value_contents_all (val),
+ value_contents_for_printing (val),
value_embedded_offset (val),
value_address (val),
- stream, 0, options,
- current_language);
+ stream, 0,
+ val, options, current_language);
if (r)
return r;
val_print_array_elements (struct type *type, const gdb_byte *valaddr,
CORE_ADDR address, struct ui_file *stream,
int recurse,
+ const struct value *val,
const struct value_print_options *options,
unsigned int i)
{
if (reps > options->repeat_count_threshold)
{
val_print (elttype, valaddr + i * eltlen, 0, address + i * eltlen,
- stream, recurse + 1, options, current_language);
+ stream, recurse + 1, val, options, current_language);
annotate_elt_rep (reps);
fprintf_filtered (stream, " <repeats %u times>", reps);
annotate_elt_rep_end ();
else
{
val_print (elttype, valaddr + i * eltlen, 0, address + i * eltlen,
- stream, recurse + 1, options, current_language);
+ stream, recurse + 1, val, options, current_language);
annotate_elt ();
things_printed++;
}
extern void val_print_array_elements (struct type *, const gdb_byte *,
CORE_ADDR, struct ui_file *, int,
+ const struct value *,
const struct value_print_options *,
unsigned int);
}
struct type *
-value_type (struct value *value)
+value_type (const struct value *value)
{
return value->type;
}
}
int
-value_offset (struct value *value)
+value_offset (const struct value *value)
{
return value->offset;
}
}
int
-value_bitpos (struct value *value)
+value_bitpos (const struct value *value)
{
return value->bitpos;
}
}
int
-value_bitsize (struct value *value)
+value_bitsize (const struct value *value)
{
return value->bitsize;
}
return value->enclosing_type;
}
+static void
+require_not_optimized_out (struct value *value)
+{
+ if (value->optimized_out)
+ error (_("value has been optimized out"));
+}
+
const gdb_byte *
-value_contents_all (struct value *value)
+value_contents_for_printing (struct value *value)
{
if (value->lazy)
value_fetch_lazy (value);
return value->contents;
}
+const gdb_byte *
+value_contents_all (struct value *value)
+{
+ const gdb_byte *result = value_contents_for_printing (value);
+ require_not_optimized_out (value);
+ return result;
+}
+
int
value_lazy (struct value *value)
{
const gdb_byte *
value_contents (struct value *value)
{
- return value_contents_writeable (value);
+ const gdb_byte *result = value_contents_writeable (value);
+ require_not_optimized_out (value);
+ return result;
}
gdb_byte *
}
int
+value_entirely_optimized_out (const struct value *value)
+{
+ if (!value->optimized_out)
+ return 0;
+ if (value->lval != lval_computed
+ || !value->location.computed.funcs->check_validity)
+ return 1;
+ return value->location.computed.funcs->check_all_valid (value);
+}
+
+int
+value_bits_valid (const struct value *value, int offset, int length)
+{
+ if (value == NULL || !value->optimized_out)
+ return 1;
+ if (value->lval != lval_computed
+ || !value->location.computed.funcs->check_validity)
+ return 0;
+ return value->location.computed.funcs->check_validity (value, offset,
+ length);
+}
+
+int
value_embedded_offset (struct value *value)
{
return value->embedded_offset;
}
void *
-value_computed_closure (struct value *v)
+value_computed_closure (const struct value *v)
{
- gdb_assert (VALUE_LVAL (v) == lval_computed);
+ gdb_assert (v->lval == lval_computed);
return v->location.computed.closure;
}
}
void
-set_value_component_location (struct value *component, struct value *whole)
+set_value_component_location (struct value *component,
+ const struct value *whole)
{
- if (VALUE_LVAL (whole) == lval_internalvar)
+ if (whole->lval == lval_internalvar)
VALUE_LVAL (component) = lval_internalvar_component;
else
- VALUE_LVAL (component) = VALUE_LVAL (whole);
+ VALUE_LVAL (component) = whole->lval;
component->location = whole->location;
- if (VALUE_LVAL (whole) == lval_computed)
+ if (whole->lval == lval_computed)
{
struct lval_funcs *funcs = whole->location.computed.funcs;
/* Type of the value. */
-extern struct type *value_type (struct value *);
+extern struct type *value_type (const struct value *);
/* This is being used to change the type of an existing value, that
code should instead be creating a new value with the changed type
/* Only used for bitfields; number of bits contained in them. */
-extern int value_bitsize (struct value *);
+extern int value_bitsize (const struct value *);
extern void set_value_bitsize (struct value *, int bit);
/* Only used for bitfields; position of start of field. For
gdbarch_bits_big_endian=0 targets, it is the position of the LSB. For
gdbarch_bits_big_endian=1 targets, it is the position of the MSB. */
-extern int value_bitpos (struct value *);
+extern int value_bitpos (const struct value *);
extern void set_value_bitpos (struct value *, int bit);
/* Only used for bitfields; the containing value. This allows a
within the registers structure. Note also the member
embedded_offset below. */
-extern int value_offset (struct value *);
+extern int value_offset (const struct value *);
extern void set_value_offset (struct value *, int offset);
/* The comment from "struct value" reads: ``Is it modifiable? Only
should call 'error'. */
void (*write) (struct value *toval, struct value *fromval);
+ /* Check the validity of some bits in VALUE. This should return 1
+ if all the bits starting at OFFSET and extending for LENGTH bits
+ are valid, or 0 if any bit is invalid. */
+ int (*check_validity) (const struct value *value, int offset, int length);
+
+ /* Return 1 if any bit in VALUE is valid, 0 if they are all invalid. */
+ int (*check_all_valid) (const struct value *value);
+
/* Return a duplicate of VALUE's closure, for use in a new value.
This may simply return the same closure, if VALUE's is
reference-counted or statically allocated.
This may be NULL, in which case VALUE's closure is re-used in the
new value. */
- void *(*copy_closure) (struct value *v);
+ void *(*copy_closure) (const struct value *v);
/* Drop VALUE's reference to its closure. Maybe this frees the
closure; maybe this decrements a reference count; maybe the
/* If VALUE is lval_computed, return its closure. The meaning of the
returned value depends on the functions VALUE uses. */
-extern void *value_computed_closure (struct value *value);
+extern void *value_computed_closure (const struct value *value);
/* If zero, contents of this value are in the contents field. If
nonzero, contents are in inferior. If the lval field is lval_memory,
extern gdb_byte *value_contents_all_raw (struct value *);
extern const gdb_byte *value_contents_all (struct value *);
+/* Like value_contents_all, but does not require that the returned
+ bits be valid. This should only be used in situations where you
+ plan to check the validity manually. */
+extern const gdb_byte *value_contents_for_printing (struct value *value);
+
extern int value_fetch_lazy (struct value *val);
extern int value_contents_equal (struct value *val1, struct value *val2);
extern int value_optimized_out (struct value *value);
extern void set_value_optimized_out (struct value *value, int val);
+/* Like value_optimized_out, but return false if any bit in the object
+ is valid. */
+extern int value_entirely_optimized_out (const struct value *value);
+
/* Set or return field indicating whether a variable is initialized or
not, based on debugging information supplied by the compiler.
1 = initialized; 0 = uninitialized. */
/* Set COMPONENT's location as appropriate for a component of WHOLE
--- regardless of what kind of lvalue WHOLE is. */
extern void set_value_component_location (struct value *component,
- struct value *whole);
+ const struct value *whole);
/* While the following fields are per- VALUE .CONTENT .PIECE (i.e., a
single value might have multiple LVALs), this hacked interface is
extern struct value *coerce_array (struct value *value);
+/* Given a value, determine whether the bits starting at OFFSET and
+ extending for LENGTH bits are valid. This returns nonzero if all
+ bits in the given range are valid, zero if any bit is invalid. */
+
+extern int value_bits_valid (const struct value *value,
+ int offset, int length);
+
\f
#include "symtab.h"
extern int val_print (struct type *type, const gdb_byte *valaddr,
int embedded_offset, CORE_ADDR address,
struct ui_file *stream, int recurse,
+ const struct value *val,
const struct value_print_options *options,
const struct language_defn *language);