* configure.tgt: Add tx49 configury based on 4300.
[deliverable/binutils-gdb.git] / gdb / values.c
index 53a411761d1b1260ebb4974161900017bedd9f97..0ffd5a63cb3fa2209fdad2f8da6d87ddd1b6afd4 100644 (file)
@@ -1,5 +1,5 @@
 /* Low level packing and unpacking of values for GDB, the GNU Debugger.
-   Copyright 1986, 1987, 1989, 1991, 1993, 1994
+   Copyright 1986, 1987, 1989, 1991, 1993, 1994, 1995, 1996, 1997
    Free Software Foundation, Inc.
 
 This file is part of GDB.
@@ -29,6 +29,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "gdbcmd.h"
 #include "target.h"
 #include "language.h"
+#include "scm-lang.h"
 #include "demangle.h"
 
 /* Local function prototypes. */
@@ -40,6 +41,8 @@ static void show_values PARAMS ((char *, int));
 
 static void show_convenience PARAMS ((char *, int));
 
+static int vb_match PARAMS ((struct type *, int, struct type *));
+
 /* The value-history records all the values printed
    by print commands during this session.  Each chunk
    records 60 consecutive values.  The first chunk on
@@ -73,10 +76,9 @@ allocate_value (type)
      struct type *type;
 {
   register value_ptr val;
+  struct type *atype = check_typedef (type);
 
-  check_stub_type (type);
-
-  val = (struct value *) xmalloc (sizeof (struct value) + TYPE_LENGTH (type));
+  val = (struct value *) xmalloc (sizeof (struct value) + TYPE_LENGTH (atype));
   VALUE_NEXT (val) = all_values;
   all_values = val;
   VALUE_TYPE (val) = type;
@@ -86,11 +88,10 @@ allocate_value (type)
   VALUE_OFFSET (val) = 0;
   VALUE_BITPOS (val) = 0;
   VALUE_BITSIZE (val) = 0;
-  VALUE_REPEATED (val) = 0;
-  VALUE_REPETITIONS (val) = 0;
   VALUE_REGNO (val) = -1;
   VALUE_LAZY (val) = 0;
   VALUE_OPTIMIZED_OUT (val) = 0;
+  VALUE_BFD_SECTION (val) = NULL;
   val->modifiable = 1;
   return val;
 }
@@ -103,25 +104,16 @@ allocate_repeat_value (type, count)
      struct type *type;
      int count;
 {
-  register value_ptr val;
-
-  val =
-    (value_ptr) xmalloc (sizeof (struct value) + TYPE_LENGTH (type) * count);
-  VALUE_NEXT (val) = all_values;
-  all_values = val;
-  VALUE_TYPE (val) = type;
-  VALUE_LVAL (val) = not_lval;
-  VALUE_ADDRESS (val) = 0;
-  VALUE_FRAME (val) = 0;
-  VALUE_OFFSET (val) = 0;
-  VALUE_BITPOS (val) = 0;
-  VALUE_BITSIZE (val) = 0;
-  VALUE_REPEATED (val) = 1;
-  VALUE_REPETITIONS (val) = count;
-  VALUE_REGNO (val) = -1;
-  VALUE_LAZY (val) = 0;
-  VALUE_OPTIMIZED_OUT (val) = 0;
-  return val;
+  int low_bound = current_language->string_lower_bound; /* ??? */
+  /* FIXME-type-allocation: need a way to free this type when we are
+     done with it.  */
+  struct type *range_type
+    = create_range_type ((struct type *) NULL, builtin_type_int,
+                        low_bound, count + low_bound - 1);
+  /* FIXME-type-allocation: need a way to free this type when we are
+     done with it.  */
+  return allocate_value (create_array_type ((struct type *) NULL,
+                                           type, range_type));
 }
 
 /* Return a mark in the value chain.  All values allocated after the
@@ -217,25 +209,23 @@ value_ptr
 value_copy (arg)
      value_ptr arg;
 {
-  register value_ptr val;
   register struct type *type = VALUE_TYPE (arg);
-  if (VALUE_REPEATED (arg))
-    val = allocate_repeat_value (type, VALUE_REPETITIONS (arg));
-  else
-    val = allocate_value (type);
+  register value_ptr val = allocate_value (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);
+  VALUE_FRAME (val) = VALUE_FRAME (arg);
   VALUE_REGNO (val) = VALUE_REGNO (arg);
   VALUE_LAZY (val) = VALUE_LAZY (arg);
+  VALUE_OPTIMIZED_OUT (val) = VALUE_OPTIMIZED_OUT (arg);
+  VALUE_BFD_SECTION (val) = VALUE_BFD_SECTION (arg);
   val->modifiable = arg->modifiable;
   if (!VALUE_LAZY (val))
     {
       memcpy (VALUE_CONTENTS_RAW (val), VALUE_CONTENTS_RAW (arg),
-             TYPE_LENGTH (VALUE_TYPE (arg))
-             * (VALUE_REPEATED (arg) ? VALUE_REPETITIONS (arg) : 1));
+             TYPE_LENGTH (VALUE_TYPE (arg)));
     }
   return val;
 }
@@ -253,14 +243,6 @@ record_latest_value (val)
 {
   int i;
 
-  /* Check error now if about to store an invalid float.  We return -1
-     to the caller, but allow them to continue, e.g. to print it as "Nan". */
-  if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FLT)
-    {
-      unpack_double (VALUE_TYPE (val), VALUE_CONTENTS (val), &i);
-      if (i) return -1;                /* Indicate value not saved in history */
-    }
-
   /* We don't want this value to have anything to do with the inferior anymore.
      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
@@ -570,16 +552,15 @@ value_as_long (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.  */
-  if (TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_ENUM)
-    COERCE_ARRAY (val);
+  COERCE_ARRAY (val);
   return unpack_long (VALUE_TYPE (val), VALUE_CONTENTS (val));
 }
 
