bfd/
[deliverable/binutils-gdb.git] / gdb / valops.c
index 14b845e7def443f22ea882a113c7622c7f530ae9..15c407c0af264e9995a5f284a522dae2e9c65cec 100644 (file)
@@ -1,6 +1,6 @@
 /* Perform non-arithmetic operations on values, for GDB.
 
-   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+   Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
    1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
    Free Software Foundation, Inc.
 
@@ -18,8 +18,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include "defs.h"
 #include "symtab.h"
@@ -201,6 +201,70 @@ allocate_space_in_inferior (int len)
   return value_as_long (value_allocate_space_in_inferior (len));
 }
 
+/* Cast one pointer or reference type to another.  Both TYPE and
+   the type of ARG2 should be pointer types, or else both should be
+   reference types.  Returns the new pointer or reference.  */
+
+struct value *
+value_cast_pointers (struct type *type, struct value *arg2)
+{
+  struct type *type2 = check_typedef (value_type (arg2));
+  struct type *t1 = check_typedef (TYPE_TARGET_TYPE (type));
+  struct type *t2 = check_typedef (TYPE_TARGET_TYPE (type2));
+
+  if (TYPE_CODE (t1) == TYPE_CODE_STRUCT
+      && TYPE_CODE (t2) == TYPE_CODE_STRUCT
+      && !value_logical_not (arg2))
+    {
+      struct value *v;
+
+      /* Look in the type of the source to see if it contains the
+        type of the target as a superclass.  If so, we'll need to
+        offset the pointer rather than just change its type.  */
+      if (TYPE_NAME (t1) != NULL)
+       {
+         struct value *v2;
+
+         if (TYPE_CODE (type2) == TYPE_CODE_REF)
+           v2 = coerce_ref (arg2);
+         else
+           v2 = value_ind (arg2);
+         v = search_struct_field (type_name_no_tag (t1),
+                                  v2, 0, t2, 1);
+         if (v)
+           {
+             v = value_addr (v);
+             deprecated_set_value_type (v, type);
+             return v;
+           }
+       }
+
+      /* Look in the type of the target to see if it contains the
+        type of the source as a superclass.  If so, we'll need to
+        offset the pointer rather than just change its type.
+        FIXME: This fails silently with virtual inheritance.  */
+      if (TYPE_NAME (t2) != NULL)
+       {
+         v = search_struct_field (type_name_no_tag (t2),
+                                  value_zero (t1, not_lval), 0, t1, 1);
+         if (v)
+           {
+             CORE_ADDR addr2 = value_as_address (arg2);
+             addr2 -= (VALUE_ADDRESS (v)
+                       + value_offset (v)
+                       + value_embedded_offset (v));
+             return value_from_pointer (type, addr2);
+           }
+       }
+    }
+
+  /* No superclass found, just change the pointer type.  */
+  deprecated_set_value_type (arg2, type);
+  arg2 = value_change_enclosing_type (arg2, type);
+  set_value_pointed_to_offset (arg2, 0);       /* pai: chk_val */
+  return arg2;
+}
+
 /* 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.  */
@@ -224,6 +288,10 @@ value_cast (struct type *type, struct value *arg2)
   arg2 = coerce_ref (arg2);
   type2 = check_typedef (value_type (arg2));
 
+  /* You can't cast to a reference type.  See value_cast_pointers
+     instead.  */
+  gdb_assert (code1 != TYPE_CODE_REF);
+
   /* A cast to an undetermined-length array_type, such as (TYPE [])OBJECT,
      is treated like a cast to (TYPE [N])OBJECT,
      where N is sizeof(OBJECT)/sizeof(TYPE). */
@@ -369,50 +437,8 @@ value_cast (struct type *type, struct value *arg2)
   else if (TYPE_LENGTH (type) == TYPE_LENGTH (type2))
     {
       if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR)
