Exemplo n.º 1
0
static struct value *
gnuv3_method_ptr_to_value (struct value **this_p, struct value *method_ptr)
{
  struct gdbarch *gdbarch;
  const gdb_byte *contents = value_contents (method_ptr);
  CORE_ADDR ptr_value;
  struct type *domain_type, *final_type, *method_type;
  LONGEST adjustment;
  struct value *adjval;
  int vbit;

  domain_type = TYPE_DOMAIN_TYPE (check_typedef (value_type (method_ptr)));
  final_type = lookup_pointer_type (domain_type);

  method_type = TYPE_TARGET_TYPE (check_typedef (value_type (method_ptr)));

  /* Extract the pointer to member.  */
  gdbarch = get_class_arch (domain_type);
  vbit = gnuv3_decode_method_ptr (gdbarch, contents, &ptr_value, &adjustment);

  /* First convert THIS to match the containing type of the pointer to
     member.  This cast may adjust the value of THIS.  */
  *this_p = value_cast (final_type, *this_p);

  /* Then apply whatever adjustment is necessary.  This creates a somewhat
     strange pointer: it claims to have type FINAL_TYPE, but in fact it
     might not be a valid FINAL_TYPE.  For instance, it might be a
     base class of FINAL_TYPE.  And if it's not the primary base class,
     then printing it out as a FINAL_TYPE object would produce some pretty
     garbage.

     But we don't really know the type of the first argument in
     METHOD_TYPE either, which is why this happens.  We can't
     dereference this later as a FINAL_TYPE, but once we arrive in the
     called method we'll have debugging information for the type of
     "this" - and that'll match the value we produce here.

     You can provoke this case by casting a Base::* to a Derived::*, for
     instance.  */
  *this_p = value_cast (builtin_type (gdbarch)->builtin_data_ptr, *this_p);
  adjval = value_from_longest (builtin_type (gdbarch)->builtin_long,
			       adjustment);
  *this_p = value_ptradd (*this_p, adjval);
  *this_p = value_cast (final_type, *this_p);

  if (vbit)
    {
      LONGEST voffset;
      voffset = ptr_value / TYPE_LENGTH (vtable_ptrdiff_type (gdbarch));
      return gnuv3_get_virtual_fn (gdbarch, value_ind (*this_p),
				   method_type, voffset);
    }
  else
    return value_from_pointer (lookup_pointer_type (method_type), ptr_value);
}
Exemplo n.º 2
0
static struct value *
gnuv3_virtual_fn_field (struct value **value_p,
                        struct fn_field *f, int j,
			struct type *vfn_base, int offset)
{
  struct type *values_type = check_typedef (value_type (*value_p));
  struct gdbarch *gdbarch;

  /* Some simple sanity checks.  */
  if (TYPE_CODE (values_type) != TYPE_CODE_CLASS)
    error (_("Only classes can have virtual functions."));

  /* Determine architecture.  */
  gdbarch = get_type_arch (values_type);

  /* Cast our value to the base class which defines this virtual
     function.  This takes care of any necessary `this'
     adjustments.  */
  if (vfn_base != values_type)
    *value_p = value_cast (vfn_base, *value_p);

  return gnuv3_get_virtual_fn (gdbarch, *value_p, TYPE_FN_FIELD_TYPE (f, j),
			       TYPE_FN_FIELD_VOFFSET (f, j));
}