2005-02-07 Andrew Cagney <cagney@gnu.org>
[deliverable/binutils-gdb.git] / gdb / value.c
index 0a829274ae4f78c0cf189e62f1a3db488698104b..0006a40eedbec492cb61766785e540bbdfbf9259 100644 (file)
@@ -1,8 +1,8 @@
 /* Low level packing and unpacking of values for GDB, the GNU Debugger.
 
    Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
-   1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003 Free Software
-   Foundation, Inc.
+   1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005 Free
+   Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -83,20 +83,20 @@ allocate_value (struct type *type)
   struct value *val;
   struct type *atype = check_typedef (type);
 
-  val = (struct value *) xmalloc (sizeof (struct value) + TYPE_LENGTH (atype));
-  VALUE_NEXT (val) = all_values;
+  val = (struct value *) xzalloc (sizeof (struct value) + TYPE_LENGTH (atype));
+  val->next = all_values;
   all_values = val;
-  VALUE_TYPE (val) = type;
-  VALUE_ENCLOSING_TYPE (val) = type;
+  val->type = type;
+  val->enclosing_type = type;
   VALUE_LVAL (val) = not_lval;
   VALUE_ADDRESS (val) = 0;
   VALUE_FRAME_ID (val) = null_frame_id;
-  VALUE_OFFSET (val) = 0;
-  VALUE_BITPOS (val) = 0;
-  VALUE_BITSIZE (val) = 0;
-  VALUE_REGNO (val) = -1;
-  VALUE_LAZY (val) = 0;
-  VALUE_OPTIMIZED_OUT (val) = 0;
+  val->offset = 0;
+  val->bitpos = 0;
+  val->bitsize = 0;
+  VALUE_REGNUM (val) = -1;
+  val->lazy = 0;
+  val->optimized_out = 0;
   VALUE_EMBEDDED_OFFSET (val) = 0;
   VALUE_POINTED_TO_OFFSET (val) = 0;
   val->modifiable = 1;
@@ -121,6 +121,96 @@ allocate_repeat_value (struct type *type, int count)
                                            type, range_type));
 }
 
+/* Accessor methods.  */
+
+struct type *
+value_type (struct value *value)
+{
+  return value->type;
+}
+
+int
+value_offset (struct value *value)
+{
+  return value->offset;
+}
+
+int
+value_bitpos (struct value *value)
+{
+  return value->bitpos;
+}
+
+int
+value_bitsize (struct value *value)
+{
+  return value->bitsize;
+}
+
+bfd_byte *
+value_contents_raw (struct value *value)
+{
+  return value->aligner.contents + value->embedded_offset;
+}
+
+bfd_byte *
+value_contents_all_raw (struct value *value)
+{
+  return value->aligner.contents;
+}
+
+struct type *
+value_enclosing_type (struct value *value)
+{
+  return value->enclosing_type;
+}
+
+const bfd_byte *
+value_contents_all (struct value *value)
+{
+  if (value->lazy)
+    value_fetch_lazy (value);
+  return value->aligner.contents;
+}
+
+int
+value_lazy (struct value *value)
+{
+  return value->lazy;
+}
+
+void
+set_value_lazy (struct value *value, int val)
+{
+  value->lazy = val;
+}
+
+const bfd_byte *
+value_contents (struct value *value)
+{
+  return value_contents_writeable (value);
+}
+
+bfd_byte *
+value_contents_writeable (struct value *value)
+{
+  if (value->lazy)
+    value_fetch_lazy (value);
+  return value->aligner.contents;
+}
+
+int
+value_optimized_out (struct value *value)
+{
+  return value->optimized_out;
+}
+
+void
+set_value_optimized_out (struct value *value, int val)
+{
+  value->optimized_out = val;
+}
+\f
 /* Return a mark in the value chain.  All values allocated after the
    mark is obtained (except for those released) are subject to being freed
    if a subsequent value_free_to_mark is passed the mark.  */
@@ -140,7 +230,7 @@ value_free_to_mark (struct value *mark)
 
   for (val = all_values; val && val != mark; val = next)
     {
-      next = VALUE_NEXT (val);
+      next = val->next;
       value_free (val);
     }
   all_values = val;
