]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/gnu-v3-abi.c
Fix latent bug in custom word point completion handling
[thirdparty/binutils-gdb.git] / gdb / gnu-v3-abi.c
index 9be9cd9de96ad0f651f2d8af6cf4d07381bb2c23..6407c9beb82fe3aeb6dd0b5ef1aa9d855bfa939e 100644 (file)
@@ -1,7 +1,7 @@
 /* Abstraction of GNU v3 abi.
    Contributed by Jim Blandy <jimb@redhat.com>
 
-   Copyright (C) 2001-2016 Free Software Foundation, Inc.
+   Copyright (C) 2001-2019 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -27,6 +27,7 @@
 #include "valprint.h"
 #include "c-lang.h"
 #include "typeprint.h"
+#include <algorithm>
 
 static struct cp_abi_ops gnu_v3_abi_ops;
 
@@ -45,7 +46,7 @@ gnuv3_is_vtable_name (const char *name)
 static int
 gnuv3_is_operator_name (const char *name)
 {
-  return startswith (name, "operator");
+  return startswith (name, CP_OPERATOR_STR);
 }
 
 
@@ -160,10 +161,10 @@ build_gdb_vtable_type (struct gdbarch *arch)
   /* We assumed in the allocation above that there were four fields.  */
   gdb_assert (field == (field_list + 4));
 
-  t = arch_type (arch, TYPE_CODE_STRUCT, offset, NULL);
+  t = arch_type (arch, TYPE_CODE_STRUCT, offset * TARGET_CHAR_BIT, NULL);
   TYPE_NFIELDS (t) = field - field_list;
   TYPE_FIELDS (t) = field_list;
-  TYPE_TAG_NAME (t) = "gdb_gnu_v3_abi_vtable";
+  TYPE_NAME (t) = "gdb_gnu_v3_abi_vtable";
   INIT_CPLUS_SPECIFIC (t);
 
   return make_type_with_address_space (t, TYPE_INSTANCE_FLAG_CODE_SPACE);
@@ -298,8 +299,9 @@ gnuv3_rtti_type (struct value *value,
   LONGEST offset_to_top;
   const char *atsign;
 
-  /* We only have RTTI for class objects.  */
-  if (TYPE_CODE (values_type) != TYPE_CODE_STRUCT)
+  /* We only have RTTI for dynamic class objects.  */
+  if (TYPE_CODE (values_type) != TYPE_CODE_STRUCT
+      || !gnuv3_dynamic_class (values_type))
     return NULL;
 
   /* Determine architecture.  */
@@ -767,9 +769,6 @@ struct value_and_voffset
   int max_voffset;
 };
 
-typedef struct value_and_voffset *value_and_voffset_p;
-DEF_VEC_P (value_and_voffset_p);
-
 /* Hash function for value_and_voffset.  */
 
 static hashval_t
@@ -792,25 +791,18 @@ eq_value_and_voffset (const void *a, const void *b)
          == value_address (ovb->value) + value_embedded_offset (ovb->value));
 }
 
-/* qsort comparison function for value_and_voffset.  */
+/* Comparison function for value_and_voffset.  */
 
