i386: Align branches within a fixed boundary
[deliverable/binutils-gdb.git] / gdb / gnu-v2-abi.c
index effac401c2786d56bd73c7da3edf01bc17f039b8..000f82579bd0aa23f64b900ca5e44bcbc5b655e0 100644 (file)
@@ -1,7 +1,6 @@
 /* Abstraction of GNU v2 abi.
 
-   Copyright (C) 2001, 2002, 2003, 2005, 2007, 2008, 2009, 2010, 2011
-   Free Software Foundation, Inc.
+   Copyright (C) 2001-2019 Free Software Foundation, Inc.
 
    Contributed by Daniel Berlin <dberlin@redhat.com>
 
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
-#include "gdb_string.h"
 #include "symtab.h"
 #include "gdbtypes.h"
 #include "value.h"
 #include "demangle.h"
+#include "gdb-demangle.h"
 #include "cp-abi.h"
 #include "cp-support.h"
-
 #include <ctype.h>
 
 struct cp_abi_ops gnu_v2_abi_ops;
@@ -39,10 +37,10 @@ static enum dtor_kinds
 gnuv2_is_destructor_name (const char *name)
 {
   if ((name[0] == '_' && is_cplus_marker (name[1]) && name[2] == '_')
-      || strncmp (name, "__dt__", 6) == 0)
+      || startswith (name, "__dt__"))
     return complete_object_dtor;
   else
-    return 0;
+    return (enum dtor_kinds) 0;
 }
 
 static enum ctor_kinds
@@ -50,10 +48,10 @@ gnuv2_is_constructor_name (const char *name)
 {
   if ((name[0] == '_' && name[1] == '_'
        && (isdigit (name[2]) || strchr ("Qt", name[2])))
-      || strncmp (name, "__ct__", 6) == 0)
+      || startswith (name, "__ct__"))
     return complete_object_ctor;
   else
-    return 0;
+    return (enum ctor_kinds) 0;
 }
 
 static int
@@ -70,7 +68,7 @@ gnuv2_is_vtable_name (const char *name)
 static int
 gnuv2_is_operator_name (const char *name)
 {
-  return strncmp (name, "operator", 8) == 0;
+  return startswith (name, CP_OPERATOR_STR);
 }
 
 \f
@@ -185,13 +183,14 @@ gnuv2_virtual_fn_field (struct value **arg1p, struct fn_field * f, int j,
 
 
 static struct type *
-gnuv2_value_rtti_type (struct value *v, int *full, int *top, int *using_enc)
+gnuv2_value_rtti_type (struct value *v, int *full, LONGEST *top, int *using_enc)
 {
   struct type *known_type;
   struct type *rtti_type;
   CORE_ADDR vtbl;
-  struct minimal_symbol *minsym;
+  struct bound_minimal_symbol minsym;
   char *demangled_name, *p;
+  const char *linkage_name;
   struct type *btype;
   struct type *known_type_vptr_basetype;
   int known_type_vptr_fieldno;
@@ -205,9 +204,9 @@ gnuv2_value_rtti_type (struct value *v, int *full, int *top, int *using_enc)
 
   /* Get declared type.  */
   known_type = value_type (v);
-  CHECK_TYPEDEF (known_type);
+  known_type = check_typedef (known_type);
   /* RTTI works only or class objects.  */
-  if (TYPE_CODE (known_type) != TYPE_CODE_CLASS)
+  if (TYPE_CODE (known_type) != TYPE_CODE_STRUCT)
     return NULL;
 
   /* Plan on this changing in the future as i get around to setting
@@ -226,7 +225,7 @@ gnuv2_value_rtti_type (struct value *v, int *full, int *top, int *using_enc)
   /* Make sure our basetype and known type match, otherwise, cast
      so we can get at the vtable properly.  */
   btype = known_type_vptr_basetype;