@@ -157,7 +247,7 @@ free_all_values (void)
 
   for (val = all_values; val; val = next)
     {
-      next = VALUE_NEXT (val);
+      next = val->next;
       value_free (val);
     }
 
@@ -195,11 +285,11 @@ value_release_to_mark (struct value *mark)
   struct value *val;
   struct value *next;
 
-  for (val = next = all_values; next; next = VALUE_NEXT (next))
-    if (VALUE_NEXT (next) == mark)
+  for (val = next = all_values; next; next = next->next)
+    if (next->next == mark)
       {
-       all_values = VALUE_NEXT (next);
-       VALUE_NEXT (next) = 0;
+       all_values = next->next;
+       next->next = NULL;
        return val;
       }
   all_values = 0;
@@ -213,25 +303,25 @@ value_release_to_mark (struct value *mark)
 struct value *
 value_copy (struct value *arg)
 {
-  struct type *encl_type = VALUE_ENCLOSING_TYPE (arg);
+  struct type *encl_type = value_enclosing_type (arg);
   struct value *val = allocate_value (encl_type);
-  VALUE_TYPE (val) = VALUE_TYPE (arg);
+  val->type = arg->type;
   VALUE_LVAL (val) = VALUE_LVAL (arg);
   VALUE_ADDRESS (val) = VALUE_ADDRESS (arg);
-  VALUE_OFFSET (val) = VALUE_OFFSET (arg);
-  VALUE_BITPOS (val) = VALUE_BITPOS (arg);
-  VALUE_BITSIZE (val) = VALUE_BITSIZE (arg);
+  val->offset = arg->offset;
+  val->bitpos = arg->bitpos;
+  val->bitsize = arg->bitsize;
   VALUE_FRAME_ID (val) = VALUE_FRAME_ID (arg);
-  VALUE_REGNO (val) = VALUE_REGNO (arg);
-  VALUE_LAZY (val) = VALUE_LAZY (arg);
-  VALUE_OPTIMIZED_OUT (val) = VALUE_OPTIMIZED_OUT (arg);
+  VALUE_REGNUM (val) = VALUE_REGNUM (arg);
+  val->lazy = arg->lazy;
+  val->optimized_out = arg->optimized_out;
   VALUE_EMBEDDED_OFFSET (val) = VALUE_EMBEDDED_OFFSET (arg);
   VALUE_POINTED_TO_OFFSET (val) = VALUE_POINTED_TO_OFFSET (arg);
   val->modifiable = arg->modifiable;
-  if (!VALUE_LAZY (val))
+  if (!value_lazy (val))
     {
-      memcpy (VALUE_CONTENTS_ALL_RAW (val), VALUE_CONTENTS_ALL_RAW (arg),
-             TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg)));
+      memcpy (value_contents_all_raw (val), value_contents_all_raw (arg),
+             TYPE_LENGTH (value_enclosing_type (arg)));
 
     }
   return val;
@@ -253,7 +343,7 @@ record_latest_value (struct value *val)
      In particular, "set $1 = 50" should not affect the variable from which
      the value was taken, and fast watchpoints should be able to assume that
      a value on the value history never changes.  */
-  if (VALUE_LAZY (val))
+  if (value_lazy (val))
     value_fetch_lazy (val);
   /* We preserve VALUE_LVAL so that the user can find out where it was fetched
      from.  This is a bit dubious, because then *&$1 does not just return $1
@@ -423,7 +513,7 @@ value_of_internalvar (struct internalvar *var)
   struct value *val;
 
   val = value_copy (var->value);
-  if (VALUE_LAZY (val))
+  if (value_lazy (val))
     value_fetch_lazy (val);
   VALUE_LVAL (val) = lval_internalvar;
   VALUE_INTERNALVAR (val) = var;
@@ -434,13 +524,13 @@ void
 set_internalvar_component (struct internalvar *var, int offset, int bitpos,
                           int bitsize, struct value *newval)
 {
-  char *addr = VALUE_CONTENTS (var->value) + offset;
+  bfd_byte *addr = value_contents_writeable (var->value) + offset;
 
   if (bitsize)
     modify_field (addr, value_as_long (newval),
                  bitpos, bitsize);
   else
-    memcpy (addr, VALUE_CONTENTS (newval), TYPE_LENGTH (VALUE_TYPE (newval)));
+    memcpy (addr, value_contents (newval), TYPE_LENGTH (value_type (newval)));
 }
 
 void
@@ -454,7 +544,7 @@ set_internalvar (struct internalvar *var, struct value *val)
   /* Force the value to be fetched from the target now, to avoid problems
      later when this internalvar is referenced and the target is gone or
      has changed.  */