-double
+DOUBLEST
 value_as_double (val)
      register value_ptr val;
 {
-  double foo;
+  DOUBLEST foo;
   int inv;
   
   foo = unpack_double (VALUE_TYPE (val), VALUE_CONTENTS (val), &inv);
@@ -628,8 +609,14 @@ unpack_long (type, valaddr)
   register int len = TYPE_LENGTH (type);
   register int nosign = TYPE_UNSIGNED (type);
 
+  if (current_language->la_language == language_scm
+      && is_scmvalue_type (type))
+    return scm_unpack (type, valaddr, TYPE_CODE_INT);
+
   switch (code)
     {
+    case TYPE_CODE_TYPEDEF:
+      return unpack_long (check_typedef (type), valaddr);
     case TYPE_CODE_ENUM:
     case TYPE_CODE_BOOL:
     case TYPE_CODE_INT:
@@ -664,7 +651,7 @@ unpack_long (type, valaddr)
    the returned double is OK to use.  Argument is in target
    format, result is in host format.  */
 
-double
+DOUBLEST
 unpack_double (type, valaddr, invp)
      struct type *type;
      char *valaddr;
@@ -675,6 +662,7 @@ unpack_double (type, valaddr, invp)
   register int nosign = TYPE_UNSIGNED (type);
 
   *invp = 0;                   /* Assume valid.   */
+  CHECK_TYPEDEF (type);
   if (code == TYPE_CODE_FLT)
     {
 #ifdef INVALID_FLOAT
@@ -689,7 +677,12 @@ unpack_double (type, valaddr, invp)
   else if (nosign)
     {
       /* Unsigned -- be sure we compensate for signed LONGEST.  */
-      return (unsigned LONGEST) unpack_long (type, valaddr);
+#if !defined (_MSC_VER) || (_MSC_VER > 900)
+      return (ULONGEST) unpack_long (type, valaddr);
+#else
+      /* FIXME!!! msvc22 doesn't support unsigned __int64 -> double */
+      return (LONGEST) unpack_long (type, valaddr);
+#endif /* _MSC_VER */
     }
   else
     {
@@ -721,12 +714,37 @@ unpack_pointer (type, valaddr)
   return unpack_long (type, valaddr);
 }
 \f
+/* Get the value of the FIELDN'th field (which must be static) of TYPE. */
+
+value_ptr
+value_static_field (type, fieldno)
+     struct type *type;
+     int fieldno;
+{
+  CORE_ADDR addr;
+  asection *sect;
+  if (TYPE_FIELD_STATIC_HAS_ADDR (type, fieldno))
+    {
+      addr = TYPE_FIELD_STATIC_PHYSADDR (type, fieldno);
+      sect = NULL;
+    }
+  else
+    {
+      char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, fieldno);
+      struct symbol *sym = lookup_symbol (phys_name, 0, VAR_NAMESPACE, 0, NULL);
+      if (sym == NULL)
+       return NULL;
+      addr = SYMBOL_VALUE_ADDRESS (sym);
+      sect = SYMBOL_BFD_SECTION (sym);
+      SET_FIELD_PHYSADDR (TYPE_FIELD (type, fieldno), addr);
+    }
+  return value_at (TYPE_FIELD_TYPE (type, fieldno), addr, sect);
+}
+
 /* Given a value ARG1 (offset by OFFSET bytes)
    of a struct or union type ARG_TYPE,
-   extract and return the value of one of its fields.
-   FIELDNO says which field.
-
-   For C++, must also be able to return values from static fields */
+   extract and return the value of one of its (non-static) fields.
+   FIELDNO says which field. */
 
 value_ptr
 value_primitive_field (arg1, offset, fieldno, arg_type)
@@ -738,18 +756,18 @@ value_primitive_field (arg1, offset, fieldno, arg_type)
   register value_ptr v;
   register struct type *type;
 
-  check_stub_type (arg_type);
+  CHECK_TYPEDEF (arg_type);
   type = TYPE_FIELD_TYPE (arg_type, fieldno);
 
   /* Handle packed fields */
 
-  offset += TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
   if (TYPE_FIELD_BITSIZE (arg_type, fieldno))
     {
       v = value_from_longest (type,
-                          unpack_field_as_long (arg_type,
-                                                VALUE_CONTENTS (arg1),
-                                                fieldno));
+                             unpack_field_as_long (arg_type,
+                                                   VALUE_CONTENTS (arg1)
+                                                     + offset,
+                                                   fieldno));
       VALUE_BITPOS (v) = TYPE_FIELD_BITPOS (arg_type, fieldno) % 8;
       VALUE_BITSIZE (v) = TYPE_FIELD_BITSIZE (arg_type, fieldno);
     }
@@ -759,22 +777,23 @@ value_primitive_field (arg1, offset, fieldno, arg_type)
       if (VALUE_LAZY (arg1))
        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_FIELD_BITPOS (arg_type, fieldno) / 8,
                TYPE_LENGTH (type));
     }
   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_OFFSET (v) = offset + VALUE_OFFSET (arg1);
