change delegation for to_read_description
[deliverable/binutils-gdb.git] / gdb / valops.c
index 4fc57ec32af20440e1e11cb6f359f2b3dca401ac..898401dc13cbf3353d94a11d94197cc9966c93c1 100644 (file)
@@ -1,6 +1,6 @@
 /* Perform non-arithmetic operations on values, for GDB.
 
-   Copyright (C) 1986-2013 Free Software Foundation, Inc.
+   Copyright (C) 1986-2014 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include <errno.h>
 #include <string.h>
 #include "gdb_assert.h"
-#include "cp-support.h"
 #include "observer.h"
 #include "objfiles.h"
-#include "symtab.h"
 #include "exceptions.h"
 
 extern unsigned int overload_debug;
@@ -1188,7 +1186,8 @@ value_assign (struct value *toval, struct value *fromval)
                                               &optim, &unavail))
                  {
                    if (optim)
-                     error (_("value has been optimized out"));
+                     throw_error (OPTIMIZED_OUT_ERROR,
+                                  _("value has been optimized out"));
                    if (unavail)
                      throw_error (NOT_AVAILABLE_ERROR,
                                   _("value is not available"));
@@ -2247,6 +2246,51 @@ value_struct_elt (struct value **argp, struct value **args,
   return v;
 }
 
+/* Given *ARGP, a value of type structure or union, or a pointer/reference
+   to a structure or union, extract and return its component (field) of
+   type FTYPE at the specified BITPOS.
+   Throw an exception on error.  */
+
+struct value *
+value_struct_elt_bitpos (struct value **argp, int bitpos, struct type *ftype,
+                        const char *err)
+{
+  struct type *t;
+  struct value *v;
+  int i;
+  int nbases;
+
+  *argp = coerce_array (*argp);
+
+  t = check_typedef (value_type (*argp));
+
+  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
+    {
+      *argp = value_ind (*argp);
+      if (TYPE_CODE (check_typedef (value_type (*argp))) != TYPE_CODE_FUNC)
+       *argp = coerce_array (*argp);
+      t = check_typedef (value_type (*argp));
+    }
+
+  if (TYPE_CODE (t) != TYPE_CODE_STRUCT
+      && TYPE_CODE (t) != TYPE_CODE_UNION)
+    error (_("Attempt to extract a component of a value that is not a %s."),
+          err);
+
+  for (i = TYPE_N_BASECLASSES (t); i < TYPE_NFIELDS (t); i++)
+    {
+      if (!field_is_static (&TYPE_FIELD (t, i))
+         && bitpos == TYPE_FIELD_BITPOS (t, i)
+         && types_equal (ftype, TYPE_FIELD_TYPE (t, i)))
+       return value_primitive_field (*argp, 0, i, t);
+    }
+
+  error (_("No field with matching bitpos and type."));
+
+  /* Never hit.  */
+  return NULL;
+}
+
 /* Search through the methods of an object (and its bases) to find a
    specified method.  Return the pointer to the fn_field list of
    overloaded instances.
@@ -3128,10 +3172,35 @@ value_struct_elt_for_reference (struct type *domain, int offset,
            return value_from_longest
              (lookup_memberptr_type (TYPE_FIELD_TYPE (t, i), domain),
               offset + (LONGEST) (TYPE_FIELD_BITPOS (t, i) >> 3));
-         else if (noside == EVAL_AVOID_SIDE_EFFECTS)
+         else if (noside != EVAL_NORMAL)
            return allocate_value (TYPE_FIELD_TYPE (t, i));
          else
-           error (_("Cannot reference non-static field \"%s\""), name);
+           {
+             /* Try to evaluate NAME as a qualified name with implicit
+                this pointer.  In this case, attempt to return the
+                equivalent to `this->*(&TYPE::NAME)'.  */
+             v = value_of_this_silent (current_language);
+             if (v != NULL)
+               {
+                 struct value *ptr;
+                 long mem_offset;
+                 struct type *type, *tmp;
+
+                 ptr = value_aggregate_elt (domain, name, NULL, 1, noside);
+                 type = check_typedef (value_type (ptr));
+                 gdb_assert (type != NULL
+                             && TYPE_CODE (type) == TYPE_CODE_MEMBERPTR);
+                 tmp = lookup_pointer_type (TYPE_DOMAIN_TYPE (type));
+                 v = value_cast_pointers (tmp, v, 1);
+                 mem_offset = value_as_long (ptr);
+                 tmp = lookup_pointer_type (TYPE_TARGET_TYPE (type));
+                 result = value_from_pointer (tmp,
+                                              value_as_long (v) + mem_offset);
+                 return value_ind (result);
+               }
+
+             error (_("Cannot reference non-static field \"%s\""), name);
+           }
        }
     }
 
@@ -3545,32 +3614,33 @@ value_slice (struct value *array, int lowbound, int length)
      done with it.  */
   slice_range_type = create_range_type ((struct type *) NULL,
                                        TYPE_TARGET_TYPE (range_type),
-                                       lowbound, 
+                                       lowbound,
                                        lowbound + length - 1);
 
-    {
-      struct type *element_type = TYPE_TARGET_TYPE (array_type);
-      LONGEST offset =
-       (lowbound - lowerbound) * TYPE_LENGTH (check_typedef (element_type));
+  {
+    struct type *element_type = TYPE_TARGET_TYPE (array_type);
+    LONGEST offset
+      = (lowbound - lowerbound) * TYPE_LENGTH (check_typedef (element_type));
 
-      slice_type = create_array_type ((struct type *) NULL, 
-                                     element_type,
-                                     slice_range_type);
-      TYPE_CODE (slice_type) = TYPE_CODE (array_type);
+    slice_type = create_array_type ((struct type *) NULL,
+                                   element_type,
+                                   slice_range_type);
+    TYPE_CODE (slice_type) = TYPE_CODE (array_type);
 
-      if (VALUE_LVAL (array) == lval_memory && value_lazy (array))
-       slice = allocate_value_lazy (slice_type);
-      else
-       {
-         slice = allocate_value (slice_type);
-         value_contents_copy (slice, 0, array, offset,
-                              TYPE_LENGTH (slice_type));
-       }
+    if (VALUE_LVAL (array) == lval_memory && value_lazy (array))
+      slice = allocate_value_lazy (slice_type);
+    else
+      {
+       slice = allocate_value (slice_type);
+       value_contents_copy (slice, 0, array, offset,
+                            TYPE_LENGTH (slice_type));
+      }
+
+    set_value_component_location (slice, array);
+    VALUE_FRAME_ID (slice) = VALUE_FRAME_ID (array);
+    set_value_offset (slice, value_offset (array) + offset);
+  }
 
-      set_value_component_location (slice, array);
-      VALUE_FRAME_ID (slice) = VALUE_FRAME_ID (array);
-      set_value_offset (slice, value_offset (array) + offset);
-    }
   return slice;
 }
 
This page took 0.027038 seconds and 4 git commands to generate.