2003-10-06 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / valops.c
index e6fb6c8dec4f5c82ef5802441e01513d0745e32d..e037441a925b1451e8a36401a81dab0e7b9765ea 100644 (file)
 #include "cp-abi.h"
 #include "block.h"
 #include "infcall.h"
+#include "dictionary.h"
+#include "cp-support.h"
 
 #include <errno.h>
 #include "gdb_string.h"
 #include "gdb_assert.h"
+#include "cp-support.h"
 
 /* Flag indicating HP compilers were used; needed to correctly handle some
    value operations with HP aCC code/runtime. */
@@ -61,6 +64,17 @@ static struct value *search_struct_method (char *, struct value **,
 
 static int check_field_in (struct type *, const char *);
 
+
+static struct value *value_struct_elt_for_reference (struct type *domain,
+                                                    int offset,
+                                                    struct type *curtype,
+                                                    char *name,
+                                                    struct type *intype);
+
+static struct value *value_namespace_elt (const struct type *curtype,
+                                         const char *name,
+                                         enum noside noside);
+
 static CORE_ADDR allocate_space_in_inferior (int);
 
 static struct value *cast_into_complex (struct type *, struct value *);
@@ -86,7 +100,7 @@ int overload_resolution = 0;
 struct value *
 find_function_in_inferior (const char *name)
 {
-  register struct symbol *sym;
+  struct symbol *sym;
   sym = lookup_symbol (name, 0, VAR_DOMAIN, 0, NULL);
   if (sym != NULL)
     {
@@ -155,9 +169,9 @@ allocate_space_in_inferior (int len)
 struct value *
 value_cast (struct type *type, struct value *arg2)
 {
-  register enum type_code code1;
-  register enum type_code code2;
-  register int scalar;
+  enum type_code code1;
+  enum type_code code2;
+  int scalar;
   struct type *type2;
 
   int convert_to_boolean = 0;
@@ -478,7 +492,7 @@ value_fetch_lazy (struct value *val)
 struct value *
 value_assign (struct value *toval, struct value *fromval)
 {
-  register struct type *type;
+  struct type *type;
   struct value *val;
   char raw_buffer[MAX_REGISTER_SIZE];
   int use_buffer = 0;
@@ -496,22 +510,6 @@ value_assign (struct value *toval, struct value *fromval)
     COERCE_ARRAY (fromval);
   CHECK_TYPEDEF (type);
 
-  /* If TOVAL is a special machine register requiring conversion
-     of program values to a special raw format,
-     convert FROMVAL's contents now, with result in `raw_buffer',
-     and set USE_BUFFER to the number of bytes to write.  */
-
-  if (VALUE_REGNO (toval) >= 0)
-    {
-      int regno = VALUE_REGNO (toval);
-      if (CONVERT_REGISTER_P (regno))
-       {
-         struct type *fromtype = check_typedef (VALUE_TYPE (fromval));
-         VALUE_TO_REGISTER (fromtype, regno, VALUE_CONTENTS (fromval), raw_buffer);
-         use_buffer = REGISTER_RAW_SIZE (regno);
-       }
-    }
-
   /* Since modifying a register can trash the frame chain, and modifying memory
      can trash the frame cache, we save the old frame and then restore the new
      frame afterwards.  */
@@ -585,17 +583,8 @@ value_assign (struct value *toval, struct value *fromval)
     case lval_reg_frame_relative:
     case lval_register:
       {
-       /* value is stored in a series of registers in the frame
-          specified by the structure.  Copy that value out, modify
-          it, and copy it back in.  */
-       int amount_copied;
-       int amount_to_copy;
-       char *buffer;
-       int value_reg;
-       int reg_offset;
-       int byte_offset;
-       int regno;
        struct frame_info *frame;
+       int value_reg;
 
        /* Figure out which frame this is in currently.  */
        if (VALUE_LVAL (toval) == lval_register)
@@ -611,92 +600,77 @@ value_assign (struct value *toval, struct value *fromval)
 
        if (!frame)
          error ("Value being assigned to is no longer active.");
-
-       /* Locate the first register that falls in the value that
-           needs to be transfered.  Compute the offset of the value in
-           that register.  */
-       {
-         int offset;
-         for (reg_offset = value_reg, offset = 0;
-              offset + REGISTER_RAW_SIZE (reg_offset) <= VALUE_OFFSET (toval);
-              reg_offset++);
-         byte_offset = VALUE_OFFSET (toval) - offset;
-       }
-
-       /* Compute the number of register aligned values that need to
-           be copied.  */
-       if (VALUE_BITSIZE (toval))
-         amount_to_copy = byte_offset + 1;
-       else
-         amount_to_copy = byte_offset + TYPE_LENGTH (type);
-
-       /* And a bounce buffer.  Be slightly over generous.  */
-       buffer = (char *) alloca (amount_to_copy + MAX_REGISTER_SIZE);
-
-       /* Copy it in.  */
-       for (regno = reg_offset, amount_copied = 0;
-            amount_copied < amount_to_copy;
-            amount_copied += REGISTER_RAW_SIZE (regno), regno++)
-         {
-           frame_register_read (frame, regno, buffer + amount_copied);
-         }
        
-       /* Modify what needs to be modified.  */
-       if (VALUE_BITSIZE (toval))
-         {
-           modify_field (buffer + byte_offset,
-                         value_as_long (fromval),
-                         VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
-         }
-       else if (use_buffer)
+       if (VALUE_LVAL (toval) == lval_reg_frame_relative
+           && CONVERT_REGISTER_P (VALUE_FRAME_REGNUM (toval), type))
          {
-           memcpy (buffer + VALUE_OFFSET (toval), raw_buffer, use_buffer);
+           /* If TOVAL is a special machine register requiring
+              conversion of program values to a special raw format.  */
+           VALUE_TO_REGISTER (frame, VALUE_FRAME_REGNUM (toval),
+                              type, VALUE_CONTENTS (fromval));
          }
        else
          {
-           memcpy (buffer + byte_offset, VALUE_CONTENTS (fromval),
-                   TYPE_LENGTH (type));
-           /* Do any conversion necessary when storing this type to
-              more than one register.  */
-#ifdef REGISTER_CONVERT_FROM_TYPE
-           REGISTER_CONVERT_FROM_TYPE (value_reg, type,
-                                       (buffer + byte_offset));
-#endif
-         }
+           /* TOVAL is stored in a series of registers in the frame
+              specified by the structure.  Copy that value out,
+              modify it, and copy it back in.  */
+           int amount_copied;
+           int amount_to_copy;
+           char *buffer;
+           int reg_offset;
+           int byte_offset;
+           int regno;
+
+           /* Locate the first register that falls in the value that
+              needs to be transfered.  Compute the offset of the
+              value in that register.  */
+           {
+             int offset;
+             for (reg_offset = value_reg, offset = 0;
+                  offset + DEPRECATED_REGISTER_RAW_SIZE (reg_offset) <= VALUE_OFFSET (toval);
+                  reg_offset++);
+             byte_offset = VALUE_OFFSET (toval) - offset;
+           }
 
-       /* Copy it out.  */
-       for (regno = reg_offset, amount_copied = 0;
-            amount_copied < amount_to_copy;
-            amount_copied += REGISTER_RAW_SIZE (regno), regno++)
-         {
-           enum lval_type lval;
-           CORE_ADDR addr;
-           int optim;
-           int realnum;
+           /* Compute the number of register aligned values that need
+              to be copied.  */
+           if (VALUE_BITSIZE (toval))
+             amount_to_copy = byte_offset + 1;
+           else
+             amount_to_copy = byte_offset + TYPE_LENGTH (type);
            
-           /* Just find out where to put it.  */
-           frame_register (frame, regno, &optim, &lval, &addr, &realnum,
-                           NULL);
+           /* And a bounce buffer.  Be slightly over generous.  */
+           buffer = (char *) alloca (amount_to_copy + MAX_REGISTER_SIZE);
+
+           /* Copy it in.  */
+           for (regno = reg_offset, amount_copied = 0;
+                amount_copied < amount_to_copy;
+                amount_copied += DEPRECATED_REGISTER_RAW_SIZE (regno), regno++)
+             frame_register_read (frame, regno, buffer + amount_copied);
            
-           if (optim)
-             error ("Attempt to assign to a value that was optimized out.");
-           if (lval == lval_memory)
-             write_memory (addr, buffer + amount_copied,
-                           REGISTER_RAW_SIZE (regno));
-           else if (lval == lval_register)
-             regcache_cooked_write (current_regcache, realnum,
-                                    (buffer + amount_copied));
+           /* Modify what needs to be modified.  */
+           if (VALUE_BITSIZE (toval))
+             modify_field (buffer + byte_offset,
+                           value_as_long (fromval),
+                           VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
+           else if (use_buffer)
+             memcpy (buffer + VALUE_OFFSET (toval), raw_buffer, use_buffer);
            else
-             error ("Attempt to assign to an unmodifiable value.");
-         }
+             memcpy (buffer + byte_offset, VALUE_CONTENTS (fromval),
+                     TYPE_LENGTH (type));
+
+           /* Copy it out.  */
+           for (regno = reg_offset, amount_copied = 0;
+                amount_copied < amount_to_copy;
+                amount_copied += DEPRECATED_REGISTER_RAW_SIZE (regno), regno++)
+             put_frame_register (frame, regno, buffer + amount_copied);
 
+         }
        if (register_changed_hook)
          register_changed_hook (-1);
        target_changed_event ();
-
+       break;
       }
-      break;
-      
       
     default:
       error ("Left operand of assignment is not an lvalue.");
@@ -838,7 +812,7 @@ value_of_variable (struct symbol *var, struct block *b)
 struct value *
 value_coerce_array (struct value *arg1)
 {
-  register struct type *type = check_typedef (VALUE_TYPE (arg1));
+  struct type *type = check_typedef (VALUE_TYPE (arg1));
 
   if (VALUE_LVAL (arg1) != lval_memory)
     error ("Attempt to take address of value not located in memory.");
@@ -958,7 +932,7 @@ value_ind (struct value *arg1)
 CORE_ADDR
 push_word (CORE_ADDR sp, ULONGEST word)
 {
-  register int len = DEPRECATED_REGISTER_SIZE;
+  int len = DEPRECATED_REGISTER_SIZE;
   char buffer[MAX_REGISTER_SIZE];
 
   store_unsigned_integer (buffer, len, word);
@@ -1007,11 +981,11 @@ push_bytes (CORE_ADDR sp, char *buffer, int len)
    it to be an argument to a function.  */
 
 static CORE_ADDR
-value_push (register CORE_ADDR sp, struct value *arg)
+value_push (CORE_ADDR sp, struct value *arg)
 {
-  register int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg));
-  register int container_len = len;
-  register int offset;
+  int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg));
+  int container_len = len;
+  int offset;
 
   /* How big is the container we're going to put this value in?  */
   if (PARM_BOUNDARY)
@@ -1270,7 +1244,7 @@ typecmp (int staticp, int varargs, int nargs,
 
 static struct value *
 search_struct_field (char *name, struct value *arg1, int offset,
-                    register struct type *type, int looking_for_baseclass)
+                    struct type *type, int looking_for_baseclass)
 {
   int i;
   int nbases = TYPE_N_BASECLASSES (type);
@@ -1510,7 +1484,7 @@ find_rt_vbase_offset (struct type *type, struct type *basetype, char *valaddr,
 static struct value *
 search_struct_method (char *name, struct value **arg1p,
                      struct value **args, int offset,
-                     int *static_memfuncp, register struct type *type)
+                     int *static_memfuncp, struct type *type)
 {
   int i;
   struct value *v;
@@ -1655,7 +1629,7 @@ struct value *
 value_struct_elt (struct value **argp, struct value **args,
                  char *name, int *static_memfuncp, char *err)
 {
-  register struct type *t;
+  struct type *t;
   struct value *v;
 
   COERCE_ARRAY (*argp);
@@ -1936,8 +1910,8 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
   int num_fns = 0;             /* Number of overloaded instances being considered */
   struct type *basetype = NULL;
   int boffset;
-  register int jj;
-  register int ix;
+  int jj;
+  int ix;
   int static_offset;
   struct cleanup *cleanups = NULL;
 
@@ -2176,9 +2150,9 @@ destructor_name_p (const char *name, const struct type *type)
    target structure/union is defined, otherwise, return 0. */
 
 static int
-check_field_in (register struct type *type, const char *name)
+check_field_in (struct type *type, const char *name)
 {
-  register int i;
+  int i;
 
   for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--)
     {
@@ -2219,7 +2193,7 @@ check_field_in (register struct type *type, const char *name)
 int
 check_field (struct value *arg1, const char *name)
 {
-  register struct type *t;
+  struct type *t;
 
   COERCE_ARRAY (arg1);
 
@@ -2245,6 +2219,30 @@ check_field (struct value *arg1, const char *name)
   return check_field_in (t, name);
 }
 
+/* C++: Given an aggregate type CURTYPE, and a member name NAME,
+   return the appropriate member.  This function is used to resolve
+   user expressions of the form "DOMAIN::NAME".  For more details on
+   what happens, see the comment before
+   value_struct_elt_for_reference.  */
+
+struct value *
+value_aggregate_elt (struct type *curtype,
+                    char *name,
+                    enum noside noside)
+{
+  switch (TYPE_CODE (curtype))
+    {
+    case TYPE_CODE_STRUCT:
+    case TYPE_CODE_UNION:
+      return value_struct_elt_for_reference (curtype, 0, curtype, name, NULL);
+    case TYPE_CODE_NAMESPACE:
+      return value_namespace_elt (curtype, name, noside);
+    default:
+      internal_error (__FILE__, __LINE__,
+                     "non-aggregate type in value_aggregate_elt");
+    }
+}
+
 /* C++: Given an aggregate type CURTYPE, and a member name NAME,
    return the address of this member as a "pointer to member"
    type.  If INTYPE is non-null, then it will be the type
@@ -2257,8 +2255,8 @@ value_struct_elt_for_reference (struct type *domain, int offset,
                                struct type *curtype, char *name,
                                struct type *intype)
 {
-  register struct type *t = curtype;
-  register int i;
+  struct type *t = curtype;
+  int i;
   struct value *v;
 
   if (TYPE_CODE (t) != TYPE_CODE_STRUCT
@@ -2385,6 +2383,37 @@ value_struct_elt_for_reference (struct type *domain, int offset,
   return 0;
 }
 
+/* C++: Return the member NAME of the namespace given by the type
+   CURTYPE.  */
+
+static struct value *
+value_namespace_elt (const struct type *curtype,
+                    const char *name,
+                    enum noside noside)
+{
+  const char *namespace_name = TYPE_TAG_NAME (curtype);
+  struct symbol *sym;
+  struct value *retval;
+
+  sym = cp_lookup_symbol_namespace (namespace_name, name, NULL,
+                                   get_selected_block (0), VAR_DOMAIN,
+                                   NULL);
+
+  if (sym == NULL)
+    retval = NULL;
+  else if ((noside == EVAL_AVOID_SIDE_EFFECTS)
+          && (SYMBOL_CLASS (sym) == LOC_TYPEDEF))
+    retval = allocate_value (SYMBOL_TYPE (sym));
+  else
+    retval = value_of_variable (sym, get_selected_block (0));
+
+  if (retval == NULL)
+    error ("No symbol \"%s\" in namespace \"%s\".", name,
+          TYPE_TAG_NAME (curtype));
+
+  return retval;
+}
+
 
 /* Given a pointer value V, find the real (RTTI) type
    of the object it points to.
@@ -2475,7 +2504,6 @@ value_of_local (const char *name, int complain)
 {
   struct symbol *func, *sym;
   struct block *b;
-  int i;
   struct value * ret;
 
   if (deprecated_selected_frame == 0)
@@ -2496,8 +2524,7 @@ value_of_local (const char *name, int complain)
     }
 
   b = SYMBOL_BLOCK_VALUE (func);
-  i = BLOCK_NSYMS (b);
-  if (i <= 0)
+  if (dict_empty (BLOCK_DICT (b)))
     {
       if (complain)
        error ("no args, no `%s'", name);
This page took 0.029632 seconds and 4 git commands to generate.