2009-05-27 Tom Tromey <tromey@redhat.com>
[deliverable/binutils-gdb.git] / gdb / valops.c
index fe011d044625debaa79d193115b53f8f3801253b..f06d32c3696b79c66833a57160e25fa2674b38ac 100644 (file)
@@ -254,10 +254,8 @@ value_cast_structs (struct type *type, struct value *v2)
       if (v)
        {
          /* Downcasting is possible (t1 is superclass of v2).  */
-         CORE_ADDR addr2 = VALUE_ADDRESS (v2);
-         addr2 -= (VALUE_ADDRESS (v)
-                   + value_offset (v)
-                   + value_embedded_offset (v));
+         CORE_ADDR addr2 = value_address (v2);
+         addr2 -= value_address (v) + value_embedded_offset (v);
          return value_at (type, addr2);
        }
     }
@@ -510,8 +508,7 @@ value_cast (struct type *type, struct value *arg2)
       return arg2;
     }
   else if (VALUE_LVAL (arg2) == lval_memory)
-    return value_at_lazy (type, 
-                         VALUE_ADDRESS (arg2) + value_offset (arg2));
+    return value_at_lazy (type, value_address (arg2));
   else if (code1 == TYPE_CODE_VOID)
     {
       return value_zero (builtin_type_void, not_lval);
@@ -593,7 +590,7 @@ value_at (struct type *type, CORE_ADDR addr)
   read_memory (addr, value_contents_all_raw (val), TYPE_LENGTH (type));
 
   VALUE_LVAL (val) = lval_memory;
-  VALUE_ADDRESS (val) = addr;
+  set_value_address (val, addr);
 
   return val;
 }
@@ -611,7 +608,7 @@ value_at_lazy (struct type *type, CORE_ADDR addr)
   val = allocate_value_lazy (type);
 
   VALUE_LVAL (val) = lval_memory;
-  VALUE_ADDRESS (val) = addr;
+  set_value_address (val, addr);
 
   return val;
 }
@@ -637,7 +634,7 @@ value_fetch_lazy (struct value *val)
   allocate_value_contents (val);
   if (VALUE_LVAL (val) == lval_memory)
     {
-      CORE_ADDR addr = VALUE_ADDRESS (val) + value_offset (val);
+      CORE_ADDR addr = value_address (val);
       int length = TYPE_LENGTH (check_typedef (value_enclosing_type (val)));
 
       if (length)
@@ -709,7 +706,7 @@ value_fetch_lazy (struct value *val)
                                    VALUE_REGNUM (new_val));
              else if (VALUE_LVAL (new_val) == lval_memory)
                fprintf_unfiltered (gdb_stdlog, " address=0x%s",
-                                   paddr_nz (VALUE_ADDRESS (new_val)));
+                                   paddr_nz (value_address (new_val)));
              else
                fprintf_unfiltered (gdb_stdlog, " computed");
 
@@ -727,6 +724,8 @@ value_fetch_lazy (struct value *val)
         watchpoints from trying to watch the saved frame pointer.  */
       value_free_to_mark (mark);
     }
+  else if (VALUE_LVAL (val) == lval_computed)
+    value_computed_funcs (val)->read (val);
   else
     internal_error (__FILE__, __LINE__, "Unexpected lazy value type.");
 
@@ -811,16 +810,15 @@ value_assign (struct value *toval, struct value *fromval)
              error (_("Can't handle bitfields which don't fit in a %d bit word."),
                     (int) sizeof (LONGEST) * HOST_CHAR_BIT);
 
-           read_memory (VALUE_ADDRESS (toval) + value_offset (toval),
-                        buffer, changed_len);
+           read_memory (value_address (toval), buffer, changed_len);
            modify_field (buffer, value_as_long (fromval),
                          value_bitpos (toval), value_bitsize (toval));
-           changed_addr = VALUE_ADDRESS (toval) + value_offset (toval);
+           changed_addr = value_address (toval);
            dest_buffer = buffer;
          }
        else
          {
-           changed_addr = VALUE_ADDRESS (toval) + value_offset (toval);
+           changed_addr = value_address (toval);
            changed_len = TYPE_LENGTH (type);
            dest_buffer = value_contents (fromval);
          }
@@ -895,7 +893,15 @@ value_assign (struct value *toval, struct value *fromval)
        observer_notify_target_changed (&current_target);
        break;
       }
-      
+
+    case lval_computed:
+      {
+       struct lval_funcs *funcs = value_computed_funcs (toval);
+
+       funcs->write (toval, fromval);
+      }
+      break;
+
     default:
       error (_("Left operand of assignment is not an lvalue."));
     }
@@ -975,11 +981,11 @@ value_repeat (struct value *arg1, int count)
 
   val = allocate_repeat_value (value_enclosing_type (arg1), count);
 
-  read_memory (VALUE_ADDRESS (arg1) + value_offset (arg1),
+  read_memory (value_address (arg1),
               value_contents_all_raw (val),
               TYPE_LENGTH (value_enclosing_type (val)));
   VALUE_LVAL (val) = lval_memory;
-  VALUE_ADDRESS (val) = VALUE_ADDRESS (arg1) + value_offset (arg1);
+  set_value_address (val, value_address (arg1));
 
   return val;
 }
