2002-05-13 Daniel Jacobowitz <drow@mvista.com>
[deliverable/binutils-gdb.git] / gdb / valops.c
index 4532da73aeac8624a1adccaf0f97ddecaa3345a1..798e31fc6462befabf7aecefc5bd00868edf86a0 100644 (file)
@@ -36,6 +36,7 @@
 
 #include <errno.h>
 #include "gdb_string.h"
+#include "gdb_assert.h"
 
 /* Flag indicating HP compilers were used; needed to correctly handle some
    value operations with HP aCC code/runtime. */
@@ -66,7 +67,7 @@ static CORE_ADDR allocate_space_in_inferior (int);
 static struct value *cast_into_complex (struct type *, struct value *);
 
 static struct fn_field *find_method_list (struct value ** argp, char *method,
-                                         int offset, int *static_memfuncp,
+                                         int offset,
                                          struct type *type, int *num_fns,
                                          struct type **basetype,
                                          int *boffset);
@@ -562,11 +563,10 @@ value_assign (struct value *toval, struct value *fromval)
   if (VALUE_REGNO (toval) >= 0)
     {
       int regno = VALUE_REGNO (toval);
-      if (REGISTER_CONVERTIBLE (regno))
+      if (CONVERT_REGISTER_P (regno))
        {
          struct type *fromtype = check_typedef (VALUE_TYPE (fromval));
-         REGISTER_CONVERT_TO_RAW (fromtype, regno,
-                                  VALUE_CONTENTS (fromval), raw_buffer);
+         VALUE_TO_REGISTER (fromtype, regno, VALUE_CONTENTS (fromval), raw_buffer);
          use_buffer = REGISTER_RAW_SIZE (regno);
        }
     }
@@ -607,7 +607,7 @@ value_assign (struct value *toval, struct value *fromval)
 
            if (changed_len > (int) sizeof (LONGEST))
              error ("Can't handle bitfields which don't fit in a %d bit word.",
-                    sizeof (LONGEST) * HOST_CHAR_BIT);
+                    (int) sizeof (LONGEST) * HOST_CHAR_BIT);
 
            read_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
                         buffer, changed_len);
@@ -644,7 +644,7 @@ value_assign (struct value *toval, struct value *fromval)
 
          if (len > (int) sizeof (LONGEST))
            error ("Can't handle bitfields in registers larger than %d bits.",
-                  sizeof (LONGEST) * HOST_CHAR_BIT);
+                  (int) sizeof (LONGEST) * HOST_CHAR_BIT);
 
          if (VALUE_BITPOS (toval) + VALUE_BITSIZE (toval)
              > len * HOST_CHAR_BIT)
@@ -1190,8 +1190,12 @@ value_arg_coerce (struct value *arg, struct type *param_type,
       type = lookup_pointer_type (type);
       break;
     case TYPE_CODE_ARRAY:
+      /* Arrays are coerced to pointers to their first element, unless
+         they are vectors, in which case we want to leave them alone,
+         because they are passed by value.  */
       if (current_language->c_style_arrays)
-       type = lookup_pointer_type (TYPE_TARGET_TYPE (type));
+       if (!TYPE_VECTOR (type))
+         type = lookup_pointer_type (TYPE_TARGET_TYPE (type));
       break;
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_PTR:
@@ -1385,6 +1389,8 @@ hand_function_call (struct value *function, int nargs, struct value **args)
   if (CALL_DUMMY_LOCATION == ON_STACK)
     {
       write_memory (start_sp, (char *) dummy1, sizeof_dummy1);
+      if (USE_GENERIC_DUMMY_FRAMES)
+       generic_save_call_dummy_addr (start_sp, start_sp + sizeof_dummy1);
     }
 
   if (CALL_DUMMY_LOCATION == BEFORE_TEXT_END)
@@ -1401,6 +1407,8 @@ hand_function_call (struct value *function, int nargs, struct value **args)
       sp = old_sp;
       real_pc = text_end - sizeof_dummy1;
       write_memory (real_pc, (char *) dummy1, sizeof_dummy1);
+      if (USE_GENERIC_DUMMY_FRAMES)
+       generic_save_call_dummy_addr (real_pc, real_pc + sizeof_dummy1);
     }
 
   if (CALL_DUMMY_LOCATION == AFTER_TEXT_END)
@@ -1412,11 +1420,18 @@ hand_function_call (struct value *function, int nargs, struct value **args)
       errcode = target_write_memory (real_pc, (char *) dummy1, sizeof_dummy1);
       if (errcode != 0)
        error ("Cannot write text segment -- call_function failed");
+      if (USE_GENERIC_DUMMY_FRAMES)
+       generic_save_call_dummy_addr (real_pc, real_pc + sizeof_dummy1);
     }
 
   if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT)
     {
       real_pc = funaddr;
+      if (USE_GENERIC_DUMMY_FRAMES)
+       /* NOTE: cagney/2002-04-13: The entry point is going to be
+           modified with a single breakpoint.  */
+       generic_save_call_dummy_addr (CALL_DUMMY_ADDRESS (),
+                                     CALL_DUMMY_ADDRESS () + 1);
     }
 
 #ifdef lint
