ubsan: visium: left shift cannot be represented in type 'int'
[deliverable/binutils-gdb.git] / gdb / gnu-v3-abi.c
index 0e037e655599d34b6ceefab73081b65abd7d720e..d630ec07b11175e8a4610bf79e88a5d5c569ad5b 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,8 @@
 #include "valprint.h"
 #include "c-lang.h"
 #include "typeprint.h"
+#include <algorithm>
+#include "cli/cli-style.h"
 
 static struct cp_abi_ops gnu_v3_abi_ops;
 
@@ -45,7 +47,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 +162,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 +300,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.  */
@@ -325,7 +328,7 @@ gnuv3_rtti_type (struct value *value,
      If we didn't like this approach, we could instead look in the
      type_info object itself to get the class name.  But this way
      should work just as well, and doesn't read target memory.  */
-  vtable_symbol_name = MSYMBOL_DEMANGLED_NAME (vtable_symbol);
+  vtable_symbol_name = vtable_symbol->demangled_name ();
   if (vtable_symbol_name == NULL
       || !startswith (vtable_symbol_name, "vtable for "))
     {
@@ -390,7 +393,7 @@ gnuv3_get_virtual_fn (struct gdbarch *gdbarch, struct value *container,
   /* If this architecture uses function descriptors directly in the vtable,
      then the address of the vtable entry is actually a "function pointer"
      (i.e. points to the descriptor).  We don't need to scale the index
-     by the size of a function descriptor; GCC does that before outputing
+     by the size of a function descriptor; GCC does that before outputting
      debug information.  */
   if (gdbarch_vtable_function_descriptors (gdbarch))
     vfn = value_addr (vfn);
@@ -675,7 +678,7 @@ gnuv3_make_method_ptr (struct type *type, gdb_byte *contents,
 {
   struct gdbarch *gdbarch = get_type_arch (type);
   int size = TYPE_LENGTH (builtin_type (gdbarch)->builtin_data_ptr);
-  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  enum bfd_endian byte_order = type_byte_order (type);
 
   /* FIXME drow/2006-12-24: The adjustment of "this" is currently
      always zero, since the method pointer is of the correct type.
@@ -767,9 +770,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 +792,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 +814,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 +840,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 +907,16 @@ 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);
+         fprintf_styled (gdb_stdout, metadata_style.style (),
+                         _("<error: %s>"), ex.what ());
          got_error = 1;
        }
-      END_CATCH
 
       if (!got_error)
        print_function_pointer_address (opts, gdbarch, addr, gdb_stdout);
@@ -940,11 +933,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 +965,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 +985,6 @@ gnuv3_print_vtable (struct value *value)
          ++count;
        }
     }
-
-  do_cleanups (cleanup);
 }
 
 /* Return a GDB type representing `struct std::type_info', laid out
@@ -1043,10 +1026,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,9 +1062,8 @@ gnuv3_get_typeid (struct value *value)
   struct type *typeinfo_type;
   struct type *type;
   struct gdbarch *gdbarch;
-  struct cleanup *cleanup;
   struct value *result;
-  char *type_name, *canonical;
+  std::string 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
@@ -1101,20 +1083,16 @@ gnuv3_get_typeid (struct value *value)
   gdbarch = get_type_arch (type);
 
   type_name = type_to_string (type);
-  if (type_name == NULL)
+  if (type_name.empty ())
     error (_("cannot find typeinfo for unnamed type"));
-  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 (type_name);
-  if (canonical != NULL)
-    {
-      make_cleanup (xfree, canonical);
-      type_name = canonical;
-    }
+  canonical = cp_canonicalize_string (type_name.c_str ());
+  if (!canonical.empty ())
+    type_name = canonical;
 
   typeinfo_type = gnuv3_get_typeid_type (gdbarch);
 
@@ -1129,33 +1107,30 @@ 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'"), type_name);
+       error (_("cannot find typeinfo for object of type '%s'"),
+              type_name.c_str ());
       typeinfo_value = value_field (vtable, vtable_field_type_info);
       result = value_ind (value_cast (make_pointer_type (typeinfo_type, NULL),
                                      typeinfo_value));
     }
   else
     {
-      char *sym_name;
-      struct bound_minimal_symbol minsym;
-
-      sym_name = concat ("typeinfo for ", type_name, (char *) NULL);
-      make_cleanup (xfree, sym_name);
-      minsym = lookup_minimal_symbol (sym_name, NULL, NULL);
+      std::string sym_name = std::string ("typeinfo for ") + type_name;
+      bound_minimal_symbol minsym
+       = lookup_minimal_symbol (sym_name.c_str (), NULL, NULL);
 
       if (minsym.minsym == NULL)
-       error (_("could not find typeinfo symbol for '%s'"), type_name);
+       error (_("could not find typeinfo symbol for '%s'"), type_name.c_str ());
 
       result = value_at_lazy (typeinfo_type, BMSYMBOL_VALUE_ADDRESS (minsym));
     }
 
-  do_cleanups (cleanup);
   return result;
 }
 
 /* Implement the 'get_typename_from_type_info' method.  */
 
-static char *
+static std::string
 gnuv3_get_typename_from_type_info (struct value *type_info_ptr)
 {
   struct gdbarch *gdbarch = get_type_arch (value_type (type_info_ptr));
@@ -1173,18 +1148,18 @@ gnuv3_get_typename_from_type_info (struct value *type_info_ptr)
 
 #define TYPEINFO_PREFIX "typeinfo for "
 #define TYPEINFO_PREFIX_LEN (sizeof (TYPEINFO_PREFIX) - 1)
-  symname = MSYMBOL_DEMANGLED_NAME (typeinfo_sym.minsym);
+  symname = typeinfo_sym.minsym->demangled_name ();
   if (symname == NULL || strncmp (symname, TYPEINFO_PREFIX,
                                  TYPEINFO_PREFIX_LEN))
     error (_("typeinfo symbol '%s' has unexpected name"),
-          MSYMBOL_LINKAGE_NAME (typeinfo_sym.minsym));
+          typeinfo_sym.minsym->linkage_name ());
   class_name = symname + TYPEINFO_PREFIX_LEN;
 
   /* Strip off @plt and version suffixes.  */
   atsign = strchr (class_name, '@');
   if (atsign != NULL)
-    return savestring (class_name, atsign - class_name);
-  return xstrdup (class_name);
+    return std::string (class_name, atsign - class_name);
+  return class_name;
 }
 
 /* Implement the 'get_type_from_type_info' method.  */
@@ -1192,28 +1167,14 @@ 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 *type_name;
-  struct cleanup *cleanup;
-  struct value *type_val;
-  struct expression *expr;
-  struct type *result;
-
-  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 (type_name);
-  make_cleanup (xfree, expr);
-
-  type_val = evaluate_type (expr);
-  result = value_type (type_val);
-
-  do_cleanups (cleanup);
-  return result;
+  std::string type_name = gnuv3_get_typename_from_type_info (type_info_ptr);
+  expression_up expr (parse_expression (type_name.c_str ()));
+  struct value *type_val = evaluate_type (expr.get ());
+  return value_type (type_val);
 }
 
 /* Determine if we are currently in a C++ thunk.  If so, get the address
@@ -1241,7 +1202,7 @@ gnuv3_skip_trampoline (struct frame_info *frame, CORE_ADDR stop_pc)
   /* The symbol's demangled name should be something like "virtual
      thunk to FUNCTION", where FUNCTION is the name of the function
      being thunked to.  */
-  thunk_name = MSYMBOL_DEMANGLED_NAME (thunk_sym.minsym);
+  thunk_name = thunk_sym.minsym->demangled_name ();
   if (thunk_name == NULL || strstr (thunk_name, " thunk to ") == NULL)
     return 0;
 
@@ -1257,7 +1218,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;
 
@@ -1399,8 +1360,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)
 {
This page took 0.032663 seconds and 4 git commands to generate.