This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 06/12] Delete value_bits_valid.


In this patch I remove value_bits_valid and merge the functionality
into value_bytes_available and a new value_bits_available.

At this point the optimized out and unavailable state are still
stored separately, the optimized out as a single bit flag, and
unavailable in the vector, but the query functions are now merged.

There are a few updates required to the expected results of the
gdb.trace/unavailable.exp test, the output is now more like the output
you would get if the values were optimized out.  I personally think this
is a good thing, but if most people disagree then we could change the
output for optimized out to be unavailable like, I do think the style of
output should match.  The reason I prefer this style is that a fully
unavailable structure is displayed with a single "<unavailable>" rather
than the full structure with lots of unavailables throughout.

OK to apply?

Thanks,
Andrew

gdb/ChangeLog

2013-08-08  Andrew Burgess  <aburgess@broadcom.com>

	* c-valprint.c (c_val_print): Remove call to value_bits_valid.
	* cp-valprint.c (cp_print_value_fields): Remove call to
	value_bits_valid, and print correct unavailability reason.
	(cp_print_value_fields_rtti): Use value_bytes_available instead of
	value_bits_valid.
	* d-valprint.c (dynamic_array_type): Likewise.
	* frame.c (frame_register_unwind): Use value_availability_flags.
	(read_frame_register_unsigned): Remove call to value_optimized_out.
	* jv-valprint.c (java_print_value_fields): Use
	value_bits_available rather than value_bits_valid.
	* opencl-lang.c (lval_func_check_validity): Likewise.
	(lval_func_check_any_valid): Likewise.
	* p-valprint.c (pascal_object_print_value_fields): Use
	value_bits_available rather than value_bits_valid, and print the
	correct unavailability reason.
	* valprint.c (valprint_check_validity): Use value_bits_available
	rather than value_bits_valid, and print the correct unavailability
	reason.  Remove additional call to value_bytes_available.
	(value_check_printable): Replace value_entirely_optimized_out with
	value_entirely_unavailable., print the corrct unavailability reason.
	(val_print_scalar_formatted): Use value_bytes_available rather
	than value_bits_valid, and print the correct unavailability
	reason.
	* value.c (value_bits_available): New function, includes old
	value_bits_valid.
	(value_bytes_available): Use value_bits_available.
	(value_entirely_available): Take account of optimized_out.
	(value_entirely_unavailable): New function, includes old
	value_entirely_optimized_out code.
	(value_availability_flags): New function.
	(value_entirely_optimized_out): Deleted, code forms part of
	value_entirely_unavailable.
	(value_bits_valid): Deleted, code forms part of
	value_bits_available.
	(value_fetch_lazy): Use value_bits_available rather than
	value_bits_valid.  If parent is unavailable, mark child value
	either opttimized out or unavailable.  Remove duplicate call to set
	chid value unavailable.
	* value.h (value_entirely_optimized_out): Deleted.
	(value_bits_valid): Deleted.
	(value_bits_available): New function.
	(value_entirely_available): Add comment.
	(value_entirely_unavailable): New function.
	(value_availability_flags): New function.

gdb/testsuite/ChangeLog

2013-08-08  Andrew Burgess  <aburgess@broadcom.com>

	* gdb.trace/unavailable.exp(gdb_collect_args_test): Update
	expected results.
	(gdb_collect_locals_test): Likewise.
	(gdb_collect_globals_test): Likewise.

diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c
index 3466df0..551080a 100644
--- a/gdb/c-valprint.c
+++ b/gdb/c-valprint.c
@@ -171,10 +171,7 @@ c_val_print (struct type *type, const gdb_byte
*valaddr,
           if (c_textual_element_type (unresolved_elttype,
 				      options->format)
 	      && value_bytes_available (original_value, embedded_offset,
-					TYPE_LENGTH (type))
-	      && value_bits_valid (original_value,
-				   TARGET_CHAR_BIT * embedded_offset,
-				   TARGET_CHAR_BIT * TYPE_LENGTH (type)))
+					TYPE_LENGTH (type)))
 	    {
 	      int force_ellipses = 0;
 diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c
index 795b7b0..5dd98b0 100644
--- a/gdb/cp-valprint.c
+++ b/gdb/cp-valprint.c
@@ -294,11 +294,17 @@ cp_print_value_fields (struct type *type, struct
type *real_type,
 		{
 		  fputs_filtered (_("<synthetic pointer>"), stream);
 		}
-	      else if (!value_bits_valid (val,
-					  TYPE_FIELD_BITPOS (type, i),
-					  TYPE_FIELD_BITSIZE (type, i)))
+	      else if (!value_bits_available (val,
+					      TYPE_FIELD_BITPOS (type, i),
+					      TYPE_FIELD_BITSIZE (type, i)))
 		{
-		  val_print_optimized_out (stream);
+		  int optimizedp, unavailablep;
+
+		  value_availability_flags (val, &optimizedp, &unavailablep);
+		  if (optimizedp)
+		    val_print_optimized_out (stream);
+		  else
+		    val_print_unavailable (stream);
 		}
 	      else
 		{
@@ -437,8 +443,7 @@ cp_print_value_fields_rtti (struct type *type,
    /* 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)))
+  if (value_bytes_available (val, offset, TYPE_LENGTH (type)))
     {
       struct value *value;
       int full, top, using_enc;
diff --git a/gdb/d-valprint.c b/gdb/d-valprint.c
index 6e9c28d..499c0e3 100644
--- a/gdb/d-valprint.c
+++ b/gdb/d-valprint.c
@@ -38,8 +38,7 @@ dynamic_array_type (struct type *type, const gdb_byte
*valaddr,
       && 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
-      && value_bits_valid (val, TARGET_CHAR_BIT * embedded_offset,
-			   TARGET_CHAR_BIT * TYPE_LENGTH (type)))
+      && value_bytes_available (val, embedded_offset, TYPE_LENGTH (type)))
     {
       CORE_ADDR addr;
       struct type *elttype;
diff --git a/gdb/frame.c b/gdb/frame.c
index f825f96..c5d85b4 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -937,8 +937,10 @@ frame_register_unwind (struct frame_info *frame,
int regnum,
    gdb_assert (value != NULL);
 -  *optimizedp = value_optimized_out (value);
-  *unavailablep = !value_entirely_available (value);
+  if (!value_entirely_available (value))
+    value_availability_flags (value, optimizedp, unavailablep);
+  else
+    *optimizedp = *unavailablep = 0;
   *lvalp = VALUE_LVAL (value);
   *addrp = value_address (value);
   *realnump = VALUE_REGNUM (value);
@@ -1116,8 +1118,7 @@ read_frame_register_unsigned (struct frame_info
*frame, int regnum,
 {
   struct value *regval = get_frame_register_value (frame, regnum);
 -  if (!value_optimized_out (regval)
-      && value_entirely_available (regval))
+  if (value_entirely_available (regval))
     {
       struct gdbarch *gdbarch = get_frame_arch (frame);
       enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
diff --git a/gdb/jv-valprint.c b/gdb/jv-valprint.c
index 3b90e54..edcd769 100644
--- a/gdb/jv-valprint.c
+++ b/gdb/jv-valprint.c
@@ -392,10 +392,16 @@ java_print_value_fields (struct type *type, const
gdb_byte *valaddr,
 		{
 		  fputs_filtered (_("<synthetic pointer>"), stream);
 		}
-	      else if (!value_bits_valid (val, TYPE_FIELD_BITPOS (type, i),
-					  TYPE_FIELD_BITSIZE (type, i)))
+	      else if (!value_bits_available (val, TYPE_FIELD_BITPOS (type, i),
+					      TYPE_FIELD_BITSIZE (type, i)))
 		{
-		  val_print_optimized_out (stream);
+		  int optimizedp, unavailablep;
+
+		  value_availability_flags (val, &optimizedp, &unavailablep);
+		  if (optimizedp)
+		    val_print_optimized_out (stream);
+		  else
+		    val_print_unavailable (stream);
 		}
 	      else
 		{
diff --git a/gdb/opencl-lang.c b/gdb/opencl-lang.c
index 4720e2b..4da2c9d 100644
--- a/gdb/opencl-lang.c
+++ b/gdb/opencl-lang.c
@@ -266,8 +266,8 @@ lval_func_check_validity (const struct value *v, int
offset, int length)
       int comp_offset = (i == start) ? startrest : 0;
       int comp_length = (i == end) ? endrest : elsize;
 -      if (!value_bits_valid (c->val, c->indices[i] * elsize + comp_offset,
-			     comp_length))
+      if (!value_bits_available (c->val, c->indices[i] * elsize +
comp_offset,
+				 comp_length))
 	return 0;
     }
 @@ -286,7 +286,7 @@ lval_func_check_any_valid (const struct value *v)
   int i;
    for (i = 0; i < c->n; i++)
-    if (value_bits_valid (c->val, c->indices[i] * elsize, elsize))
+    if (value_bits_available (c->val, c->indices[i] * elsize, elsize))
       return 1;
    return 0;
diff --git a/gdb/p-valprint.c b/gdb/p-valprint.c
index cfafe99..bc57541 100644
--- a/gdb/p-valprint.c
+++ b/gdb/p-valprint.c
@@ -626,10 +626,16 @@ pascal_object_print_value_fields (struct type
*type, const gdb_byte *valaddr,
 		{
 		  fputs_filtered (_("<synthetic pointer>"), stream);
 		}
-	      else if (!value_bits_valid (val, TYPE_FIELD_BITPOS (type, i),
-					  TYPE_FIELD_BITSIZE (type, i)))
+	      else if (!value_bits_available (val, TYPE_FIELD_BITPOS (type, i),
+					      TYPE_FIELD_BITSIZE (type, i)))
 		{
-		  val_print_optimized_out (stream);
+		  int optimizedp, unavailablep;
+		  +		  value_availability_flags (val, &optimizedp, &unavailablep);
+		  if (optimizedp)
+		    val_print_optimized_out (stream);
+		  else
+		    val_print_unavailable (stream);
 		}
 	      else
 		{
diff --git a/gdb/testsuite/gdb.trace/unavailable.exp
b/gdb/testsuite/gdb.trace/unavailable.exp
index 8e2e105..304f1ef 100644
--- a/gdb/testsuite/gdb.trace/unavailable.exp
+++ b/gdb/testsuite/gdb.trace/unavailable.exp
@@ -170,14 +170,14 @@ proc gdb_collect_args_test {} {
 	# struct arg as one of several args (near end of list)
  	gdb_test "print argstruct" \
-	    " = \{memberc = <unavailable>, memberi = <unavailable>, memberf =
<unavailable>, memberd = <unavailable>\}"
+	    " = <unavailable>"
  	gdb_test "print argstruct.memberc" " = <unavailable>"
 	gdb_test "print argstruct.memberi" " = <unavailable>"
 	gdb_test "print argstruct.memberf" " = <unavailable>"
 	gdb_test "print argstruct.memberd" " = <unavailable>"
 -	gdb_test "print argarray" " = \\(int \\*\\) <unavailable>"
+	gdb_test "print argarray" " = <unavailable>"
  	gdb_test "print &argarray" \
 	    "Can't take address of \"argarray\" which isn't an lvalue\."
@@ -190,7 +190,7 @@ proc gdb_collect_args_test {} {
 	set r "${r}argi = <unavailable>${cr}"
 	set r "${r}argf = <unavailable>${cr}"
 	set r "${r}argd = <unavailable>${cr}"
-	set r "${r}argstruct = {memberc = <unavailable>, memberi =
<unavailable>, memberf = <unavailable>, memberd = <unavailable>}${cr}"
+	set r "${r}argstruct = <unavailable>${cr}"
 	set r "${r}argarray = <unavailable>${cr}"
 	gdb_test "info args" "$r" "info args"
 @@ -237,11 +237,11 @@ proc gdb_collect_locals_test { func msg } {
 	set r ""
 	set r "${r}locf = <unavailable>${cr}"
 	set r "${r}locd = <unavailable>${cr}"
-	set r "${r}locst = {memberc = <unavailable>, memberi = <unavailable>,
memberf = <unavailable>, memberd = <unavailable>}${cr}"
-	set r "${r}locar = {<unavailable>, <unavailable>, <unavailable>,
<unavailable>}${cr}"
+	set r "${r}locst = <unavailable>${cr}"
+	set r "${r}locar = <unavailable>${cr}"
 	set r "${r}i = <unavailable>${cr}"
 	if { $func == "local_test_func" } {
-	    set r "${r}locdefst = {<No data fields>}${cr}"
+	    set r "${r}locdefst = <unavailable>${cr}"
 	}
 	set r "${r}locc = <unavailable>${cr}"
 	set r "${r}loci = <unavailable>${cr}"
@@ -399,7 +399,7 @@ proc gdb_collect_globals_test { } {
 	gdb_test "print globalstruct.memberd" " = <unavailable>"
  	gdb_test "print globalstruct" \
-	    " = {memberc = <unavailable>, memberi = <unavailable>, memberf =
<unavailable>, memberd = <unavailable>}"
+	    " = <unavailable>"
  	gdb_test "print globalp == &globalstruct" \
 	    "value is not available" \
@@ -450,7 +450,7 @@ proc gdb_collect_globals_test { } {
 	# Static fields
  	gdb_test "print struct_b.static_struct_a" \
-	    " = {a = <unavailable>, b = <unavailable>, array = {<unavailable>
<repeats 10000 times>}, ptr = <unavailable>, bitfield = <unavailable>}"
+	    " = <unavailable>"
  	# Bitfields
 @@ -469,7 +469,7 @@ proc gdb_collect_globals_test { } {
 	    "referenced integer was not collected (taking address of reference)"
  	gdb_test "print *g_structref_p" \
-	    " = {d = <unavailable>, ref = <unavailable>}"
+	    " = <unavailable>"
  	# Strings
 @@ -483,7 +483,7 @@ proc gdb_collect_globals_test { } {
 	    "printing constant string through collected pointer"
  	gdb_test "print g_string_unavail" \
-	    " = \{<unavailable> <repeats 12 times>\}" \
+	    " = <unavailable>" \
 	    "printing non collected string"
  	# Incomplete strings print as an array.
@@ -521,15 +521,15 @@ proc gdb_collect_globals_test { } {
 	# unavailable-ness is propagated.  History values are easy
 	# non-lazy values, so use those.  The first test just sets up for
 	# the second.
-	gdb_test "print g_smallstruct" " = \\{member = <unavailable>\\}"
+	gdb_test "print g_smallstruct" " = <unavailable>"
 	gdb_test "print \$.member" " = <unavailable>"
  	# Cast to baseclass, checking the unavailable-ness is propagated.
-	gdb_test "print (small_struct) g_smallstruct_b" " = \\{member =
<unavailable>\\}"
+	gdb_test "print (small_struct) g_smallstruct_b" " = <unavailable>"
  	# Same cast, but starting from a non-lazy, value.
-	gdb_test "print g_smallstruct_b" " = \\{<small_struct> = \\{member =
<unavailable>\\}, <No data fields>\\}"
-	gdb_test "print (small_struct) \$" " = \\{member = <unavailable>\\}"
+	gdb_test "print g_smallstruct_b" " = <unavailable>"
+	gdb_test "print (small_struct) \$" " = <unavailable>"
  	gdb_test_no_output "set print object on"
 @@ -538,11 +538,11 @@ proc gdb_collect_globals_test { } {
 	    # the pointed-to object, to check its run-time type.  Make
 	    # sure that fails gracefully and transparently when the
 	    # pointer itself is unavailable.
-	    gdb_test "print virtualp" " = \\(Virtual \\*\\) <unavailable>"
+	    gdb_test "print virtualp" " = <unavailable>"
  	    # no vtable pointer available
 	    gdb_test "print derived_unavail" \
-		" = {<Middle> = <unavailable>, _vptr.Derived = <unavailable>, z =
<unavailable>}"
+		" = <unavailable>"
  	    # vtable pointer available, but nothing else
 	    gdb_test "print derived_partial" \
@@ -556,11 +556,11 @@ proc gdb_collect_globals_test { } {
 	gdb_test_no_output "set print object off"
  	with_test_prefix "print object off" {
-	    gdb_test "print virtualp" " = \\(Virtual \\*\\) <unavailable>"
+	    gdb_test "print virtualp" " = <unavailable>"
  	    # no vtable pointer available
 	    gdb_test "print derived_unavail" \
-		" = {<Middle> = <unavailable>, _vptr.Derived = <unavailable>, z =
<unavailable>}"
+		" = <unavailable>"
  	    # vtable pointer available, but nothing else
 	    gdb_test "print derived_partial" \
diff --git a/gdb/valprint.c b/gdb/valprint.c
index 753ae34..4e165b4 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -311,10 +311,16 @@ valprint_check_validity (struct ui_file *stream,
       && TYPE_CODE (type) != TYPE_CODE_STRUCT
       && TYPE_CODE (type) != TYPE_CODE_ARRAY)
     {
-      if (!value_bits_valid (val, TARGET_CHAR_BIT * embedded_offset,
-			     TARGET_CHAR_BIT * TYPE_LENGTH (type)))
+      if (!value_bits_available (val, TARGET_CHAR_BIT * embedded_offset,
+				 TARGET_CHAR_BIT * TYPE_LENGTH (type)))
 	{
-	  val_print_optimized_out (stream);
+	  int optimizedp, unavailablep;
+	  +	  value_availability_flags (val, &optimizedp, &unavailablep);
+	  if (optimizedp)
+	    val_print_optimized_out (stream);
+	  else
+	    val_print_unavailable (stream);
 	  return 0;
 	}
 @@ -324,12 +330,6 @@ valprint_check_validity (struct ui_file *stream,
 	  fputs_filtered (_("<synthetic pointer>"), stream);
 	  return 0;
 	}
-
-      if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH
(type)))
-	{
-	  val_print_unavailable (stream);
-	  return 0;
-	}
     }
    return 1;
@@ -800,12 +800,20 @@ value_check_printable (struct value *val, struct
ui_file *stream,
       return 0;
     }
 -  if (value_entirely_optimized_out (val))
+  if (value_entirely_unavailable (val))
     {
       if (options->summary && !scalar_type_p (value_type (val)))
 	fprintf_filtered (stream, "...");
       else
-	val_print_optimized_out (stream);
+	{
+	  int optimizedp, unavailablep;
+
+	  value_availability_flags (val, &optimizedp, &unavailablep);
+	  if (optimizedp)
+	    val_print_optimized_out (stream);
+	  else
+	    val_print_unavailable (stream);
+	}
       return 0;
     }
 @@ -964,11 +972,16 @@ val_print_scalar_formatted (struct type *type,
    /* A scalar object that does not have all bits available can't be
      printed, because all bits contribute to its representation.  */
-  if (!value_bits_valid (val, TARGET_CHAR_BIT * embedded_offset,
-			      TARGET_CHAR_BIT * TYPE_LENGTH (type)))
-    val_print_optimized_out (stream);
-  else if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH
(type)))
-    val_print_unavailable (stream);
+  if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type)))
+    {
+      int optimizedp, unavailablep;
+      +      value_availability_flags (val, &optimizedp, &unavailablep);
+      if (optimizedp)
+	val_print_optimized_out (stream);
+      else
+	val_print_unavailable (stream);
+    }
   else
     print_scalar_formatted (valaddr + embedded_offset, type,
 			    options, size, stream);