-static int
-compare_value_and_voffset (const void *a, const void *b)
+static bool
+compare_value_and_voffset (const struct value_and_voffset *va,
+                          const struct value_and_voffset *vb)
 {
-  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
-    = (const struct value_and_voffset * const *) b;
-  CORE_ADDR addrb = (value_address ((*ovb)->value)
-                    + value_embedded_offset ((*ovb)->value));
-
-  if (addra < addrb)
-    return -1;
-  if (addra > addrb)
-    return 1;
-  return 0;
+  CORE_ADDR addra = (value_address (va->value)
+                    + value_embedded_offset (va->value));
+  CORE_ADDR addrb = (value_address (vb->value)
+                    + value_embedded_offset (vb->value));
+
+  return addra < addrb;
 }
 
 /* A helper function used when printing vtables.  This determines the
@@ -821,7 +813,7 @@ compare_value_and_voffset (const void *a, const void *b)
 
 static void
 compute_vtable_size (htab_t offset_hash,
-                    VEC (value_and_voffset_p) **offset_vec,
+                    std::vector<value_and_voffset *> *offset_vec,
                     struct value *value)
 {
   int i;
@@ -847,7 +839,7 @@ compute_vtable_size (htab_t offset_hash,
       current_vo->value = value;
       current_vo->max_voffset = -1;
       *slot = current_vo;
-      VEC_safe_push (value_and_voffset_p, *offset_vec, current_vo);
+      offset_vec->push_back (current_vo);
     }
 
   /* Update the value_and_voffset object with the highest vtable
@@ -914,16 +906,15 @@ print_one_vtable (struct gdbarch *gdbarch, struct value *value,
       if (gdbarch_vtable_function_descriptors (gdbarch))
        vfn = value_addr (vfn);
 
-      TRY
+      try
        {
          addr = value_as_address (vfn);
        }
-      CATCH (ex, RETURN_MASK_ERROR)
+      catch (const gdb_exception_error &ex)
        {
-         printf_filtered (_("<error: %s>"), ex.message);
+         printf_filtered (_("<error: %s>"), ex.what ());
          got_error = 1;
        }
-      END_CATCH
 
       if (!got_error)
        print_function_pointer_address (opts, gdbarch, addr, gdb_stdout);
@@ -940,11 +931,7 @@ gnuv3_print_vtable (struct value *value)
   struct type *type;
   struct value *vtable;
   struct value_print_options opts;
-  htab_t offset_hash;
-  struct cleanup *cleanup;
-  VEC (value_and_voffset_p) *result_vec = NULL;
-  struct value_and_voffset *iter;
-  int i, count;
+  int count;
 
   value = coerce_ref (value);
   type = check_typedef (value_type (value));
@@ -976,21 +963,17 @@ gnuv3_print_vtable (struct value *value)
       return;
     }
 
-  offset_hash = htab_create_alloc (1, hash_value_and_voffset,
-                                  eq_value_and_voffset,
-                                  xfree, xcalloc, xfree);
-  cleanup = make_cleanup_htab_delete (offset_hash);
-  make_cleanup (VEC_cleanup (value_and_voffset_p), &result_vec);
-
-  compute_vtable_size (offset_hash, &result_vec, value);
+  htab_up offset_hash (htab_create_alloc (1, hash_value_and_voffset,
+                                         eq_value_and_voffset,
+                                         xfree, xcalloc, xfree));
+  std::vector<value_and_voffset *> result_vec;
 
-  qsort (VEC_address (value_and_voffset_p, result_vec),
-        VEC_length (value_and_voffset_p, result_vec),
-        sizeof (value_and_voffset_p),
-        compare_value_and_voffset);
+  compute_vtable_size (offset_hash.get (), &result_vec, value);
+  std::sort (result_vec.begin (), result_vec.end (),
+            compare_value_and_voffset);
 
   count = 0;
-  for (i = 0; VEC_iterate (value_and_voffset_p, result_vec, i, iter); ++i)
+  for (value_and_voffset *iter : result_vec)
     {
       if (iter->max_voffset >= 0)
        {
@@ -1000,8 +983,6 @@ gnuv3_print_vtable (struct value *value)
          ++count;
        }
     }
-
-  do_cleanups (cleanup);
 }
 
 /* Return a GDB type representing `struct std::type_info', laid out
@@ -1043,10 +1024,10 @@ build_std_type_info_type (struct gdbarch *arch)
 
   gdb_assert (field == (field_list + 2));
 
-  t = arch_type (arch, TYPE_CODE_STRUCT, offset, NULL);
+  t = arch_type (arch, TYPE_CODE_STRUCT, offset * TARGET_CHAR_BIT, NULL);
   TYPE_NFIELDS (t) = field - field_list;
   TYPE_FIELDS (t) = field_list;
-  TYPE_TAG_NAME (t) = "gdb_gnu_v3_type_info";
+  TYPE_NAME (t) = "gdb_gnu_v3_type_info";
   INIT_CPLUS_SPECIFIC (t);
 
   return t;
@@ -1079,7 +1060,6 @@ gnuv3_get_typeid (struct value *value)
   struct type *typeinfo_type;
   struct type *type;
   struct gdbarch *gdbarch;
-  struct cleanup *cleanup;
   struct value *result;
   std::string type_name, canonical;
 
@@ -1236,7 +1216,7 @@ gnuv3_skip_trampoline (struct frame_info *frame, CORE_ADDR stop_pc)
      of the real function from the function descriptor before passing on
      the address to other layers of GDB.  */
   func_addr = gdbarch_convert_from_func_ptr_addr (gdbarch, method_stop_pc,
-                                                  &current_target);
+                                                 current_top_target ());
   if (func_addr != 0)
     method_stop_pc = func_addr;
 
@@ -1378,8 +1358,6 @@ init_gnuv3_ops (void)
   gnu_v3_abi_ops.pass_by_reference = gnuv3_pass_by_reference;
 }
 
-extern initialize_file_ftype _initialize_gnu_v3_abi; /* -Wmissing-prototypes */
-
 void
 _initialize_gnu_v3_abi (void)
 {