+  VALUE_OFFSET (v) = VALUE_OFFSET (arg1) + offset
+                    + TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
   return v;
 }
 
 /* Given a value ARG1 of a struct or union type,
-   extract and return the value of one of its fields.
-   FIELDNO says which field.
-
-   For C++, must also be able to return values from static fields */
+   extract and return the value of one of its (non-static) fields.
+   FIELDNO says which field. */
 
 value_ptr
 value_field (arg1, fieldno)
@@ -844,6 +863,8 @@ value_virtual_fn_field (arg1p, f, j, type, offset)
      int offset;
 {
   value_ptr arg1 = *arg1p;
+  struct type *type1 = check_typedef (VALUE_TYPE (arg1));
+  struct type *entry_type;
   /* First, get the virtual function table pointer.  That comes
      with a strange type, so cast it to type `pointer to long' (which
      should serve just fine as a function type).  Then, index into
@@ -861,10 +882,13 @@ value_virtual_fn_field (arg1p, f, j, type, offset)
     fcontext = TYPE_VPTR_BASETYPE (type);
   context = lookup_pointer_type (fcontext);
   /* Now context is a pointer to the basetype containing the vtbl.  */
-  if (TYPE_TARGET_TYPE (context) != VALUE_TYPE (arg1))
-    arg1 = value_ind (value_cast (context, value_addr (arg1)));
+  if (TYPE_TARGET_TYPE (context) != type1)
+    {
+      arg1 = value_ind (value_cast (context, value_addr (arg1)));
+      type1 = check_typedef (VALUE_TYPE (arg1));
+    }
 
-  context = VALUE_TYPE (arg1);
+  context = type1;
   /* Now context is the basetype containing the vtbl.  */
 
   /* This type may have been defined before its virtual function table
@@ -884,8 +908,9 @@ value_virtual_fn_field (arg1p, f, j, type, offset)
      time, e.g. if the user has set a conditional breakpoint calling
      a virtual function.  */
   entry = value_subscript (vtbl, vi);
+  entry_type = check_typedef (VALUE_TYPE (entry));
 
-  if (TYPE_CODE (VALUE_TYPE (entry)) == TYPE_CODE_STRUCT)
+  if (TYPE_CODE (entry_type) == TYPE_CODE_STRUCT)
     {
       /* Move the `this' pointer according to the virtual function table. */
       VALUE_OFFSET (arg1) += value_as_long (value_field (entry, 0));
@@ -898,7 +923,7 @@ value_virtual_fn_field (arg1p, f, j, type, offset)
 
       vfn = value_field (entry, 2);
     }
-  else if (TYPE_CODE (VALUE_TYPE (entry)) == TYPE_CODE_PTR)
+  else if (TYPE_CODE (entry_type) == TYPE_CODE_PTR)
     vfn = entry;
   else
     error ("I'm confused:  virtual function table has bad type");
@@ -934,7 +959,7 @@ value_headof (in_arg, btype, dtype)
   struct minimal_symbol *msymbol;
 
   btype = TYPE_VPTR_BASETYPE (dtype);
-  check_stub_type (btype);
+  CHECK_TYPEDEF (btype);
   arg = in_arg;
   if (btype != dtype)
     arg = value_cast (lookup_pointer_type (btype), arg);
@@ -964,7 +989,7 @@ value_headof (in_arg, btype, dtype)
       entry = value_subscript (vtbl, value_from_longest (builtin_type_int, 
                                                      (LONGEST) i));
       /* This won't work if we're using thunks. */
-      if (TYPE_CODE (VALUE_TYPE (entry)) != TYPE_CODE_STRUCT)
+      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
@@ -1019,7 +1044,7 @@ value_from_vtable_info (arg, type)
   /* Take care of preliminaries.  */
   if (TYPE_VPTR_FIELDNO (type) < 0)
     fill_in_vptr_fieldno (type);
-  if (TYPE_VPTR_FIELDNO (type) < 0 || VALUE_REPEATED (arg))
+  if (TYPE_VPTR_FIELDNO (type) < 0)
     return 0;
 
   return value_headof (arg, 0, type);
@@ -1041,7 +1066,7 @@ vb_match (type, index, basetype)
   if (*name != '_')
     return 0;
   /* gcc 2.4 uses _vb$.  */
-  if (name[1] == 'v' && name[2] == 'b' && name[3] == CPLUS_MARKER)
+  if (name[1] == 'v' && name[2] == 'b' && is_cplus_marker (name[3]))
     field_class_name = name + 4;
   /* gcc 2.5 will use __vb_.  */
   if (name[1] == '_' && name[2] == 'v' && name[3] == 'b' && name[4] == '_')
@@ -1075,19 +1100,19 @@ vb_match (type, index, basetype)
 }
 
 /* Compute the offset of the baseclass which is
-   the INDEXth baseclass of class TYPE, for a value ARG,
-   wih extra offset of OFFSET.
-   The result is the offste of the baseclass value relative
+   the INDEXth baseclass of class TYPE,
+   for value at VALADDR (in host) at ADDRESS (in target).
+   The result is the offset of the baseclass value relative
    to (the address of)(ARG) + OFFSET.
 
    -1 is returned on error. */
 
 int
