import gdb-19990422 snapshot
[deliverable/binutils-gdb.git] / gdb / eval.c
index 4a7da00e6028e1a11d056103cbb1fb9d20273dce..d3c346573960294753ec5d74c0f126c03443b29a 100644 (file)
@@ -1,5 +1,5 @@
 /* Evaluate expressions for GDB.
-   Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+   Copyright 1986, 87, 89, 91, 92, 93, 94, 95, 96, 97, 1998
    Free Software Foundation, Inc.
 
 This file is part of GDB.
@@ -29,11 +29,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "demangle.h"
 #include "language.h"  /* For CAST_IS_CONVERSION */
 #include "f-lang.h"    /* for array bound stuff */
-/* start-sanitize-gm */
-#ifdef GENERAL_MAGIC
-#include "gmagic.h"
-#endif /* GENERAL_MAGIC */
-/* end-sanitize-gm */
+
+/* Defined in symtab.c */ 
+extern int hp_som_som_object_present;
+
+/* This is defined in valops.c */ 
+extern int overload_resolution;
+
 
 /* Prototypes for local functions. */
 
@@ -79,7 +81,7 @@ 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);
+      make_cleanup ((make_cleanup_func) free_current_contents, &expr);
 
   addr = value_as_pointer (evaluate_expression (expr));
   do_cleanups (old_chain);
@@ -96,7 +98,7 @@ 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);
+      make_cleanup ((make_cleanup_func) free_current_contents, &expr);
 
   addr = value_as_pointer (evaluate_expression (expr));
   do_cleanups (old_chain);
@@ -110,7 +112,7 @@ parse_and_eval (exp)
   struct expression *expr = parse_expression (exp);
   register value_ptr val;
   register struct cleanup *old_chain
-    = make_cleanup (free_current_contents, &expr);
+    = make_cleanup ((make_cleanup_func) free_current_contents, &expr);
 
   val = evaluate_expression (expr);
   do_cleanups (old_chain);
@@ -128,7 +130,7 @@ parse_to_comma_and_eval (expp)
   struct expression *expr = parse_exp_1 (expp, (struct block *) 0, 1);
   register value_ptr val;
   register struct cleanup *old_chain
-    = make_cleanup (free_current_contents, &expr);
+    = make_cleanup ((make_cleanup_func) free_current_contents, &expr);
 
   val = evaluate_expression (expr);
   do_cleanups (old_chain);
@@ -388,6 +390,11 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
   value_ptr *argvec;
   int upper, lower, retcode; 
   int code;
+  int ix;
+  long mem_offset;
+  struct symbol * sym;
+  struct type ** arg_types;
+  int save_pos1;
 
   /* This expect_type crap should not be used for C.  C expressions do
      not have any notion of expected types, never has and (goddess
@@ -468,9 +475,16 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
        access_value_history (longest_to_int (exp->elts[pc + 1].longconst));
 
     case OP_REGISTER:
-      (*pos) += 2;
-      return value_of_register (longest_to_int (exp->elts[pc + 1].longconst));
+      {
+       int regno     = longest_to_int (exp->elts[pc + 1].longconst);
+       value_ptr val = value_of_register (regno);
 
+       (*pos) += 2;
+       if (val == NULL)
+         error ("Value of register %s not available.", REGISTER_NAME (regno));
+       else
+         return val;
+      }
     case OP_BOOL:
       (*pos) += 2;
       return value_from_longest (LA_BOOL_TYPE,
@@ -694,6 +708,14 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
        {
          LONGEST fnptr;
 
+          /* 1997-08-01 Currently we do not support function invocation
+             via pointers-to-methods with HP aCC. Pointer does not point
+             to the function, but possibly to some thunk. */
+          if (hp_som_som_object_present)
+            {
+              error ("Not implemented: function invocation through pointer to method with HP aCC");
+            }
+
          nargs++;
          /* First, evaluate the structure into arg2 */
          pc2 = (*pos)++;