-       {
-         struct type *t1 = check_typedef (TYPE_TARGET_TYPE (type));
-         struct type *t2 = check_typedef (TYPE_TARGET_TYPE (type2));
-         if (TYPE_CODE (t1) == TYPE_CODE_STRUCT
-             && TYPE_CODE (t2) == TYPE_CODE_STRUCT
-             && !value_logical_not (arg2))
-           {
-             struct value *v;
-
-             /* Look in the type of the source to see if it contains the
-                type of the target as a superclass.  If so, we'll need to
-                offset the pointer rather than just change its type.  */
-             if (TYPE_NAME (t1) != NULL)
-               {
-                 v = search_struct_field (type_name_no_tag (t1),
-                                          value_ind (arg2), 0, t2, 1);
-                 if (v)
-                   {
-                     v = value_addr (v);
-                     deprecated_set_value_type (v, type);
-                     return v;
-                   }
-               }
+       return value_cast_pointers (type, arg2);
 
-             /* Look in the type of the target to see if it contains the
-                type of the source as a superclass.  If so, we'll need to
-                offset the pointer rather than just change its type.
-                FIXME: This fails silently with virtual inheritance.  */
-             if (TYPE_NAME (t2) != NULL)
-               {
-                 v = search_struct_field (type_name_no_tag (t2),
-                                      value_zero (t1, not_lval), 0, t1, 1);
-                 if (v)
-                   {
-                      CORE_ADDR addr2 = value_as_address (arg2);
-                      addr2 -= (VALUE_ADDRESS (v)
-                                + value_offset (v)
-                                + value_embedded_offset (v));
-                      return value_from_pointer (type, addr2);
-                   }
-               }
-           }
-         /* No superclass found, just fall through to change ptr type.  */
-       }
       deprecated_set_value_type (arg2, type);
       arg2 = value_change_enclosing_type (arg2, type);
       set_value_pointed_to_offset (arg2, 0);   /* pai: chk_val */
@@ -886,6 +912,22 @@ value_addr (struct value *arg1)
   return arg2;
 }
 
+/* Return a reference value for the object for which ARG1 is the contents.  */
+
+struct value *
+value_ref (struct value *arg1)
+{
+  struct value *arg2;
+
+  struct type *type = check_typedef (value_type (arg1));
+  if (TYPE_CODE (type) == TYPE_CODE_REF)
+    return arg1;
+
+  arg2 = value_addr (arg1);
+  deprecated_set_value_type (arg2, lookup_reference_type (type));
+  return arg2;
+}
+
 /* Given a value of a pointer type, apply the C unary * operator to it.  */
 
 struct value *
@@ -1106,7 +1148,7 @@ typecmp (int staticp, int varargs, int nargs,
          if (TYPE_CODE (tt2) == TYPE_CODE_ARRAY)
            t2[i] = value_coerce_array (t2[i]);
          else
-           t2[i] = value_addr (t2[i]);
+           t2[i] = value_ref (t2[i]);
          continue;
        }
 
@@ -1587,7 +1629,7 @@ value_struct_elt (struct value **argp, struct value **args,
       v = search_struct_method (name, argp, args, 0, static_memfuncp, t);
 
       if (v == (struct value *) - 1)
-       error (_("Cannot take address of a method"));
+       error (_("Cannot take address of method %s."), name);
       else if (v == 0)
        {
          if (TYPE_NFN_FIELDS (t))
@@ -1847,10 +1889,15 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
   else
     {
       const char *qualified_name = SYMBOL_CPLUS_DEMANGLED_NAME (fsym);
-      func_name        = cp_func_name (qualified_name);
 
-      /* If the name is NULL this must be a C-style function.
-         Just return the same symbol. */
+      /* If we have a C++ name, try to extract just the function
+        part.  */
+      if (qualified_name)
+       func_name = cp_func_name (qualified_name);
+
+      /* If there was no C++ name, this must be a C-style function.
+        Just return the same symbol.  Do the same if cp_func_name
+        fails for some reason.  */
       if (func_name == NULL)
         {
          *symp = fsym;
@@ -2269,7 +2316,7 @@ check_field_in (struct type *type, const char *name)
    target structure/union is defined, otherwise, return 0.  */
 
 int
-check_field (struct value *arg1, const gdb_byte *name)
+check_field (struct value *arg1, const char *name)
 {
   struct type *t;
 
This page took 0.027743 seconds and 4 git commands to generate.