]> Git Repo - binutils.git/blobdiff - gdb/valops.c
remove parentdir support
[binutils.git] / gdb / valops.c
index 8135cde2b58ff3f916293537647e99641dbcf62b..2180c03baa2863bf9f789e5d30bd3310c2677219 100644 (file)
@@ -25,11 +25,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "inferior.h"
 #include "gdbcore.h"
 #include "target.h"
+#include "demangle.h"
 
 #include <errno.h>
 
 /* Local functions.  */
 
+static int
+typecmp PARAMS ((int staticp, struct type *t1[], value t2[]));
+
 static CORE_ADDR
 find_function_addr PARAMS ((value, struct type **));
 
@@ -43,13 +47,67 @@ static value
 search_struct_field PARAMS ((char *, value, int, struct type *, int));
 
 static value
-search_struct_method PARAMS ((char *, value, value *, int, int *,
+search_struct_method PARAMS ((char *, value *, value *, int, int *,
                              struct type *));
 
 static int
 check_field_in PARAMS ((struct type *, const char *));
 
+static CORE_ADDR
+allocate_space_in_inferior PARAMS ((int));
+
 \f
+/* Allocate NBYTES of space in the inferior using the inferior's malloc
+   and return a value that is a pointer to the allocated space. */
+
+static CORE_ADDR
+allocate_space_in_inferior (len)
+     int len;
+{
+  register value val;
+  register struct symbol *sym;
+  struct minimal_symbol *msymbol;
+  struct type *type;
+  value blocklen;
+  LONGEST maddr;
+
+  /* Find the address of malloc in the inferior.  */
+
+  sym = lookup_symbol ("malloc", 0, VAR_NAMESPACE, 0, NULL);
+  if (sym != NULL)
+    {
+      if (SYMBOL_CLASS (sym) != LOC_BLOCK)
+       {
+         error ("\"malloc\" exists in this program but is not a function.");
+       }
+      val = value_of_variable (sym);
+    }
+  else
+    {
+      msymbol = lookup_minimal_symbol ("malloc", (struct objfile *) NULL);
+      if (msymbol != NULL)
+       {
+         type = lookup_pointer_type (builtin_type_char);
+         type = lookup_function_type (type);
+         type = lookup_pointer_type (type);
+         maddr = (LONGEST) SYMBOL_VALUE_ADDRESS (msymbol);
+         val = value_from_longest (type, maddr);
+       }
+      else
+       {
+         error ("evaluation of this expression requires the program to have a function \"malloc\".");
+       }
+    }
+
+  blocklen = value_from_longest (builtin_type_int, (LONGEST) len);
+  val = call_function_by_hand (val, 1, &blocklen);
+  if (value_logical_not (val))
+    {
+      error ("No memory available to program.");
+    }
+  return (value_as_long (val));
+}
+
 /* Cast value ARG2 to type TYPE and return as a value.
    More general than a C cast: accepts any two types of the same length,
    and if ARG2 is an lvalue it can be cast into anything at all.  */
@@ -130,7 +188,7 @@ value_zero (type, lv)
 {
   register value val = allocate_value (type);
 
-  (void) memset (VALUE_CONTENTS (val), 0, TYPE_LENGTH (type));
+  memset (VALUE_CONTENTS (val), 0, TYPE_LENGTH (type));
   VALUE_LVAL (val) = lv;
 
   return val;
@@ -234,7 +292,7 @@ value_assign (toval, fromval)
        fromval = value_cast (REGISTER_VIRTUAL_TYPE (regno), fromval);
       memcpy (virtual_buffer, VALUE_CONTENTS (fromval),
             REGISTER_VIRTUAL_SIZE (regno));
-      target_convert_from_virtual (regno, virtual_buffer, raw_buffer);
+      REGISTER_CONVERT_TO_RAW (regno, virtual_buffer, raw_buffer);
       use_buffer = REGISTER_RAW_SIZE (regno);
     }
 
@@ -333,10 +391,10 @@ value_assign (toval, fromval)
                        (int) value_as_long (fromval),
                        VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
        else if (use_buffer)
-         (void) memcpy (buffer + byte_offset, raw_buffer, use_buffer);
+         memcpy (buffer + byte_offset, raw_buffer, use_buffer);
        else
-         (void) memcpy (buffer + byte_offset, VALUE_CONTENTS (fromval),
-                        TYPE_LENGTH (type));
+         memcpy (buffer + byte_offset, VALUE_CONTENTS (fromval),
+                 TYPE_LENGTH (type));
 
        /* Copy it back.  */
        for ((regno = VALUE_FRAME_REGNUM (toval) + reg_offset,
@@ -379,9 +437,9 @@ value_assign (toval, fromval)
     }
 
   val = allocate_value (type);
-  (void) memcpy (val, toval, VALUE_CONTENTS_RAW (val) - (char *) val);
-  (void) memcpy (VALUE_CONTENTS_RAW (val), VALUE_CONTENTS (fromval),
-                TYPE_LENGTH (type));
+  memcpy (val, toval, VALUE_CONTENTS_RAW (val) - (char *) val);
+  memcpy (VALUE_CONTENTS_RAW (val), VALUE_CONTENTS (fromval),
+         TYPE_LENGTH (type));
   VALUE_TYPE (val) = type;
   
   return val;
@@ -420,13 +478,32 @@ value_of_variable (var)
 
   val = read_var_value (var, (FRAME) 0);
   if (val == 0)
-    error ("Address of symbol \"%s\" is unknown.", SYMBOL_NAME (var));
+    error ("Address of symbol \"%s\" is unknown.", SYMBOL_SOURCE_NAME (var));
   return val;
 }
 
-/* Given a value which is an array, return a value which is
-   a pointer to its first (actually, zeroth) element. 
-   FIXME, this should be subtracting the array's lower bound. */
+/* Given a value which is an array, return a value which is a pointer to its
+   first element, regardless of whether or not the array has a nonzero lower
+   bound.
+
+   FIXME:  A previous comment here indicated that this routine should be
+   substracting the array's lower bound.  It's not clear to me that this
+   is correct.  Given an array subscripting operation, it would certainly
+   work to do the adjustment here, essentially computing:
+
+   (&array[0] - (lowerbound * sizeof array[0])) + (index * sizeof array[0])
+
+   However I believe a more appropriate and logical place to account for
+   the lower bound is to do so in value_subscript, essentially computing:
+
+   (&array[0] + ((index - lowerbound) * sizeof array[0]))
+
+   As further evidence consider what would happen with operations other
+   than array subscripting, where the caller would get back a value that
+   had an address somewhere before the actual first element of the array,
+   and the information about the lower bound would be lost because of
+   the coercion to pointer type.
+   */
 
 value
 value_coerce_array (arg1)
@@ -590,6 +667,13 @@ value_arg_coerce (arg)
   register struct type *type;
 
   COERCE_ENUM (arg);
+#if 1  /* FIXME:  This is only a temporary patch.  -fnf */
+  if (VALUE_REPEATED (arg)
+      || TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_ARRAY)
+    arg = value_coerce_array (arg);
+  if (TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_FUNC)
+    arg = value_coerce_function (arg);
+#endif
 
   type = VALUE_TYPE (arg);
 
@@ -704,6 +788,7 @@ call_function_by_hand (function, nargs, args)
   struct cleanup *old_chain;
   CORE_ADDR funaddr;
   int using_gcc;
+  CORE_ADDR real_pc;
 
   if (!target_has_execution)
     noprocess();
@@ -742,11 +827,18 @@ call_function_by_hand (function, nargs, args)
 
   /* Create a call sequence customized for this function
      and the number of arguments for it.  */
-  (void) memcpy (dummy1, dummy, sizeof dummy);
+  memcpy (dummy1, dummy, sizeof dummy);
   for (i = 0; i < sizeof dummy / sizeof (REGISTER_TYPE); i++)
     SWAP_TARGET_AND_HOST (&dummy1[i], sizeof (REGISTER_TYPE));
+
+#ifdef GDB_TARGET_IS_HPPA
+  real_pc = FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args,
+                           value_type, using_gcc);
+#else
   FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args,
                  value_type, using_gcc);
