* ada-lang.c (ada_coerce_to_simple_array_type): Use builtin_type_int32
[deliverable/binutils-gdb.git] / gdb / gnu-v3-abi.c
index fa251267ecc2b308754f6a407a14874d8996cb29..1ae6d9a079e15d737de65e883cd08f04064e2f57 100644 (file)
@@ -107,9 +107,9 @@ build_gdb_vtable_type (struct gdbarch *arch)
   int offset;
 
   struct type *void_ptr_type
-    = lookup_pointer_type (builtin_type_void);
+    = builtin_type (arch)->builtin_data_ptr;
   struct type *ptr_to_void_fn_type
-    = lookup_pointer_type (lookup_function_type (builtin_type_void));
+    = builtin_type (arch)->builtin_func_ptr;
 
   /* ARCH can't give us the true ptrdiff_t type, so we guess.  */
   struct type *ptrdiff_type
@@ -132,7 +132,7 @@ build_gdb_vtable_type (struct gdbarch *arch)
   FIELD_NAME (*field) = "vcall_and_vbase_offsets";
   FIELD_TYPE (*field)
     = create_array_type (0, ptrdiff_type,
-                         create_range_type (0, builtin_type_int, 0, -1));
+                         create_range_type (0, builtin_type_int32, 0, -1));
   FIELD_BITPOS (*field) = offset * TARGET_CHAR_BIT;
   offset += TYPE_LENGTH (FIELD_TYPE (*field));
   field++;
@@ -155,7 +155,7 @@ build_gdb_vtable_type (struct gdbarch *arch)
   FIELD_NAME (*field) = "virtual_functions";
   FIELD_TYPE (*field)
     = create_array_type (0, ptr_to_void_fn_type,
-                         create_range_type (0, builtin_type_int, 0, -1));
+                         create_range_type (0, builtin_type_int32, 0, -1));
   FIELD_BITPOS (*field) = offset * TARGET_CHAR_BIT;
   offset += TYPE_LENGTH (FIELD_TYPE (*field));
   field++;
