gdb/
[deliverable/binutils-gdb.git] / gdb / value.c
index 236b42f12a56ecffb73abf02417fc0ee20a0de0d..087cdfd5c25ce81b7efed97918470a0f30d0d2e8 100644 (file)
@@ -39,9 +39,9 @@
 #include "objfiles.h"
 #include "valprint.h"
 #include "cli/cli-decode.h"
-
+#include "exceptions.h"
 #include "python/python.h"
-
+#include <ctype.h>
 #include "tracepoint.h"
 
 /* Prototypes for exported functions.  */
@@ -194,8 +194,11 @@ struct value
        for them to use.  */
     struct
     {
-      struct lval_funcs *funcs; /* Functions to call.  */
-      void *closure;            /* Closure for those functions to use.  */
+      /* Functions to call.  */
+      const struct lval_funcs *funcs;
+
+      /* Closure for those functions to use.  */
+      void *closure;
     } computed;
   } location;
 
@@ -439,7 +442,7 @@ mark_value_bytes_unavailable (struct value *value, int offset, int length)
   i = VEC_lower_bound (range_s, value->unavailable, &newr, range_lessthan);
   if (i > 0)
     {
-      struct range *bef = VEC_index (range_s, value->unavailable, i - i);
+      struct range *bef = VEC_index (range_s, value->unavailable, i - 1);
 
       if (ranges_overlap (bef->offset, bef->length, offset, length))
        {
@@ -533,21 +536,13 @@ value_available_contents_eq (const struct value *val1, int offset1,
                             const struct value *val2, int offset2,
                             int length)
 {
-  int org_len = length;
-  int org_offset1 = offset1;
-  int org_offset2 = offset2;
   int idx1 = 0, idx2 = 0;
-  int prev_avail;
 
   /* This routine is used by printing routines, where we should
      already have read the value.  Note that we only know whether a
      value chunk is available if we've tried to read it.  */
   gdb_assert (!val1->lazy && !val2->lazy);
 
-  /* The offset from either ORG_OFFSET1 or ORG_OFFSET2 where the
-     available contents we haven't compared yet start.  */
-  prev_avail = 0;
-
   while (length > 0)
     {
       range_s *r1, *r2;
@@ -561,9 +556,9 @@ value_available_contents_eq (const struct value *val1, int offset1,
 
       /* The usual case is for both values to be completely available.  */
       if (idx1 == -1 && idx2 == -1)
-       return (memcmp (val1->contents + org_offset1 + prev_avail,
-                       val2->contents + org_offset2 + prev_avail,
-                       org_len - prev_avail) == 0);
+       return (memcmp (val1->contents + offset1,
+                       val2->contents + offset2,
+                       length) == 0);
       /* The contents only match equal if the available set matches as
         well.  */
       else if (idx1 == -1 || idx2 == -1)
@@ -596,12 +591,11 @@ value_available_contents_eq (const struct value *val1, int offset1,
        return 0;
 
       /* Compare the _available_ contents.  */
-      if (memcmp (val1->contents + org_offset1 + prev_avail,
-                 val2->contents + org_offset2 + prev_avail,
-                 l2 - prev_avail) != 0)
+      if (memcmp (val1->contents + offset1,
+                 val2->contents + offset2,
+                 l1) != 0)
        return 0;
 
-      prev_avail += h1;
       length -= h1;
       offset1 += h1;
       offset2 += h1;
@@ -725,7 +719,7 @@ allocate_repeat_value (struct type *type, int count)
 
 struct value *
 allocate_computed_value (struct type *type,
-                         struct lval_funcs *funcs,
+                         const struct lval_funcs *funcs,
                          void *closure)
 {
   struct value *v = allocate_value_lazy (type);
@@ -737,6 +731,18 @@ allocate_computed_value (struct type *type,
   return v;
 }
 
+/* Allocate NOT_LVAL value for type TYPE being OPTIMIZED_OUT.  */
+
+struct value *
+allocate_optimized_out_value (struct type *type)
+{
+  struct value *retval = allocate_value_lazy (type);
+
+  set_value_optimized_out (retval, 1);
+
+  return retval;
+}
+
 /* Accessor methods.  */
 
 struct value *
@@ -826,7 +832,7 @@ static void
 require_available (const struct value *value)
 {
   if (!VEC_empty (range_s, value->unavailable))
-    error (_("value is not available"));
+    throw_error (NOT_AVAILABLE_ERROR, _("value is not available"));
 }
 
 const gdb_byte *
@@ -853,11 +859,15 @@ value_contents_all (struct value *value)
   return result;
 }
 
-/* Copy LENGTH bytes of SRC value's contents starting at SRC_OFFSET,
-   into DST value's contents, starting at DST_OFFSET.  If unavailable
-   contents are being copied from SRC, the corresponding DST contents
-   are marked unavailable accordingly.  Neither DST nor SRC may be
-   lazy values.  */
+/* Copy LENGTH bytes of SRC value's (all) contents
+   (value_contents_all) starting at SRC_OFFSET, into DST value's (all)
+   contents, starting at DST_OFFSET.  If unavailable contents are
+   being copied from SRC, the corresponding DST contents are marked
+   unavailable accordingly.  Neither DST nor SRC may be lazy
+   values.
+
+   It is assumed the contents of DST in the [DST_OFFSET,
+   DST_OFFSET+LENGTH) range are wholly available.  */
 
 void
 value_contents_copy_raw (struct value *dst, int dst_offset,
@@ -872,6 +882,11 @@ value_contents_copy_raw (struct value *dst, int dst_offset,
      mean we'd be copying garbage.  */
   gdb_assert (!dst->lazy && !src->lazy);
 
+  /* The overwritten DST range gets unavailability ORed in, not
+     replaced.  Make sure to remember to implement replacing if it
+     turns out actually necessary.  */
+  gdb_assert (value_bytes_available (dst, dst_offset, length));
+
   /* Copy the data.  */
   memcpy (value_contents_all_raw (dst) + dst_offset,
          value_contents_all_raw (src) + src_offset,
@@ -892,12 +907,16 @@ value_contents_copy_raw (struct value *dst, int dst_offset,
     }
 }
 
-/* Copy LENGTH bytes of SRC value's contents starting at SRC_OFFSET
-   byte, into DST value's contents, starting at DST_OFFSET.  If
-   unavailable contents are being copied from SRC, the corresponding
-   DST contents are marked unavailable accordingly.  DST must not be
-   lazy.  If SRC is lazy, it will be fetched now.  If SRC is not valid
-   (is optimized out), an error is thrown.  */
+/* Copy LENGTH bytes of SRC value's (all) contents
+   (value_contents_all) starting at SRC_OFFSET byte, into DST value's
+   (all) contents, starting at DST_OFFSET.  If unavailable contents
+   are being copied from SRC, the corresponding DST contents are
+   marked unavailable accordingly.  DST must not be lazy.  If SRC is
+   lazy, it will be fetched now.  If SRC is not valid (is optimized
+   out), an error is thrown.
+
+   It is assumed the contents of DST in the [DST_OFFSET,
+   DST_OFFSET+LENGTH) range are wholly available.  */
 
 void
 value_contents_copy (struct value *dst, int dst_offset,
@@ -998,7 +1017,7 @@ value_entirely_optimized_out (const struct value *value)
 int
 value_bits_valid (const struct value *value, int offset, int length)
 {
-  if (value == NULL || !value->optimized_out)
+  if (!value->optimized_out)
     return 1;
   if (value->lval != lval_computed
       || !value->location.computed.funcs->check_validity)
@@ -1011,7 +1030,7 @@ int
 value_bits_synthetic_pointer (const struct value *value,
                              int offset, int length)
 {
-  if (value == NULL || value->lval != lval_computed
+  if (value->lval != lval_computed
       || !value->location.computed.funcs->check_synthetic_pointer)
     return 0;
   return value->location.computed.funcs->check_synthetic_pointer (value,
@@ -1043,7 +1062,7 @@ set_value_pointed_to_offset (struct value *value, int val)
   value->pointed_to_offset = val;
 }
 
-struct lval_funcs *
+const struct lval_funcs *
 value_computed_funcs (struct value *v)
 {
   gdb_assert (VALUE_LVAL (v) == lval_computed);
@@ -1159,7 +1178,7 @@ value_free (struct value *val)
 
       if (VALUE_LVAL (val) == lval_computed)
        {
-         struct lval_funcs *funcs = val->location.computed.funcs;
+         const struct lval_funcs *funcs = val->location.computed.funcs;
 
          if (funcs->free_closure)
            funcs->free_closure (val);
@@ -1303,7 +1322,7 @@ value_copy (struct value *arg)
     value_incref (val->parent);
   if (VALUE_LVAL (val) == lval_computed)
     {
-      struct lval_funcs *funcs = val->location.computed.funcs;
+      const struct lval_funcs *funcs = val->location.computed.funcs;
 
       if (funcs->copy_closure)
         val->location.computed.closure = funcs->copy_closure (val);
@@ -1343,7 +1362,7 @@ set_value_component_location (struct value *component,
   component->location = whole->location;
   if (whole->lval == lval_computed)
     {
-      struct lval_funcs *funcs = whole->location.computed.funcs;
+      const struct lval_funcs *funcs = whole->location.computed.funcs;
 
       if (funcs->copy_closure)
         component->location.computed.closure = funcs->copy_closure (whole);
@@ -2076,13 +2095,23 @@ show_convenience (char *ignore, int from_tty)
   get_user_print_options (&opts);
   for (var = internalvars; var; var = var->next)
     {
+      volatile struct gdb_exception ex;
+
       if (!varseen)
        {
          varseen = 1;
        }
       printf_filtered (("$%s = "), var->name);
-      value_print (value_of_internalvar (gdbarch, var), gdb_stdout,
-                  &opts);
+
+      TRY_CATCH (ex, RETURN_MASK_ERROR)
+       {
+         struct value *val;
+
+         val = value_of_internalvar (gdbarch, var);
+         value_print (val, gdb_stdout, &opts);
+       }
+      if (ex.reason < 0)
+       fprintf_filtered (gdb_stdout, _("<error: %s>"), ex.message);
       printf_filtered (("\n"));
     }
   if (!varseen)
@@ -2384,7 +2413,7 @@ value_static_field (struct type *type, int fieldno)
       break;
     case FIELD_LOC_KIND_PHYSNAME:
     {
-      char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, fieldno);
+      const char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, fieldno);
       /* TYPE_FIELD_NAME (type, fieldno); */
       struct symbol *sym = lookup_symbol (phys_name, 0, VAR_DOMAIN, 0);
 
@@ -2555,7 +2584,7 @@ value_fn_field (struct value **arg1p, struct fn_field *f,
 {
   struct value *v;
   struct type *ftype = TYPE_FN_FIELD_TYPE (f, j);
-  char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
+  const char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
   struct symbol *sym;
   struct minimal_symbol *msym;
 
@@ -2961,6 +2990,19 @@ value_from_contents_and_address (struct type *type,
   return v;
 }
 
+/* Create a value of type TYPE holding the contents CONTENTS.
+   The new value is `not_lval'.  */
+
+struct value *
+value_from_contents (struct type *type, const gdb_byte *contents)
+{
+  struct value *result;
+
+  result = allocate_value (type);
+  memcpy (value_contents_raw (result), contents, TYPE_LENGTH (type));
+  return result;
+}
+
 struct value *
 value_from_double (struct type *type, DOUBLEST num)
 {
@@ -2987,6 +3029,59 @@ value_from_decfloat (struct type *type, const gdb_byte *dec)
   return val;
 }
 
+/* Extract a value from the history file.  Input will be of the form
+   $digits or $$digits.  See block comment above 'write_dollar_variable'
+   for details.  */
+
+struct value *
+value_from_history_ref (char *h, char **endp)
+{
+  int index, len;
+
+  if (h[0] == '$')
+    len = 1;
+  else
+    return NULL;
+
+  if (h[1] == '$')
+    len = 2;
+
+  /* Find length of numeral string.  */
+  for (; isdigit (h[len]); len++)
+    ;
+
+  /* Make sure numeral string is not part of an identifier.  */
+  if (h[len] == '_' || isalpha (h[len]))
+    return NULL;
+
+  /* Now collect the index value.  */
+  if (h[1] == '$')
+    {
+      if (len == 2)
+       {
+         /* For some bizarre reason, "$$" is equivalent to "$$1", 
+            rather than to "$$0" as it ought to be!  */
+         index = -1;
+         *endp += len;
+       }
+      else
+       index = -strtol (&h[2], endp, 10);
+    }
+  else
+    {
+      if (len == 1)
+       {
+         /* "$" is equivalent to "$0".  */
+         index = 0;
+         *endp += len;
+       }
+      else
+       index = strtol (&h[1], endp, 10);
+    }
+
+  return access_value_history (index);
+}
+
 struct value *
 coerce_ref (struct value *arg)
 {
@@ -3074,7 +3169,7 @@ A few convenience variables are given values automatically:\n\
 \"$__\" holds the contents of the last address examined with \"x\"."),
           &showlist);
 
-  add_cmd ("values", no_class, show_values, _("\
+  add_cmd ("values", no_set_class, show_values, _("\
 Elements of value history around item number IDX (or last ten)."),
           &showlist);
 
This page took 0.028306 seconds and 4 git commands to generate.