More C++ improvements (pointers to members, qualified names). See ChangeLog.
authorPer Bothner <per@bothner.com>
Fri, 20 Mar 1992 21:57:17 +0000 (21:57 +0000)
committerPer Bothner <per@bothner.com>
Fri, 20 Mar 1992 21:57:17 +0000 (21:57 +0000)
gdb/ChangeLog
gdb/c-exp.y
gdb/eval.c
gdb/valops.c
gdb/value.h
gdb/values.c

index 6fb9b11d9ea5ddc2b76a5629388a7dcc8c99ffe6..346d7189503099503b25291541e0d03d1ef4a819 100644 (file)
@@ -1,3 +1,35 @@
+Thu Mar 19 18:49:45 1992  Per Bothner  (bothner@cygnus.com)
+
+       More C++ improvements (pointers to members, qualified names).
+       * c-exp.y:  Support exp.type::name and exp->type::name
+       syntaxes.  (Unfortunately, doesn't work for static members.)
+       * c-exp.y, eval.c:   Make type::~type work better.
+       * eval.c (evaluate_subexp: OP_SCOPE):  Replace use of
+       value_static_field by value_struct_elt_for_reference.
+       * eval.c (evaluate_subexp):  Merge code for STRUCTOP_MEMBER
+       and STRUCTOP_MPTR; cast arg1 to domain-type of arg2.
+       * eval.c (evaluate_subexp):  Remove special case for UNOP_ADDR
+       for OP_SCOPE operand; no point in it now that we use lazy
+       reading of values, and use "reference to member" objects.
+       * gdbtypes.h:  Clarify comment.
+       * valops.c:  Change value_struct_elt_for_address to return
+       a reference (or variable), rather than a pointer.  Change
+       the name to value_struct_elt_for_reference to reflect this.
+       Returning a reference instead of a address provides a
+       generalization, since we can use the routine for both
+       class::name as well as &class::name.
+       Also, recurse to handle multiple inheritance properly.
+       * valprint.c:  Moved code to print pointer-to-members
+       to new function point_class_member.  This allows a
+       "reference-to-member" to be printed using the same code.
+       * valprint.c (type_print_varspec_prefix):  Avoid printing
+       "struct " for domains of class-member types.
+       * valops.c (search_struct_field):  Inline code for simplified
+       version of value_static_field (which can then be deleted).
+       * value.h:  Rename value_struct_elt_for_address to
+       value_struct_elt_for_reference.  Delete value_static_field.
+       * values.c:  Remove no longer used function value_static_field.
+
 Thu Mar 19 13:54:11 1992  Fred Fish  (fnf@cygnus.com)
 
        * coffread.c, mipsread.c, xcoffread.c, coffread.c, dbxread.c,
index c1316431b5ff13509c608a068035f1395987cbd9..bbf66e00c844571bb89b518ce90586fa9bc4d3ec 100644 (file)
@@ -120,7 +120,7 @@ static int
 parse_number PARAMS ((char *, int, int, YYSTYPE *));
 %}
 
-%type <voidval> exp exp1 type_exp start variable
+%type <voidval> exp exp1 type_exp start variable qualified_name
 %type <tval> type typebase
 %type <tvec> nonempty_typelist
 /* %type <bval> block */
@@ -257,6 +257,13 @@ exp        :       exp ARROW name
                          write_exp_elt_opcode (STRUCTOP_PTR); }
        ;
 
+exp    :       exp ARROW qualified_name
+                       { /* exp->type::name becomes exp->*(&type::name) */
+                         /* Note: this doesn't work if name is a
+                            static member!  FIXME */
+                         write_exp_elt_opcode (UNOP_ADDR);
+                         write_exp_elt_opcode (STRUCTOP_MPTR); }
+       ;
 exp    :       exp ARROW '*' exp
                        { write_exp_elt_opcode (STRUCTOP_MPTR); }
        ;
@@ -267,6 +274,14 @@ exp        :       exp '.' name
                          write_exp_elt_opcode (STRUCTOP_STRUCT); }
        ;
 
+exp    :       exp '.' qualified_name
+                       { /* exp.type::name becomes exp.*(&type::name) */
+                         /* Note: this doesn't work if name is a
+                            static member!  FIXME */
+                         write_exp_elt_opcode (UNOP_ADDR);
+                         write_exp_elt_opcode (STRUCTOP_MEMBER); }
+       ;
+
 exp    :       exp '.' '*' exp
                        { write_exp_elt_opcode (STRUCTOP_MEMBER); }
        ;
@@ -549,7 +564,7 @@ variable:   block COLONCOLON name
                          write_exp_elt_opcode (OP_VAR_VALUE); }
        ;
 