diff --git a/gdb/value.c b/gdb/value.c
index 49af876..b9f5709 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -335,11 +335,25 @@ struct value
 int
 value_bytes_available (const struct value *value, int offset, int length)
 {
+  return value_bits_available (value,
+			       offset * TARGET_CHAR_BIT,
+			       length * TARGET_CHAR_BIT);
+}
+
+int
+value_bits_available (const struct value *value, int offset, int length)
+{
   gdb_assert (!value->lazy);
 -  return !ranges_contain (value->unavailable,
-			  offset * TARGET_CHAR_BIT,
-			  length * TARGET_CHAR_BIT);
+  if (ranges_contain (value->unavailable, offset, length))
+    return 0;
+  if (!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
@@ -350,11 +364,43 @@ value_entirely_available (struct value *value)
   if (value->lazy)
     value_fetch_lazy (value);
 -  if (VEC_empty (range_s, value->unavailable))
+  if (VEC_empty (range_s, value->unavailable)
+      && !value->optimized_out)
     return 1;
   return 0;
 }
 +int
+value_entirely_unavailable (struct value *value)
+{
+  if (value->lazy)
+    value_fetch_lazy (value);
+
+  /* Check if the unavailable vector covers the entire value.  As we merge
+     entries in the vector, if the entire value is covered then we'll
+     have a single entry starting at offset 0 and length as long as the
+     type.  */
+  if (VEC_length (range_s, value->unavailable) == 1)
+    {
+      const range_s *r;
+      struct type *type;
+
+      type = check_typedef (value_type (value));
+      r = VEC_index (range_s, value->unavailable, 0);
+      if (r->offset == 0 && r->length >= TARGET_CHAR_BIT * TYPE_LENGTH
(type))
+	return 1;
+    }
+
+  /* At least some of the value contents are NOT covered by the unavailable
+     vector, fall back to the optimized out heuristic.  */
+  if (!value->optimized_out)
+    return 0;
+  if (value->lval != lval_computed
+      || !value->location.computed.funcs->check_any_valid)
+    return 1;
+  return !value->location.computed.funcs->check_any_valid (value);
+}
+
 /* Insert into the vector pointed to by VECTORP the bit range starting of
    OFFSET bits, and extending for the next LENGTH bits.  */
 @@ -531,6 +577,15 @@ mark_value_bytes_unavailable (struct value *value,
int offset, int length)
 				length * TARGET_CHAR_BIT);
 }
 +void
