Add gdbarch callback to provide formats for debug info float types
[deliverable/binutils-gdb.git] / gdb / gnu-v3-abi.c
index 558ec06ccfadffb6e3b775d143feb5e5fa902a14..5bf36a276dc6636fb0273819bf9b42ebb327ad5b 100644 (file)
@@ -1,7 +1,7 @@
 /* Abstraction of GNU v3 abi.
    Contributed by Jim Blandy <jimb@redhat.com>
 
-   Copyright (C) 2001-2014 Free Software Foundation, Inc.
+   Copyright (C) 2001-2016 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -39,13 +39,13 @@ static struct gdbarch_data *std_type_info_gdbarch_data;
 static int
 gnuv3_is_vtable_name (const char *name)
 {
-  return strncmp (name, "_ZTV", 4) == 0;
+  return startswith (name, "_ZTV");
 }
 
 static int
 gnuv3_is_operator_name (const char *name)
 {
-  return strncmp (name, "operator", 8) == 0;
+  return startswith (name, "operator");
 }
 
 
@@ -125,8 +125,7 @@ build_gdb_vtable_type (struct gdbarch *arch)
      the alignment that type requires, and then use that here.  */
 
   /* Build the field list.  */
-  field_list = xmalloc (sizeof (struct field [4]));
-  memset (field_list, 0, sizeof (struct field [4]));
+  field_list = XCNEWVEC (struct field, 4);
   field = &field_list[0];
   offset = 0;
 
