2012-05-09 Frank Ch. Eigler <fche@redhat.com>
[deliverable/binutils-gdb.git] / gdb / value.c
index 85ea9703be07946227a3391a22c79ab90f73bd65..d49828913f90ccf85b09a1cb90d89731a950f91d 100644 (file)
@@ -41,6 +41,7 @@
 #include "python/python.h"
 #include <ctype.h>
 #include "tracepoint.h"
+#include "cp-abi.h"
 
 /* Prototypes for exported functions.  */
 
@@ -805,6 +806,14 @@ value_parent (struct value *value)
   return value->parent;
 }
 
+/* See value.h.  */
+
+void
+set_value_parent (struct value *value, struct value *parent)
+{
+  value->parent = parent;
+}
+
 gdb_byte *
 value_contents_raw (struct value *value)
 {
@@ -825,6 +834,47 @@ value_enclosing_type (struct value *value)
   return value->enclosing_type;
 }
 
+/* Look at value.h for description.  */
+
+struct type *
+value_actual_type (struct value *value, int resolve_simple_types,
+                  int *real_type_found)
+{
+  struct value_print_options opts;
+  struct value *target;
+  struct type *result;
+
+  get_user_print_options (&opts);
+
+  if (real_type_found)
+    *real_type_found = 0;
+  result = value_type (value);
+  if (opts.objectprint)
+    {
+      if (TYPE_CODE (result) == TYPE_CODE_PTR
+         || TYPE_CODE (result) == TYPE_CODE_REF)
+        {
+          struct type *real_type;
+
+          real_type = value_rtti_indirect_type (value, NULL, NULL, NULL);
+          if (real_type)
+            {
+              if (real_type_found)
+                *real_type_found = 1;
+              result = real_type;
+            }
+        }
+      else if (resolve_simple_types)
+        {
+          if (real_type_found)
+            *real_type_found = 1;
+          result = value_enclosing_type (value);
+        }
+    }
+
+  return result;
+}
+
 static void
 require_not_optimized_out (const struct value *value)
 {
@@ -1100,7 +1150,10 @@ value_address (const struct value *value)
   if (value->lval == lval_internalvar
       || value->lval == lval_internalvar_component)
     return 0;
-  return value->location.address + value->offset;
+  if (value->parent != NULL)
+    return value_address (value->parent) + value->offset;
+  else
+    return value->location.address + value->offset;
 }
 
 CORE_ADDR
@@ -1576,7 +1629,14 @@ struct internalvar
       struct value *value;
 
       /* The call-back routine used with INTERNALVAR_MAKE_VALUE.  */
-      internalvar_make_value make_value;
+      struct
+        {
+         /* The functions to call.  */
+         const struct internalvar_funcs *functions;
+
+         /* The function's user-data.  */
+         void *data;
+        } make_value;
 
       /* The internal function used with INTERNALVAR_FUNCTION.  */
       struct
@@ -1675,18 +1735,39 @@ create_internalvar (const char *name)
 /* Create an internal variable with name NAME and register FUN as the
    function that value_of_internalvar uses to create a value whenever
    this variable is referenced.  NAME should not normally include a
-   dollar sign.  */
+   dollar sign.  DATA is passed uninterpreted to FUN when it is
+   called.  CLEANUP, if not NULL, is called when the internal variable
+   is destroyed.  It is passed DATA as its only argument.  */
 
 struct internalvar *
-create_internalvar_type_lazy (char *name, internalvar_make_value fun)
+create_internalvar_type_lazy (const char *name,
+                             const struct internalvar_funcs *funcs,
+                             void *data)
 {
   struct internalvar *var = create_internalvar (name);
 
   var->kind = INTERNALVAR_MAKE_VALUE;
-  var->u.make_value = fun;
+  var->u.make_value.functions = funcs;
+  var->u.make_value.data = data;
   return var;
 }
 
+/* See documentation in value.h.  */
+
+int
+compile_internalvar_to_ax (struct internalvar *var,
+                          struct agent_expr *expr,
+                          struct axs_value *value)
+{
+  if (var->kind != INTERNALVAR_MAKE_VALUE
+      || var->u.make_value.functions->compile_to_ax == NULL)
+    return 0;
+
+  var->u.make_value.functions->compile_to_ax (var, expr, value,
+                                             var->u.make_value.data);
+  return 1;
+}
+
 /* Look up an internal variable with name NAME.  NAME should not
    normally include a dollar sign.
 
@@ -1759,7 +1840,8 @@ value_of_internalvar (struct gdbarch *gdbarch, struct internalvar *var)
       break;
 
     case INTERNALVAR_MAKE_VALUE:
-      val = (*var->u.make_value) (gdbarch, var);
+      val = (*var->u.make_value.functions->make_value) (gdbarch, var,
+                                                       var->u.make_value.data);
       break;
 
     default:
@@ -1955,6 +2037,11 @@ clear_internalvar (struct internalvar *var)
       xfree (var->u.string);
       break;
 
+    case INTERNALVAR_MAKE_VALUE:
+      if (var->u.make_value.functions->destroy != NULL)
+       var->u.make_value.functions->destroy (var->u.make_value.data);
+      break;
+
     default:
       break;
     }
@@ -2549,11 +2636,24 @@ value_primitive_field (struct value *arg1, int offset,
       /* This field is actually a base subobject, so preserve the
         entire object's contents for later references to virtual
         bases, etc.  */
+      int boffset;
 
       /* Lazy register values with offsets are not supported.  */
       if (VALUE_LVAL (arg1) == lval_register && value_lazy (arg1))
        value_fetch_lazy (arg1);
 
+      /* We special case virtual inheritance here because this
+        requires access to the contents, which we would rather avoid
+        for references to ordinary fields of unavailable values.  */
+      if (BASETYPE_VIA_VIRTUAL (arg_type, fieldno))
+       boffset = baseclass_offset (arg_type, fieldno,
+                                   value_contents (arg1),
+                                   value_embedded_offset (arg1),
+                                   value_address (arg1),
+                                   arg1);
+      else
+       boffset = TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
+
       if (value_lazy (arg1))
        v = allocate_value_lazy (value_enclosing_type (arg1));
       else
@@ -2564,8 +2664,7 @@ value_primitive_field (struct value *arg1, int offset,
        }
       v->type = type;
       v->offset = value_offset (arg1);
-      v->embedded_offset = (offset + value_embedded_offset (arg1)
-                           + TYPE_FIELD_BITPOS (arg_type, fieldno) / 8);
+      v->embedded_offset = offset + value_embedded_offset (arg1) + boffset;
     }
   else
     {
@@ -2929,7 +3028,7 @@ pack_long (gdb_byte *buf, struct type *type, LONGEST num)
 
 /* Pack NUM into BUF using a target format of TYPE.  */
 
-void
+static void
 pack_unsigned_long (gdb_byte *buf, struct type *type, ULONGEST num)
 {
   int len;
This page took 0.028383 seconds and 4 git commands to generate.