@@ -797,6 +819,8 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
        }
       else
        {
+         /* Non-method function call */
+         save_pos1 = *pos;
          argvec[0] = evaluate_subexp_with_coercion (exp, pos, noside);
          tem = 1;
          type = VALUE_TYPE (argvec[0]);
@@ -806,16 +830,18 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
            {
              for (; tem <= nargs && tem <= TYPE_NFIELDS (type); tem++)
                {
+                  /* pai: FIXME This seems to be coercing arguments before
+                   * overload resolution has been done! */
                  argvec[tem] = evaluate_subexp (TYPE_FIELD_TYPE (type, tem-1),
                                                 exp, pos, noside);
                }
            }
        }
 
+      /* Evaluate arguments */
       for (; tem <= nargs; tem++)
        {
          /* Ensure that array expressions are coerced into pointer objects. */
-         
          argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
        }
 
@@ -826,23 +852,48 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
        {
          int static_memfuncp;
          value_ptr temp = arg2;
-         char tstr[64];
-
-         argvec[1] = arg2;
-         argvec[0] = 0;
-         strcpy(tstr, &exp->elts[pc2+2].string);
-          if (!argvec[0]) 
-           {
-             temp = arg2;
-             argvec[0] =
-             value_struct_elt (&temp, argvec+1, tstr,
-                             &static_memfuncp,
-                             op == STRUCTOP_STRUCT
-                             ? "structure" : "structure pointer");
-           }
-         arg2 = value_from_longest (lookup_pointer_type(VALUE_TYPE (temp)),
-                        VALUE_ADDRESS (temp)+VALUE_OFFSET (temp));
-         argvec[1] = arg2;
+         char tstr[256];
+          struct fn_field * fns_ptr;
+          int num_fns;
+          struct type * basetype;
+          int boffset;
+
+          /* Method invocation : stuff "this" as first parameter */
+          /* pai: this used to have lookup_pointer_type for some reason,
+           * but temp is already a pointer to the object */
+         argvec[1] = value_from_longest (VALUE_TYPE (temp),
+                                          VALUE_ADDRESS (temp)+VALUE_OFFSET (temp));
+          /* Name of method from expression */ 
+          strcpy(tstr, &exp->elts[pc2+2].string);
+          
+          if (overload_resolution && (exp->language_defn->la_language == language_cplus))
+            {
+              /* Language is C++, do some overload resolution before evaluation */
+              value_ptr valp = NULL;
+              
+              /* Prepare list of argument types for overload resolution */ 
+              arg_types = (struct type **) xmalloc (nargs * (sizeof (struct type *)));
+              for (ix=1; ix <= nargs; ix++)
+                arg_types[ix-1] = VALUE_TYPE (argvec[ix]);
+
+              (void) find_overload_match (arg_types, nargs, tstr,
+                                          1 /* method */, 0 /* strict match */,
+                                          arg2 /* the object */, NULL,
+                                          &valp, NULL, &static_memfuncp);
+
+
+              argvec[1] = arg2;  /* the ``this'' pointer */
+              argvec[0] = valp;  /* use the method found after overload resolution */ 
+            }
+          else /* Non-C++ case -- or no overload resolution */ 
+            {
+              temp = arg2;
+              argvec[0] = value_struct_elt (&temp, argvec+1, tstr,
+                                            &static_memfuncp,
+                                            op == STRUCTOP_STRUCT
+                                            ? "structure" : "structure pointer");
+              argvec[1] = arg2; /* the ``this'' pointer */
+            }
 
          if (static_memfuncp)
            {
@@ -856,6 +907,35 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
          argvec[1] = arg2;
          argvec[0] = arg1;
        }
+      else
+        { 
+         /* Non-member function being called */
+
+          if (overload_resolution && (exp->language_defn->la_language == language_cplus))
+            {
+              /* Language is C++, do some overload resolution before evaluation */
+             struct symbol * symp;
+
+              /* Prepare list of argument types for overload resolution */ 
+              arg_types = (struct type **) xmalloc (nargs * (sizeof (struct type *)));
+              for (ix=1; ix <= nargs; ix++)
+                arg_types[ix-1] = VALUE_TYPE (argvec[ix]);
+
+              (void) find_overload_match (arg_types, nargs, NULL /* no need for name */,
+                                          0 /* not method */, 0 /* strict match */,
+                                          NULL, exp->elts[5].symbol /* the function */,
+                                          NULL, &symp, NULL);
+              
+              /* Now fix the expression being evaluated */ 
+              exp->elts[5].symbol = symp;
+              argvec[0] = evaluate_subexp_with_coercion (exp, &save_pos1, noside);
+            } 
+          else
+            {
+              /* Not C++, or no overload resolution allowed */ 
+              /* nothing to be done; argvec already correctly set up */ 
+            }
+        }
 
     do_call_it:
 
@@ -878,7 +958,10 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
          else
            error ("Expression of type other than \"Function returning ...\" used as function");
        }
