This commit was generated by cvs2svn to track changes on a CVS vendor
[deliverable/binutils-gdb.git] / gdb / values.c
index b4381cda54800ff1e91f220dc4d17250357ad2d5..ff4951dba03c9d40558705a7411a74f9449ba4c3 100644 (file)
 
 /* Prototypes for exported functions. */
 
-void _initialize_values PARAMS ((void));
+void _initialize_values (void);
 
 /* Prototypes for local functions. */
 
-static value_ptr value_headof PARAMS ((value_ptr, struct type *,
-                                      struct type *));
+static value_ptr value_headof (value_ptr, struct type *, struct type *);
 
-static void show_values PARAMS ((char *, int));
+static void show_values (char *, int);
 
-static void show_convenience PARAMS ((char *, int));
+static void show_convenience (char *, int);
 
-static int vb_match PARAMS ((struct type *, int, struct type *));
+static int vb_match (struct type *, int, struct type *);
 
 /* The value-history records all the values printed
    by print commands during this session.  Each chunk
@@ -580,8 +579,9 @@ value_as_double (val)
     error ("Invalid floating value found in program.");
   return foo;
 }
-/* Extract a value as a C pointer.
-   Does not deallocate the value.  */
+/* Extract a value as a C pointer. Does not deallocate the value.  
+   Note that val's type may not actually be a pointer; value_as_long
+   handles all the cases.  */
 CORE_ADDR
 value_as_pointer (val)
      value_ptr val;
@@ -649,7 +649,7 @@ unpack_long (type, valaddr)
       if (GDB_TARGET_IS_D10V
          && len == 2)
        return D10V_MAKE_DADDR (extract_address (valaddr, len));
-      return extract_address (valaddr, len);
+      return extract_typed_address (valaddr, type);
 
     case TYPE_CODE_MEMBER:
       error ("not implemented: member types in unpack_long");
@@ -731,6 +731,7 @@ unpack_pointer (type, valaddr)
      whether we want this to be true eventually.  */
   return unpack_long (type, valaddr);
 }
+
 \f
 /* Get the value of the FIELDN'th field (which must be static) of TYPE. */
 
@@ -802,6 +803,8 @@ value_primitive_field (arg1, offset, fieldno, arg_type)
                                                    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
+       + TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
     }
   else if (fieldno < TYPE_N_BASECLASSES (arg_type))
     {
@@ -838,6 +841,7 @@ value_primitive_field (arg1, offset, fieldno, arg_type)
   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_OFFSET (v) = VALUE_OFFSET (arg1) + offset
    + TYPE_FIELD_BITPOS (arg_type, fieldno) / 8; */
   return v;
@@ -890,7 +894,7 @@ value_fn_field (arg1p, f, j, type, offset)
        *arg1p = value_ind (value_cast (lookup_pointer_type (type),
                                        value_addr (*arg1p)));
 
-      /* Move the `this' pointer according to the offset. 
+      /* Move the `this' pointer according to the offset.
          VALUE_OFFSET (*arg1p) += offset;
        */
     }
@@ -922,7 +926,6 @@ value_virtual_fn_field (arg1p, f, j, type, offset)
       /* Deal with HP/Taligent runtime model for virtual functions */
       value_ptr vp;
       value_ptr argp;          /* arg1 cast to base */
-      CORE_ADDR vfunc_addr;    /* address of virtual method */
       CORE_ADDR coreptr;       /* pointer to target address */
       int class_index;         /* which class segment pointer to use */
       struct type *ftype = TYPE_FN_FIELD_TYPE (f, j);  /* method type */
@@ -1101,7 +1104,12 @@ value_virtual_fn_field (arg1p, f, j, type, offset)
    return the most derived type we find.  The caller must
    be satisfied when the return value == DTYPE.
 
