Esempio 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 *self_type, *final_type, *method_type;
  LONGEST adjustment;
  int vbit;

  self_type = TYPE_SELF_TYPE (check_typedef (value_type (method_ptr)));
  final_type = lookup_pointer_type (self_type);

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

  /* Extract the pointer to member.  */
  gdbarch = get_type_arch (self_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);
  *this_p = value_ptradd (*this_p, adjustment);
  *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);
}
static gcc_type
compile_cplus_convert_memberptr (compile_cplus_instance *instance,
				 struct type *type)
{
  struct type *containing_class = TYPE_SELF_TYPE (type);

  if (containing_class == nullptr)
    return GCC_TYPE_NONE;

  gcc_type class_type = instance->convert_type (containing_class);
  gcc_type member_type
    = instance->convert_type (TYPE_TARGET_TYPE (type));

  return instance->plugin ().build_pointer_to_member_type
    (class_type, member_type);
}
Esempio n. 3
0
static void
c_type_print_varspec_prefix (struct type *type,
			     struct ui_file *stream,
			     int show, int passed_a_ptr,
			     int need_post_space,
			     const struct type_print_options *flags)
{
  const char *name;

  if (type == 0)
    return;

  if (TYPE_NAME (type) && show <= 0)
    return;

  QUIT;

  switch (TYPE_CODE (type))
    {
    case TYPE_CODE_PTR:
      c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
				   stream, show, 1, 1, flags);
      fprintf_filtered (stream, "*");
      c_type_print_modifier (type, stream, 1, need_post_space);
      break;

    case TYPE_CODE_MEMBERPTR:
      c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
				   stream, show, 0, 0, flags);
      name = type_name_no_tag (TYPE_SELF_TYPE (type));
      if (name)
	print_name_maybe_canonical (name, flags, stream);
      else
	c_type_print_base (TYPE_SELF_TYPE (type),
			   stream, -1, passed_a_ptr, flags);
      fprintf_filtered (stream, "::*");
      break;

    case TYPE_CODE_METHODPTR:
      c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
				   stream, show, 0, 0, flags);
      fprintf_filtered (stream, "(");
      name = type_name_no_tag (TYPE_SELF_TYPE (type));
      if (name)
	print_name_maybe_canonical (name, flags, stream);
      else
	c_type_print_base (TYPE_SELF_TYPE (type),
			   stream, -1, passed_a_ptr, flags);
      fprintf_filtered (stream, "::*");
      break;

    case TYPE_CODE_REF:
      c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
				   stream, show, 1, 0, flags);
      fprintf_filtered (stream, "&");
      c_type_print_modifier (type, stream, 1, need_post_space);
      break;

    case TYPE_CODE_METHOD:
    case TYPE_CODE_FUNC:
      c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
				   stream, show, 0, 0, flags);
      if (passed_a_ptr)
	fprintf_filtered (stream, "(");
      break;

    case TYPE_CODE_ARRAY:
      c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
				   stream, show, 0, 0, flags);
      if (passed_a_ptr)
	fprintf_filtered (stream, "(");
      break;

    case TYPE_CODE_TYPEDEF:
      c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
				   stream, show, passed_a_ptr, 0, flags);
      break;

    case TYPE_CODE_UNDEF:
    case TYPE_CODE_STRUCT:
    case TYPE_CODE_UNION:
    case TYPE_CODE_ENUM:
    case TYPE_CODE_INT:
    case TYPE_CODE_FLT:
    case TYPE_CODE_VOID:
    case TYPE_CODE_ERROR:
    case TYPE_CODE_CHAR:
    case TYPE_CODE_BOOL:
    case TYPE_CODE_SET:
    case TYPE_CODE_RANGE:
    case TYPE_CODE_STRING:
    case TYPE_CODE_COMPLEX:
    case TYPE_CODE_NAMESPACE:
    case TYPE_CODE_DECFLOAT:
      /* These types need no prefix.  They are listed here so that
         gcc -Wall will reveal any types that haven't been handled.  */
      break;
    default:
      error (_("type not handled in c_type_print_varspec_prefix()"));
      break;
    }
}
Esempio n. 4
0
static void
gnuv3_print_method_ptr (const gdb_byte *contents,
			struct type *type,
			struct ui_file *stream)
{
  struct type *self_type = TYPE_SELF_TYPE (type);
  struct gdbarch *gdbarch = get_type_arch (self_type);
  CORE_ADDR ptr_value;
  LONGEST adjustment;
  int vbit;

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

  /* Check for NULL.  */
  if (ptr_value == 0 && vbit == 0)
    {
      fprintf_filtered (stream, "NULL");
      return;
    }

