Implement pahole-like 'ptype /o' option
[deliverable/binutils-gdb.git] / gdb / valops.c
index 8675e6c00e2dbb2d9963edb28731a424e7388f30..ccc2bc2afe6c7bb34eedb5e39217320f32c1117e 100644 (file)
 #include "infcall.h"
 #include "dictionary.h"
 #include "cp-support.h"
-#include "dfp.h"
+#include "target-float.h"
 #include "tracepoint.h"
 #include "observer.h"
 #include "objfiles.h"
 #include "extension.h"
+#include "byte-vector.h"
 
 extern unsigned int overload_debug;
 /* Local functions.  */
@@ -100,8 +101,6 @@ static void find_method_list (struct value **, const char *,
                              VEC (xmethod_worker_ptr) **,
                              struct type **, LONGEST *);
 
-void _initialize_valops (void);
-
 #if 0
 /* Flag for whether we want to abandon failed expression evals by
    default.  */
@@ -191,7 +190,7 @@ value_allocate_space_in_inferior (int len)
   struct value *blocklen;
 
   blocklen = value_from_longest (builtin_type (gdbarch)->builtin_int, len);
-  val = call_function_by_hand (val, 1, &blocklen);
+  val = call_function_by_hand (val, NULL, 1, &blocklen);
   if (value_logical_not (val))
     {
       if (!target_has_execution)
@@ -378,6 +377,11 @@ value_cast (struct type *type, struct value *arg2)
     /* We deref the value and then do the cast.  */
     return value_cast (type, coerce_ref (arg2)); 
 
+  /* Strip typedefs / resolve stubs in order to get at the type's
+     code/length, but remember the original type, to use as the
+     resulting type of the cast, in case it was a typedef.  */
+  struct type *to_type = type;
+
   type = check_typedef (type);
   code1 = TYPE_CODE (type);
   arg2 = coerce_ref (arg2);
@@ -433,7 +437,7 @@ value_cast (struct type *type, struct value *arg2)
   code2 = TYPE_CODE (type2);
 
   if (code1 == TYPE_CODE_COMPLEX)
-    return cast_into_complex (type, arg2);
+    return cast_into_complex (to_type, arg2);
   if (code1 == TYPE_CODE_BOOL)
     {
       code1 = TYPE_CODE_INT;
@@ -452,30 +456,27 @@ value_cast (struct type *type, struct value *arg2)
       && (code2 == TYPE_CODE_STRUCT || code2 == TYPE_CODE_UNION)
       && TYPE_NAME (type) != 0)
     {
-      struct value *v = value_cast_structs (type, arg2);
+      struct value *v = value_cast_structs (to_type, arg2);
 
       if (v)
        return v;
     }
 
-  if (code1 == TYPE_CODE_FLT && scalar)
-    return value_from_double (type, value_as_double (arg2));
-  else if (code1 == TYPE_CODE_DECFLOAT && scalar)
+  if (is_floating_type (type) && scalar)
     {
-      enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
-      int dec_len = TYPE_LENGTH (type);
-      gdb_byte dec[16];
+      if (is_floating_value (arg2))
+       {
+         struct value *v = allocate_value (to_type);
+         target_float_convert (value_contents (arg2), type2,
+                               value_contents_raw (v), type);
+         return v;
+       }
 
-      if (code2 == TYPE_CODE_FLT)
-       decimal_from_floating (arg2, dec, dec_len, byte_order);
-      else if (code2 == TYPE_CODE_DECFLOAT)
-       decimal_convert (value_contents (arg2), TYPE_LENGTH (type2),
-                        byte_order, dec, dec_len, byte_order);
+      /* The only option left is an integral type.  */
+      if (TYPE_UNSIGNED (type2))
+       return value_from_ulongest (to_type, value_as_long (arg2));
       else
-       /* The only option left is an integral type.  */
-       decimal_from_integral (arg2, dec, dec_len, byte_order);
-
-      return value_from_decfloat (type, dec);
+       return value_from_longest (to_type, value_as_long (arg2));
     }
   else if ((code1 == TYPE_CODE_INT || code1 == TYPE_CODE_ENUM
            || code1 == TYPE_CODE_RANGE)
@@ -496,7 +497,7 @@ value_cast (struct type *type, struct value *arg2)
                     gdbarch_byte_order (get_type_arch (type2)));
       else
         longest = value_as_long (arg2);
-      return value_from_longest (type, convert_to_boolean ?
+      return value_from_longest (to_type, convert_to_boolean ?
                                 (LONGEST) (longest ? 1 : 0) : longest);
     }
   else if (code1 == TYPE_CODE_PTR && (code2 == TYPE_CODE_INT  
@@ -522,14 +523,14 @@ value_cast (struct type *type, struct value *arg2)
              || longest <= -((LONGEST) 1 << addr_bit))
            warning (_("value truncated"));
        }
-      return value_from_longest (type, longest);
+      return value_from_longest (to_type, longest);
     }
   else if (code1 == TYPE_CODE_METHODPTR && code2 == TYPE_CODE_INT
           && value_as_long (arg2) == 0)
     {
-      struct value *result = allocate_value (type);
+      struct value *result = allocate_value (to_type);
 
-      cplus_make_method_ptr (type, value_contents_writeable (result), 0, 0);
+      cplus_make_method_ptr (to_type, value_contents_writeable (result), 0, 0);
       return result;
     }
   else if (code1 == TYPE_CODE_MEMBERPTR && code2 == TYPE_CODE_INT
@@ -537,7 +538,7 @@ value_cast (struct type *type, struct value *arg2)
     {
       /* The Itanium C++ ABI represents NULL pointers to members as
         minus one, instead of biasing the normal case.  */
-      return value_from_longest (type, -1);
+      return value_from_longest (to_type, -1);
     }
   else if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type)
           && code2 == TYPE_CODE_ARRAY && TYPE_VECTOR (type2)