-  if (VALUE_LAZY (newval))
+  if (value_lazy (newval))
     value_fetch_lazy (newval);
 
   /* Begin code which must not call error().  If var->value points to
@@ -526,8 +616,8 @@ value_as_long (struct value *val)
   /* This coerces arrays and functions, which is necessary (e.g.
      in disassemble_command).  It also dereferences references, which
      I suspect is the most logical thing to do.  */
-  COERCE_ARRAY (val);
-  return unpack_long (VALUE_TYPE (val), VALUE_CONTENTS (val));
+  val = coerce_array (val);
+  return unpack_long (value_type (val), value_contents (val));
 }
 
 DOUBLEST
@@ -536,7 +626,7 @@ value_as_double (struct value *val)
   DOUBLEST foo;
   int inv;
 
-  foo = unpack_double (VALUE_TYPE (val), VALUE_CONTENTS (val), &inv);
+  foo = unpack_double (value_type (val), value_contents (val), &inv);
   if (inv)
     error ("Invalid floating value found in program.");
   return foo;
@@ -593,11 +683,11 @@ value_as_address (struct value *val)
 
      The following shortcut avoids this whole mess.  If VAL is a
      function, just return its address directly.  */
-  if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FUNC
-      || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_METHOD)
+  if (TYPE_CODE (value_type (val)) == TYPE_CODE_FUNC
+      || TYPE_CODE (value_type (val)) == TYPE_CODE_METHOD)
     return VALUE_ADDRESS (val);
 
-  COERCE_ARRAY (val);
+  val = coerce_array (val);
 
   /* Some architectures (e.g. Harvard), map instruction and data
      addresses onto a single large unified address space.  For
@@ -628,7 +718,7 @@ value_as_address (struct value *val)
      take an address from a disassembly listing and give it to `x/i'.
      This is certainly important.
 
-     Adding an architecture method like INTEGER_TO_ADDRESS certainly
+     Adding an architecture method like integer_to_address() certainly
      makes it possible for GDB to "get it right" in all circumstances
      --- the target has complete control over how things get done, so
      people can Do The Right Thing for their target without breaking
@@ -636,12 +726,13 @@ value_as_address (struct value *val)
      converted to pointers; usually, the ABI doesn't either, but
      ABI-specific code is a more reasonable place to handle it.  */
 
-  if (TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_PTR
-      && TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_REF
-      && INTEGER_TO_ADDRESS_P ())
-    return INTEGER_TO_ADDRESS (VALUE_TYPE (val), VALUE_CONTENTS (val));
+  if (TYPE_CODE (value_type (val)) != TYPE_CODE_PTR
+      && TYPE_CODE (value_type (val)) != TYPE_CODE_REF
+      && gdbarch_integer_to_address_p (current_gdbarch))
+    return gdbarch_integer_to_address (current_gdbarch, value_type (val),
+                                      value_contents (val));
 
-  return unpack_long (VALUE_TYPE (val), VALUE_CONTENTS (val));
+  return unpack_long (value_type (val), value_contents (val));
 #endif
 }
 \f
