diff options
-rw-r--r-- | gdb/valops.c | 2 | ||||
-rw-r--r-- | gdb/values.c | 19 |
2 files changed, 17 insertions, 4 deletions
diff --git a/gdb/valops.c b/gdb/valops.c index a3269ac..0284ea0 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -1041,7 +1041,7 @@ search_struct_method (name, arg1, args, offset, static_memfuncp, type) TYPE_FN_FIELD_ARGS (f, j), args)) { if (TYPE_FN_FIELD_VIRTUAL_P (f, j)) - return (value)value_virtual_fn_field (arg1, f, j); + return (value)value_virtual_fn_field (arg1, f, j, type); if (TYPE_FN_FIELD_STATIC_P (f, j) && static_memfuncp) *static_memfuncp = 1; return (value)value_fn_field (arg1, i, j); diff --git a/gdb/values.c b/gdb/values.c index 2449da5..88ceb3d 100644 --- a/gdb/values.c +++ b/gdb/values.c @@ -839,12 +839,15 @@ value_fn_field (arg1, fieldno, subfieldno) table pointer. ARG1 is side-effected in calling this function. F is the list of member functions which contains the desired virtual function. - J is an index into F which provides the desired virtual function. */ + J is an index into F which provides the desired virtual function. + + TYPE is the type in which F is located. */ value -value_virtual_fn_field (arg1, f, j) +value_virtual_fn_field (arg1, f, j, type) value arg1; struct fn_field *f; int j; + struct type *type; { /* First, get the virtual function table pointer. That comes with a strange type, so cast it to type `pointer to long' (which @@ -853,11 +856,21 @@ value_virtual_fn_field (arg1, f, j) value entry, vfn, vtbl; value vi = value_from_long (builtin_type_int, (LONGEST) TYPE_FN_FIELD_VOFFSET (f, j)); - struct type *context = lookup_pointer_type (TYPE_FN_FIELD_FCONTEXT (f, j)); + struct type *fcontext = TYPE_FN_FIELD_FCONTEXT (f, j); + struct type *context; + 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. + This won't work right for multiple inheritance, but at least we + should do as well as GDB 3.x did. */ + fcontext = TYPE_VPTR_BASETYPE (type); + context = lookup_pointer_type (fcontext); + /* Now context is a pointer to the basetype containing the vtbl. */ if (TYPE_TARGET_TYPE (context) != VALUE_TYPE (arg1)) arg1 = value_ind (value_cast (context, value_addr (arg1))); context = VALUE_TYPE (arg1); + /* Now context is the basetype containing the vtbl. */ /* This type may have been defined before its virtual function table was. If so, fill in the virtual function table entry for the |