-variable:      typebase COLONCOLON name
+qualified_name:        typebase COLONCOLON name
                        {
                          struct type *type = $1;
                          if (TYPE_CODE (type) != TYPE_CODE_STRUCT
@@ -565,6 +580,7 @@ variable:   typebase COLONCOLON name
        |       typebase COLONCOLON '~' name
                        {
                          struct type *type = $1;
+                         struct stoken tmp_token;
                          if (TYPE_CODE (type) != TYPE_CODE_STRUCT
                              && TYPE_CODE (type) != TYPE_CODE_UNION)
                            error ("`%s' is not defined as an aggregate type.",
@@ -574,12 +590,19 @@ variable: typebase COLONCOLON name
                            error ("invalid destructor `%s::~%s'",
                                   type_name_no_tag (type), $4.ptr);
 
+                         tmp_token.ptr = (char*) alloca ($4.length + 2);
+                         tmp_token.length = $4.length + 1;
+                         tmp_token.ptr[0] = '~';
+                         memcpy (tmp_token.ptr+1, $4.ptr, $4.length);
+                         tmp_token.ptr[tmp_token.length] = 0;
                          write_exp_elt_opcode (OP_SCOPE);
                          write_exp_elt_type (type);
-                         write_exp_string ($4);
+                         write_exp_string (tmp_token);
                          write_exp_elt_opcode (OP_SCOPE);
-                         write_exp_elt_opcode (UNOP_LOGNOT);
                        }
+       ;
+
+variable:      qualified_name
        |       COLONCOLON name
                        {
                          char *name = copy_name ($2);
index aff3a3a1c1ef105ba44c1541768257849aef91cc..c4ba5abb4345718686e694052b95efcd41b77374 100644 (file)
@@ -17,15 +17,45 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
-#include <stdio.h>
 #include "defs.h"
 #include "symtab.h"
+#include "gdbtypes.h"
 #include "value.h"
 #include "expression.h"
 #include "target.h"
 #include "frame.h"
 
-#define        NULL_TYPE       ((struct type *)0)
+/* Values of NOSIDE argument to eval_subexp.  */
+enum noside
+{ EVAL_NORMAL,
+  EVAL_SKIP,                   /* Only effect is to increment pos.  */
+  EVAL_AVOID_SIDE_EFFECTS      /* Don't modify any variables or
+                                  call any functions.  The value
+                                  returned will have the correct
+                                  type, and will have an
+                                  approximately correct lvalue
+                                  type (inaccuracy: anything that is
+                                  listed as being in a register in
+                                  the function in which it was
+                                  declared will be lval_register).  */
+};
+
+/* Prototypes for local functions. */
+
+static value
+evaluate_subexp_for_sizeof PARAMS ((struct expression *, int *));
+
+static value
+evaluate_subexp_with_coercion PARAMS ((struct expression *, int *,
+                                      enum noside));
+
+static value
+evaluate_subexp_for_address PARAMS ((struct expression *, int *,
+                                    enum noside));
+
+static value
+evaluate_subexp PARAMS ((struct type *, struct expression *, int *,
+                        enum noside));
 
 \f
 /* Parse the string EXP as a C expression, evaluate it,
@@ -37,8 +67,8 @@ parse_and_eval_address (exp)
 {
   struct expression *expr = parse_expression (exp);
   register CORE_ADDR addr;
-  register struct cleanup *old_chain
-    = make_cleanup (free_current_contents, &expr);
+  register struct cleanup *old_chain = 
+      make_cleanup (free_current_contents, &expr);
 
   addr = value_as_pointer (evaluate_expression (expr));
   do_cleanups (old_chain);
@@ -54,8 +84,8 @@ parse_and_eval_address_1 (expptr)
 {
   struct expression *expr = parse_exp_1 (expptr, (struct block *)0, 0);
   register CORE_ADDR addr;
-  register struct cleanup *old_chain
-    = make_cleanup (free_current_contents, &expr);
+  register struct cleanup *old_chain =
+      make_cleanup (free_current_contents, &expr);
 
   addr = value_as_pointer (evaluate_expression (expr));
   do_cleanups (old_chain);
@@ -104,21 +134,6 @@ static value evaluate_subexp_for_address ();
 static value evaluate_subexp_for_sizeof ();
 static value evaluate_subexp_with_coercion ();
 
-/* Values of NOSIDE argument to eval_subexp.  */
-enum noside
-{ EVAL_NORMAL,
-  EVAL_SKIP,                   /* Only effect is to increment pos.  */
-  EVAL_AVOID_SIDE_EFFECTS      /* Don't modify any variables or
-                                  call any functions.  The value
-                                  returned will have the correct
-                                  type, and will have an
-                                  approximately correct lvalue
-                                  type (inaccuracy: anything that is
-                                  listed as being in a register in
-                                  the function in which it was
-                                  declared will be lval_register).  */
-};
-
 value
 evaluate_expression (exp)
      struct expression *exp;
@@ -149,6 +164,7 @@ evaluate_subexp (expect_type, exp, pos, noside)
   int tem;
   register int pc, pc2, oldpos;
   register value arg1, arg2, arg3;
+  struct type *type;
   int nargs;
   value *argvec;
 
@@ -161,8 +177,10 @@ evaluate_subexp (expect_type, exp, pos, noside)
       tem = strlen (&exp->elts[pc + 2].string);
       (*pos) += 3 + ((tem + sizeof (union exp_element))
                     / sizeof (union exp_element));
-      arg1 = value_static_field (exp->elts[pc + 1].type,
-                                &exp->elts[pc + 2].string, -1);
+      arg1 = value_struct_elt_for_reference (exp->elts[pc + 1].type,
+                                            exp->elts[pc + 1].type,
+                                            &exp->elts[pc + 2].string,
+                                            expect_type);
       if (arg1 == NULL)
        error ("There is no field named %s", &exp->elts[pc + 2].string);
       return arg1;
@@ -448,35 +466,28 @@ evaluate_subexp (expect_type, exp, pos, noside)
 
     case STRUCTOP_MEMBER:
       arg1 = evaluate_subexp_for_address (exp, pos, noside);
-      arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
-      if (noside == EVAL_SKIP)
-       goto nosideret;
-      /* Now, convert these values to an address.  */
-      if (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_PTR
-         || ((TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2)))
-              != TYPE_CODE_MEMBER)
-             && (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2)))
-                 != TYPE_CODE_METHOD)))
-       error ("non-pointer-to-member value used in pointer-to-member construct");
-      arg3 = value_from_longest (
-       lookup_pointer_type (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2)))),
-                             value_as_long (arg1) + value_as_long (arg2));
-      return value_ind (arg3);
-
+      goto handle_pointer_to_member;
     case STRUCTOP_MPTR:
       arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+    handle_pointer_to_member:
       arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
       if (noside == EVAL_SKIP)
        goto nosideret;