@@ -837,9 +928,9 @@ value_static_field (struct type *type, int fieldno)
 struct value *
 value_change_enclosing_type (struct value *val, struct type *new_encl_type)
 {
-  if (TYPE_LENGTH (new_encl_type) <= TYPE_LENGTH (VALUE_ENCLOSING_TYPE (val))) 
+  if (TYPE_LENGTH (new_encl_type) <= TYPE_LENGTH (value_enclosing_type (val))) 
     {
-      VALUE_ENCLOSING_TYPE (val) = new_encl_type;
+      val->enclosing_type = new_encl_type;
       return val;
     }
   else
@@ -849,7 +940,7 @@ value_change_enclosing_type (struct value *val, struct type *new_encl_type)
       
       new_val = (struct value *) xrealloc (val, sizeof (struct value) + TYPE_LENGTH (new_encl_type));
 
-      VALUE_ENCLOSING_TYPE (new_val) = new_encl_type;
+      new_val->enclosing_type = new_encl_type;
  
       /* We have to make sure this ends up in the same place in the value
         chain as the original copy, so it's clean-up behavior is the same. 
@@ -893,12 +984,12 @@ value_primitive_field (struct value *arg1, int offset,
     {
       v = value_from_longest (type,
                              unpack_field_as_long (arg_type,
-                                                   VALUE_CONTENTS (arg1)
+                                                   value_contents (arg1)
                                                    + offset,
                                                    fieldno));
-      VALUE_BITPOS (v) = TYPE_FIELD_BITPOS (arg_type, fieldno) % 8;
-      VALUE_BITSIZE (v) = TYPE_FIELD_BITSIZE (arg_type, fieldno);
-      VALUE_OFFSET (v) = VALUE_OFFSET (arg1) + offset
+      v->bitpos = TYPE_FIELD_BITPOS (arg_type, fieldno) % 8;
+      v->bitsize = TYPE_FIELD_BITSIZE (arg_type, fieldno);
+      v->offset = value_offset (arg1) + offset
        + TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
     }
   else if (fieldno < TYPE_N_BASECLASSES (arg_type))
@@ -906,14 +997,14 @@ value_primitive_field (struct value *arg1, int offset,
       /* This field is actually a base subobject, so preserve the
          entire object's contents for later references to virtual
          bases, etc.  */
-      v = allocate_value (VALUE_ENCLOSING_TYPE (arg1));
-      VALUE_TYPE (v) = type;
-      if (VALUE_LAZY (arg1))
-       VALUE_LAZY (v) = 1;
+      v = allocate_value (value_enclosing_type (arg1));
+      v->type = type;
+      if (value_lazy (arg1))
+       set_value_lazy (v, 1);
       else
-       memcpy (VALUE_CONTENTS_ALL_RAW (v), VALUE_CONTENTS_ALL_RAW (arg1),
-               TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg1)));
-      VALUE_OFFSET (v) = VALUE_OFFSET (arg1);
+       memcpy (value_contents_all_raw (v), value_contents_all_raw (arg1),
+               TYPE_LENGTH (value_enclosing_type (arg1)));
+      v->offset = value_offset (arg1);
       VALUE_EMBEDDED_OFFSET (v)
        = offset +
        VALUE_EMBEDDED_OFFSET (arg1) +