@@ -175,7 +174,8 @@ build_gdb_vtable_type (struct gdbarch *arch)
 static struct type *
 vtable_ptrdiff_type (struct gdbarch *gdbarch)
 {
-  struct type *vtable_type = gdbarch_data (gdbarch, vtable_type_gdbarch_data);
+  struct type *vtable_type
+    = (struct type *) gdbarch_data (gdbarch, vtable_type_gdbarch_data);
 
   /* The "offset_to_top" field has the appropriate (ptrdiff_t) type.  */
   return TYPE_FIELD_TYPE (vtable_type, vtable_field_offset_to_top);
@@ -187,7 +187,8 @@ vtable_ptrdiff_type (struct gdbarch *gdbarch)
 static int
 vtable_address_point_offset (struct gdbarch *gdbarch)
 {
-  struct type *vtable_type = gdbarch_data (gdbarch, vtable_type_gdbarch_data);
+  struct type *vtable_type
+    = (struct type *) gdbarch_data (gdbarch, vtable_type_gdbarch_data);
 
   return (TYPE_FIELD_BITPOS (vtable_type, vtable_field_virtual_functions)
           / TARGET_CHAR_BIT);
@@ -202,6 +203,13 @@ gnuv3_dynamic_class (struct type *type)
 {
   int fieldnum, fieldelem;
 
+  type = check_typedef (type);
+  gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT
+             || TYPE_CODE (type) == TYPE_CODE_UNION);
+
+  if (TYPE_CODE (type) == TYPE_CODE_UNION)
+    return 0;
+
   if (TYPE_CPLUS_DYNAMIC (type))
     return TYPE_CPLUS_DYNAMIC (type) == 1;
 
@@ -240,15 +248,18 @@ static struct value *
 gnuv3_get_vtable (struct gdbarch *gdbarch,
                  struct type *container_type, CORE_ADDR container_addr)
 {
-  struct type *vtable_type = gdbarch_data (gdbarch,
-                                          vtable_type_gdbarch_data);
+  struct type *vtable_type
+    = (struct type *) gdbarch_data (gdbarch, vtable_type_gdbarch_data);
   struct type *vtable_pointer_type;
   struct value *vtable_pointer;
   CORE_ADDR vtable_address;
 
+  container_type = check_typedef (container_type);
+  gdb_assert (TYPE_CODE (container_type) == TYPE_CODE_STRUCT);
+
   /* If this type does not have a virtual table, don't read the first
      field.  */
-  if (!gnuv3_dynamic_class (check_typedef (container_type)))
+  if (!gnuv3_dynamic_class (container_type))
     return NULL;
 
   /* We do not consult the debug information to find the virtual table.
@@ -275,7 +286,7 @@ gnuv3_get_vtable (struct gdbarch *gdbarch,
 
 static struct type *
 gnuv3_rtti_type (struct value *value,
-                 int *full_p, int *top_p, int *using_enc_p)
+                 int *full_p, LONGEST *top_p, int *using_enc_p)
 {
   struct gdbarch *gdbarch;
   struct type *values_type = check_typedef (value_type (value));
@@ -285,10 +296,10 @@ gnuv3_rtti_type (struct value *value,
   const char *class_name;
   struct type *run_time_type;
   LONGEST offset_to_top;
-  char *atsign;
+  const char *atsign;
 
   /* We only have RTTI for class objects.  */
-  if (TYPE_CODE (values_type) != TYPE_CODE_CLASS)
+  if (TYPE_CODE (values_type) != TYPE_CODE_STRUCT)
     return NULL;
 
   /* Java doesn't have RTTI following the C++ ABI.  */
@@ -301,7 +312,7 @@ gnuv3_rtti_type (struct value *value,
   if (using_enc_p)
     *using_enc_p = 0;
 
-  vtable = gnuv3_get_vtable (gdbarch, value_type (value),
+  vtable = gnuv3_get_vtable (gdbarch, values_type,
                             value_as_address (value_addr (value)));
   if (vtable == NULL)
     return NULL;
@@ -320,7 +331,7 @@ gnuv3_rtti_type (struct value *value,
      should work just as well, and doesn't read target memory.  */
   vtable_symbol_name = MSYMBOL_DEMANGLED_NAME (vtable_symbol);
   if (vtable_symbol_name == NULL
-      || strncmp (vtable_symbol_name, "vtable for ", 11))
+      || !startswith (vtable_symbol_name, "vtable for "))
     {
       warning (_("can't find linker symbol for virtual table for `%s' value"),
               TYPE_SAFE_NAME (values_type));
@@ -336,7 +347,7 @@ gnuv3_rtti_type (struct value *value,
     {
       char *copy;
 
-      copy = alloca (atsign - class_name + 1);
+      copy = (char *) alloca (atsign - class_name + 1);
       memcpy (copy, class_name, atsign - class_name);
       copy[atsign - class_name] = '\0';
       class_name = copy;
@@ -406,7 +417,7 @@ gnuv3_virtual_fn_field (struct value **value_p,
   struct gdbarch *gdbarch;
 
   /* Some simple sanity checks.  */
-  if (TYPE_CODE (values_type) != TYPE_CODE_CLASS)
+  if (TYPE_CODE (values_type) != TYPE_CODE_STRUCT)
     error (_("Only classes can have virtual functions."));
 
   /* Determine architecture.  */
@@ -432,7 +443,7 @@ gnuv3_virtual_fn_field (struct value **value_p,
 
 static int
 gnuv3_baseclass_offset (struct type *type, int index,
-                       const bfd_byte *valaddr, int embedded_offset,
+                       const bfd_byte *valaddr, LONGEST embedded_offset,
                        CORE_ADDR address, const struct value *val)
 {
   struct gdbarch *gdbarch;
@@ -575,8 +586,8 @@ gnuv3_print_method_ptr (const gdb_byte *contents,
                        struct type *type,
                        struct ui_file *stream)
 {
-  struct type *domain = TYPE_DOMAIN_TYPE (type);
-  struct gdbarch *gdbarch = get_type_arch (domain);
+  struct type *self_type = TYPE_SELF_TYPE (type);
+  struct gdbarch *gdbarch = get_type_arch (self_type);
   CORE_ADDR ptr_value;
   LONGEST adjustment;
   int vbit;
@@ -602,7 +613,7 @@ gnuv3_print_method_ptr (const gdb_byte *contents,
         to an index, as used in TYPE_FN_FIELD_VOFFSET.  */
       voffset = ptr_value / TYPE_LENGTH (vtable_ptrdiff_type (gdbarch));
 
-      physname = gnuv3_find_method_in (domain, voffset, adjustment);
+      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.  */
@@ -700,17 +711,17 @@ 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;
+  struct type *self_type, *final_type, *method_type;
   LONGEST adjustment;
   int vbit;
 
-  domain_type = TYPE_DOMAIN_TYPE (check_typedef (value_type (method_ptr)));
-  final_type = lookup_pointer_type (domain_type);
+  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 (domain_type);
+  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
@@ -769,7 +780,7 @@ DEF_VEC_P (value_and_voffset_p);
 static hashval_t
 hash_value_and_voffset (const void *p)
 {
-  const struct value_and_voffset *o = p;
+  const struct value_and_voffset *o = (const struct value_and_voffset *) p;
 
   return value_address (o->value) + value_embedded_offset (o->value);
 }
@@ -779,8 +790,8 @@ hash_value_and_voffset (const void *p)
 static int
 eq_value_and_voffset (const void *a, const void *b)
 {
-  const struct value_and_voffset *ova = a;
-  const struct value_and_voffset *ovb = b;
+  const struct value_and_voffset *ova = (const struct value_and_voffset *) a;
+  const struct value_and_voffset *ovb = (const struct value_and_voffset *) b;
 
   return (value_address (ova->value) + value_embedded_offset (ova->value)
          == value_address (ovb->value) + value_embedded_offset (ovb->value));
@@ -791,10 +802,12 @@ eq_value_and_voffset (const void *a, const void *b)
 static int
 compare_value_and_voffset (const void *a, const void *b)
 {
-  const struct value_and_voffset * const *ova = a;
+  const struct value_and_voffset * const *ova
+    = (const struct value_and_voffset * const *) a;
   CORE_ADDR addra = (value_address ((*ova)->value)
                     + value_embedded_offset ((*ova)->value));
-  const struct value_and_voffset * const *ovb = b;
+  const struct value_and_voffset * const *ovb
+    = (const struct value_and_voffset * const *) b;
   CORE_ADDR addrb = (value_address ((*ovb)->value)
                     + value_embedded_offset ((*ovb)->value));
 
@@ -821,6 +834,8 @@ compute_vtable_size (htab_t offset_hash,
   void **slot;
   struct value_and_voffset search_vo, *current_vo;
 
+  gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT);
+
   /* If the object is not dynamic, then we are done; as it cannot have
      dynamic base types either.  */
   if (!gnuv3_dynamic_class (type))
@@ -830,7 +845,7 @@ compute_vtable_size (htab_t offset_hash,
   search_vo.value = value;
   slot = htab_find_slot (offset_hash, &search_vo, INSERT);
   if (*slot)
-    current_vo = *slot;
+    current_vo = (struct value_and_voffset *) *slot;
   else
     {
       current_vo = XNEW (struct value_and_voffset);
@@ -892,8 +907,8 @@ print_one_vtable (struct gdbarch *gdbarch, struct value *value,
     {
       /* Initialize it just to avoid a GCC false warning.  */
       CORE_ADDR addr = 0;
+      int got_error = 0;
       struct value *vfn;
-      volatile struct gdb_exception ex;
 
       printf_filtered ("[%d]: ", i);
 
@@ -904,13 +919,18 @@ print_one_vtable (struct gdbarch *gdbarch, struct value *value,
       if (gdbarch_vtable_function_descriptors (gdbarch))
        vfn = value_addr (vfn);
 
-      TRY_CATCH (ex, RETURN_MASK_ERROR)
+      TRY
        {
          addr = value_as_address (vfn);
        }
-      if (ex.reason < 0)
-       printf_filtered (_("<error: %s>"), ex.message);
-      else
+      CATCH (ex, RETURN_MASK_ERROR)
+       {
+         printf_filtered (_("<error: %s>"), ex.message);
+         got_error = 1;
+       }
+      END_CATCH
+
+      if (!got_error)
        print_function_pointer_address (opts, gdbarch, addr, gdb_stdout);
       printf_filtered ("\n");
     }
@@ -949,8 +969,11 @@ gnuv3_print_vtable (struct value *value)
     }
 
   gdbarch = get_type_arch (type);
-  vtable = gnuv3_get_vtable (gdbarch, type,
-                            value_as_address (value_addr (value)));
+
+  vtable = NULL;
+  if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
+    vtable = gnuv3_get_vtable (gdbarch, type,
+                              value_as_address (value_addr (value)));
 
   if (!vtable)
     {
@@ -1005,8 +1028,7 @@ build_std_type_info_type (struct gdbarch *arch)
   struct type *char_ptr_type
     = make_pointer_type (make_cv_type (1, 0, char_type, NULL), NULL);
 
-  field_list = xmalloc (sizeof (struct field [2]));
-  memset (field_list, 0, sizeof (struct field [2]));
+  field_list = XCNEWVEC (struct field, 2);
   field = &field_list[0];
   offset = 0;
 
@@ -1043,9 +1065,11 @@ gnuv3_get_typeid_type (struct gdbarch *gdbarch)
   struct symbol *typeinfo;
   struct type *typeinfo_type;
 
-  typeinfo = lookup_symbol ("std::type_info", NULL, STRUCT_DOMAIN, NULL);
+  typeinfo = lookup_symbol ("std::type_info", NULL, STRUCT_DOMAIN,
+                           NULL).symbol;
   if (typeinfo == NULL)
-    typeinfo_type = gdbarch_data (gdbarch, std_type_info_gdbarch_data);
+    typeinfo_type
+      = (struct type *) gdbarch_data (gdbarch, std_type_info_gdbarch_data);
   else
     typeinfo_type = SYMBOL_TYPE (typeinfo);
 
@@ -1062,7 +1086,7 @@ gnuv3_get_typeid (struct value *value)
   struct gdbarch *gdbarch;
   struct cleanup *cleanup;
   struct value *result;
-  char *typename, *canonical;
+  char *type_name, *canonical;
 
   /* We have to handle values a bit trickily here, to allow this code
      to work properly with non_lvalue values that are really just
@@ -1081,27 +1105,27 @@ gnuv3_get_typeid (struct value *value)
   type = make_cv_type (0, 0, type, NULL);
   gdbarch = get_type_arch (type);
 
-  typename = type_to_string (type);
-  if (typename == NULL)
+  type_name = type_to_string (type);
+  if (type_name == NULL)
     error (_("cannot find typeinfo for unnamed type"));
-  cleanup = make_cleanup (xfree, typename);
+  cleanup = make_cleanup (xfree, type_name);
 
   /* We need to canonicalize the type name here, because we do lookups
      using the demangled name, and so we must match the format it
      uses.  E.g., GDB tends to use "const char *" as a type name, but
      the demangler uses "char const *".  */
-  canonical = cp_canonicalize_string (typename);
+  canonical = cp_canonicalize_string (type_name);
   if (canonical != NULL)
     {
       make_cleanup (xfree, canonical);
-      typename = canonical;
+      type_name = canonical;
     }
 
   typeinfo_type = gnuv3_get_typeid_type (gdbarch);
 
   /* We check for lval_memory because in the "typeid (type-id)" case,
      the type is passed via a not_lval value object.  */
-  if (TYPE_CODE (type) == TYPE_CODE_CLASS
+  if (TYPE_CODE (type) == TYPE_CODE_STRUCT
       && value_lval_const (value) == lval_memory
       && gnuv3_dynamic_class (type))
     {
@@ -1110,7 +1134,7 @@ gnuv3_get_typeid (struct value *value)
 
       vtable = gnuv3_get_vtable (gdbarch, type, address);
       if (vtable == NULL)
-       error (_("cannot find typeinfo for object of type '%s'"), typename);
+       error (_("cannot find typeinfo for object of type '%s'"), type_name);
       typeinfo_value = value_field (vtable, vtable_field_type_info);
       result = value_ind (value_cast (make_pointer_type (typeinfo_type, NULL),
                                      typeinfo_value));
@@ -1120,12 +1144,12 @@ gnuv3_get_typeid (struct value *value)
       char *sym_name;
       struct bound_minimal_symbol minsym;
 
-      sym_name = concat ("typeinfo for ", typename, (char *) NULL);
+      sym_name = concat ("typeinfo for ", type_name, (char *) NULL);
       make_cleanup (xfree, sym_name);
       minsym = lookup_minimal_symbol (sym_name, NULL, NULL);
 
       if (minsym.minsym == NULL)
-       error (_("could not find typeinfo symbol for '%s'"), typename);
+       error (_("could not find typeinfo symbol for '%s'"), type_name);
 
       result = value_at_lazy (typeinfo_type, BMSYMBOL_VALUE_ADDRESS (minsym));
     }
@@ -1173,21 +1197,21 @@ gnuv3_get_typename_from_type_info (struct value *type_info_ptr)
 static struct type *
 gnuv3_get_type_from_type_info (struct value *type_info_ptr)
 {
-  char *typename;
+  char *type_name;
   struct cleanup *cleanup;
   struct value *type_val;
   struct expression *expr;
   struct type *result;
 
-  typename = gnuv3_get_typename_from_type_info (type_info_ptr);
-  cleanup = make_cleanup (xfree, typename);
+  type_name = gnuv3_get_typename_from_type_info (type_info_ptr);
+  cleanup = make_cleanup (xfree, type_name);
 
   /* We have to parse the type name, since in general there is not a
      symbol for a type.  This is somewhat bogus since there may be a
      mis-parse.  Another approach might be to re-use the demangler's
      internal form to reconstruct the type somehow.  */
 
-  expr = parse_expression (typename);
+  expr = parse_expression (type_name);
   make_cleanup (xfree, expr);
 
   type_val = evaluate_type (expr);
@@ -1273,14 +1297,18 @@ gnuv3_pass_by_reference (struct type *type)
 {
   int fieldnum, fieldelem;
 
-  CHECK_TYPEDEF (type);
+  type = check_typedef (type);
 
   /* We're only interested in things that can have methods.  */
   if (TYPE_CODE (type) != TYPE_CODE_STRUCT
-      && TYPE_CODE (type) != TYPE_CODE_CLASS
       && TYPE_CODE (type) != TYPE_CODE_UNION)
     return 0;
 
+  /* A dynamic class has a non-trivial copy constructor.
+     See c++98 section 12.8 Copying class objects [class.copy].  */
+  if (gnuv3_dynamic_class (type))
+    return 1;
+
   for (fieldnum = 0; fieldnum < TYPE_NFN_FIELDS (type); fieldnum++)
     for (fieldelem = 0; fieldelem < TYPE_FN_FIELDLIST_LENGTH (type, fieldnum);
         fieldelem++)
@@ -1315,13 +1343,15 @@ gnuv3_pass_by_reference (struct type *type)
        if (TYPE_NFIELDS (fieldtype) == 2)
          {
            struct type *arg_type = TYPE_FIELD_TYPE (fieldtype, 1);
-           struct type *arg_target_type;
 
-           arg_target_type = check_typedef (TYPE_TARGET_TYPE (arg_type));
+           if (TYPE_CODE (arg_type) == TYPE_CODE_REF)
+             {
+               struct type *arg_target_type;
 
-           if (TYPE_CODE (arg_type) == TYPE_CODE_REF
-               && class_types_same_p (arg_target_type, type))
-             return 1;
+               arg_target_type = check_typedef (TYPE_TARGET_TYPE (arg_type));
+               if (class_types_same_p (arg_target_type, type))
+                 return 1;
+             }
          }
       }
 
This page took 0.029918 seconds and 4 git commands to generate.