+      if (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_PTR)
+       goto bad_pointer_to_member;
+      type = TYPE_TARGET_TYPE (VALUE_TYPE (arg2));
+      if (TYPE_CODE (type) == TYPE_CODE_METHOD)
+       error ("not implemented: pointer-to-method in pointer-to-member construct");
+      if (TYPE_CODE (type) != TYPE_CODE_MEMBER)
+       goto bad_pointer_to_member;
       /* Now, convert these values to an address.  */
-      if (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_PTR
-         || (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) != TYPE_CODE_MEMBER
-             && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) != TYPE_CODE_METHOD))
-       error ("non-pointer-to-member value used in pointer-to-member construct");
-      arg3 = value_from_longest (
-       lookup_pointer_type (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2)))),
-                             value_as_long (arg1) + value_as_long (arg2));
+      arg1 = value_cast (lookup_pointer_type (TYPE_DOMAIN_TYPE (type)),
+                        arg1);
+      arg3 = value_from_longest (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
+                                value_as_long (arg1) + value_as_long (arg2));
       return value_ind (arg3);
+    bad_pointer_to_member:
+      error("non-pointer-to-member value used in pointer-to-member construct");
 
     case BINOP_ASSIGN:
       arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
@@ -732,10 +743,6 @@ evaluate_subexp (expect_type, exp, pos, noside)
       /* C++: check for and handle destructor names.  */
       op = exp->elts[*pos].opcode;
 
-      /* FIXME-tiemann: this is a cop-out.  */
-      if (op == OP_SCOPE)
-       error ("destructor in eval");
-
       arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
       if (noside == EVAL_SKIP)
        goto nosideret;
@@ -795,19 +802,7 @@ evaluate_subexp (expect_type, exp, pos, noside)
          goto nosideret;
        }
 
-      if (op == OP_SCOPE)
-       {
-         char *name = &exp->elts[pc+3].string;
-         int temm = strlen (name);
-         struct type *domain = exp->elts[pc+2].type;
-         (*pos) += 2 + (temm + sizeof (union exp_element)) / sizeof (union exp_element);
-         arg1 = value_struct_elt_for_address (domain, expect_type, name);
-         if (arg1)
-           return arg1;
-         error ("no field `%s' in structure", name);
-       }
-      else
-       return evaluate_subexp_for_address (exp, pos, noside);
+      return evaluate_subexp_for_address (exp, pos, noside);
 
     case UNOP_SIZEOF:
       if (noside == EVAL_SKIP)
index 83d6ec89c9367aafe33b9cf94a4d36f9609f2b09..1213e9ed18965d0e73da286e64739dee368fabbe 100644 (file)
@@ -17,9 +17,9 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
-#include <stdio.h>
 #include "defs.h"
 #include "symtab.h"
+#include "gdbtypes.h"
 #include "value.h"
 #include "frame.h"
 #include "inferior.h"
@@ -29,7 +29,26 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <errno.h>
 
 /* Local functions.  */
-static value search_struct_field ();
+
+static CORE_ADDR
+find_function_addr PARAMS ((value, struct type **));
+
+static CORE_ADDR
+value_push PARAMS ((CORE_ADDR, value));
+
+static CORE_ADDR
+value_arg_push PARAMS ((CORE_ADDR, value));
+
+static value
+search_struct_field PARAMS ((char *, value, int, struct type *, int));
+
+static value
+search_struct_method PARAMS ((char *, value, value *, int, int *,
+                             struct type *));
+
+static int
+check_field_in PARAMS ((struct type *, const char *));
+
 \f
 /* 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,
@@ -238,7 +257,7 @@ value_assign (toval, fromval)
        {
          int v;                /* FIXME, this won't work for large bitfields */
          read_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
