aboutsummaryrefslogtreecommitdiff
path: root/gdb/gnu-v2-abi.c
diff options
context:
space:
mode:
authorDoug Evans <dje@google.com>2008-02-03 22:13:30 +0000
committerDoug Evans <dje@google.com>2008-02-03 22:13:30 +0000
commit81fe80802cc3746401e3393b6edc884151c83881 (patch)
tree4ccb189b615a0da1f09ebd1e5a9cdf9cb2905da0 /gdb/gnu-v2-abi.c
parentcda4ce5a1080f6a6e3143cae4534fe60214365d2 (diff)
downloadgdb-81fe80802cc3746401e3393b6edc884151c83881.zip
gdb-81fe80802cc3746401e3393b6edc884151c83881.tar.gz
gdb-81fe80802cc3746401e3393b6edc884151c83881.tar.bz2
PR 2384
* gdbtypes.c (get_vptr_fieldno): Renamed from fill_in_vptr_fieldno. Return basetype, fieldno if found. All callers updated. Don't cache TYPE_VPTR_FIELDNO, TYPE_VPTR_BASETYPE if from different objfile. * gdbtypes.h (get_vptr_fieldno): Renamed from fill_in_vptr_fieldno. * symfile.h (fill_in_vptr_fieldno): Delete. * gdb.cp/gdb2384.exp: New file. * gdb.cp/gdb2384.cc: New file. * gdb.cp/gdb2384-base.h: New file. * gdb.cp/gdb2384-base.cc: New file.
Diffstat (limited to 'gdb/gnu-v2-abi.c')
-rw-r--r--gdb/gnu-v2-abi.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/gdb/gnu-v2-abi.c b/gdb/gnu-v2-abi.c
index 6623813..9cc34e6 100644
--- a/gdb/gnu-v2-abi.c
+++ b/gdb/gnu-v2-abi.c
@@ -89,8 +89,6 @@ gnuv2_virtual_fn_field (struct value **arg1p, struct fn_field * f, int j,
{
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
@@ -103,6 +101,9 @@ gnuv2_virtual_fn_field (struct value **arg1p, struct fn_field * f, int j,
(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.
@@ -124,13 +125,13 @@ gnuv2_virtual_fn_field (struct value **arg1p, struct fn_field * f, int j,
/* 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. */
@@ -195,6 +196,8 @@ gnuv2_value_rtti_type (struct value *v, int *full, int *top, int *using_enc)
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;
@@ -215,18 +218,18 @@ gnuv2_value_rtti_type (struct value *v, int *full, int *top, int *using_enc)
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 )
{
@@ -239,10 +242,10 @@ gnuv2_value_rtti_type (struct value *v, int *full, int *top, int *using_enc)
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);