/* Abstraction of GNU v2 abi.
- Copyright (C) 2001, 2002, 2003, 2005, 2007, 2008, 2009, 2010, 2011
- Free Software Foundation, Inc.
+ Copyright (C) 2001-2016 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;
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
{
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
static int
gnuv2_is_operator_name (const char *name)
{
- return strncmp (name, "operator", 8) == 0;
+ return startswith (name, "operator");
}
\f
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;
/* 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
/* 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);
/* 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=MSYMBOL_LINKAGE_NAME (minsym.minsym))==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';
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;
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, int embedded_offset,
+ CORE_ADDR address, const struct value *val)
{
struct type *basetype = TYPE_BASECLASS (type, 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;
+ int field_offset;
+ int field_length;
+ CORE_ADDR addr;
- return addr - (LONGEST) address;
+ field_type = check_typedef (TYPE_FIELD_TYPE (type, i));
+ field_offset = TYPE_FIELD_BITPOS (type, i) / 8;
+ field_length = TYPE_LENGTH (field_type);
+
+ 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. */
{
init_gnuv2_ops ();
register_cp_abi (&gnu_v2_abi_ops);
- set_cp_abi_as_auto_default (gnu_v2_abi_ops.shortname);
}