-                      &v, sizeof v);
+                      (char *) &v, sizeof v);
          modify_field ((char *) &v, (int) value_as_long (fromval),
                        VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
          write_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
@@ -450,7 +469,6 @@ value
 value_addr (arg1)
      value arg1;
 {
-  extern value value_copy ();
   struct type *type = VALUE_TYPE (arg1);
   if (TYPE_CODE (type) == TYPE_CODE_REF)
     {
@@ -543,7 +561,7 @@ push_bytes (sp, buffer, len)
 
 /* Push onto the stack the specified value VALUE.  */
 
-CORE_ADDR
+static CORE_ADDR
 value_push (sp, arg)
      register CORE_ADDR sp;
      value arg;
@@ -588,7 +606,7 @@ value_arg_coerce (arg)
 /* Push the value ARG, first coercing it as an argument
    to a C function.  */
 
-CORE_ADDR
+static CORE_ADDR
 value_arg_push (sp, arg)
      register CORE_ADDR sp;
      value arg;
@@ -599,7 +617,7 @@ value_arg_push (sp, arg)
 /* Determine a function's address and its return type from its value. 
    Calls error() if the function is not valid for calling.  */
 
-CORE_ADDR
+static CORE_ADDR
 find_function_addr (function, retval_type)
      value function;
      struct type **retval_type;
@@ -941,13 +959,13 @@ value_string (ptr, len)
     }
   else
     {
-      register int j;
-      j = lookup_misc_func ("malloc");
-      if (j >= 0)
-       val = value_from_longest (
-               lookup_pointer_type (lookup_function_type (
-                                     lookup_pointer_type (builtin_type_char))),
-                              (LONGEST) misc_function_vector[j].address);
+      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\".");
     }
@@ -988,9 +1006,20 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
 
        if (t_field_name && !strcmp (t_field_name, name))
          {
-           value v = (TYPE_FIELD_STATIC (type, i)
-                      ? value_static_field (type, name, i)
-                      : value_primitive_field (arg1, offset, i, type));
+           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);
+               v = value_at (TYPE_FIELD_TYPE (type, i),
+                             (CORE_ADDR)SYMBOL_BLOCK_VALUE (sym));
+             }
+           else
+             v = value_primitive_field (arg1, offset, i, type);
            if (v == 0)
              error("there is no field named %s", name);
            return v;
@@ -1016,10 +1045,8 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
            return v2;
          v = search_struct_field (name, v2, 0, TYPE_BASECLASS (type, i),
                                   looking_for_baseclass);
-         if (v) return v;
-         else continue;
        }
