This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: RFC: optimized-out pieces
>>>>> "Jan" == Jan Kratochvil <jan.kratochvil@redhat.com> writes:
Jan> a fixup is needed there.
Jan> print operand0
Jan> -$1 = <value optimized out>
Jan> -(gdb) PASS: gdb.opt/clobbered-registers-O2.exp: print operand0
Jan> +$1 = (unsigned int *) <value optimized out>
Jan> +(gdb) FAIL: gdb.opt/clobbered-registers-O2.exp: print operand0
I think if the entire value is optimized out, we should not print the
type. So, I fixed it that way.
With my gcc, this isn't actually optimized out, though.
>> +static int
>> +check_pieced_value_validity (const struct value *value, int bit_offset,
>> + int bit_length)
Jan> I miss some `value_bitpos (value)' possibility here.
Yeah, oops. Fixed.
Jan> Here should be `bit_length -= this_size_bits - bit_offset'.
Fixed.
New patch appended.
Tom
b/gdb/ChangeLog:
2010-06-10 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.
b/gdb/testsuite/ChangeLog:
2010-06-03 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.
diff --git a/gdb/ada-lang.h b/gdb/ada-lang.h
index f6b613f..c51964a 100644
--- a/gdb/ada-lang.h
+++ b/gdb/ada-lang.h
@@ -164,6 +164,7 @@ extern void ada_print_typedef (struct type *type, struct symbol *new_symbol,
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 *,
diff --git a/gdb/ada-valprint.c b/gdb/ada-valprint.c
index 7e93e3a..2ab2ba2 100644
--- a/gdb/ada-valprint.c
+++ b/gdb/ada-valprint.c
@@ -36,33 +36,23 @@
#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 *);
@@ -146,6 +136,7 @@ static void
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;
@@ -217,7 +208,7 @@ val_print_packed_array_elements (struct type *type, const gdb_byte *valaddr,
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 ();
@@ -247,7 +238,7 @@ val_print_packed_array_elements (struct type *type, const gdb_byte *valaddr,
stream, options);
}
val_print (elttype, value_contents (v0), 0, 0, stream,
- recurse + 1, &opts, current_language);
+ recurse + 1, val, &opts, current_language);
annotate_elt ();
}
}
@@ -581,30 +572,22 @@ int
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
@@ -615,6 +598,7 @@ ada_val_print_stub (void *args0)
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));
@@ -663,10 +647,10 @@ ada_val_print_array (struct type *type, const gdb_byte *valaddr,
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, ")");
}
@@ -680,6 +664,7 @@ static int
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;
@@ -706,7 +691,8 @@ ada_val_print_1 (struct type *type, const gdb_byte *valaddr0,
}
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;
}
@@ -719,12 +705,12 @@ ada_val_print_1 (struct type *type, const gdb_byte *valaddr0,
{
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))
{
@@ -765,12 +751,12 @@ ada_val_print_1 (struct type *type, const gdb_byte *valaddr0,
(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
{
@@ -855,7 +841,7 @@ ada_val_print_1 (struct type *type, const gdb_byte *valaddr0,
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;
@@ -869,13 +855,14 @@ ada_val_print_1 (struct type *type, const gdb_byte *valaddr0,
}
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
@@ -899,7 +886,7 @@ ada_val_print_1 (struct type *type, const gdb_byte *valaddr0,
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);
@@ -916,6 +903,7 @@ ada_val_print_1 (struct type *type, const gdb_byte *valaddr0,
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)
{
@@ -929,7 +917,7 @@ print_variant_part (struct type *type, int field_num, const gdb_byte *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);
}
@@ -973,19 +961,20 @@ ada_value_print (struct value *val0, struct ui_file *stream,
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");
@@ -1012,6 +1001,7 @@ print_record (struct type *type, const gdb_byte *valaddr,
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)
@@ -1031,7 +1021,7 @@ print_field_values (struct type *type, const gdb_byte *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;
}
@@ -1039,7 +1029,7 @@ print_field_values (struct type *type, const gdb_byte *valaddr,
{
comma_needed =
print_variant_part (type, i, valaddr,
- stream, recurse, options, comma_needed,
+ stream, recurse, val, options, comma_needed,
outer_type, outer_valaddr);
continue;
}
@@ -1106,7 +1096,8 @@ print_field_values (struct type *type, const gdb_byte *valaddr,
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
@@ -1116,7 +1107,7 @@ print_field_values (struct type *type, const gdb_byte *valaddr,
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 ();
}
diff --git a/gdb/c-lang.h b/gdb/c-lang.h
index c2cdd56..8da1ff6 100644
--- a/gdb/c-lang.h
+++ b/gdb/c-lang.h
@@ -70,6 +70,7 @@ extern void c_print_typedef (struct type *, struct symbol *, struct ui_file *);
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 *,
@@ -104,12 +105,14 @@ extern void cp_print_class_member (const gdb_byte *, struct type *,
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);
diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c
index 9d2da35..e2a5b95 100644
--- a/gdb/c-valprint.c
+++ b/gdb/c-valprint.c
@@ -150,6 +150,7 @@ c_textual_element_type (struct type *type, char format)
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);
@@ -177,8 +178,12 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
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. */
@@ -217,7 +222,7 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
i = 0;
}
val_print_array_elements (type, valaddr + embedded_offset, address, stream,
- recurse, options, i);
+ recurse, original_value, options, i);
fprintf_filtered (stream, "}");
}
break;
@@ -394,7 +399,7 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
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:
@@ -695,9 +700,9 @@ c_value_print (struct value *val, struct ui_file *stream,
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 */
}
@@ -707,15 +712,16 @@ c_value_print (struct value *val, struct ui_file *stream,
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);
}
diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c
index 3fbb1f1..209a752 100644
--- a/gdb/cp-valprint.c
+++ b/gdb/cp-valprint.c
@@ -81,6 +81,7 @@ static void cp_print_static_field (struct type *, struct value *,
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 **);
@@ -151,6 +152,7 @@ void
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)
{
@@ -177,7 +179,7 @@ cp_print_value_fields (struct type *type, struct type *real_type,
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 */
@@ -278,6 +280,11 @@ cp_print_value_fields (struct type *type, struct type *real_type,
{
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;
@@ -315,7 +322,7 @@ cp_print_value_fields (struct type *type, struct type *real_type,
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);
}
}
@@ -377,26 +384,35 @@ cp_print_value_fields_rtti (struct type *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)
{
- 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);
}
@@ -407,6 +423,7 @@ static void
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)
{
@@ -508,14 +525,14 @@ cp_print_value (struct type *type, struct type *real_type,
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);
@@ -582,9 +599,10 @@ cp_print_static_field (struct type *type,
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;
}
@@ -616,9 +634,10 @@ cp_print_static_field (struct type *type,
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);
}
diff --git a/gdb/d-lang.h b/gdb/d-lang.h
index be27827..c2ec728 100644
--- a/gdb/d-lang.h
+++ b/gdb/d-lang.h
@@ -27,6 +27,7 @@ extern char *d_demangle (const char *mangled, int options);
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) */
diff --git a/gdb/d-valprint.c b/gdb/d-valprint.c
index ba3f1f0..87edddb 100644
--- a/gdb/d-valprint.c
+++ b/gdb/d-valprint.c
@@ -31,12 +31,15 @@ static int
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;
@@ -60,7 +63,7 @@ dynamic_array_type (struct type *type, const gdb_byte *valaddr,
ptraddr = value_contents (val);
return d_val_print (true_type, ptraddr, 0, addr, stream, recurse + 1,
- options);
+ NULL, options);
}
return -1;
}
@@ -69,6 +72,7 @@ dynamic_array_type (struct type *type, const gdb_byte *valaddr,
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;
@@ -78,12 +82,12 @@ d_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
{
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;
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index ce5d485..f987b0f 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -490,7 +490,13 @@ read_pieced_value (struct value *v)
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++)
{
@@ -614,13 +620,7 @@ read_pieced_value (struct value *v)
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:
@@ -664,7 +664,14 @@ write_pieced_value (struct value *to, struct value *from)
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];
@@ -767,17 +774,76 @@ write_pieced_value (struct value *to, struct value *from)
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);
@@ -802,6 +868,8 @@ free_pieced_value_closure (struct value *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
};
diff --git a/gdb/f-lang.h b/gdb/f-lang.h
index 094d6fa..ee3d91f 100644
--- a/gdb/f-lang.h
+++ b/gdb/f-lang.h
@@ -30,6 +30,7 @@ extern void f_print_type (struct type *, char *, struct ui_file *, int,
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 */
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
index acd6487..4db0b27 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -164,6 +164,7 @@ static void
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)
{
@@ -177,7 +178,7 @@ f77_print_array_1 (int nss, int ndimensions, struct type *type,
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))
@@ -192,7 +193,7 @@ f77_print_array_1 (int nss, int ndimensions, struct type *type,
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, ", ");
@@ -210,7 +211,9 @@ f77_print_array_1 (int nss, int ndimensions, struct type *type,
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;
@@ -228,7 +231,7 @@ f77_print_array (struct type *type, const gdb_byte *valaddr,
f77_create_arrayprint_offset_tbl (type, stream);
f77_print_array_1 (1, ndimensions, type, valaddr, address, stream,
- recurse, options, &elts);
+ recurse, val, options, &elts);
}
@@ -242,6 +245,7 @@ f77_print_array (struct type *type, const gdb_byte *valaddr,
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);
@@ -263,7 +267,7 @@ f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
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;
@@ -424,7 +428,8 @@ f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
{
/* 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;
}
@@ -456,8 +461,9 @@ f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
{
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);
}
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 5ada1e8..4a91a40 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -1957,7 +1957,7 @@ default_print_registers_info (struct gdbarch *gdbarch,
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++)
@@ -1980,8 +1980,7 @@ default_print_registers_info (struct gdbarch *gdbarch,
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)
@@ -1990,7 +1989,7 @@ default_print_registers_info (struct gdbarch *gdbarch,
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);
}
}
diff --git a/gdb/jv-lang.h b/gdb/jv-lang.h
index 95d6384..24ca61e 100644
--- a/gdb/jv-lang.h
+++ b/gdb/jv-lang.h
@@ -44,6 +44,7 @@ extern const struct builtin_java_type *builtin_java_type (struct gdbarch *);
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 *,
diff --git a/gdb/jv-valprint.c b/gdb/jv-valprint.c
index 165f14e..1819b50 100644
--- a/gdb/jv-valprint.c
+++ b/gdb/jv-valprint.c
@@ -259,6 +259,7 @@ static void
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;
@@ -302,7 +303,7 @@ java_print_value_fields (struct type *type, const gdb_byte *valaddr,
base_valaddr = valaddr;
java_print_value_fields (baseclass, base_valaddr, address + boffset,
- stream, recurse + 1, options);
+ stream, recurse + 1, val, options);
fputs_filtered (", ", stream);
}
@@ -392,6 +393,11 @@ java_print_value_fields (struct type *type, const gdb_byte *valaddr,
{
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;
@@ -440,7 +446,7 @@ java_print_value_fields (struct type *type, const gdb_byte *valaddr,
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);
}
}
@@ -467,6 +473,7 @@ int
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);
@@ -543,12 +550,12 @@ java_val_print (struct type *type, const gdb_byte *valaddr,
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;
diff --git a/gdb/language.c b/gdb/language.c
index c20d7c0..90bb228 100644
--- a/gdb/language.c
+++ b/gdb/language.c
@@ -1107,6 +1107,7 @@ static int
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."));
diff --git a/gdb/language.h b/gdb/language.h
index 9306a82..0c04208 100644
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -233,6 +233,7 @@ struct language_defn
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. */
@@ -401,9 +402,9 @@ extern enum language set_language (enum 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))
diff --git a/gdb/m2-lang.h b/gdb/m2-lang.h
index 75623e2..161b4b6 100644
--- a/gdb/m2-lang.h
+++ b/gdb/m2-lang.h
@@ -34,6 +34,7 @@ extern int m2_is_unbounded_array (struct type *type);
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,
diff --git a/gdb/m2-valprint.c b/gdb/m2-valprint.c
index edfd324..95a7a93 100644
--- a/gdb/m2-valprint.c
+++ b/gdb/m2-valprint.c
@@ -38,6 +38,7 @@ static void
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);
@@ -202,7 +203,7 @@ m2_print_unbounded_array (struct type *type, const gdb_byte *valaddr,
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);
}
@@ -277,6 +278,7 @@ static void
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)
{
@@ -299,7 +301,8 @@ m2_print_array_contents (struct type *type, const gdb_byte *valaddr,
{
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, "}");
}
}
@@ -316,6 +319,7 @@ m2_print_array_contents (struct type *type, const gdb_byte *valaddr,
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);
@@ -367,7 +371,8 @@ m2_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
{
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;
@@ -436,7 +441,8 @@ m2_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
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:
@@ -508,7 +514,7 @@ m2_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
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
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index ec6753d..85a3f99 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -1131,7 +1131,7 @@ get_register (struct frame_info *frame, int regnum, int format)
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);
}
@@ -1222,9 +1222,7 @@ mi_cmd_data_evaluate_expression (char *command, char **argv, int argc)
/* 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);
diff --git a/gdb/mt-tdep.c b/gdb/mt-tdep.c
index 1548151..e8ea5bc 100644
--- a/gdb/mt-tdep.c
+++ b/gdb/mt-tdep.c
@@ -710,8 +710,8 @@ mt_registers_info (struct gdbarch *gdbarch,
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)
diff --git a/gdb/p-lang.h b/gdb/p-lang.h
index 4090caa..0ea2fc9 100644
--- a/gdb/p-lang.h
+++ b/gdb/p-lang.h
@@ -37,6 +37,7 @@ extern void pascal_print_typedef (struct type *, struct symbol *,
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 *,
@@ -70,6 +71,7 @@ extern void
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);
diff --git a/gdb/p-valprint.c b/gdb/p-valprint.c
index e58f9d2..3d00a69 100644
--- a/gdb/p-valprint.c
+++ b/gdb/p-valprint.c
@@ -54,6 +54,7 @@ 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);
@@ -125,7 +126,7 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr,
i = 0;
}
val_print_array_elements (type, valaddr + embedded_offset, address, stream,
- recurse, options, i);
+ recurse, original_value, options, i);
fprintf_filtered (stream, "}");
}
break;
@@ -317,7 +318,7 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr,
}
else
pascal_object_print_value_fields (type, valaddr + embedded_offset, address, stream,
- recurse, options, NULL, 0);
+ recurse, original_value, options, NULL, 0);
}
break;
@@ -611,6 +612,7 @@ static void pascal_object_print_static_field (struct value *,
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 **);
@@ -668,6 +670,7 @@ void
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)
@@ -685,7 +688,7 @@ pascal_object_print_value_fields (struct type *type, const gdb_byte *valaddr,
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>");
@@ -774,6 +777,11 @@ pascal_object_print_value_fields (struct type *type, const gdb_byte *valaddr,
{
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;
@@ -818,7 +826,7 @@ pascal_object_print_value_fields (struct type *type, const gdb_byte *valaddr,
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);
}
}
@@ -849,6 +857,7 @@ static void
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)
{
@@ -923,7 +932,7 @@ pascal_object_print_value (struct type *type, const gdb_byte *valaddr,
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);
@@ -987,7 +996,8 @@ pascal_object_print_static_field (struct value *val,
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;
}
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 58cb1f6..42aff63 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -374,7 +374,7 @@ print_scalar_formatted (const void *valaddr, struct type *type,
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;
}
diff --git a/gdb/python/py-prettyprint.c b/gdb/python/py-prettyprint.c
index 4d60c96..9a205b4 100644
--- a/gdb/python/py-prettyprint.c
+++ b/gdb/python/py-prettyprint.c
@@ -603,6 +603,7 @@ 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)
{
@@ -621,6 +622,16 @@ apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
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)
@@ -735,6 +746,7 @@ 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)
{
diff --git a/gdb/python/python.h b/gdb/python/python.h
index ae808c0..affd4a4 100644
--- a/gdb/python/python.h
+++ b/gdb/python/python.h
@@ -31,6 +31,7 @@ void source_python_script (FILE *stream, const char *file);
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);
diff --git a/gdb/scm-lang.h b/gdb/scm-lang.h
index bcb29d8..1adeee5 100644
--- a/gdb/scm-lang.h
+++ b/gdb/scm-lang.h
@@ -50,6 +50,7 @@ extern int scm_value_print (struct value *, struct ui_file *,
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);
diff --git a/gdb/scm-valprint.c b/gdb/scm-valprint.c
index 8000c78..c5e1ce1 100644
--- a/gdb/scm-valprint.c
+++ b/gdb/scm-valprint.c
@@ -422,9 +422,12 @@ int
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
@@ -443,7 +446,8 @@ scm_val_print (struct type *type, const gdb_byte *valaddr,
}
else
{
- return c_val_print (type, valaddr, 0, address, stream, recurse, options);
+ return c_val_print (type, valaddr, 0, address, stream, recurse,
+ val, options);
}
}
diff --git a/gdb/sh64-tdep.c b/gdb/sh64-tdep.c
index 8d7782a..6267541 100644
--- a/gdb/sh64-tdep.c
+++ b/gdb/sh64-tdep.c
@@ -2121,12 +2121,12 @@ sh64_do_register (struct gdbarch *gdbarch, struct ui_file *file,
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");
}
diff --git a/gdb/testsuite/gdb.dwarf2/pieces.exp b/gdb/testsuite/gdb.dwarf2/pieces.exp
index 4264d69..1e3ef7f 100644
--- a/gdb/testsuite/gdb.dwarf2/pieces.exp
+++ b/gdb/testsuite/gdb.dwarf2/pieces.exp
@@ -76,8 +76,6 @@ proc pieces_test_f3 {} {
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"
}
@@ -90,7 +88,7 @@ proc pieces_test_f6 {} {
"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" \
diff --git a/gdb/valops.c b/gdb/valops.c
index 08a64ce..506d40e 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -941,11 +941,17 @@ value_fetch_lazy (struct value *val)
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)
@@ -1246,6 +1252,7 @@ value_assign (struct value *toval, struct value *fromval)
{
case lval_memory:
case lval_register:
+ case lval_computed:
reinit_frame_cache ();
diff --git a/gdb/valprint.c b/gdb/valprint.c
index 2b06579..ad6268e 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -245,6 +245,39 @@ scalar_type_p (struct type *type)
}
}
+/* 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.
@@ -263,6 +296,7 @@ scalar_type_p (struct type *type)
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)
{
@@ -283,16 +317,19 @@ val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
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;
}
@@ -308,7 +345,8 @@ val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
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>"));
@@ -329,7 +367,7 @@ value_check_printable (struct value *val, struct ui_file *stream)
return 0;
}
- if (value_optimized_out (val))
+ if (value_entirely_optimized_out (val))
{
fprintf_filtered (stream, _("<value optimized out>"));
return 0;
@@ -369,9 +407,10 @@ common_val_print (struct value *val, struct ui_file *stream, int recurse,
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
@@ -390,11 +429,11 @@ value_print (struct value *val, struct ui_file *stream,
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;
@@ -1097,6 +1136,7 @@ void
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)
{
@@ -1175,7 +1215,7 @@ val_print_array_elements (struct type *type, const gdb_byte *valaddr,
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 ();
@@ -1186,7 +1226,7 @@ val_print_array_elements (struct type *type, const gdb_byte *valaddr,
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++;
}
diff --git a/gdb/valprint.h b/gdb/valprint.h
index 070d796..6e339d1 100644
--- a/gdb/valprint.h
+++ b/gdb/valprint.h
@@ -118,6 +118,7 @@ extern void maybe_print_array_index (struct type *index_type, LONGEST index,
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);
diff --git a/gdb/value.c b/gdb/value.c
index ec33403..5e0e8d8 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -349,7 +349,7 @@ value_next (struct value *value)
}
struct type *
-value_type (struct value *value)
+value_type (const struct value *value)
{
return value->type;
}
@@ -360,7 +360,7 @@ deprecated_set_value_type (struct value *value, struct type *type)
}
int
-value_offset (struct value *value)
+value_offset (const struct value *value)
{
return value->offset;
}
@@ -371,7 +371,7 @@ set_value_offset (struct value *value, int offset)
}
int
-value_bitpos (struct value *value)
+value_bitpos (const struct value *value)
{
return value->bitpos;
}
@@ -382,7 +382,7 @@ set_value_bitpos (struct value *value, int bit)
}
int
-value_bitsize (struct value *value)
+value_bitsize (const struct value *value)
{
return value->bitsize;
}
@@ -418,14 +418,29 @@ value_enclosing_type (struct value *value)
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)
{
@@ -453,7 +468,9 @@ set_value_stack (struct value *value, int val)
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 *
@@ -497,6 +514,29 @@ set_value_optimized_out (struct value *value, int val)
}
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;
@@ -529,9 +569,9 @@ value_computed_funcs (struct value *v)
}
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;
}
@@ -771,15 +811,16 @@ value_copy (struct value *arg)
}
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;
diff --git a/gdb/value.h b/gdb/value.h
index 7f71dc4..c3dfb17 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -50,7 +50,7 @@ struct value *value_next (struct value *);
/* 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
@@ -61,14 +61,14 @@ extern void deprecated_set_value_type (struct value *value,
/* 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
@@ -83,7 +83,7 @@ struct value *value_parent (struct value *);
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
@@ -164,13 +164,21 @@ struct lval_funcs
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
@@ -195,7 +203,7 @@ extern struct lval_funcs *value_computed_funcs (struct value *value);
/* 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,
@@ -249,6 +257,11 @@ extern gdb_byte *value_contents_writeable (struct value *);
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);
@@ -257,6 +270,10 @@ 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. */
@@ -266,7 +283,7 @@ extern void set_value_initialized (struct value *, int);
/* 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
@@ -313,6 +330,13 @@ extern struct value *coerce_ref (struct value *value);
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);
+
#include "symtab.h"
@@ -647,6 +671,7 @@ extern struct value *value_release_to_mark (struct value *mark);
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);