-   FIXME-tiemann: should work with dossier entries as well.  */
+   FIXME-tiemann: should work with dossier entries as well.
+   NOTICE - djb: I see no good reason at all to keep this function now that
+   we have RTTI support. It's used in literally one place, and it's
+   hard to keep this function up to date when it's purpose is served
+   by value_rtti_type efficiently.
+   Consider it gone for 5.1. */
 
 static value_ptr
 value_headof (in_arg, btype, dtype)
@@ -1109,12 +1117,8 @@ value_headof (in_arg, btype, dtype)
      struct type *btype, *dtype;
 {
   /* First collect the vtables we must look at for this object.  */
-  /* FIXME-tiemann: right now, just look at top-most vtable.  */
-  value_ptr arg, vtbl, entry, best_entry = 0;
-  int i, nelems;
-  int offset, best_offset = 0;
+  value_ptr arg, vtbl;
   struct symbol *sym;
-  CORE_ADDR pc_for_sym;
   char *demangled_name;
   struct minimal_symbol *msymbol;
 
@@ -1122,72 +1126,45 @@ value_headof (in_arg, btype, dtype)
   CHECK_TYPEDEF (btype);
   arg = in_arg;
   if (btype != dtype)
-    arg = value_cast (lookup_pointer_type (btype), arg);
+      arg = value_cast (lookup_pointer_type (btype), arg);
+  if (TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_REF)
+      {
+         /*
+          * Copy the value, but change the type from (T&) to (T*).
+          * We keep the same location information, which is efficient,
+          * and allows &(&X) to get the location containing the reference.
+          */
+         arg = value_copy (arg);
+         VALUE_TYPE (arg) = lookup_pointer_type (TYPE_TARGET_TYPE (VALUE_TYPE (arg)));
+      }
+  if (VALUE_ADDRESS(value_field (value_ind(arg), TYPE_VPTR_FIELDNO (btype)))==0)
+      return arg;
+
   vtbl = value_ind (value_field (value_ind (arg), TYPE_VPTR_FIELDNO (btype)));
+  /* Turn vtable into typeinfo function */
+  VALUE_OFFSET(vtbl)+=4;
 
-  /* Check that VTBL looks like it points to a virtual function table.  */
-  msymbol = lookup_minimal_symbol_by_pc (VALUE_ADDRESS (vtbl));
+  msymbol = lookup_minimal_symbol_by_pc ( value_as_pointer(value_ind(vtbl)) );
   if (msymbol == NULL
-      || (demangled_name = SYMBOL_NAME (msymbol)) == NULL
-      || !VTBL_PREFIX_P (demangled_name))
-    {
-      /* If we expected to find a vtable, but did not, let the user
-         know that we aren't happy, but don't throw an error.
-         FIXME: there has to be a better way to do this.  */
-      struct type *error_type = (struct type *) xmalloc (sizeof (struct type));
-      memcpy (error_type, VALUE_TYPE (in_arg), sizeof (struct type));
-      TYPE_NAME (error_type) = savestring ("suspicious *", sizeof ("suspicious *"));
-      VALUE_TYPE (in_arg) = error_type;
-      return in_arg;
-    }
+      || (demangled_name = SYMBOL_NAME (msymbol)) == NULL)
+      {
+         /* If we expected to find a vtable, but did not, let the user
+            know that we aren't happy, but don't throw an error.
+            FIXME: there has to be a better way to do this.  */
+         struct type *error_type = (struct type *) xmalloc (sizeof (struct type));
+         memcpy (error_type, VALUE_TYPE (in_arg), sizeof (struct type));
+         TYPE_NAME (error_type) = savestring ("suspicious *", sizeof ("suspicious *"));
+         VALUE_TYPE (in_arg) = error_type;
+         return in_arg;
+      }
+  demangled_name = cplus_demangle(demangled_name,DMGL_ANSI);
+  *(strchr (demangled_name, ' ')) = '\0';
 