+      if (argvec[0] == NULL)
+        error ("Cannot evaluate function -- may be inlined");
       return call_function_by_hand (argvec[0], nargs, argvec + 1);
+      /* pai: FIXME save value from call_function_by_hand, then adjust pc by adjust_fn_pc if +ve  */
 
     case OP_F77_UNDETERMINED_ARGLIST: 
 
@@ -987,43 +1070,40 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
                                   NULL, "structure pointer");
        }
 
-/* start-sanitize-gm */
-#ifdef GENERAL_MAGIC
-    case STRUCTOP_FIELD:
-      tem = longest_to_int (exp->elts[pc + 1].longconst);
-      (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
-      arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
-      if (noside == EVAL_SKIP)
-       goto nosideret;
-      {
-       CORE_ADDR object = value_as_long (arg1);
-       struct type *type = type_of_object (object);
-
-       if (noside == EVAL_AVOID_SIDE_EFFECTS)
-         return value_zero (lookup_struct_elt_type (type,
-                                                    &exp->elts[pc + 2].string,
-                                                    0),
-                            lval_memory);
-       else
-         {
-           value_ptr temp = value_from_longest (builtin_type_unsigned_long,
-                                                baseptr_of_object (value_as_long(arg1)));
-
-           VALUE_TYPE (temp) = type;
-           return value_struct_elt (&temp, NULL, &exp->elts[pc + 2].string,
-                                    NULL, "structure pointer");
-         }
-      }
-#endif /* GENERAL_MAGIC */
-/* end-sanitize-gm */
-
     case STRUCTOP_MEMBER:
       arg1 = evaluate_subexp_for_address (exp, pos, noside);
+      arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+
+      /* With HP aCC, pointers to methods do not point to the function code */ 
+      if (hp_som_som_object_present &&
+          (TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_PTR) &&
+          (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) == TYPE_CODE_METHOD))
+        error ("Pointers to methods not supported with HP aCC"); /* 1997-08-19 */
+        
+      mem_offset = value_as_long (arg2);
       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);
+
+      /* With HP aCC, pointers to methods do not point to the function code */ 
+      if (hp_som_som_object_present &&
+          (TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_PTR) &&
+          (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) == TYPE_CODE_METHOD))
+        error ("Pointers to methods not supported with HP aCC"); /* 1997-08-19 */
+
+      mem_offset = value_as_long (arg2);
+
+handle_pointer_to_member:
+      /* HP aCC generates offsets that have bit #29 set; turn it off to get
+         a real offset to the member. */
+      if (hp_som_som_object_present)
+        {
+          if (!mem_offset) /* no bias -> really null */ 
+            error ("Attempted dereference of null pointer-to-member");
+          mem_offset &= ~0x20000000;
+        }
       if (noside == EVAL_SKIP)
        goto nosideret;
       type = check_typedef (VALUE_TYPE (arg2));
