Adjust byte order variable display/change if DW_AT_endianity is present.
[deliverable/binutils-gdb.git] / gdb / gnu-v3-abi.c
index 0e037e655599d34b6ceefab73081b65abd7d720e..2a5486c8a10e39426c2b70cea52981b5f5eba85b 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.  */
@@ -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));
@@ -1183,8 +1158,8 @@ gnuv3_get_typename_from_type_info (struct value *type_info_ptr)
   /* 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
@@ -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.028755 seconds and 4 git commands to generate.