@@ -548,21 +549,21 @@ value_cast (struct type *type, struct value *arg2)
     error (_("can only cast scalar to vector of same size"));
   else if (code1 == TYPE_CODE_VOID)
     {
-      return value_zero (type, not_lval);
+      return value_zero (to_type, not_lval);
     }
   else if (TYPE_LENGTH (type) == TYPE_LENGTH (type2))
     {
       if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR)
-       return value_cast_pointers (type, arg2, 0);
+       return value_cast_pointers (to_type, arg2, 0);
 
       arg2 = value_copy (arg2);
-      deprecated_set_value_type (arg2, type);
-      set_value_enclosing_type (arg2, type);
+      deprecated_set_value_type (arg2, to_type);
+      set_value_enclosing_type (arg2, to_type);
       set_value_pointed_to_offset (arg2, 0);   /* pai: chk_val */
       return arg2;
     }
   else if (VALUE_LVAL (arg2) == lval_memory)
-    return value_at_lazy (type, value_address (arg2));
+    return value_at_lazy (to_type, value_address (arg2));
   else
     {
       error (_("Invalid cast."));
@@ -859,19 +860,7 @@ value_one (struct type *type)
   struct type *type1 = check_typedef (type);
   struct value *val;
 
-  if (TYPE_CODE (type1) == TYPE_CODE_DECFLOAT)
-    {
-      enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
-      gdb_byte v[16];
-
-      decimal_from_string (v, TYPE_LENGTH (type), byte_order, "1");
-      val = value_from_decfloat (type, v);
-    }
-  else if (TYPE_CODE (type1) == TYPE_CODE_FLT)
-    {
-      val = value_from_double (type, (DOUBLEST) 1);
-    }
-  else if (is_integral_type (type1))
+  if (is_integral_type (type1) || is_floating_type (type1))
     {
       val = value_from_longest (type, (LONGEST) 1);
     }
@@ -2076,24 +2065,20 @@ search_struct_method (const char *name, struct value **arg1p,
 
          if (offset < 0 || offset >= TYPE_LENGTH (type))
            {
-             gdb_byte *tmp;
-             struct cleanup *back_to;
              CORE_ADDR address;
 
-             tmp = (gdb_byte *) xmalloc (TYPE_LENGTH (baseclass));
-             back_to = make_cleanup (xfree, tmp);
+             gdb::byte_vector tmp (TYPE_LENGTH (baseclass));
              address = value_address (*arg1p);
 
              if (target_read_memory (address + offset,
-                                     tmp, TYPE_LENGTH (baseclass)) != 0)
+                                     tmp.data (), TYPE_LENGTH (baseclass)) != 0)
                error (_("virtual baseclass botch"));
 
              base_val = value_from_contents_and_address (baseclass,
-                                                         tmp,
+                                                         tmp.data (),
                                                          address + offset);
              base_valaddr = value_contents_for_printing (base_val);
              this_offset = 0;
-             do_cleanups (back_to);
            }
          else
            {
@@ -3422,6 +3407,11 @@ value_struct_elt_for_reference (struct type *domain, int offset,
            {
              for (j = 0; j < len; ++j)
                {
+                 if (TYPE_CONST (intype) != TYPE_FN_FIELD_CONST (f, j))
+                   continue;
+                 if (TYPE_VOLATILE (intype) != TYPE_FN_FIELD_VOLATILE (f, j))
+                   continue;
+
                  if (compare_parameters (TYPE_FN_FIELD_TYPE (f, j), intype, 0)
                      || compare_parameters (TYPE_FN_FIELD_TYPE (f, j),
                                             intype, 1))
This page took 0.02826 seconds and 4 git commands to generate.