-baseclass_offset (type, index, arg, offset)
+baseclass_offset (type, index, valaddr, address)
      struct type *type;
      int index;
-     value_ptr arg;
-     int offset;
+     char *valaddr;
+     CORE_ADDR address;
 {
   struct type *basetype = TYPE_BASECLASS (type, index);
 
@@ -1105,22 +1130,16 @@ baseclass_offset (type, index, arg, offset)
            {
              CORE_ADDR addr
                = unpack_pointer (TYPE_FIELD_TYPE (type, i),
-                                 VALUE_CONTENTS (arg) + VALUE_OFFSET (arg)
-                                 + offset
-                                 + (TYPE_FIELD_BITPOS (type, i) / 8));
-
-             if (VALUE_LVAL (arg) != lval_memory)
-                 return -1;
+                                 valaddr + (TYPE_FIELD_BITPOS (type, i) / 8));
 
-             return addr -
-                 (LONGEST) (VALUE_ADDRESS (arg) + VALUE_OFFSET (arg) + offset);
+             return addr - (LONGEST) address;
            }
        }
       /* Not in the fields, so try looking through the baseclasses.  */
       for (i = index+1; i < n_baseclasses; i++)
        {
          int boffset =
-             baseclass_offset (type, i, arg, offset);
+             baseclass_offset (type, i, valaddr, address);
          if (boffset)
            return boffset;
        }