+  real_pc = start_sp;
+#endif
 
 #if CALL_DUMMY_LOCATION == ON_STACK
   write_memory (start_sp, (char *)dummy1, sizeof dummy);
@@ -891,7 +983,7 @@ call_function_by_hand (function, nargs, args)
     /* Execute the stack dummy routine, calling FUNCTION.
        When it is done, discard the empty frame
        after storing the contents of all regs into retbuf.  */
-    run_stack_dummy (start_sp + CALL_DUMMY_START_OFFSET, retbuf);
+    run_stack_dummy (real_pc + CALL_DUMMY_START_OFFSET, retbuf);
 
     do_cleanups (old_chain);
 
@@ -908,78 +1000,147 @@ call_function_by_hand (function, nargs, args)
   error ("Cannot invoke functions on this machine.");
 }
 #endif /* no CALL_DUMMY.  */
+
 \f
-/* Create a value for a string constant:
-   Call the function malloc in the inferior to get space for it,
-   then copy the data into that space
-   and then return the address with type char *.
-   PTR points to the string constant data; LEN is number of characters.  */
+/* Create a value for an array by allocating space in the inferior, copying
+   the data into that space, and then setting up an array value.
+
+   The array bounds are set from LOWBOUND and HIGHBOUND, and the array is
+   populated from the values passed in ELEMVEC.
+
+   The element type of the array is inherited from the type of the
+   first element, and all elements must have the same size (though we
+   don't currently enforce any restriction on their types). */
 
 value