@@ -924,20 +1015,21 @@ value_primitive_field (struct value *arg1, int offset,
       /* Plain old data member */
       offset += TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
       v = allocate_value (type);
-      if (VALUE_LAZY (arg1))
-       VALUE_LAZY (v) = 1;
+      if (value_lazy (arg1))
+       set_value_lazy (v, 1);
       else
-       memcpy (VALUE_CONTENTS_RAW (v),
-               VALUE_CONTENTS_RAW (arg1) + offset,
+       memcpy (value_contents_raw (v),
+               value_contents_raw (arg1) + offset,
                TYPE_LENGTH (type));
-      VALUE_OFFSET (v) = VALUE_OFFSET (arg1) + offset
-                        + VALUE_EMBEDDED_OFFSET (arg1);
+      v->offset = (value_offset (arg1) + offset
+                  + VALUE_EMBEDDED_OFFSET (arg1));
     }
   VALUE_LVAL (v) = VALUE_LVAL (arg1);
   if (VALUE_LVAL (arg1) == lval_internalvar)
     VALUE_LVAL (v) = lval_internalvar_component;
   VALUE_ADDRESS (v) = VALUE_ADDRESS (arg1);
-  VALUE_REGNO (v) = VALUE_REGNO (arg1);
+  VALUE_REGNUM (v) = VALUE_REGNUM (arg1);
+  VALUE_FRAME_ID (v) = VALUE_FRAME_ID (arg1);
 /*  VALUE_OFFSET (v) = VALUE_OFFSET (arg1) + offset
    + TYPE_FIELD_BITPOS (arg_type, fieldno) / 8; */
   return v;
@@ -950,7 +1042,7 @@ value_primitive_field (struct value *arg1, int offset,
 struct value *
 value_field (struct value *arg1, int fieldno)
 {
-  return value_primitive_field (arg1, 0, fieldno, VALUE_TYPE (arg1));
+  return value_primitive_field (arg1, 0, fieldno, value_type (arg1));
 }
 
 /* Return a non-virtual function as a value.
@@ -996,7 +1088,7 @@ value_fn_field (struct value **arg1p, struct fn_field *f, int j, struct type *ty
 
   if (arg1p)
     {
-      if (type != VALUE_TYPE (*arg1p))
+      if (type != value_type (*arg1p))
        *arg1p = value_ind (value_cast (lookup_pointer_type (type),
                                        value_addr (*arg1p)));
 
@@ -1126,12 +1218,12 @@ retry:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_BOOL:
     case TYPE_CODE_RANGE:
-      store_signed_integer (VALUE_CONTENTS_RAW (val), len, num);
+      store_signed_integer (value_contents_raw (val), len, num);
       break;
 
     case TYPE_CODE_REF:
     case TYPE_CODE_PTR:
-      store_typed_address (VALUE_CONTENTS_RAW (val), type, (CORE_ADDR) num);
+      store_typed_address (value_contents_raw (val), type, (CORE_ADDR) num);
       break;
 
     default:
@@ -1147,7 +1239,7 @@ struct value *
 value_from_pointer (struct type *type, CORE_ADDR addr)
 {
   struct value *val = allocate_value (type);
-  store_typed_address (VALUE_CONTENTS_RAW (val), type, addr);
+  store_typed_address (value_contents_raw (val), type, addr);
   return val;
 }
 
@@ -1176,7 +1268,7 @@ value_from_string (char *ptr)
                                  string_char_type,
                                  rangetype);
   val = allocate_value (stringtype);
-  memcpy (VALUE_CONTENTS_RAW (val), ptr, len);
+  memcpy (value_contents_raw (val), ptr, len);
   return val;
 }
 
@@ -1190,13 +1282,52 @@ value_from_double (struct type *type, DOUBLEST num)
 
   if (code == TYPE_CODE_FLT)
     {
-      store_typed_floating (VALUE_CONTENTS_RAW (val), base_type, num);
+      store_typed_floating (value_contents_raw (val), base_type, num);
     }
   else
     error ("Unexpected type encountered for floating constant.");
 
   return val;
 }
+
+struct value *
+coerce_ref (struct value *arg)
+{
+  struct type *value_type_arg_tmp = check_typedef (value_type (arg));
+  if (TYPE_CODE (value_type_arg_tmp) == TYPE_CODE_REF)
+    arg = value_at_lazy (TYPE_TARGET_TYPE (value_type_arg_tmp),
+                        unpack_pointer (value_type (arg),              
+                                        value_contents (arg)));
+  return arg;
+}
+
+struct value *
+coerce_array (struct value *arg)
+{
+  arg = coerce_ref (arg);
+  if (current_language->c_style_arrays
+      && TYPE_CODE (value_type (arg)) == TYPE_CODE_ARRAY)
+    arg = value_coerce_array (arg);
+  if (TYPE_CODE (value_type (arg)) == TYPE_CODE_FUNC)
+    arg = value_coerce_function (arg);
+  return arg;
+}
+
+struct value *
+coerce_number (struct value *arg)
+{
+  arg = coerce_array (arg);
+  arg = coerce_enum (arg);
+  return arg;
+}
+
+struct value *
+coerce_enum (struct value *arg)
+{
+  if (TYPE_CODE (check_typedef (value_type (arg))) == TYPE_CODE_ENUM)
+    arg = value_cast (builtin_type_unsigned_int, arg);
+  return arg;
+}
 \f
 
 /* Should we use DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS instead of
This page took 0.034478 seconds and 4 git commands to generate.