-      if (found_baseclass)
+      else if (found_baseclass)
        v = value_primitive_field (arg1, offset, i, type);
       else
        v = search_struct_field (name, arg1,
@@ -1076,23 +1103,23 @@ search_struct_method (name, arg1, args, offset, static_memfuncp, type)
 
   for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
     {
-      value v;
+      value v, v2;
+      int base_offset;
 
       if (BASETYPE_VIA_VIRTUAL (type, i))
        {
-         value v2;
          baseclass_addr (type, i, VALUE_CONTENTS (arg1) + offset,
                          &v2, (int *)NULL);
          if (v2 == 0)
            error ("virtual baseclass botch");
-         v = search_struct_method (name, v2, args, 0,
-                                   static_memfuncp, TYPE_BASECLASS (type, i));
-         if (v) return v;
-         else continue;
+         base_offset = 0;
        }
-
-      v = search_struct_method (name, arg1, args,
-                               TYPE_BASECLASS_BITPOS (type, i) / 8,
+      else
+       {
+         v2 = arg1;
+         base_offset = TYPE_BASECLASS_BITPOS (type, i) / 8;
+        }
+      v = search_struct_method (name, v2, args, base_offset,
                                static_memfuncp, TYPE_BASECLASS (type, i));
       if (v) return v;
     }
@@ -1234,7 +1261,7 @@ destructor_name_p (name, type)
 static int
 check_field_in (type, name)
      register struct type *type;
-     char *name;
+     const char *name;
 {
   register int i;
 
@@ -1272,7 +1299,7 @@ check_field_in (type, name)
 
 int
 check_field (arg1, name)
-     register const value arg1;
+     register value arg1;
      const char *name;
 {
   register struct type *t;
@@ -1296,70 +1323,56 @@ check_field (arg1, name)
   return check_field_in (t, name);
 }
 
-/* C++: Given an aggregate type DOMAIN, and a member name NAME,
+/* 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
    of the member we are looking for.  This will help us resolve
-   "pointers to member functions".  This function is only used
-   to resolve user expressions of the form "&class::member".  */
+   "pointers to member functions".  This function is used
+   to resolve user expressions of the form "DOMAIN::NAME".  */
 
 value
-value_struct_elt_for_address (domain, intype, name)
-     struct type *domain, *intype;
+value_struct_elt_for_reference (domain, curtype, name, intype)
+     struct type *domain, *curtype, *intype;
      char *name;
 {
-  register struct type *t = domain;
+  register struct type *t = curtype;
   register int i;
   value v;
 
-  struct type *baseclass;
-
   if (   TYPE_CODE (t) != TYPE_CODE_STRUCT
       && TYPE_CODE (t) != TYPE_CODE_UNION)
-    error ("Internal error: non-aggregate type to value_struct_elt_for_address");
-
-  baseclass = t;
+    error ("Internal error: non-aggregate type to value_struct_elt_for_reference");
 
-  while (t)
+  for (i = TYPE_NFIELDS (t) - 1; i >= TYPE_N_BASECLASSES (t); i--)
     {
-      for (i = TYPE_NFIELDS (t) - 1; i >= TYPE_N_BASECLASSES (t); i--)
+      char *t_field_name = TYPE_FIELD_NAME (t, i);
+      
+      if (t_field_name && !strcmp (t_field_name, name))
        {
-         char *t_field_name = TYPE_FIELD_NAME (t, i);
-
-         if (t_field_name && !strcmp (t_field_name, name))
+         if (TYPE_FIELD_STATIC (t, i))
            {
-             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",
-                          phys_name);
-                 return value_from_longest (
-                       lookup_pointer_type (TYPE_FIELD_TYPE (t, i)),
-                                     (LONGEST)SYMBOL_BLOCK_VALUE (sym));
-               }
-             if (TYPE_FIELD_PACKED (t, i))
-               error ("pointers to bitfield members not allowed");
-
-             return value_from_longest (
-                   lookup_pointer_type (
-                     lookup_member_type (TYPE_FIELD_TYPE (t, i), baseclass)),
-                                  (LONGEST) (TYPE_FIELD_BITPOS (t, i) >> 3));
+             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",
+                      phys_name);
+             return value_at (SYMBOL_TYPE (sym),
+                              (CORE_ADDR)SYMBOL_BLOCK_VALUE (sym));
            }
+         if (TYPE_FIELD_PACKED (t, i))
+           error ("pointers to bitfield members not allowed");
+         
+         return value_from_longest
+           (lookup_reference_type (lookup_member_type (TYPE_FIELD_TYPE (t, i),
+                                                       domain)),
+            (LONGEST) (TYPE_FIELD_BITPOS (t, i) >> 3));
        }
-
-      if (TYPE_N_BASECLASSES (t) == 0)
-       break;
-
-      t = TYPE_BASECLASS (t, 0);
     }
 
   /* C++: If it was not found as a data field, then try to
      return it as a pointer to a method.  */
-  t = baseclass;
 
   /* Destructors are a special case.  */
   if (destructor_name_p (name, t))
@@ -1371,55 +1384,59 @@ value_struct_elt_for_address (domain, intype, name)
   while (intype && TYPE_CODE (intype) == TYPE_CODE_PTR)
     intype = TYPE_TARGET_TYPE (intype);
 
-  while (t)
+  for (i = TYPE_NFN_FIELDS (t) - 1; i >= 0; --i)
     {
-      for (i = TYPE_NFN_FIELDS (t) - 1; i >= 0; --i)
+      if (!strcmp (TYPE_FN_FIELDLIST_NAME (t, i), name))
        {
-         if (!strcmp (TYPE_FN_FIELDLIST_NAME (t, i), name))
+         int j = TYPE_FN_FIELDLIST_LENGTH (t, i);
+         struct fn_field *f = TYPE_FN_FIELDLIST1 (t, i);
+         
+         if (intype == 0 && j > 1)
+           error ("non-unique member `%s' requires type instantiation", name);
+         if (intype)
            {
-             int j = TYPE_FN_FIELDLIST_LENGTH (t, i);
-             struct fn_field *f = TYPE_FN_FIELDLIST1 (t, i);
-
-             if (intype == 0 && j > 1)
-               error ("non-unique member `%s' requires type instantiation", name);
-             if (intype)
-               {
-                 while (j--)
-                   if (TYPE_FN_FIELD_TYPE (f, j) == intype)
-                     break;
-                 if (j < 0)
-                   error ("no member function matches that type instantiation");
-               }
-             else
-               j = 0;
-
-             if (TYPE_FN_FIELD_STUB (f, j))
-               check_stub_method (t, i, j);
-             if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
-               {
-                 return value_from_longest (
-                       lookup_pointer_type (
-                         lookup_member_type (TYPE_FN_FIELD_TYPE (f, j),
-                                             baseclass)),
-                                      (LONGEST) TYPE_FN_FIELD_VOFFSET (f, j));
-               }
-             else
-               {
-                 struct symbol *s = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, j),
-                                                   0, VAR_NAMESPACE, 0, NULL);
-                 v = locate_var_value (s, 0);
-                 VALUE_TYPE (v) = lookup_pointer_type (
-                       lookup_member_type (TYPE_FN_FIELD_TYPE (f, j),
-                                           baseclass));
-                 return v;
+             while (j--)
+               if (TYPE_FN_FIELD_TYPE (f, j) == intype)
+                 break;
+             if (j < 0)
+               error ("no member function matches that type instantiation");
+           }
+         else
+           j = 0;
+         
+         if (TYPE_FN_FIELD_STUB (f, j))
+           check_stub_method (t, i, j);
+         if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
+           {
+             return value_from_longest
+               (lookup_reference_type
+                (lookup_member_type (TYPE_FN_FIELD_TYPE (f, j),
+                                     domain)),
+                (LONGEST) 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 0
+             VALUE_TYPE (v) = lookup_reference_type
+               (lookup_member_type (TYPE_FN_FIELD_TYPE (f, j),
+                                    domain));
+#endif
+             return v;
                }
            }
        }
 
-      if (TYPE_N_BASECLASSES (t) == 0)
-       break;
-
-      t = TYPE_BASECLASS (t, 0);
+  for (i = TYPE_N_BASECLASSES (t) - 1; i >= 0; i--)
+    {
+      v = value_struct_elt_for_reference (domain,
+                                         TYPE_BASECLASS (t, i),
+                                         name,
+                                         intype);
+      if (v)
+       return v;
     }
   return 0;
 }
index a6840d17f79b95f044c5bb0194695a8b4c16a459..7333578b276339f946dce260b77da5be62fda27b 100644 (file)
@@ -19,6 +19,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #if !defined (VALUE_H)
 #define VALUE_H 1