-  /* Now search through the virtual function table.  */
-  entry = value_ind (vtbl);
-  nelems = longest_to_int (value_as_long (value_field (entry, 2)));
-  for (i = 1; i <= nelems; i++)
-    {
-      entry = value_subscript (vtbl, value_from_longest (builtin_type_int,
-                                                        (LONGEST) i));
-      /* This won't work if we're using thunks. */
-      if (TYPE_CODE (check_typedef (VALUE_TYPE (entry))) != TYPE_CODE_STRUCT)
-       break;
-      offset = longest_to_int (value_as_long (value_field (entry, 0)));
-      /* If we use '<=' we can handle single inheritance
-       * where all offsets are zero - just use the first entry found. */
-      if (offset <= best_offset)
-       {
-         best_offset = offset;
-         best_entry = entry;
-       }
-    }
-  /* Move the pointer according to BEST_ENTRY's offset, and figure
-     out what type we should return as the new pointer.  */
-  if (best_entry == 0)
-    {
-      /* An alternative method (which should no longer be necessary).
-       * But we leave it in for future use, when we will hopefully
-       * have optimizes the vtable to use thunks instead of offsets. */
-      /* Use the name of vtable itself to extract a base type. */
-      demangled_name += 4;     /* Skip _vt$ prefix. */
-    }
-  else
-    {
-      pc_for_sym = value_as_pointer (value_field (best_entry, 2));
-      sym = find_pc_function (pc_for_sym);
-      demangled_name = cplus_demangle (SYMBOL_NAME (sym), DMGL_ANSI);
-      *(strchr (demangled_name, ':')) = '\0';
-    }
   sym = lookup_symbol (demangled_name, 0, VAR_NAMESPACE, 0, 0);
   if (sym == NULL)
-    error ("could not find type declaration for `%s'", demangled_name);
-  if (best_entry)
-    {
-      free (demangled_name);
-      arg = value_add (value_cast (builtin_type_int, arg),
-                      value_field (best_entry, 0));
-    }
-  else
-    arg = in_arg;
+      error ("could not find type declaration for `%s'", demangled_name);
+
+  arg = in_arg;
   VALUE_TYPE (arg) = lookup_pointer_type (SYMBOL_TYPE (sym));
   return arg;
 }
@@ -1445,9 +1422,7 @@ retry:
 
     case TYPE_CODE_REF:
     case TYPE_CODE_PTR:
-      /* This assumes that all pointers of a given length
-         have the same form.  */
-      store_address (VALUE_CONTENTS_RAW (val), len, (CORE_ADDR) num);
+      store_typed_address (VALUE_CONTENTS_RAW (val), type, (CORE_ADDR) num);
       break;
 
     default:
@@ -1456,8 +1431,20 @@ retry:
   return val;
 }
 
+
+/* Create a value representing a pointer of type TYPE to the address
+   ADDR.  */
+value_ptr
+value_from_pointer (struct type *type, CORE_ADDR addr)
+{
+  value_ptr val = allocate_value (type);
+  store_typed_address (VALUE_CONTENTS_RAW (val), type, addr);
+  return val;
+}
+
+
 /* Create a value for a string constant to be stored locally
-   (not in the inferior's memory space, but in GDB memory).  
+   (not in the inferior's memory space, but in GDB memory).
    This is analogous to value_from_longest, which also does not
    use inferior memory.  String shall NOT contain embedded nulls.  */
 
@@ -1574,13 +1561,6 @@ generic_use_struct_convention (gcc_p, value_type)
 #define USE_STRUCT_CONVENTION(gcc_p,type) generic_use_struct_convention (gcc_p, type)
 #endif
 
-/* Some fundamental types (such as long double) are returned on the stack for
-   certain architectures.  This macro should return true for any type besides
-   struct, union or array that gets returned on the stack.  */
-
-#ifndef RETURN_VALUE_ON_STACK
-#define RETURN_VALUE_ON_STACK(TYPE) 0
-#endif
 
 /* Return true if the function specified is using the structure returning
    convention on this machine to return arguments, or 0 if it is using
This page took 0.029847 seconds and 4 git commands to generate.