-value_string (ptr, len)
-     char *ptr;
-     int len;
+value_array (lowbound, highbound, elemvec)
+     int lowbound;
+     int highbound;
+     value *elemvec;
 {
-  register value val;
-  register struct symbol *sym;
-  value blocklen;
-  register char *copy = (char *) alloca (len + 1);
-  char *i = ptr;
-  register char *o = copy, *ibeg = ptr;
-  register int c;
+  int nelem;
+  int idx;
+  int typelength;
+  value val;
+  struct type *rangetype;
+  struct type *arraytype;
+  CORE_ADDR addr;
 
-  /* Copy the string into COPY, processing escapes.
-     We could not conveniently process them in the parser
-     because the string there wants to be a substring of the input.  */
+  /* Validate that the bounds are reasonable and that each of the elements
+     have the same size. */
 
-  while (i - ibeg < len)
+  nelem = highbound - lowbound + 1;
+  if (nelem <= 0)
     {
-      c = *i++;
-      if (c == '\\')
+      error ("bad array bounds (%d, %d)", lowbound, highbound);
+    }
+  typelength = TYPE_LENGTH (VALUE_TYPE (elemvec[0]));
+  for (idx = 0; idx < nelem; idx++)
+    {
+      if (TYPE_LENGTH (VALUE_TYPE (elemvec[idx])) != typelength)
        {
-         c = parse_escape (&i);
-         if (c == -1)
-           continue;
+         error ("array elements must all be the same size");
        }
-      *o++ = c;
     }
-  *o = 0;
-
-  /* Get the length of the string after escapes are processed.  */
 
-  len = o - copy;
+  /* Allocate space to store the array in the inferior, and then initialize
+     it by copying in each element.  FIXME:  Is it worth it to create a
+     local buffer in which to collect each value and then write all the
+     bytes in one operation? */
 
-  /* Find the address of malloc in the inferior.  */
-
-  sym = lookup_symbol ("malloc", 0, VAR_NAMESPACE, 0, NULL);
-  if (sym != 0)
-    {
-      if (SYMBOL_CLASS (sym) != LOC_BLOCK)
-       error ("\"malloc\" exists in this program but is not a function.");
-      val = value_of_variable (sym);
-    }
-  else
+  addr = allocate_space_in_inferior (nelem * typelength);
+  for (idx = 0; idx < nelem; idx++)
     {
-      struct minimal_symbol *msymbol;
-      msymbol = lookup_minimal_symbol ("malloc", (struct objfile *) NULL);
-      if (msymbol != NULL)
-       val =
-         value_from_longest (lookup_pointer_type (lookup_function_type (
-                               lookup_pointer_type (builtin_type_char))),
-                             (LONGEST) msymbol -> address);
-      else
-       error ("String constants require the program to have a function \"malloc\".");
+      write_memory (addr + (idx * typelength), VALUE_CONTENTS (elemvec[idx]),
+                   typelength);
     }
 
-  blocklen = value_from_longest (builtin_type_int, (LONGEST) (len + 1));
-  val = call_function_by_hand (val, 1, &blocklen);
-  if (value_zerop (val))
-    error ("No memory available for string constant.");
-  write_memory (value_as_pointer (val), copy, len + 1);
-  VALUE_TYPE (val) = lookup_pointer_type (builtin_type_char);
-  return val;
+  /* Create the array type and set up an array value to be evaluated lazily. */
+
+  rangetype = create_range_type ((struct type *) NULL, builtin_type_int,
+                                lowbound, highbound);
+  arraytype = create_array_type ((struct type *) NULL, 
+                                VALUE_TYPE (elemvec[0]), rangetype);
+  val = value_at_lazy (arraytype, addr);
+  return (val);
+}
+
+/* Create a value for a string constant by allocating space in the inferior,
+   copying the data into that space, and returning the address with type
+   TYPE_CODE_STRING.  PTR points to the string constant data; LEN is number
+   of characters.
+   Note that string types are like array of char types with a lower bound of
+   zero and an upper bound of LEN - 1.  Also note that the string may contain
+   embedded null bytes. */
+
+value
+value_string (ptr, len)
+     char *ptr;
+     int len;
+{
+  value val;
+  struct type *rangetype;
+  struct type *stringtype;
+  CORE_ADDR addr;
+
+  /* Allocate space to store the string in the inferior, and then
+     copy LEN bytes from PTR in gdb to that address in the inferior. */
+
+  addr = allocate_space_in_inferior (len);
+  write_memory (addr, ptr, len);
+
+  /* Create the string type and set up a string value to be evaluated
+     lazily. */
+
+  rangetype = create_range_type ((struct type *) NULL, builtin_type_int,
+                                0, len - 1);
+  stringtype = create_string_type ((struct type *) NULL, rangetype);
+  val = value_at_lazy (stringtype, addr);
+  return (val);
 }
 \f