@@ -201,6 +201,8 @@ gnuv3_rtti_type (struct value *value,
   struct type *run_time_type;
   struct type *base_type;
   LONGEST offset_to_top;
+  struct type *values_type_vptr_basetype;
+  int values_type_vptr_fieldno;
 
   /* We only have RTTI for class objects.  */
   if (TYPE_CODE (values_type) != TYPE_CODE_CLASS)
@@ -208,8 +210,9 @@ gnuv3_rtti_type (struct value *value,
 
   /* If we can't find the virtual table pointer for values_type, we
      can't find the RTTI.  */
-  fill_in_vptr_fieldno (values_type);
-  if (TYPE_VPTR_FIELDNO (values_type) == -1)
+  values_type_vptr_fieldno = get_vptr_fieldno (values_type,
+                                              &values_type_vptr_basetype);
+  if (values_type_vptr_fieldno == -1)
     return NULL;
 
   if (using_enc_p)
@@ -217,7 +220,7 @@ gnuv3_rtti_type (struct value *value,
 
   /* Fetch VALUE's virtual table pointer, and tweak it to point at
      an instance of our imaginary gdb_gnu_v3_abi_vtable structure.  */
-  base_type = check_typedef (TYPE_VPTR_BASETYPE (values_type));
+  base_type = check_typedef (values_type_vptr_basetype);
   if (values_type != base_type)
     {
       value = value_cast (base_type, value);
@@ -225,7 +228,7 @@ gnuv3_rtti_type (struct value *value,
        *using_enc_p = 1;
     }
   vtable_address
-    = value_as_address (value_field (value, TYPE_VPTR_FIELDNO (values_type)));
+    = value_as_address (value_field (value, values_type_vptr_fieldno));
   vtable = value_at_lazy (vtable_type,
                           vtable_address - vtable_address_point_offset ());
   
@@ -323,7 +326,7 @@ gnuv3_get_virtual_fn (struct value *container, struct type *fntype,
 
   /* Fetch the appropriate function pointer from the vtable.  */
   vfn = value_subscript (value_field (vtable, vtable_field_virtual_functions),
-                         value_from_longest (builtin_type_int, vtable_index));
+                         value_from_longest (builtin_type_int32, vtable_index));
 
   /* If this architecture uses function descriptors directly in the vtable,
      then the address of the vtable entry is actually a "function pointer"
@@ -381,6 +384,7 @@ gnuv3_baseclass_offset (struct type *type, int index, const bfd_byte *valaddr,
   struct value *offset_val, *vbase_array;
   CORE_ADDR vtable_address;
   long int cur_base_offset, base_offset;
+  int vbasetype_vptr_fieldno;
 
   /* If it isn't a virtual base, this is easy.  The offset is in the
      type definition.  */
@@ -414,11 +418,10 @@ gnuv3_baseclass_offset (struct type *type, int index, const bfd_byte *valaddr,
      we have debugging information for that baseclass.  */
 
   vbasetype = TYPE_VPTR_BASETYPE (type);
-  if (TYPE_VPTR_FIELDNO (vbasetype) < 0)
-    fill_in_vptr_fieldno (vbasetype);
+  vbasetype_vptr_fieldno = get_vptr_fieldno (vbasetype, NULL);
 
-  if (TYPE_VPTR_FIELDNO (vbasetype) >= 0
-      && TYPE_FIELD_BITPOS (vbasetype, TYPE_VPTR_FIELDNO (vbasetype)) != 0)
+  if (vbasetype_vptr_fieldno >= 0
+      && TYPE_FIELD_BITPOS (vbasetype, vbasetype_vptr_fieldno) != 0)
     error (_("Illegal vptr offset in class %s"),
           TYPE_NAME (vbasetype) ? TYPE_NAME (vbasetype) : "<unknown>");
 
@@ -426,7 +429,7 @@ gnuv3_baseclass_offset (struct type *type, int index, const bfd_byte *valaddr,
                                                    address));
   vtable = value_at_lazy (vtable_type,
                           vtable_address - vtable_address_point_offset ());
-  offset_val = value_from_longest(builtin_type_int, cur_base_offset);
+  offset_val = value_from_longest(builtin_type_int32, cur_base_offset);
   vbase_array = value_field (vtable, vtable_field_vcall_and_vbase_offsets);
   base_offset = value_as_long (value_subscript (vbase_array, offset_val));
   return base_offset;
@@ -486,6 +489,46 @@ gnuv3_find_method_in (struct type *domain, CORE_ADDR voffset,
   return NULL;
 }
 
+/* Decode GNU v3 method pointer.  */
+
+static int
+gnuv3_decode_method_ptr (const gdb_byte *contents,
+                        CORE_ADDR *value_p,
+                        LONGEST *adjustment_p)
+{
+  struct type *funcptr_type = builtin_type_void_func_ptr;
+  struct type *offset_type = builtin_type_long;
+  CORE_ADDR ptr_value;
+  LONGEST voffset, adjustment;
+  int vbit;
+
+  /* Extract the pointer to member.  The first element is either a pointer
+     or a vtable offset.  For pointers, we need to use extract_typed_address
+     to allow the back-end to convert the pointer to a GDB address -- but
+     vtable offsets we must handle as integers.  At this point, we do not
+     yet know which case we have, so we extract the value under both
+     interpretations and choose the right one later on.  */
+  ptr_value = extract_typed_address (contents, funcptr_type);
+  voffset = extract_signed_integer (contents, TYPE_LENGTH (funcptr_type));
+  contents += TYPE_LENGTH (funcptr_type);
+  adjustment = extract_signed_integer (contents, TYPE_LENGTH (offset_type));
+
+  if (!gdbarch_vbit_in_delta (current_gdbarch))
+    {
+      vbit = voffset & 1;
+      voffset = voffset ^ vbit;
+    }
+  else
+    {
+      vbit = adjustment & 1;
+      adjustment = adjustment >> 1;
+    }
+
+  *value_p = vbit? voffset : ptr_value;
+  *adjustment_p = adjustment;
+  return vbit;
+}
+
 /* GNU v3 implementation of cplus_print_method_ptr.  */
 
 static void
@@ -501,21 +544,7 @@ gnuv3_print_method_ptr (const gdb_byte *contents,
   domain = TYPE_DOMAIN_TYPE (type);
 
   /* Extract the pointer to member.  */
-  ptr_value = extract_typed_address (contents, builtin_type_void_func_ptr);
-  contents += TYPE_LENGTH (builtin_type_void_func_ptr);
-  adjustment = extract_signed_integer (contents,
-                                      TYPE_LENGTH (builtin_type_long));
-
-  if (!gdbarch_vbit_in_delta (current_gdbarch))
-    {
-      vbit = ptr_value & 1;
-      ptr_value = ptr_value ^ vbit;
-    }
-  else
-    {
-      vbit = adjustment & 1;
-      adjustment = adjustment >> 1;
-    }
+  vbit = gnuv3_decode_method_ptr (contents, &ptr_value, &adjustment);
 
   /* Check for NULL.  */
   if (ptr_value == 0 && vbit == 0)
@@ -622,21 +651,8 @@ gnuv3_method_ptr_to_value (struct value **this_p, struct value *method_ptr)
 
   method_type = TYPE_TARGET_TYPE (check_typedef (value_type (method_ptr)));
 
-  ptr_value = extract_typed_address (contents, builtin_type_void_func_ptr);
-  contents += TYPE_LENGTH (builtin_type_void_func_ptr);
-  adjustment = extract_signed_integer (contents,
-                                      TYPE_LENGTH (builtin_type_long));
-
-  if (!gdbarch_vbit_in_delta (current_gdbarch))
-    {
-      vbit = ptr_value & 1;
-      ptr_value = ptr_value ^ vbit;
-    }
-  else
-    {
-      vbit = adjustment & 1;
-      adjustment = adjustment >> 1;
-    }
+  /* Extract the pointer to member.  */
+  vbit = gnuv3_decode_method_ptr (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.  */
@@ -659,7 +675,7 @@ gnuv3_method_ptr_to_value (struct value **this_p, struct value *method_ptr)
      instance.  */
   *this_p = value_cast (builtin_type_void_data_ptr, *this_p);
   adjval = value_from_longest (builtin_type_long, adjustment);
-  *this_p = value_add (*this_p, adjval);
+  *this_p = value_ptradd (*this_p, adjval);
   *this_p = value_cast (final_type, *this_p);
 
   if (vbit)
This page took 0.028315 seconds and 4 git commands to generate.