+
 /*
  * The structure which defines the type of a value.  It should never
  * be possible for a program lval value to survive over a call to the inferior
@@ -120,7 +121,9 @@ typedef struct value *value;
 #define VALUE_CONTENTS_RAW(val) ((char *) (val)->aligner.contents)
 #define VALUE_CONTENTS(val) ((void)(VALUE_LAZY(val) && value_fetch_lazy(val)),\
                             VALUE_CONTENTS_RAW(val))
-extern int value_fetch_lazy ();
+extern int
+value_fetch_lazy PARAMS ((value val));
+
 #define VALUE_LVAL(val) (val)->lval
 #define VALUE_ADDRESS(val) (val)->location.address
 #define VALUE_INTERNALVAR(val) (val)->location.internalvar
@@ -178,124 +181,287 @@ struct internalvar
   char *name;
   value value;
 };
+
 \f
 #include "symtab.h"
-LONGEST value_as_long (
-#ifdef __STDC__
-                      value
-#endif
-                      );
-double value_as_double (
-#ifdef __STDC__
-                       value
-#endif
-                       );
-CORE_ADDR value_as_pointer (
-#ifdef __STDC__
-                           value
-#endif
-                           );
-LONGEST unpack_long (
-#ifdef __STDC__
-                    struct type *, char *
-#endif
-                    );
-double unpack_double (
-#ifdef __STDC__
-                     struct type *, char *, int *
-#endif
-                     );
-CORE_ADDR unpack_pointer (
+#include "gdbtypes.h"
+#include "expression.h"
+
 #ifdef __STDC__
-                         struct type *, char *
+struct frame_info;
 #endif
-                         );
-long unpack_field_as_long ();
-value value_from_longest ();
-value value_from_double ();
-value value_at ();
-value value_at_lazy ();
-value value_from_register ();
-value value_of_variable ();
-value value_of_register ();
-value read_var_value ();
-value locate_var_value ();
-value allocate_value ();
-value allocate_repeat_value ();
-value value_mark ();
-void value_free_to_mark ();
-value value_string ();
-
-value value_binop ();
-value value_add ();
-value value_sub ();
-value value_coerce_array ();
-value value_coerce_function ();
-value value_ind ();
-value value_addr ();
-value value_assign ();
-value value_neg ();
-value value_lognot ();
-value value_struct_elt (), value_struct_elt_for_address ();
-value value_field (), value_primitive_field ();
-value value_cast ();
-value value_zero ();
-value value_repeat ();
-value value_subscript ();
-value value_from_vtable_info ();
-
-value value_being_returned ();
-int using_struct_return ();
-void set_return_value ();
-
-value evaluate_expression ();
-value evaluate_type ();
-value parse_and_eval ();
-value parse_to_comma_and_eval ();
-struct type *parse_and_eval_type ();
-extern CORE_ADDR parse_and_eval_address ();
-extern CORE_ADDR parse_and_eval_address_1 ();
-
-value access_value_history ();
-value value_of_internalvar ();
-void set_internalvar ();
-void set_internalvar_component ();
-struct internalvar *lookup_internalvar ();
-
-int value_equal ();
-int value_less ();
-int value_zerop ();
+
+extern void
+print_address_demangle PARAMS ((CORE_ADDR, FILE *, int));
+
+extern LONGEST
+value_as_long PARAMS ((value val));
+
+extern double
+value_as_double PARAMS ((value val));
+
+extern CORE_ADDR
+value_as_pointer PARAMS ((value val));
+
+extern LONGEST
+unpack_long PARAMS ((struct type *type, char *valaddr));
+
+extern double
+unpack_double PARAMS ((struct type *type, char *valaddr, int *invp));
+
+extern CORE_ADDR
+unpack_pointer PARAMS ((struct type *type, char *valaddr));
+
+extern long
+unpack_field_as_long PARAMS ((struct type *type, char *valaddr,
+                             int fieldno));
+
+extern value
+value_from_longest PARAMS ((struct type *type, LONGEST num));
+
+extern value
+value_from_double PARAMS ((struct type *type, double num));
+
+extern value
+value_at PARAMS ((struct type *type, CORE_ADDR addr));
+
+extern value
+value_at_lazy PARAMS ((struct type *type, CORE_ADDR addr));
+
+/* FIXME:  Assumes equivalence of "struct frame_info *" and "FRAME" */
+extern value
+value_from_register PARAMS ((struct type *type, int regnum,
+                            struct frame_info * frame));
+
+extern value
+value_of_variable PARAMS ((struct symbol *var));
+
+extern value
+value_of_register PARAMS ((int regnum));
+
+/* FIXME:  Assumes equivalence of "struct frame_info *" and "FRAME" */
+extern value
+read_var_value PARAMS ((struct symbol *var, struct frame_info *frame));
+
+/* FIXME:  Assumes equivalence of "struct frame_info *" and "FRAME" */
+extern value
+locate_var_value PARAMS ((struct symbol *var, struct frame_info *frame));
+
+extern value
+allocate_value PARAMS ((struct type *type));
+
+extern value
+allocate_repeat_value PARAMS ((struct type *type, int count));
+
+extern value
+value_mark PARAMS ((void));
+
+extern void
+value_free_to_mark PARAMS ((value mark));
+
+extern value
+value_string PARAMS ((char *ptr, int len));
+
+extern value
+value_binop PARAMS ((value arg1, value arg2, enum exp_opcode op));
+
+extern value
+value_add PARAMS ((value arg1, value arg2));
+
+extern value
+value_sub PARAMS ((value arg1, value arg2));
+
+extern value
+value_coerce_array PARAMS ((value arg1));
+
+extern value
+value_coerce_function PARAMS ((value arg1));
+
+extern value
+value_ind PARAMS ((value arg1));
+
+extern value
+value_addr PARAMS ((value arg1));
+
+extern value
+value_assign PARAMS ((value toval, value fromval));
+
+extern value
+value_neg PARAMS ((value arg1));
+
+extern value
+value_lognot PARAMS ((value arg1));
+
+extern value
+value_struct_elt PARAMS ((value *argp, value *args, char *name,
+                         int *static_memfuncp, char *err));
+
+extern value
+value_struct_elt_for_reference PARAMS ((struct type *domain,
+                                       struct type *curtype,
+                                       char *name,
+                                       struct type *intype));
+
+extern value
+value_field PARAMS ((value arg1, int fieldno));
+
+extern value
+value_primitive_field PARAMS ((value arg1, int offset, int fieldno,
+                              struct type *arg_type));
+
+extern value
+value_cast PARAMS ((struct type *type, value arg2));
+
+extern value
+value_zero PARAMS ((struct type *type, enum lval_type lv));
+
+extern value
+value_repeat PARAMS ((value arg1, int count));
+
+extern value
+value_subscript PARAMS ((value array, value idx));
+
+extern value
+value_from_vtable_info PARAMS ((value arg, struct type *type));
+
+extern value
+value_being_returned PARAMS ((struct type *valtype, 
+                             char retbuf[REGISTER_BYTES],
+                             int struct_return));
+
+extern int
+using_struct_return PARAMS ((value function, CORE_ADDR funcaddr,
+                            struct type *value_type, int gcc_p));
+
+extern void
+set_return_value PARAMS ((value val));
+
+extern value
+evaluate_expression PARAMS ((struct expression *exp));
+
+extern value
+evaluate_type PARAMS ((struct expression *exp));
+
+extern value
+parse_and_eval PARAMS ((char *exp));
+
+extern value
+parse_to_comma_and_eval PARAMS ((char **expp));
+
+extern struct type *
+parse_and_eval_type PARAMS ((char *p, int length));
+
+extern CORE_ADDR
+parse_and_eval_address PARAMS ((char *exp));
+
+extern CORE_ADDR
+parse_and_eval_address_1 PARAMS ((char **expptr));
+
+extern value
+access_value_history PARAMS ((int num));
+
+extern value
+value_of_internalvar PARAMS ((struct internalvar *var));
+
+extern void
+set_internalvar PARAMS ((struct internalvar *var, value val));
+
+extern void
+set_internalvar_component PARAMS ((struct internalvar *var, int offset,
+                                  int bitpos, int bitsize,
+                                  value newvalue));
+
+extern struct internalvar *
+lookup_internalvar PARAMS ((char *name));
+
+extern int
+value_equal PARAMS ((value arg1, value arg2));
+
+extern int
+value_less PARAMS ((value arg1, value arg2));
+
+extern int
+value_zerop PARAMS ((value arg1));
 
 /* C++ */