+/* Compare two argument lists and return the position in which they differ,
+   or zero if equal.
+
+   STATICP is nonzero if the T1 argument list came from a
+   static member function.
+
+   For non-static member functions, we ignore the first argument,
+   which is the type of the instance variable.  This is because we want
+   to handle calls with objects from derived classes.  This is not
+   entirely correct: we should actually check to make sure that a
+   requested operation is type secure, shouldn't we?  FIXME.  */
+
+static int
+typecmp (staticp, t1, t2)
+     int staticp;
+     struct type *t1[];
+     value t2[];
+{
+  int i;
+
+  if (t2 == 0)
+    return 1;
+  if (staticp && t1 == 0)
+    return t2[1] != 0;
+  if (t1 == 0)
+    return 1;
+  if (TYPE_CODE (t1[0]) == TYPE_CODE_VOID) return 0;
+  if (t1[!staticp] == 0) return 0;
+  for (i = !staticp; t1[i] && TYPE_CODE (t1[i]) != TYPE_CODE_VOID; i++)
+    {
+      if (! t2[i])
+       return i+1;
+      if (TYPE_CODE (t1[i]) == TYPE_CODE_REF
+         && TYPE_TARGET_TYPE (t1[i]) == VALUE_TYPE (t2[i]))
+       continue;
+      if (TYPE_CODE (t1[i]) != TYPE_CODE (VALUE_TYPE (t2[i])))
+       return i+1;
+    }
+  if (!t1[i]) return 0;
+  return t2[i] ? i+1 : 0;
+}
+
 /* Helper function used by value_struct_elt to recurse through baseclasses.
    Look for a field NAME in ARG1. Adjust the address of ARG1 by OFFSET bytes,
    and search in it assuming it has (class) type TYPE.
@@ -1005,17 +1166,17 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
       {
        char *t_field_name = TYPE_FIELD_NAME (type, i);
 
-       if (t_field_name && !strcmp (t_field_name, name))
+       if (t_field_name && STREQ (t_field_name, name))
          {
            value v;
            if (TYPE_FIELD_STATIC (type, i))
              {
                char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, i);
                struct symbol *sym =
-                 lookup_symbol (phys_name, 0, VAR_NAMESPACE, 0, NULL);
-               if (! sym) error (
-         "Internal error: could not find physical static variable named %s",
-                                 phys_name);
+                   lookup_symbol (phys_name, 0, VAR_NAMESPACE, 0, NULL);
+               if (sym == NULL)
+                   error ("Internal error: could not find physical static variable named %s",
+                          phys_name);
                v = value_at (TYPE_FIELD_TYPE (type, i),
                              (CORE_ADDR)SYMBOL_BLOCK_VALUE (sym));
              }
@@ -1033,11 +1194,12 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
       /* If we are looking for baseclasses, this is what we get when we
         hit them.  */
       int found_baseclass = (looking_for_baseclass
-                            && !strcmp (name, TYPE_BASECLASS_NAME (type, i)));
+                            && STREQ (name, TYPE_BASECLASS_NAME (type, i)));
 
       if (BASETYPE_VIA_VIRTUAL (type, i))
        {
          value v2;
+         /* Fix to use baseclass_offset instead. FIXME */
          baseclass_addr (type, i, VALUE_CONTENTS (arg1) + offset,
                          &v2, (int *)NULL);
          if (v2 == 0)
@@ -1065,9 +1227,9 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
    If found, return value, else return NULL. */
 
 static value
-search_struct_method (name, arg1, args, offset, static_memfuncp, type)
+search_struct_method (name, arg1p, args, offset, static_memfuncp, type)
      char *name;
-     register value arg1, *args;
+     register value *arg1p, *args;
      int offset, *static_memfuncp;
      register struct type *type;
 {
@@ -1077,7 +1239,7 @@ search_struct_method (name, arg1, args, offset, static_memfuncp, type)
   for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; i--)
     {
       char *t_field_name = TYPE_FN_FIELDLIST_NAME (type, i);
-      if (t_field_name && !strcmp (t_field_name, name))
+      if (t_field_name && STREQ (t_field_name, name))
        {
          int j = TYPE_FN_FIELDLIST_LENGTH (type, i) - 1;
          struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
@@ -1092,10 +1254,10 @@ 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, type);
+                   return (value)value_virtual_fn_field (arg1p, f, j, type, offset);
                  if (TYPE_FN_FIELD_STATIC_P (f, j) && static_memfuncp)
                    *static_memfuncp = 1;
-                 return (value)value_fn_field (f, j);
+                 return (value)value_fn_field (arg1p, f, j, type, offset);
                }
              j--;
            }