@@ -1038,9 +1118,9 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
       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));
+                                value_as_long (arg1) + mem_offset);
       return value_ind (arg3);
-    bad_pointer_to_member:
+bad_pointer_to_member:
       error("non-pointer-to-member value used in pointer-to-member construct");
 
     case BINOP_CONCAT:
@@ -1056,6 +1136,27 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
     case BINOP_ASSIGN:
       arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
       arg2 = evaluate_subexp (VALUE_TYPE (arg1), exp, pos, noside);
+
+      /* Do special stuff for HP aCC pointers to members */ 
+      if (hp_som_som_object_present)
+        {
+          /* 1997-08-19 Can't assign HP aCC pointers to methods. No details of
+             the implementation yet; but the pointer appears to point to a code
+             sequence (thunk) in memory -- in any case it is *not* the address
+             of the function as it would be in a naive implementation. */ 
+          if ((TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR) &&
+              (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) == TYPE_CODE_METHOD))
+            error ("Assignment to pointers to methods not implemented with HP aCC");
+
+          /* HP aCC pointers to data members require a constant bias */ 
+          if ((TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR) &&
+              (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) == TYPE_CODE_MEMBER))
+              {
+                unsigned int * ptr = (unsigned int *) VALUE_CONTENTS (arg2); /* forces evaluation */ 
+                *ptr |= 0x20000000; /* set 29th bit */
+              }
+        }
+                                                    
       if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
        return arg1;
       if (binop_user_defined_p (op, arg1, arg2))
@@ -1488,16 +1589,22 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
       if (unop_user_defined_p (op, arg1))
        return value_x_unop (arg1, op, noside);
       else
-       return value_from_longest (builtin_type_int,
+       return value_from_longest (LA_BOOL_TYPE,
                                   (LONGEST) value_logical_not (arg1));
 
     case UNOP_IND:
       if (expect_type && TYPE_CODE (expect_type) == TYPE_CODE_PTR)
         expect_type = TYPE_TARGET_TYPE (check_typedef (expect_type));
       arg1 = evaluate_subexp (expect_type, exp, pos, noside);
+      if ((TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) &&
+         ((TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) == TYPE_CODE_METHOD) ||
+          (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) == TYPE_CODE_MEMBER)))
+        error ("Attempt to dereference pointer to member without an object");
       if (noside == EVAL_SKIP)
        goto nosideret;
-      if (noside == EVAL_AVOID_SIDE_EFFECTS)
+      if (unop_user_defined_p (op, arg1))
+       return value_x_unop (arg1, op, noside);
+      else if (noside == EVAL_AVOID_SIDE_EFFECTS)
        {
          type = check_typedef (VALUE_TYPE (arg1));
          if (TYPE_CODE (type) == TYPE_CODE_PTR
@@ -1531,9 +1638,20 @@ evaluate_subexp_standard (expect_type, exp, pos, noside)
            evaluate_subexp (expect_type, exp, pos, EVAL_SKIP);
          goto nosideret;
        }
-
-      return evaluate_subexp_for_address (exp, pos, noside);
-
+      else 
+        {
+          value_ptr retvalp = evaluate_subexp_for_address (exp, pos, noside);
+          /* If HP aCC object, use bias for pointers to members */ 
+          if (hp_som_som_object_present &&
+              (TYPE_CODE (VALUE_TYPE (retvalp)) == TYPE_CODE_PTR) &&
+              (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (retvalp))) == TYPE_CODE_MEMBER))
+            {
+              unsigned int * ptr = (unsigned int *) VALUE_CONTENTS (retvalp); /* forces evaluation */
+              *ptr |= 0x20000000; /* set 29th bit */
+            }
+          return retvalp;
+        }
+      
     case UNOP_SIZEOF:
       if (noside == EVAL_SKIP)
        {
This page took 0.027268 seconds and 4 git commands to generate.