+value_availability_flags (const struct value *value,
+			  int *optimizedp,
+			  int *unavailablep)
+{
+  *optimizedp = value->optimized_out;
+  *unavailablep = !VEC_empty (range_s, value->unavailable);
+}
+
 /* Find the first range in RANGES that overlaps the range defined by
    OFFSET and LENGTH, starting at element POS in the RANGES vector,
    Returns the index into RANGES where such overlapping range was
@@ -1112,29 +1167,6 @@ mark_value_bits_optimized_out (struct value *value,
 }
  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_any_valid)
-    return 1;
-  return !value->location.computed.funcs->check_any_valid (value);
-}
-
-int
-value_bits_valid (const struct value *value, int offset, int length)
-{
-  if (!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_bits_synthetic_pointer (const struct value *value,
 			      int offset, int length)
 {
@@ -3473,19 +3505,26 @@ value_fetch_lazy (struct value *val)
       if (value_lazy (parent))
 	value_fetch_lazy (parent);
 -      if (!value_bits_valid (parent,
-			     TARGET_CHAR_BIT * offset + value_bitpos (val),
-			     value_bitsize (val)))
-	mark_value_bytes_optimized_out (val, value_embedded_offset (val),
-					TYPE_LENGTH (type));
+      if (!value_bits_available (parent,
+				 TARGET_CHAR_BIT * offset + value_bitpos (val),
+				 value_bitsize (val)))
+	{
+	  int optimizedp, unavailablep;
+
+	  value_availability_flags (parent, &optimizedp, &unavailablep);
+	  if (optimizedp)
+	    mark_value_bytes_optimized_out (val, value_embedded_offset (val),
+					    TYPE_LENGTH (type));
+	  else
+	    mark_value_bytes_unavailable (val, value_embedded_offset (val),
+					  TYPE_LENGTH (type));
+	}
       else if (!unpack_value_bits_as_long (value_type (val),
 				      value_contents_for_printing (parent),
 				      offset,
 				      value_bitpos (val),
 				      value_bitsize (val), parent, &num))
-	mark_value_bytes_unavailable (val,
-				      value_embedded_offset (val),
-				      TYPE_LENGTH (type));
+	error (_("unable to unpack bitfield"));
       else
 	store_signed_integer (value_contents_raw (val), TYPE_LENGTH (type),
 			      byte_order, num);
diff --git a/gdb/value.h b/gdb/value.h
index dd8a0c1..81c1cc5 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -335,10 +335,6 @@ extern void mark_value_bytes_optimized_out (struct
value *value,
 extern void mark_value_bits_optimized_out (struct value *value,
 					   int offset, int length);
 -/* 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.  */