@@ -1104,25 +1266,27 @@ search_struct_method (name, arg1, args, offset, static_memfuncp, type)
 
   for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
     {
-      value v, v2;
+      value v;
       int base_offset;
 
       if (BASETYPE_VIA_VIRTUAL (type, i))
        {
-         baseclass_addr (type, i, VALUE_CONTENTS (arg1) + offset,
-                         &v2, (int *)NULL);
-         if (v2 == 0)
+         base_offset = baseclass_offset (type, i, *arg1p, offset);
+         if (base_offset == -1)
            error ("virtual baseclass botch");
-         base_offset = 0;
        }
       else
        {
-         v2 = arg1;
          base_offset = TYPE_BASECLASS_BITPOS (type, i) / 8;
         }
-      v = search_struct_method (name, v2, args, base_offset,
+      v = search_struct_method (name, arg1p, args, base_offset + offset,
                                static_memfuncp, TYPE_BASECLASS (type, i));
-      if (v) return v;
+      if (v)
+       {
+/* FIXME-bothner:  Why is this commented out?  Why is it here?  */
+/*       *arg1p = arg1_tmp;*/
+         return v;
+        }
     }
   return NULL;
 }
@@ -1193,7 +1357,7 @@ value_struct_elt (argp, args, name, static_memfuncp, err)
       if (destructor_name_p (name, t))
        error ("Cannot get value of destructor");
 