-value value_of_this ();
-value value_static_field ();
-value value_x_binop ();
-value value_x_unop ();
-value value_fn_field ();
-value value_virtual_fn_field ();
-int binop_user_defined_p ();
-int unop_user_defined_p ();
-int typecmp ();
-void fill_in_vptr_fieldno ();
-int destructor_name_p ();
+
+extern value
+value_of_this PARAMS ((int complain));
+
+extern value
+value_x_binop PARAMS ((value arg1, value arg2, enum exp_opcode op,
+                      enum exp_opcode otherop));
+
+extern value
+value_x_unop PARAMS ((value arg1, enum exp_opcode op));
+
+extern value
+value_fn_field PARAMS ((struct fn_field *f, int j));
+
+extern value
+value_virtual_fn_field PARAMS ((value arg1, struct fn_field *f, int j,
+                               struct type *type));
+
+extern int
+binop_user_defined_p PARAMS ((enum exp_opcode op, value arg1, value arg2));
+
+extern int
+unop_user_defined_p PARAMS ((enum exp_opcode op, value arg1));
+
+extern int
+typecmp PARAMS ((int staticp, struct type *t1[], value t2[]));
+
+extern int
+destructor_name_p PARAMS ((const char *name, const struct type *type));
 
 #define value_free(val) free (val)
-void free_all_values ();
-void release_value ();
-int record_latest_value ();
-
-void registers_changed ();
-void read_register_bytes ();
-void write_register_bytes ();
-void read_register_gen ();
-CORE_ADDR read_register ();
-void write_register ();
-void supply_register ();
-void get_saved_register ();
-
-void modify_field ();
-void type_print ();
-void type_print_1 ();
+
+extern void
+free_all_values PARAMS ((void));
+
+extern void
+release_value PARAMS ((value val));
+
+extern int
+record_latest_value PARAMS ((value val));
+
+extern void
+registers_changed PARAMS ((void));
+
+extern void
+read_register_bytes PARAMS ((int regbyte, char *myaddr, int len));
+
+extern void
+write_register_bytes PARAMS ((int regbyte, char *myaddr, int len));
+
+extern void
+read_register_gen PARAMS ((int regno, char *myaddr));
+
+extern CORE_ADDR
+read_register PARAMS ((int regno));
+
+extern void
+write_register PARAMS ((int regno, int val));
+
+extern void
+supply_register PARAMS ((int regno, char *val));
+
+/* FIXME:  Assumes equivalence of "struct frame_info *" and "FRAME" */
+extern void
+get_saved_register PARAMS ((char *raw_buffer, int *optimized,
+                           CORE_ADDR *addrp, struct frame_info *frame,
+                           int regnum, enum lval_type *lval));
+
+extern void
+modify_field PARAMS ((char *addr, int fieldval, int bitpos, int bitsize));
+
+extern void
+type_print PARAMS ((struct type *type, char *varstring, FILE *stream,
+                   int show));
+
+extern void
+type_print_1 PARAMS ((struct type *type, char *varstring, FILE *stream,
+                     int show, int level));
 
 /* Possibilities for prettyprint parameters to routines which print
    things.  */