@@ -417,13 +413,6 @@ 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);
-
-/* Given a value, determine whether the bits starting at OFFSET and
    extending for LENGTH bits are a synthetic pointer.  */
  extern int value_bits_synthetic_pointer (const struct value *value,
@@ -437,16 +426,37 @@ extern int value_bits_synthetic_pointer (const
struct value *value,
 extern int value_bytes_available (const struct value *value,
 				  int offset, int length);
 -/* Like value_bytes_available, but return false if any byte in the
-   whole object is unavailable.  */
+/* Given a value, determine whether the bits starting at OFFSET and
+   extending for LENGTH bits are available.  This returns nonzero if all
+   bits in the given range are available, zero if any bit is
unavailable.  */
+
+extern int value_bits_available (const struct value *value,
+				 int offset, int length);
+
+/* Return true if the entire contents of VALUE are available, if any part
+   of VALUE is not available then return false.  */
+
 extern int value_entirely_available (struct value *value);
 +/* Return true if the entire contents of VALUE are unavailable.  If any
+   part of VALUE is available then return false.  */
+
+extern int value_entirely_unavailable (struct value *value);
+
 /* Mark VALUE's content bytes starting at OFFSET and extending for
    LENGTH bytes as unavailable.  */
  extern void mark_value_bytes_unavailable (struct value *value,
 					  int offset, int length);
 +/* Set contents of OPTIMIZEDP to nonzero if any part of VALUE is optimized
+   out, otherwise set to zero.  Set contents of UNAVAILABLEP to nonzero if
+   any part of VALUE is unavailable, otherwise set to zero.  */
+
+extern void value_availability_flags (const struct value *value,
+				      int *optimizedp,
+				      int *unavailablep);
+
 /* Compare LENGTH bytes of VAL1's contents starting at OFFSET1 with
    LENGTH bytes of VAL2's contents starting at OFFSET2.




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]