@@ -988,11 +994,13 @@ struct value *
 value_of_variable (struct symbol *var, struct block *b)
 {
   struct value *val;
-  struct frame_info *frame = NULL;
+  struct frame_info *frame;
 
-  if (!b)
-    frame = NULL;              /* Use selected frame.  */
-  else if (symbol_read_needs_frame (var))
+  if (!symbol_read_needs_frame (var))
+    frame = NULL;
+  else if (!b)
+    frame = get_selected_frame (_("No frame selected."));
+  else
     {
       frame = block_innermost_frame (b);
       if (!frame)
@@ -1013,6 +1021,54 @@ value_of_variable (struct symbol *var, struct block *b)
   return val;
 }
 
+struct value *
+address_of_variable (struct symbol *var, struct block *b)
+{
+  struct type *type = SYMBOL_TYPE (var);
+  struct value *val;
+
+  /* Evaluate it first; if the result is a memory address, we're fine.
+     Lazy evaluation pays off here. */
+
+  val = value_of_variable (var, b);
+
+  if ((VALUE_LVAL (val) == lval_memory && value_lazy (val))
+      || TYPE_CODE (type) == TYPE_CODE_FUNC)
+    {
+      CORE_ADDR addr = value_address (val);
+      return value_from_pointer (lookup_pointer_type (type), addr);
+    }
+
+  /* Not a memory address; check what the problem was.  */
+  switch (VALUE_LVAL (val))
+    {
+    case lval_register:
+      {
+       struct frame_info *frame;
+       const char *regname;
+
+       frame = frame_find_by_id (VALUE_FRAME_ID (val));
+       gdb_assert (frame);
+
+       regname = gdbarch_register_name (get_frame_arch (frame),
+                                        VALUE_REGNUM (val));
+       gdb_assert (regname && *regname);
+
+       error (_("Address requested for identifier "
+                "\"%s\" which is in register $%s"),
+              SYMBOL_PRINT_NAME (var), regname);
+       break;
+      }
+
+    default:
+      error (_("Can't take address of \"%s\" which isn't an lvalue."),
+            SYMBOL_PRINT_NAME (var));
+      break;
+    }
+
+  return val;
+}
+
 /* Return one if VAL does not live in target memory, but should in order
    to operate on it.  Otherwise return zero.  */
 
@@ -1095,7 +1151,7 @@ value_coerce_array (struct value *arg1)
     error (_("Attempt to take address of value not located in memory."));
 
   return value_from_pointer (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
-                            (VALUE_ADDRESS (arg1) + value_offset (arg1)));
+                            value_address (arg1));
 }
 
 /* Given a value which is a function, return a value which is a pointer
@@ -1110,7 +1166,7 @@ value_coerce_function (struct value *arg1)
     error (_("Attempt to take address of value not located in memory."));
 
   retval = value_from_pointer (lookup_pointer_type (value_type (arg1)),
-                              (VALUE_ADDRESS (arg1) + value_offset (arg1)));
+                              value_address (arg1));
   return retval;
 }
 
@@ -1145,8 +1201,7 @@ value_addr (struct value *arg1)
 
   /* Get target memory address */
   arg2 = value_from_pointer (lookup_pointer_type (value_type (arg1)),
-                            (VALUE_ADDRESS (arg1)
-                             + value_offset (arg1)
+                            (value_address (arg1)
                              + value_embedded_offset (arg1)));
 
   /* This may be a pointer to a base subobject; so remember the
@@ -1292,6 +1347,24 @@ value_array (int lowbound, int highbound, struct value **elemvec)
   return val;
 }
 
+struct value *
+value_typed_string (char *ptr, int len, struct type *char_type)
+{
+  struct value *val;
+  int lowbound = current_language->string_lower_bound;
+  int highbound = len / TYPE_LENGTH (char_type);
+  struct type *rangetype = create_range_type ((struct type *) NULL,
+                                             builtin_type_int32,
+                                             lowbound, 
+                                             highbound + lowbound - 1);
+  struct type *stringtype
+    = create_array_type ((struct type *) NULL, char_type, rangetype);
+
+  val = allocate_value (stringtype);
+  memcpy (value_contents_raw (val), ptr, len);
+  return val;
+}
+
 /* Create a value for a string constant by allocating space in the
    inferior, copying the data into that space, and returning the
    address with type TYPE_CODE_STRING.  PTR points to the string
@@ -1540,8 +1613,7 @@ search_struct_field (char *name, struct value *arg1, int offset,
 
          boffset = baseclass_offset (type, i,
                                      value_contents (arg1) + offset,
-                                     VALUE_ADDRESS (arg1)
-                                     + value_offset (arg1) + offset);
+                                     value_address (arg1) + offset);
          if (boffset == -1)
            error (_("virtual baseclass botch"));
 
@@ -1555,14 +1627,13 @@ search_struct_field (char *name, struct value *arg1, int offset,
              CORE_ADDR base_addr;
 
              v2  = allocate_value (basetype);
-             base_addr = 
-               VALUE_ADDRESS (arg1) + value_offset (arg1) + boffset;
+             base_addr = value_address (arg1) + boffset;
              if (target_read_memory (base_addr, 
                                      value_contents_raw (v2),
                                      TYPE_LENGTH (basetype)) != 0)
                error (_("virtual baseclass botch"));
              VALUE_LVAL (v2) = lval_memory;
-             VALUE_ADDRESS (v2) = base_addr;
+             set_value_address (v2, base_addr);
            }
          else
            {
@@ -1575,8 +1646,7 @@ search_struct_field (char *name, struct value *arg1, int offset,
                          value_contents_raw (arg1) + boffset,
                          TYPE_LENGTH (basetype));
                }
-             VALUE_LVAL (v2) = VALUE_LVAL (arg1);
-             VALUE_ADDRESS (v2) = VALUE_ADDRESS (arg1);
+             set_value_component_location (v2, arg1);
              VALUE_FRAME_ID (v2) = VALUE_FRAME_ID (arg1);
              set_value_offset (v2, value_offset (arg1) + boffset);
            }
@@ -1686,8 +1756,7 @@ search_struct_method (char *name, struct value **arg1p,
          if (offset < 0 || offset >= TYPE_LENGTH (type))
            {
              gdb_byte *tmp = alloca (TYPE_LENGTH (baseclass));
-             if (target_read_memory (VALUE_ADDRESS (*arg1p)
-                                     + value_offset (*arg1p) + offset,
+             if (target_read_memory (value_address (*arg1p) + offset,
                                      tmp, TYPE_LENGTH (baseclass)) != 0)
                error (_("virtual baseclass botch"));
              base_valaddr = tmp;
@@ -1696,8 +1765,7 @@ search_struct_method (char *name, struct value **arg1p,
            base_valaddr = value_contents (*arg1p) + offset;
 
          base_offset = baseclass_offset (type, i, base_valaddr,
-                                         VALUE_ADDRESS (*arg1p)
-                                         + value_offset (*arg1p) + offset);
+                                         value_address (*arg1p) + offset);
          if (base_offset == -1)
            error (_("virtual baseclass botch"));
        }
@@ -1906,7 +1974,7 @@ find_method_list (struct value **argp, char *method,
          base_offset = value_offset (*argp) + offset;
          base_offset = baseclass_offset (type, i,
                                          value_contents (*argp) + base_offset,
-                                         VALUE_ADDRESS (*argp) + base_offset);
+                                         value_address (*argp) + base_offset);
          if (base_offset == -1)
            error (_("virtual baseclass botch"));
        }
@@ -2124,9 +2192,11 @@ find_overload_match (struct type **arg_types, int nargs,
 
   if (objp)
     {
-      if (TYPE_CODE (value_type (temp)) != TYPE_CODE_PTR
-         && (TYPE_CODE (value_type (*objp)) == TYPE_CODE_PTR
-             || TYPE_CODE (value_type (*objp)) == TYPE_CODE_REF))
+      struct type *temp_type = check_typedef (value_type (temp));
+      struct type *obj_type = check_typedef (value_type (*objp));
+      if (TYPE_CODE (temp_type) != TYPE_CODE_PTR
+         && (TYPE_CODE (obj_type) == TYPE_CODE_PTR
+             || TYPE_CODE (obj_type) == TYPE_CODE_REF))
        {
          temp = value_addr (temp);
        }
@@ -2664,7 +2734,7 @@ value_struct_elt_for_reference (struct type *domain, int offset,
                  result = allocate_value (lookup_methodptr_type (TYPE_FN_FIELD_TYPE (f, j)));
                  cplus_make_method_ptr (value_type (result),
                                         value_contents_writeable (result),
-                                        VALUE_ADDRESS (v), 0);
+                                        value_address (v), 0);
                }
            }
          return result;
@@ -2823,7 +2893,7 @@ value_full_object (struct value *argp,
   /* Go back by the computed top_offset from the beginning of the
      object, adjusting for the embedded offset of argp if that's what
      value_rtti_type used for its computation.  */
-  new_val = value_at_lazy (real_type, VALUE_ADDRESS (argp) - top +
+  new_val = value_at_lazy (real_type, value_address (argp) - top +
                           (using_enc ? 0 : value_embedded_offset (argp)));
   deprecated_set_value_type (new_val, value_type (argp));
   set_value_embedded_offset (new_val, (using_enc
@@ -2984,12 +3054,7 @@ value_slice (struct value *array, int lowbound, int length)
                  TYPE_LENGTH (slice_type));
        }
 
-      if (VALUE_LVAL (array) == lval_internalvar)
-       VALUE_LVAL (slice) = lval_internalvar_component;
-      else
-       VALUE_LVAL (slice) = VALUE_LVAL (array);
-
-      VALUE_ADDRESS (slice) = VALUE_ADDRESS (array);
+      set_value_component_location (slice, array);
       VALUE_FRAME_ID (slice) = VALUE_FRAME_ID (array);
       set_value_offset (slice, value_offset (array) + offset);
     }
This page took 0.029224 seconds and 4 git commands to generate.