-  CHECK_TYPEDEF (btype);
+  btype = check_typedef (btype);
   if (btype != known_type )
     {
       v = value_cast (btype, v);
@@ -243,13 +242,13 @@ gnuv2_value_rtti_type (struct value *v, int *full, int *top, int *using_enc)
 
   /* Try to find a symbol that is the vtable.  */
   minsym=lookup_minimal_symbol_by_pc(vtbl);
-  if (minsym==NULL
-      || (demangled_name=SYMBOL_LINKAGE_NAME (minsym))==NULL
-      || !is_vtable_name (demangled_name))
+  if (minsym.minsym==NULL
+      || (linkage_name=minsym.minsym->linkage_name ())==NULL
+      || !is_vtable_name (linkage_name))
     return NULL;
 
   /* If we just skip the prefix, we get screwed by namespaces.  */
-  demangled_name=cplus_demangle(demangled_name,DMGL_PARAMS|DMGL_ANSI);
+  demangled_name=gdb_demangle(linkage_name,DMGL_PARAMS|DMGL_ANSI);
   p = strchr (demangled_name, ' ');
   if (p)
     *p = '\0';
@@ -295,8 +294,8 @@ static int
 vb_match (struct type *type, int index, struct type *basetype)
 {
   struct type *fieldtype;
-  char *name = TYPE_FIELD_NAME (type, index);
-  char *field_class_name = NULL;
+  const char *name = TYPE_FIELD_NAME (type, index);
+  const char *field_class_name = NULL;
 
   if (*name != '_')
     return 0;
@@ -334,17 +333,15 @@ vb_match (struct type *type, int index, struct type *basetype)
   return 0;
 }
 
-/* Compute the offset of the baseclass which is
-   the INDEXth baseclass of class TYPE,
-   for value at VALADDR (in host) at ADDRESS (in target).
-   The result is the offset of the baseclass value relative
-   to (the address of)(ARG) + OFFSET.
-
-   -1 is returned on error.  */
+/* Compute the offset of the baseclass which is the INDEXth baseclass
+   of class TYPE, for value at VALADDR (in host) at ADDRESS (in
+   target).  The result is the offset of the baseclass value relative
+   to (the address of)(ARG) + OFFSET.  */
 
 static int
 gnuv2_baseclass_offset (struct type *type, int index,
-                       const bfd_byte *valaddr, CORE_ADDR address)
+                       const bfd_byte *valaddr, LONGEST embedded_offset,
+                       CORE_ADDR address, const struct value *val)
 {
   struct type *basetype = TYPE_BASECLASS (type, index);
 
@@ -360,24 +357,41 @@ gnuv2_baseclass_offset (struct type *type, int index,
        {
          if (vb_match (type, i, basetype))
            {
-             CORE_ADDR addr
-               = unpack_pointer (TYPE_FIELD_TYPE (type, i),
-                                 valaddr + (TYPE_FIELD_BITPOS (type, i) / 8));
+             struct type *field_type;
+             LONGEST field_offset;
+             int field_length;
+             CORE_ADDR addr;
+
+             field_type = check_typedef (TYPE_FIELD_TYPE (type, i));
+             field_offset = TYPE_FIELD_BITPOS (type, i) / 8;
+             field_length = TYPE_LENGTH (field_type);
 
-             return addr - (LONGEST) address;
+             if (!value_bytes_available (val, embedded_offset + field_offset,
+                                         field_length))
+               throw_error (NOT_AVAILABLE_ERROR,
+                            _("Virtual baseclass pointer is not available"));
+
+             addr = unpack_pointer (field_type,
+                                    valaddr + embedded_offset + field_offset);
+
+             return addr - (LONGEST) address + embedded_offset;
            }
        }
       /* Not in the fields, so try looking through the baseclasses.  */
       for (i = index + 1; i < n_baseclasses; i++)
        {
+         /* Don't go through baseclass_offset, as that wraps
+            exceptions, thus, inner exceptions would be wrapped more
+            than once.  */
          int boffset =
-           baseclass_offset (type, i, valaddr, address);
+           gnuv2_baseclass_offset (type, i, valaddr,
+                                   embedded_offset, address, val);
 
          if (boffset)
            return boffset;
        }
-      /* Not found.  */
-      return -1;
+
+      error (_("Baseclass offset not found"));
     }
 
   /* Baseclass is easily computed.  */
@@ -399,12 +413,9 @@ init_gnuv2_ops (void)
   gnu_v2_abi_ops.baseclass_offset = gnuv2_baseclass_offset;
 }
 
-extern initialize_file_ftype _initialize_gnu_v2_abi; /* -Wmissing-prototypes */
-
 void
 _initialize_gnu_v2_abi (void)
 {
   init_gnuv2_ops ();
   register_cp_abi (&gnu_v2_abi_ops);
-  set_cp_abi_as_auto_default (gnu_v2_abi_ops.shortname);
 }
This page took 0.032667 seconds and 4 git commands to generate.