-      v = search_struct_method (name, *argp, args, 0, static_memfuncp, t);
+      v = search_struct_method (name, argp, args, 0, static_memfuncp, t);
 
       if (v == 0)
        {
@@ -1210,8 +1374,9 @@ value_struct_elt (argp, args, name, static_memfuncp, err)
       if (!args[1])
        {
          /* destructors are a special case.  */
-         return (value)value_fn_field (TYPE_FN_FIELDLIST1 (t, 0),
-                                       TYPE_FN_FIELDLIST_LENGTH (t, 0));
+         return (value)value_fn_field (NULL, TYPE_FN_FIELDLIST1 (t, 0),
+                                       TYPE_FN_FIELDLIST_LENGTH (t, 0),
+                                       0, 0);
        }
       else
        {
@@ -1219,7 +1384,7 @@ value_struct_elt (argp, args, name, static_memfuncp, err)
        }
     }
   else
-    v = search_struct_method (name, *argp, args, 0, static_memfuncp, t);
+    v = search_struct_method (name, argp, args, 0, static_memfuncp, t);
 
   if (v == 0)
     {
@@ -1247,7 +1412,7 @@ destructor_name_p (name, type)
   if (name[0] == '~')
     {
       char *dname = type_name_no_tag (type);
-      if (strcmp (dname, name+1))
+      if (!STREQ (dname, name+1))
        error ("name of destructor must equal name of class");
       else
        return 1;
@@ -1269,7 +1434,7 @@ check_field_in (type, name)
   for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--)
     {
       char *t_field_name = TYPE_FIELD_NAME (type, i);
-      if (t_field_name && !strcmp (t_field_name, name))
+      if (t_field_name && STREQ (t_field_name, name))
        return 1;
     }
 
@@ -1282,7 +1447,7 @@ check_field_in (type, name)
 
   for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; --i)
     {
-      if (!strcmp (TYPE_FN_FIELDLIST_NAME (type, i), name))
+      if (STREQ (TYPE_FN_FIELDLIST_NAME (type, i), name))
        return 1;
     }
 
