]> Git Repo - binutils.git/blobdiff - gdb/valops.c
always keep mpw subdir
[binutils.git] / gdb / valops.c
index b30f4b0b48ad2e8c5fd60e71449efb4f8973f6d5..684b224cc8856d9c262860922d570ae1ca4dbc4c 100644 (file)
@@ -32,6 +32,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include <errno.h>
 #include "gdb_string.h"
 
+/* Default to coercing float to double in function calls only when there is
+   no prototype.  Otherwise on targets where the debug information is incorrect
+   for either the prototype or non-prototype case, we can force it by defining
+   COERCE_FLOAT_TO_DOUBLE in the target configuration file. */
+
+#ifndef COERCE_FLOAT_TO_DOUBLE
+#define COERCE_FLOAT_TO_DOUBLE (param_type == NULL)
+#endif
+
 /* Local functions.  */
 
 static int typecmp PARAMS ((int staticp, struct type *t1[], value_ptr t2[]));
@@ -57,7 +66,9 @@ static value_ptr cast_into_complex PARAMS ((struct type *, value_ptr));
 
 /* Flag for whether we want to abandon failed expression evals by default.  */
 
+#if 0
 static int auto_abandon = 0;
+#endif
 
 \f
 /* Find the address of function name NAME in the inferior.  */
@@ -187,11 +198,11 @@ value_cast (type, arg2)
   COERCE_VARYING_ARRAY (arg2, type2);
   code2 = TYPE_CODE (type2);
 
-  if (code1 == TYPE_CODE_COMPLEX) 
-    return cast_into_complex (type, arg2); 
-  if (code1 == TYPE_CODE_BOOL
+  if (code1 == TYPE_CODE_COMPLEX)
+    return cast_into_complex (type, arg2);
+  if (code1 == TYPE_CODE_BOOL || code1 == TYPE_CODE_CHAR)
     code1 = TYPE_CODE_INT; 
-  if (code2 == TYPE_CODE_BOOL
+  if (code2 == TYPE_CODE_BOOL || code2 == TYPE_CODE_CHAR)
     code2 = TYPE_CODE_INT;
 
   scalar = (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_FLT
@@ -407,12 +418,13 @@ value_assign (toval, fromval)
   if (!toval->modifiable)
     error ("Left operand of assignment is not a modifiable lvalue.");
 
-  COERCE_ARRAY (fromval);
   COERCE_REF (toval);
 
   type = VALUE_TYPE (toval);
   if (VALUE_LVAL (toval) != lval_internalvar)
     fromval = value_cast (type, fromval);
+  else
+    COERCE_ARRAY (fromval);
   CHECK_TYPEDEF (type);
 
   /* If TOVAL is a special machine register requiring conversion
@@ -439,7 +451,7 @@ value_assign (toval, fromval)
     {
     case lval_internalvar:
       set_internalvar (VALUE_INTERNALVAR (toval), fromval);
-      return VALUE_INTERNALVAR (toval)->value;
+      return value_copy (VALUE_INTERNALVAR (toval)->value);
 
     case lval_internalvar_component:
       set_internalvar_component (VALUE_INTERNALVAR (toval),
@@ -460,7 +472,7 @@ value_assign (toval, fromval)
                     + HOST_CHAR_BIT - 1)
                    / HOST_CHAR_BIT;
 
-         if (len > sizeof (LONGEST))
+         if (len > (int) sizeof (LONGEST))
            error ("Can't handle bitfields which don't fit in a %d bit word.",
                   sizeof (LONGEST) * HOST_CHAR_BIT);
 
@@ -485,7 +497,7 @@ value_assign (toval, fromval)
          char buffer[sizeof (LONGEST)];
           int len = REGISTER_RAW_SIZE (VALUE_REGNO (toval));
 
-         if (len > sizeof (LONGEST))
+         if (len > (int) sizeof (LONGEST))
            error ("Can't handle bitfields in registers larger than %d bits.",
                   sizeof (LONGEST) * HOST_CHAR_BIT);
 
@@ -614,7 +626,7 @@ Can't handle bitfield which doesn't fit in a single register.");
   /* 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 ((VALUE_BITSIZE (toval) > 0)
-      && (VALUE_BITSIZE (toval) < 8 * sizeof (LONGEST)))
+      && (VALUE_BITSIZE (toval) < 8 * (int) sizeof (LONGEST)))
     {
       LONGEST fieldval = value_as_long (fromval);
       LONGEST valmask = (((unsigned LONGEST) 1) << VALUE_BITSIZE (toval)) - 1;
@@ -886,10 +898,16 @@ value_arg_coerce (arg, param_type)
       if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int))
        type = builtin_type_int;
       break;
-    case TYPE_CODE_FLT:
-      if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double))
-       type = builtin_type_double;
-      break;
+   case TYPE_CODE_FLT:
+     /* coerce float to double, unless the function prototype specifies float */
+     if (COERCE_FLOAT_TO_DOUBLE)
+       {
+        if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double))
+          type = builtin_type_double;
+        else if (TYPE_LENGTH (type) > TYPE_LENGTH (builtin_type_double))
+          type = builtin_type_long_double;
+       }
+     break;
     case TYPE_CODE_FUNC:
       type = lookup_pointer_type (type);
       break;
@@ -1059,7 +1077,7 @@ call_function_by_hand (function, nargs, args)
 
   /* Create a call sequence customized for this function
      and the number of arguments for it.  */
-  for (i = 0; i < sizeof dummy / sizeof (dummy[0]); i++)
+  for (i = 0; i < (int) (sizeof (dummy) / sizeof (dummy[0])); i++)
     store_unsigned_integer (&dummy1[i * REGISTER_SIZE],
                            REGISTER_SIZE,
                            (unsigned LONGEST)dummy[i]);
@@ -1137,7 +1155,12 @@ call_function_by_hand (function, nargs, args)
        if ((TYPE_CODE (arg_type) == TYPE_CODE_STRUCT
             || TYPE_CODE (arg_type) == TYPE_CODE_UNION
             || TYPE_CODE (arg_type) == TYPE_CODE_ARRAY
-            || TYPE_CODE (arg_type) == TYPE_CODE_STRING)
+            || TYPE_CODE (arg_type) == TYPE_CODE_STRING
+            || TYPE_CODE (arg_type) == TYPE_CODE_BITSTRING
+            || TYPE_CODE (arg_type) == TYPE_CODE_SET
+            || (TYPE_CODE (arg_type) == TYPE_CODE_FLT
+                && TYPE_LENGTH (arg_type) > 8)
+            )
          && REG_STRUCT_HAS_ADDR (using_gcc, arg_type))
          {
            CORE_ADDR addr;
@@ -1338,7 +1361,7 @@ value_array (lowbound, highbound, elemvec)
 {
   int nelem;
   int idx;
-  int typelength;
+  unsigned int typelength;
   value_ptr val;
   struct type *rangetype;
   struct type *arraytype;
@@ -1361,6 +1384,23 @@ value_array (lowbound, highbound, elemvec)
        }
     }
 