@@ -1473,7 +1488,7 @@ hand_function_call (struct value *function, int nargs, struct value **args)
        if (param_type)
          /* if this parameter is a pointer to function */
          if (TYPE_CODE (param_type) == TYPE_CODE_PTR)
-           if (TYPE_CODE (param_type->target_type) == TYPE_CODE_FUNC)
+           if (TYPE_CODE (TYPE_TARGET_TYPE (param_type)) == TYPE_CODE_FUNC)
              /* elz: FIXME here should go the test about the compiler used
                 to compile the target. We want to issue the error
                 message only if the compiler used was HP's aCC.
@@ -1948,10 +1963,13 @@ typecmp (int staticp, struct type *t1[], struct value *t2[])
     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;
+  if (TYPE_CODE (t1[0]) == TYPE_CODE_VOID)
+    return 0;
+  /* Skip ``this'' argument if applicable.  T2 will always include THIS.  */
+  if (staticp)
+    t2++;
   for (i = !staticp; t1[i] && TYPE_CODE (t1[i]) != TYPE_CODE_VOID; i++)
     {
       struct type *tt1, *tt2;
@@ -2505,7 +2523,7 @@ value_struct_elt (struct value **argp, struct value **args,
 
 static struct fn_field *
 find_method_list (struct value **argp, char *method, int offset,
-                 int *static_memfuncp, struct type *type, int *num_fns,
+                 struct type *type, int *num_fns,
                  struct type **basetype, int *boffset)
 {
   int i;
@@ -2521,10 +2539,22 @@ find_method_list (struct value **argp, char *method, int offset,
       char *fn_field_name = TYPE_FN_FIELDLIST_NAME (type, i);
       if (fn_field_name && (strcmp_iw (fn_field_name, method) == 0))
        {
-         *num_fns = TYPE_FN_FIELDLIST_LENGTH (type, i);
+         /* Resolve any stub methods.  */
+         int len = TYPE_FN_FIELDLIST_LENGTH (type, i);
+         struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
+         int j;
+
+         *num_fns = len;
          *basetype = type;
          *boffset = offset;
-         return TYPE_FN_FIELDLIST1 (type, i);
+
+         for (j = 0; j < len; j++)
+           {
+             if (TYPE_FN_FIELD_STUB (f, j))
+               check_stub_method (type, i, j);
+           }
+
+         return f;
        }
     }
 
@@ -2564,7 +2594,8 @@ find_method_list (struct value **argp, char *method, int offset,
          base_offset = TYPE_BASECLASS_BITPOS (type, i) / 8;
        }
       f = find_method_list (argp, method, base_offset + offset,
-      static_memfuncp, TYPE_BASECLASS (type, i), num_fns, basetype, boffset);
+                           TYPE_BASECLASS (type, i), num_fns, basetype,
+                           boffset);
       if (f)
        return f;
     }
@@ -2582,8 +2613,8 @@ find_method_list (struct value **argp, char *method, int offset,
 
 struct fn_field *
 value_find_oload_method_list (struct value **argp, char *method, int offset,
-                             int *static_memfuncp, int *num_fns,
-                             struct type **basetype, int *boffset)
+                             int *num_fns, struct type **basetype,
+                             int *boffset)
 {
   struct type *t;
 
@@ -2606,12 +2637,7 @@ value_find_oload_method_list (struct value **argp, char *method, int offset,
       && TYPE_CODE (t) != TYPE_CODE_UNION)
     error ("Attempt to extract a component of a value that is not a struct or union");
 
-  /* Assume it's not static, unless we see that it is.  */
-  if (static_memfuncp)
-    *static_memfuncp = 0;
-
-  return find_method_list (argp, method, 0, static_memfuncp, t, num_fns, basetype, boffset);
-
+  return find_method_list (argp, method, 0, t, num_fns, basetype, boffset);
 }
 
 /* Given an array of argument types (ARGTYPES) (which includes an
@@ -2670,6 +2696,7 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
   int boffset;
   register int jj;
   register int ix;
+  int static_offset;
 
   char *obj_type_name = NULL;
   char *func_name = NULL;
@@ -2677,9 +2704,6 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
   /* Get the list of overloaded methods or functions */
   if (method)
     {
-      int i;
-      int len;
-      struct type *domain;
       obj_type_name = TYPE_NAME (VALUE_TYPE (obj));
       /* Hack: evaluate_subexp_standard often passes in a pointer
          value rather than the object itself, so try again */
@@ -2688,7 +2712,6 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
        obj_type_name = TYPE_NAME (TYPE_TARGET_TYPE (VALUE_TYPE (obj)));
 
       fns_ptr = value_find_oload_method_list (&temp, name, 0,
-                                             staticp,
                                              &num_fns,
                                              &basetype, &boffset);
       if (!fns_ptr || !num_fns)
@@ -2696,26 +2719,10 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
               obj_type_name,
               (obj_type_name && *obj_type_name) ? "::" : "",
               name);
-      domain = TYPE_DOMAIN_TYPE (fns_ptr[0].type);
-      len = TYPE_NFN_FIELDS (domain);
-      /* NOTE: dan/2000-03-10: This stuff is for STABS, which won't
-         give us the info we need directly in the types. We have to
-         use the method stub conversion to get it. Be aware that this
-         is by no means perfect, and if you use STABS, please move to
-         DWARF-2, or something like it, because trying to improve
-         overloading using STABS is really a waste of time. */
-      for (i = 0; i < len; i++)
-       {
-         int j;
-         struct fn_field *f = TYPE_FN_FIELDLIST1 (domain, i);
-         int len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
-
-         for (j = 0; j < len2; j++)
-           {
-             if (TYPE_FN_FIELD_STUB (f, j) && (!strcmp_iw (TYPE_FN_FIELDLIST_NAME (domain,i),name)))
-               check_stub_method (domain, i, j);
-           }
-       }
+      /* If we are dealing with stub method types, they should have
+        been resolved by find_method_list via value_find_oload_method_list
+        above.  */
+      gdb_assert (TYPE_DOMAIN_TYPE (fns_ptr[0].type) != NULL);
     }
   else
     {
@@ -2742,10 +2749,11 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
   /* Consider each candidate in turn */
   for (ix = 0; ix < num_fns; ix++)
     {
+      static_offset = 0;
       if (method)
        {
-         /* For static member functions, we won't have a this pointer, but nothing
-            else seems to handle them right now, so we just pretend ourselves */
+         if (TYPE_FN_FIELD_STATIC_P (fns_ptr, ix))
+           static_offset = 1;
          nparms=0;
 
          if (TYPE_FN_FIELD_ARGS(fns_ptr,ix))
@@ -2767,8 +2775,10 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
                          ? (TYPE_FN_FIELD_ARGS (fns_ptr, ix)[jj])
                          : TYPE_FIELD_TYPE (SYMBOL_TYPE (oload_syms[ix]), jj));
 
-      /* Compare parameter types to supplied argument types */
-      bv = rank_function (parm_types, nparms, arg_types, nargs);
+      /* Compare parameter types to supplied argument types.  Skip THIS for
+         static methods.  */
+      bv = rank_function (parm_types, nparms, arg_types + static_offset,
+                         nargs - static_offset);
 
       if (!oload_champ_bv)
        {
@@ -2806,7 +2816,7 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
            fprintf_filtered (gdb_stderr,"Overloaded method instance %s, # of parms %d\n", fns_ptr[ix].physname, nparms);
          else
            fprintf_filtered (gdb_stderr,"Overloaded function instance %s # of parms %d\n", SYMBOL_DEMANGLED_NAME (oload_syms[ix]), nparms);
-         for (jj = 0; jj < nargs; jj++)
+         for (jj = 0; jj < nargs - static_offset; jj++)
            fprintf_filtered (gdb_stderr,"...Badness @ %d : %d\n", jj, bv->rank[jj]);
          fprintf_filtered (gdb_stderr,"Overload resolution champion is %d, ambiguous? %d\n", oload_champ, oload_ambiguous);
        }
@@ -2829,8 +2839,11 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
     }
 #endif
 
-  /* Check how bad the best match is */
-  for (ix = 1; ix <= nargs; ix++)
+  /* Check how bad the best match is.  */
+  static_offset = 0;
+  if (method && TYPE_FN_FIELD_STATIC_P (fns_ptr, oload_champ))
+    static_offset = 1;
+  for (ix = 1; ix <= nargs - static_offset; ix++)
     {
       if (oload_champ_bv->rank[ix] >= 100)
        oload_incompatible = 1; /* truly mismatched types */
@@ -2863,6 +2876,10 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
 
   if (method)
     {
+      if (staticp && TYPE_FN_FIELD_STATIC_P (fns_ptr, oload_champ))
+       *staticp = 1;
+      else if (staticp)
+       *staticp = 0;
       if (TYPE_FN_FIELD_VIRTUAL_P (fns_ptr, oload_champ))
        *valp = value_virtual_fn_field (&temp, fns_ptr, oload_champ, basetype, boffset);
       else
@@ -3250,7 +3267,7 @@ value_of_this (int complain)
 
   /* Calling lookup_block_symbol is necessary to get the LOC_REGISTER
      symbol instead of the LOC_ARG one (if both exist).  */
-  sym = lookup_block_symbol (b, funny_this, VAR_NAMESPACE);
+  sym = lookup_block_symbol (b, funny_this, NULL, VAR_NAMESPACE);
   if (sym == NULL)
     {
       if (complain)
This page took 0.047983 seconds and 4 git commands to generate.