@@ -1131,95 +1150,6 @@ baseclass_offset (type, index, arg, offset)
   /* Baseclass is easily computed.  */
   return TYPE_BASECLASS_BITPOS (type, index) / 8;
 }
-
-/* Compute the address of the baseclass which is
-   the INDEXth baseclass of class TYPE.  The TYPE base
-   of the object is at VALADDR.
-
-   If ERRP is non-NULL, set *ERRP to be the errno code of any error,
-   or 0 if no error.  In that case the return value is not the address
-   of the baseclasss, but the address which could not be read
-   successfully.  */
-
-/* FIXME Fix remaining uses of baseclass_addr to use baseclass_offset */
-
-char *
-baseclass_addr (type, index, valaddr, valuep, errp)
-     struct type *type;
-     int index;
-     char *valaddr;
-     value_ptr *valuep;
-     int *errp;
-{
-  struct type *basetype = TYPE_BASECLASS (type, index);
-
-  if (errp)
-    *errp = 0;
-
-  if (BASETYPE_VIA_VIRTUAL (type, index))
-    {
-      /* Must hunt for the pointer to this virtual baseclass.  */
-      register int i, len = TYPE_NFIELDS (type);
-      register int n_baseclasses = TYPE_N_BASECLASSES (type);
-
-      /* First look for the virtual baseclass pointer
-        in the fields.  */
-      for (i = n_baseclasses; i < len; i++)
-       {
-         if (vb_match (type, i, basetype))
-           {
-             value_ptr val = allocate_value (basetype);
-             CORE_ADDR addr;
-             int status;
-
-             addr
-               = unpack_pointer (TYPE_FIELD_TYPE (type, i),
-                                 valaddr + (TYPE_FIELD_BITPOS (type, i) / 8));
-
-             status = target_read_memory (addr,
-                                          VALUE_CONTENTS_RAW (val),
-                                          TYPE_LENGTH (basetype));
-             VALUE_LVAL (val) = lval_memory;
-             VALUE_ADDRESS (val) = addr;
-
-             if (status != 0)
-               {
-                 if (valuep)
-                   *valuep = NULL;
-                 release_value (val);
-                 value_free (val);
-                 if (errp)
-                   *errp = status;
-                 return (char *)addr;
-               }
-             else
-               {
-                 if (valuep)
-                   *valuep = val;
-                 return (char *) VALUE_CONTENTS (val);
-               }
-           }
-       }
-      /* Not in the fields, so try looking through the baseclasses.  */
-      for (i = index+1; i < n_baseclasses; i++)
-       {
-         char *baddr;
-
-         baddr = baseclass_addr (type, i, valaddr, valuep, errp);
-         if (baddr)
-           return baddr;
-       }
-      /* Not found.  */
-      if (valuep)
-       *valuep = 0;
-      return 0;
-    }
-
-  /* Baseclass is easily computed.  */
-  if (valuep)
-    *valuep = 0;
-  return valaddr + TYPE_BASECLASS_BITPOS (type, index) / 8;
-}
 \f
 /* Unpack a field FIELDNO of the specified TYPE, from the anonymous object at
    VALADDR.
@@ -1241,8 +1171,8 @@ unpack_field_as_long (type, valaddr, fieldno)
      char *valaddr;
      int fieldno;
 {
-  unsigned LONGEST val;
-  unsigned LONGEST valmask;
+  ULONGEST val;
+  ULONGEST valmask;
   int bitpos = TYPE_FIELD_BITPOS (type, fieldno);
   int bitsize = TYPE_FIELD_BITSIZE (type, fieldno);
   int lsbcount;
@@ -1260,9 +1190,9 @@ unpack_field_as_long (type, valaddr, fieldno)
   /* If the field does not entirely fill a LONGEST, then zero the sign bits.
      If the field is signed, and is negative, then sign extend. */
 
