values.c (value_virtual_fn_field): If there is no fcontext,
authorJim Kingdon <jkingdon@engr.sgi.com>
Wed, 24 Apr 1991 01:01:09 +0000 (01:01 +0000)
committerJim Kingdon <jkingdon@engr.sgi.com>
Wed, 24 Apr 1991 01:01:09 +0000 (01:01 +0000)
then do things the way GDB 3.x did.
valops.c (search_struct_method): Add type to value_virtual_fn_field
arguments.

gdb/valops.c
gdb/values.c

index a3269ac..0284ea0 100644 (file)
@@ -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);
index 2449da5..88ceb3d 100644 (file)
@@ -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