+  rangetype = create_range_type ((struct type *) NULL, builtin_type_int,
+                                lowbound, highbound);
+  arraytype = create_array_type ((struct type *) NULL, 
+                                VALUE_TYPE (elemvec[0]), rangetype);
+
+  if (!current_language->c_style_arrays)
+    {
+      val = allocate_value (arraytype);
+      for (idx = 0; idx < nelem; idx++)
+       {
+         memcpy (VALUE_CONTENTS_RAW (val) + (idx * typelength),
+                 VALUE_CONTENTS (elemvec[idx]),
+                 typelength);
+       }
+      return val;
+    }
+
   /* Allocate space to store the array in the inferior, and then initialize
      it by copying in each element.  FIXME:  Is it worth it to create a
      local buffer in which to collect each value and then write all the
@@ -1375,10 +1415,6 @@ value_array (lowbound, highbound, elemvec)
 
   /* Create the array type and set up an array value to be evaluated lazily. */
 
-  rangetype = create_range_type ((struct type *) NULL, builtin_type_int,
-                                lowbound, highbound);
-  arraytype = create_array_type ((struct type *) NULL, 
-                                VALUE_TYPE (elemvec[0]), rangetype);
   val = value_at_lazy (arraytype, addr);
   return (val);
 }
@@ -1862,7 +1898,7 @@ destructor_name_p (name, type)
     {
       char *dname = type_name_no_tag (type);
       char *cp = strchr (dname, '<');
-      int len;
+      unsigned int len;
 
       /* Do not compare the template part for template classes.  */
       if (cp == NULL)
@@ -2155,35 +2191,60 @@ value_slice (array, lowbound, length)
      value_ptr array;
      int lowbound, length;
 {
+  struct type *slice_range_type, *slice_type, *range_type;
+  LONGEST lowerbound, upperbound, offset;
+  value_ptr slice;
   struct type *array_type;
   array_type = check_typedef (VALUE_TYPE (array));
   COERCE_VARYING_ARRAY (array, array_type);
-  if (TYPE_CODE (array_type) == TYPE_CODE_BITSTRING)
-    error ("not implemented - bitstring slice");
   if (TYPE_CODE (array_type) != TYPE_CODE_ARRAY
-      && TYPE_CODE (array_type) != TYPE_CODE_STRING)
+      && TYPE_CODE (array_type) != TYPE_CODE_STRING
+      && TYPE_CODE (array_type) != TYPE_CODE_BITSTRING)
     error ("cannot take slice of non-array");
+  range_type = TYPE_INDEX_TYPE (array_type);
+  if (get_discrete_bounds (range_type, &lowerbound, &upperbound) < 0)
+    error ("slice from bad array or bitstring");
+  if (lowbound < lowerbound || length < 0
+      || lowbound + length - 1 > upperbound
+      /* Chill allows zero-length strings but not arrays. */
+      || (current_language->la_language == language_chill
+         && length == 0 && TYPE_CODE (array_type) == TYPE_CODE_ARRAY))
+    error ("slice out of range");
+  /* FIXME-type-allocation: need a way to free this type when we are
+     done with it.  */
+  slice_range_type = create_range_type ((struct type*) NULL,
+                                       TYPE_TARGET_TYPE (range_type),
+                                       lowerbound, lowerbound + length - 1);
+  if (TYPE_CODE (array_type) == TYPE_CODE_BITSTRING)
+    {
+      int i;
+      slice_type = create_set_type ((struct type*) NULL, slice_range_type);
+      TYPE_CODE (slice_type) = TYPE_CODE_BITSTRING;
+      slice = value_zero (slice_type, not_lval);
+      for (i = 0; i < length; i++)
+       {
+         int element = value_bit_index (array_type,
+                                        VALUE_CONTENTS (array),
+                                        lowbound + i);
+         if (element < 0)
+           error ("internal error accessing bitstring");
+         else if (element > 0)
+           {
+             int j = i % TARGET_CHAR_BIT;
+             if (BITS_BIG_ENDIAN)
+               j = TARGET_CHAR_BIT - 1 - j;
+             VALUE_CONTENTS_RAW (slice)[i / TARGET_CHAR_BIT] |= (1 << j);
+           }
+       }
+      /* We should set the address, bitssize, and bitspos, so the clice
+        can be used on the LHS, but that may require extensions to
+        value_assign.  For now, just leave as a non_lval.  FIXME.  */
+    }
   else
     {
-      struct type *slice_range_type, *slice_type;
-      value_ptr slice;
-      struct type *range_type = TYPE_FIELD_TYPE (array_type,0);
       struct type *element_type = TYPE_TARGET_TYPE (array_type);
-      LONGEST lowerbound, upperbound, offset;
-
-      if (get_discrete_bounds (range_type, &lowerbound, &upperbound) < 0)
-        error ("slice from bad array");
       offset
        = (lowbound - lowerbound) * TYPE_LENGTH (check_typedef (element_type));
-      if (lowbound < lowerbound || length < 0
-         || lowbound + length - 1 > upperbound)
-       error ("slice out of range");
-      /* FIXME-type-allocation: need a way to free this type when we are
-        done with it.  */
-      slice_range_type = create_range_type ((struct type*) NULL,
-                                           TYPE_TARGET_TYPE (range_type),
-                                           lowerbound,
-                                           lowerbound + length - 1);
       slice_type = create_array_type ((struct type*) NULL, element_type,
                                      slice_range_type);
       TYPE_CODE (slice_type) = TYPE_CODE (array_type);
@@ -2199,8 +2260,8 @@ value_slice (array, lowbound, length)
        VALUE_LVAL (slice) = VALUE_LVAL (array);
       VALUE_ADDRESS (slice) = VALUE_ADDRESS (array);
       VALUE_OFFSET (slice) = VALUE_OFFSET (array) + offset;
-      return slice;
     }
+  return slice;
 }
 
 /* Assuming chill_varying_type (VARRAY) is true, return an equivalent
This page took 0.033881 seconds and 4 git commands to generate.