-  if ((bitsize > 0) && (bitsize < 8 * sizeof (val)))
+  if ((bitsize > 0) && (bitsize < 8 * (int) sizeof (val)))
     {
-      valmask = (((unsigned LONGEST) 1) << bitsize) - 1;
+      valmask = (((ULONGEST) 1) << bitsize) - 1;
       val &= valmask;
       if (!TYPE_UNSIGNED (TYPE_FIELD_TYPE (type, fieldno)))
        {
@@ -1288,14 +1218,22 @@ modify_field (addr, fieldval, bitpos, bitsize)
 {
   LONGEST oword;
 
-  /* Reject values too big to fit in the field in question,
-     otherwise adjoining fields may be corrupted.  */
-  if (bitsize < (8 * sizeof (fieldval))
+  /* If a negative fieldval fits in the field in question, chop
+     off the sign extension bits.  */
+  if (bitsize < (8 * (int) sizeof (fieldval))
+      && (~fieldval & ~((1 << (bitsize - 1)) - 1)) == 0)
+    fieldval = fieldval & ((1 << bitsize) - 1);
+
+  /* Warn if value is too big to fit in the field in question.  */
+  if (bitsize < (8 * (int) sizeof (fieldval))
       && 0 != (fieldval & ~((1<<bitsize)-1)))
     {
       /* FIXME: would like to include fieldval in the message, but
         we don't have a sprintf_longest.  */
-      error ("Value does not fit in %d bits.", bitsize);
+      warning ("Value does not fit in %d bits.", bitsize);
+
+      /* Truncate it, otherwise adjoining fields may be corrupted.  */
+      fieldval = fieldval & ((1 << bitsize) - 1);
     }
 
   oword = extract_signed_integer (addr, sizeof oword);
@@ -1305,10 +1243,10 @@ modify_field (addr, fieldval, bitpos, bitsize)
     bitpos = sizeof (oword) * 8 - bitpos - bitsize;
 
   /* Mask out old value, while avoiding shifts >= size of oword */
-  if (bitsize < 8 * sizeof (oword))
-    oword &= ~(((((unsigned LONGEST)1) << bitsize) - 1) << bitpos);
+  if (bitsize < 8 * (int) sizeof (oword))
+    oword &= ~(((((ULONGEST)1) << bitsize) - 1) << bitpos);
   else
-    oword &= ~((~(unsigned LONGEST)0) << bitpos);
+    oword &= ~((~(ULONGEST)0) << bitpos);
   oword |= fieldval << bitpos;
 
   store_signed_integer (addr, sizeof oword, oword);
@@ -1322,11 +1260,17 @@ value_from_longest (type, num)
      register LONGEST num;
 {
   register value_ptr val = allocate_value (type);
-  register enum type_code code = TYPE_CODE (type);
-  register int len = TYPE_LENGTH (type);
+  register enum type_code code;
+  register int len;
+ retry:
+  code = TYPE_CODE (type);
+  len = TYPE_LENGTH (type);
 
   switch (code)
     {
+    case TYPE_CODE_TYPEDEF:
+      type = check_typedef (type);
+      goto retry;
     case TYPE_CODE_INT:
     case TYPE_CODE_CHAR:
     case TYPE_CODE_ENUM:
@@ -1341,7 +1285,7 @@ value_from_longest (type, num)
         have the same form.  */
       store_address (VALUE_CONTENTS_RAW (val), len, (CORE_ADDR) num);
       break;
-
+      
     default:
       error ("Unexpected type encountered for integer constant.");
     }
@@ -1351,11 +1295,12 @@ value_from_longest (type, num)
 value_ptr
 value_from_double (type, num)
      struct type *type;
-     double num;
+     DOUBLEST num;
 {
   register value_ptr val = allocate_value (type);
-  register enum type_code code = TYPE_CODE (type);
-  register int len = TYPE_LENGTH (type);
+  struct type *base_type = check_typedef (type);
+  register enum type_code code = TYPE_CODE (base_type);
+  register int len = TYPE_LENGTH (base_type);
 
   if (code == TYPE_CODE_FLT)
     {
@@ -1397,11 +1342,12 @@ value_being_returned (valtype, retbuf, struct_return)
     addr = EXTRACT_STRUCT_VALUE_ADDRESS (retbuf);
     if (!addr)
       error ("Function return value unknown");
-    return value_at (valtype, addr);
+    return value_at (valtype, addr, NULL);
   }
 #endif
 
   val = allocate_value (valtype);
+  CHECK_TYPEDEF (valtype);
   EXTRACT_RETURN_VALUE (valtype, retbuf, VALUE_CONTENTS_RAW (val));
 
   return val;
@@ -1431,6 +1377,14 @@ value_being_returned (valtype, retbuf, struct_return)
      ))
 #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
    the value returning convention.  FUNCTION is the value representing
@@ -1451,9 +1405,10 @@ using_struct_return (function, funcaddr, value_type, gcc_p)
   if (code == TYPE_CODE_ERROR)
     error ("Function return type unknown.");
 
-  if (code == TYPE_CODE_STRUCT ||
-      code == TYPE_CODE_UNION ||
-      code == TYPE_CODE_ARRAY)
+  if (code == TYPE_CODE_STRUCT
+      || code == TYPE_CODE_UNION
+      || code == TYPE_CODE_ARRAY
+      || RETURN_VALUE_ON_STACK (value_type))
     return USE_STRUCT_CONVENTION (gcc_p, value_type);
 
   return 0;
@@ -1467,7 +1422,8 @@ void
 set_return_value (val)
      value_ptr val;
 {
-  register enum type_code code = TYPE_CODE (VALUE_TYPE (val));
+  struct type *type = check_typedef (VALUE_TYPE (val));
+  register enum type_code code = TYPE_CODE (type);
 
   if (code == TYPE_CODE_ERROR)
     error ("Function return type unknown.");
@@ -1476,7 +1432,7 @@ set_return_value (val)
       || code == TYPE_CODE_UNION)      /* FIXME, implement struct return.  */
     error ("GDB does not support specifying a struct or union return value.");
 
-  STORE_RETURN_VALUE (VALUE_TYPE (val), VALUE_CONTENTS (val));
+  STORE_RETURN_VALUE (type, VALUE_CONTENTS (val));
 }
 \f
 void
This page took 0.032818 seconds and 4 git commands to generate.