  /* Search for a virtual method.  */
  if (vbit)
    {
      CORE_ADDR voffset;
      const char *physname;

      /* It's a virtual table offset, maybe in this class.  Search
	 for a field with the correct vtable offset.  First convert it
	 to an index, as used in TYPE_FN_FIELD_VOFFSET.  */
      voffset = ptr_value / TYPE_LENGTH (vtable_ptrdiff_type (gdbarch));

      physname = gnuv3_find_method_in (self_type, voffset, adjustment);

      /* If we found a method, print that.  We don't bother to disambiguate
	 possible paths to the method based on the adjustment.  */
      if (physname)
	{
	  char *demangled_name = gdb_demangle (physname,
					       DMGL_ANSI | DMGL_PARAMS);

	  fprintf_filtered (stream, "&virtual ");
	  if (demangled_name == NULL)
	    fputs_filtered (physname, stream);
	  else
	    {
	      fputs_filtered (demangled_name, stream);
	      xfree (demangled_name);
	    }
	  return;
	}
    }
  else if (ptr_value != 0)
    {
      /* Found a non-virtual function: print out the type.  */
      fputs_filtered ("(", stream);
      c_print_type (type, "", stream, -1, 0, &type_print_raw_options);
      fputs_filtered (") ", stream);
    }

  /* We didn't find it; print the raw data.  */
  if (vbit)
    {
      fprintf_filtered (stream, "&virtual table offset ");
      print_longest (stream, 'd', 1, ptr_value);
    }
  else
    {
      struct value_print_options opts;

      get_user_print_options (&opts);
      print_address_demangle (&opts, gdbarch, ptr_value, stream, demangle);
    }

  if (adjustment)
    {
      fprintf_filtered (stream, ", this adjustment ");
      print_longest (stream, 'd', 1, adjustment);
    }
}
Esempio n. 5
0
void
pascal_type_print_varspec_prefix (struct type *type, struct ui_file *stream,
				  int show, int passed_a_ptr,
				  const struct type_print_options *flags)
{
  if (type == 0)
    return;

  if (TYPE_NAME (type) && show <= 0)
    return;

  QUIT;

  switch (TYPE_CODE (type))
    {
    case TYPE_CODE_PTR:
      fprintf_filtered (stream, "^");
      pascal_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1,
					flags);
      break;			/* Pointer should be handled normally
				   in pascal.  */

    case TYPE_CODE_METHOD:
      if (passed_a_ptr)
	fprintf_filtered (stream, "(");
      if (TYPE_TARGET_TYPE (type) != NULL
	  && TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
	{
	  fprintf_filtered (stream, "function  ");
	}
      else
	{
	  fprintf_filtered (stream, "procedure ");
	}

      if (passed_a_ptr)
	{
	  fprintf_filtered (stream, " ");
	  pascal_type_print_base (TYPE_SELF_TYPE (type),
				  stream, 0, passed_a_ptr, flags);
	  fprintf_filtered (stream, "::");
	}
      break;

    case TYPE_CODE_REF:
      pascal_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1,
					flags);
      fprintf_filtered (stream, "&");
      break;

    case TYPE_CODE_FUNC:
      if (passed_a_ptr)
	fprintf_filtered (stream, "(");

      if (TYPE_TARGET_TYPE (type) != NULL
	  && TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
	{
	  fprintf_filtered (stream, "function  ");
	}
      else
	{
	  fprintf_filtered (stream, "procedure ");
	}

      break;

    case TYPE_CODE_ARRAY:
      if (passed_a_ptr)
	fprintf_filtered (stream, "(");
      fprintf_filtered (stream, "array ");
      if (TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0
	&& !TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type))
	fprintf_filtered (stream, "[%s..%s] ",
			  plongest (TYPE_ARRAY_LOWER_BOUND_VALUE (type)),
			  plongest (TYPE_ARRAY_UPPER_BOUND_VALUE (type)));
      fprintf_filtered (stream, "of ");
      break;

    case TYPE_CODE_UNDEF:
    case TYPE_CODE_STRUCT:
    case TYPE_CODE_UNION:
    case TYPE_CODE_ENUM:
    case TYPE_CODE_INT:
    case TYPE_CODE_FLT:
    case TYPE_CODE_VOID:
    case TYPE_CODE_ERROR:
    case TYPE_CODE_CHAR:
    case TYPE_CODE_BOOL:
    case TYPE_CODE_SET:
    case TYPE_CODE_RANGE:
    case TYPE_CODE_STRING:
    case TYPE_CODE_COMPLEX:
    case TYPE_CODE_TYPEDEF:
      /* These types need no prefix.  They are listed here so that
         gcc -Wall will reveal any types that haven't been handled.  */
      break;
    default:
      error (_("type not handled in pascal_type_print_varspec_prefix()"));
      break;
    }
}