@@ -1349,16 +1514,15 @@ value_struct_elt_for_reference (domain, offset, curtype, name, intype)
     {
       char *t_field_name = TYPE_FIELD_NAME (t, i);
       
-      if (t_field_name && !strcmp (t_field_name, name))
+      if (t_field_name && STREQ (t_field_name, name))
        {
          if (TYPE_FIELD_STATIC (t, i))
            {
              char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (t, i);
              struct symbol *sym =
                lookup_symbol (phys_name, 0, VAR_NAMESPACE, 0, NULL);
-             if (! sym)
-               error (
-           "Internal error: could not find physical static variable named %s",
+             if (sym == NULL)
+               error ("Internal error: could not find physical static variable named %s",
                       phys_name);
              return value_at (SYMBOL_TYPE (sym),
                               (CORE_ADDR)SYMBOL_BLOCK_VALUE (sym));
@@ -1388,7 +1552,7 @@ value_struct_elt_for_reference (domain, offset, curtype, name, intype)
 
   for (i = TYPE_NFN_FIELDS (t) - 1; i >= 0; --i)
     {
-      if (!strcmp (TYPE_FN_FIELDLIST_NAME (t, i), name))
+      if (STREQ (TYPE_FN_FIELDLIST_NAME (t, i), name))
        {
          int j = TYPE_FN_FIELDLIST_LENGTH (t, i);
          struct fn_field *f = TYPE_FN_FIELDLIST1 (t, i);
@@ -1414,23 +1578,30 @@ value_struct_elt_for_reference (domain, offset, curtype, name, intype)
                (lookup_reference_type
                 (lookup_member_type (TYPE_FN_FIELD_TYPE (f, j),
                                      domain)),
-                (LONGEST) TYPE_FN_FIELD_VOFFSET (f, j));
+                (LONGEST) METHOD_PTR_FROM_VOFFSET
+                 (TYPE_FN_FIELD_VOFFSET (f, j)));
            }
          else
            {
              struct symbol *s = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, j),
                                                0, VAR_NAMESPACE, 0, NULL);
-             v = read_var_value (s, 0);
+             if (s == NULL)
+               {
+                 v = 0;
+               }
+             else
+               {
+                 v = read_var_value (s, 0);
 #if 0
-             VALUE_TYPE (v) = lookup_reference_type
-               (lookup_member_type (TYPE_FN_FIELD_TYPE (f, j),
-                                    domain));
+                 VALUE_TYPE (v) = lookup_reference_type
+                   (lookup_member_type (TYPE_FN_FIELD_TYPE (f, j),
+                                        domain));
 #endif
-             return v;
                }
+             return v;
            }
        }
-
+    }
   for (i = TYPE_N_BASECLASSES (t) - 1; i >= 0; i--)
     {
       value v;
@@ -1451,46 +1622,6 @@ value_struct_elt_for_reference (domain, offset, curtype, name, intype)
   return 0;
 }
 
-/* Compare two argument lists and return the position in which they differ,
-   or zero if equal.
-
-   STATICP is nonzero if the T1 argument list came from a
-   static member function.
-
-   For non-static member functions, we ignore the first argument,
-   which is the type of the instance variable.  This is because we want
-   to handle calls with objects from derived classes.  This is not
-   entirely correct: we should actually check to make sure that a
-   requested operation is type secure, shouldn't we?  FIXME.  */
-
-int
-typecmp (staticp, t1, t2)
-     int staticp;
-     struct type *t1[];
-     value t2[];
-{
-  int i;
-
-  if (t2 == 0)
-    return 1;
-  if (staticp && t1 == 0)
-    return t2[1] != 0;
-  if (t1 == 0)
-    return 1;
-  if (t1[0]->code == TYPE_CODE_VOID) return 0;
-  if (t1[!staticp] == 0) return 0;
-  for (i = !staticp; t1[i] && t1[i]->code != TYPE_CODE_VOID; i++)
-    {
-      if (! t2[i]
-         || t1[i]->code != t2[i]->type->code
-/* Too pessimistic:  || t1[i]->target_type != t2[i]->type->target_type */
- )
-       return i+1;
-    }
-  if (!t1[i]) return 0;
-  return t2[i] ? i+1 : 0;
-}
-
 /* C++: return the value of the class instance variable, if one exists.
    Flag COMPLAIN signals an error if the request is made in an
    inappropriate context.  */
This page took 0.046619 seconds and 4 git commands to generate.