/* Abstraction of GNU v2 abi.
- Copyright (C) 2001, 2002, 2003, 2005, 2007, 2008
+ Copyright (C) 2001, 2002, 2003, 2005, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Contributed by Daniel Berlin <dberlin@redhat.com>
#include "demangle.h"
#include "cp-abi.h"
#include "cp-support.h"
-#include "gnu-v2-abi.h"
#include <ctype.h>
{
struct value *arg1 = *arg1p;
struct type *type1 = check_typedef (value_type (arg1));
-
-
struct type *entry_type;
/* First, get the virtual function table pointer. That comes
with a strange type, so cast it to type `pointer to long' (which
struct value *entry;
struct value *vfn;
struct value *vtbl;
- struct value *vi = value_from_longest (builtin_type_int,
- (LONGEST) TYPE_FN_FIELD_VOFFSET (f, j));
+ LONGEST vi = (LONGEST) TYPE_FN_FIELD_VOFFSET (f, j);
struct type *fcontext = TYPE_FN_FIELD_FCONTEXT (f, j);
struct type *context;
+ struct type *context_vptr_basetype;
+ int context_vptr_fieldno;
+
if (fcontext == NULL)
/* We don't have an fcontext (e.g. the program was compiled with
g++ version 1). Try to get the vtbl from the TYPE_VPTR_BASETYPE.
if (TYPE_TARGET_TYPE (context) != type1)
{
struct value *tmp = value_cast (context, value_addr (arg1));
+
arg1 = value_ind (tmp);
type1 = check_typedef (value_type (arg1));
}
/* This type may have been defined before its virtual function table
was. If so, fill in the virtual function table entry for the
type now. */
- if (TYPE_VPTR_FIELDNO (context) < 0)
- fill_in_vptr_fieldno (context);
+ context_vptr_fieldno = get_vptr_fieldno (context, &context_vptr_basetype);
+ /* FIXME: What to do if vptr_fieldno is still -1? */
/* The virtual function table is now an array of structures
which have the form { int16 offset, delta; void *pfn; }. */
- vtbl = value_primitive_field (arg1, 0, TYPE_VPTR_FIELDNO (context),
- TYPE_VPTR_BASETYPE (context));
+ vtbl = value_primitive_field (arg1, 0, context_vptr_fieldno,
+ context_vptr_basetype);
/* With older versions of g++, the vtbl field pointed to an array
of structures. Nowadays it points directly to the structure. */
else
{
/* Handle the case where the vtbl field points directly to a structure. */
- vtbl = value_add (vtbl, vi);
+ vtbl = value_ptradd (vtbl, vi);
entry = value_ind (vtbl);
}
{
struct type *known_type;
struct type *rtti_type;
- CORE_ADDR coreptr;
- struct value *vp;
- long top_offset = 0;
- char rtti_type_name[256];
CORE_ADDR vtbl;
struct minimal_symbol *minsym;
- struct symbol *sym;
char *demangled_name, *p;
struct type *btype;
+ struct type *known_type_vptr_basetype;
+ int known_type_vptr_fieldno;
if (full)
*full = 0;
the type info functions, which are always right. Deal with it
until then. */
- /* If the type has no vptr fieldno, try to get it filled in */
- if (TYPE_VPTR_FIELDNO(known_type) < 0)
- fill_in_vptr_fieldno(known_type);
+ /* Try to get the vptr basetype, fieldno. */
+ known_type_vptr_fieldno = get_vptr_fieldno (known_type,
+ &known_type_vptr_basetype);
- /* If we still can't find one, give up */
- if (TYPE_VPTR_FIELDNO(known_type) < 0)
+ /* If we can't find it, give up. */
+ if (known_type_vptr_fieldno < 0)
return NULL;
/* Make sure our basetype and known type match, otherwise, cast
so we can get at the vtable properly.
*/
- btype = TYPE_VPTR_BASETYPE (known_type);
+ btype = known_type_vptr_basetype;
CHECK_TYPEDEF (btype);
if (btype != known_type )
{
we'd waste a bunch of time figuring out we already know the type.
Besides, we don't care about the type, just the actual pointer
*/
- if (VALUE_ADDRESS (value_field (v, TYPE_VPTR_FIELDNO (known_type))) == 0)
+ if (value_address (value_field (v, known_type_vptr_fieldno)) == 0)
return NULL;
- vtbl=value_as_address(value_field(v,TYPE_VPTR_FIELDNO(known_type)));
+ vtbl = value_as_address (value_field (v, known_type_vptr_fieldno));
/* Try to find a symbol that is the vtable */
minsym=lookup_minimal_symbol_by_pc(vtbl);
if (minsym==NULL
- || (demangled_name=DEPRECATED_SYMBOL_NAME (minsym))==NULL
+ || (demangled_name=SYMBOL_LINKAGE_NAME (minsym))==NULL
|| !is_vtable_name (demangled_name))
return NULL;
-1 is returned on error. */
-int
+static int
gnuv2_baseclass_offset (struct type *type, int index,
const bfd_byte *valaddr, CORE_ADDR address)
{
if (vb_match (type, i, basetype))
{
CORE_ADDR addr
- = unpack_pointer (TYPE_FIELD_TYPE (type, i),
- valaddr + (TYPE_FIELD_BITPOS (type, i) / 8));
+ = unpack_pointer (TYPE_FIELD_TYPE (type, i),
+ valaddr + (TYPE_FIELD_BITPOS (type, i) / 8));
return addr - (LONGEST) address;
}
for (i = index + 1; i < n_baseclasses; i++)
{
int boffset =
- baseclass_offset (type, i, valaddr, address);
+ baseclass_offset (type, i, valaddr, address);
+
if (boffset)
return boffset;
}