@@ -306,17 +472,53 @@ enum val_prettyprint {
   Val_pretty_default
   };
 
-char *baseclass_addr ();
-void print_floating ();
-int value_print ();
-int val_print ();
-void print_variable_value ();
-void typedef_print ();
-char *internalvar_name ();
-void clear_value_history ();
-void clear_internalvars ();
+extern char *
+baseclass_addr PARAMS ((struct type *type, int index, char *valaddr,
+                       value *valuep, int *errp));
+
+extern void
+print_floating PARAMS ((char *valaddr, struct type *type, FILE *stream));
+
+extern int
+value_print PARAMS ((value val, FILE *stream, int format,
+                    enum val_prettyprint pretty));
+
+extern int
+val_print PARAMS ((struct type *type, char *valaddr, CORE_ADDR address,
+                  FILE *stream, int format, int deref_ref,
+                  int recurse, enum val_prettyprint pretty));
+
+/* FIXME:  Assumes equivalence of "struct frame_info *" and "FRAME" */
+extern void
+print_variable_value PARAMS ((struct symbol *var, struct frame_info *frame,
+                             FILE *stream));
+
+extern value
+value_arg_coerce PARAMS ((value));
+
+extern int
+check_field PARAMS ((value, const char *));
+
+extern void
+typedef_print PARAMS ((struct type *type, struct symbol *new, FILE *stream));
+
+extern char *
+internalvar_name PARAMS ((struct internalvar *var));
+
+extern void
+clear_value_history PARAMS ((void));
+
+extern void
+clear_internalvars PARAMS ((void));
+
+/* From values.c */
+
+extern value
+value_copy PARAMS ((value));
+
+/* From valops.c */
 
 extern value
-call_function_by_hand PARAMS ((value, int value *));
+call_function_by_hand PARAMS ((value, int, value *));
 
-#endif /* value.h not already included.  */
+#endif /* !defined (VALUE_H) */
index bb5fa68c29d48aee69eee0c831838071c6253752..3dc1accff4c2a6bf13221c4e31e3d034753d90b4 100644 (file)
@@ -1101,81 +1101,6 @@ value_from_vtable_info (arg, type)
   return value_headof (arg, 0, type);
 }
 
-/* The value of a static class member does not depend
-   on its instance, only on its type.  If FIELDNO >= 0,
-   then fieldno is a valid field number and is used directly.
-   Otherwise, FIELDNAME is the name of the field we are
-   searching for.  If it is not a static field name, an
-   error is signaled.  TYPE is the type in which we look for the
-   static field member.
-
-   Return zero if we couldn't find anything; the caller may signal
-   an error in that case.  */
-
-value
-value_static_field (type, fieldname, fieldno)
-     register struct type *type;
-     char *fieldname;
-     register int fieldno;
-{
-  register value v;
-  struct symbol *sym;
-  char *phys_name;
-
-  if (fieldno < 0)
-    {
-      char **physnames;
-      struct symbol **sym_arr;
-      /* Look for static field.  */
-      int i;
-      for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--)
-       if (! strcmp (TYPE_FIELD_NAME (type, i), fieldname))
-         {
-           if (TYPE_FIELD_STATIC (type, i))
-             {
-               fieldno = i;
-               goto found;
-             }
-           else
-             error ("field `%s' is not static", fieldname);
-         }
-      for (; i > 0; i--)
-       {
-         v = value_static_field (TYPE_BASECLASS (type, i), fieldname, -1);
-         if (v != 0)
-           return v;
-       }
-
-      sym_arr = (struct symbol **)
-         alloca(TYPE_NFN_FIELDS_TOTAL (type) * sizeof(struct symbol*));
-      physnames = (char **)
-         alloca (TYPE_NFN_FIELDS_TOTAL (type) * sizeof(char*));
-      /* Note: This does duplicate work, since find_methods does a
-        recursive search *and* so does value_static_field.  FIXME */
-      i = find_methods (type, fieldname, physnames, sym_arr);
-      if (i > 1)
-       error ("Cannot get value of overloaded method \"%s\"", fieldname);
-      else if (i)
-       {
-         struct symbol *sym = sym_arr[0];
-         value val = read_var_value (sym, (FRAME) 0);
-         if (val == 0)
-            error ("Address of method \"%s\" is unknown (possibly inlined).",
-                   fieldname);
-         return val;
-        }
-      error("there is no field named %s", fieldname);
-    }
-
- found:
-  phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, fieldno);
-  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);
-
-  type = TYPE_FIELD_TYPE (type, fieldno);
-  return value_at (type, (CORE_ADDR)SYMBOL_BLOCK_VALUE (sym));
-}
-
 /* Compute the address of the baseclass which is
    the INDEXth baseclass of class TYPE.  The TYPE base
    of the object is at VALADDR.
@@ -1343,7 +1268,8 @@ value_from_longest (type, num)
   /* FIXME, we assume that pointers have the same form and byte order as
      integers, and that all pointers have the same form.  */
   if (code == TYPE_CODE_INT  || code == TYPE_CODE_ENUM || 
-      code == TYPE_CODE_CHAR || code == TYPE_CODE_PTR)
+      code == TYPE_CODE_CHAR || code == TYPE_CODE_PTR ||
+      code == TYPE_CODE_REF)
     {
       if (len == sizeof (char))
        * (char *) VALUE_CONTENTS_RAW (val) = num;