* blockframe.c (block_innermost_frame): Uncomment.
authorJim Kingdon <jkingdon@engr.sgi.com>
Wed, 18 Aug 1993 19:33:39 +0000 (19:33 +0000)
committerJim Kingdon <jkingdon@engr.sgi.com>
Wed, 18 Aug 1993 19:33:39 +0000 (19:33 +0000)
Return NULL if passed NULL.
* frame.h: Declare it.
* expression.h (union exp_element): Add field block.
* parse.c (write_exp_elt_block): New function.
* expression.h (OP_VAR_VALUE): Now takes additional struct block *.
* *-exp.y: Write block for OP_VAR_VALUE.
* eval.c, expprint.c, parse.c: Deal with block for OP_VAR_VALUE.
* valops.c, value.h (value_of_variable), callers:
Add second argument, for block.

gdb/ChangeLog
gdb/blockframe.c
gdb/c-exp.y
gdb/ch-exp.y
gdb/eval.c
gdb/frame.h
gdb/m2-exp.y
gdb/parse.c
gdb/valops.c

index ecea9bedcb43cd1b17c3af92474ff7cf11032f3d..c85a36930cbdda191bd7993abfce4858a422af90 100644 (file)
@@ -1,5 +1,16 @@
 Wed Aug 18 12:03:00 1993  Jim Kingdon  (kingdon@lioth.cygnus.com)
 
+       * blockframe.c (block_innermost_frame): Uncomment.
+       Return NULL if passed NULL.
+       * frame.h: Declare it.
+       * expression.h (union exp_element): Add field block.
+       * parse.c (write_exp_elt_block): New function.
+       * expression.h (OP_VAR_VALUE): Now takes additional struct block *.
+       * *-exp.y: Write block for OP_VAR_VALUE.
+       * eval.c, expprint.c, parse.c: Deal with block for OP_VAR_VALUE.
+       * valops.c, value.h (value_of_variable), callers:
+       Add second argument, for block.
+
        * main.c (gdb_readline): If we read some characters followed by EOF,
        return them rather than returning NULL.
 
index 0e5dc1ab6c283368583ecb2a44bb70c9beacaa8d..6430cba7b921b6f4a8a3f2e733629bcac1fc0867 100644 (file)
@@ -724,10 +724,8 @@ find_pc_partial_function (pc, name, address, endaddr)
   return 1;
 }
 
-/* Return the innermost stack frame executing inside of the specified block,
-   or zero if there is no such frame.  */
-
-#if 0  /* Currently unused */
+/* Return the innermost stack frame executing inside of BLOCK,
+   or zero if there is no such frame.  If BLOCK is NULL, just return NULL.  */
 
 FRAME
 block_innermost_frame (block)
@@ -738,6 +736,9 @@ block_innermost_frame (block)
   register CORE_ADDR start = BLOCK_START (block);
   register CORE_ADDR end = BLOCK_END (block);
 
+  if (block == NULL)
+    return NULL;
+
   frame = 0;
   while (1)
     {
@@ -750,8 +751,6 @@ block_innermost_frame (block)
     }
 }
 
-#endif /* 0 */
-
 #ifdef SIGCONTEXT_PC_OFFSET
 /* Get saved user PC for sigtramp from sigcontext for BSD style sigtramp.  */
 
index b841498275b6412c2e36c0773ea8b97df418e773..42e482b357d86e6bf21e297426e8da020ba3b4f5 100644 (file)
@@ -564,6 +564,8 @@ variable:   block COLONCOLON name
                                   copy_name ($3));
 
                          write_exp_elt_opcode (OP_VAR_VALUE);
+                         /* block_found is set by lookup_symbol.  */
+                         write_exp_elt_block (block_found);
                          write_exp_elt_sym (sym);
                          write_exp_elt_opcode (OP_VAR_VALUE); }
        ;
@@ -620,6 +622,7 @@ variable:   qualified_name
                          if (sym)
                            {
                              write_exp_elt_opcode (OP_VAR_VALUE);
+                             write_exp_elt_block (NULL);
                              write_exp_elt_sym (sym);
                              write_exp_elt_opcode (OP_VAR_VALUE);
                              break;
@@ -689,6 +692,10 @@ variable:  name_not_typename
                                  break;
                                }
                              write_exp_elt_opcode (OP_VAR_VALUE);
+                             /* We want to use the selected frame, not
+                                another more inner frame which happens to
+                                be in the same block.  */
+                             write_exp_elt_block (NULL);
                              write_exp_elt_sym (sym);
                              write_exp_elt_opcode (OP_VAR_VALUE);
                            }
index 166d01aebadec0d700aa65e0deaa6a946e3c96d5..58b82ead562cc622261cfc607634de40d72f2033 100644 (file)
@@ -346,6 +346,7 @@ location    :       access_name
 access_name    :       LOCATION_NAME
                        {
                          write_exp_elt_opcode (OP_VAR_VALUE);
+                         write_exp_elt_block (NULL);
                          write_exp_elt_sym ($1.sym);
                          write_exp_elt_opcode (OP_VAR_VALUE);
                        }
@@ -477,6 +478,7 @@ value_name  :       synonym_name
                |       GENERAL_PROCEDURE_NAME
                        {
                          write_exp_elt_opcode (OP_VAR_VALUE);
+                         write_exp_elt_block (NULL);
                          write_exp_elt_sym ($1.sym);
                          write_exp_elt_opcode (OP_VAR_VALUE);
                        }
index 98774bfc419f2e6a54fb531f43b94ebb60ba6af9..4aba99f777b2abf207bed5ef3ca463f9532bad97 100644 (file)
@@ -197,7 +197,7 @@ evaluate_subexp (expect_type, exp, pos, noside)
                                exp->elts[pc + 2].doubleconst);
 
     case OP_VAR_VALUE:
-      (*pos) += 2;
+      (*pos) += 3;
       if (noside == EVAL_SKIP)
        goto nosideret;
       if (noside == EVAL_AVOID_SIDE_EFFECTS)
@@ -226,7 +226,8 @@ evaluate_subexp (expect_type, exp, pos, noside)
          return value_zero (SYMBOL_TYPE (sym), lv);
        }
       else
-       return value_of_variable (exp->elts[pc + 1].symbol);
+       return value_of_variable (exp->elts[pc + 2].symbol,
+                                 exp->elts[pc + 1].block);
 
     case OP_LAST:
       (*pos) += 2;
@@ -373,6 +374,20 @@ evaluate_subexp (expect_type, exp, pos, noside)
 
          if (op == STRUCTOP_STRUCT)
            {
+             /* If v is a variable in a register, and the user types
+                v.method (), this will produce an error, because v has
+                no address.
+
+                A possible way around this would be to allocate a
+                copy of the variable on the stack, copy in the
+                contents, call the function, and copy out the
+                contents.  I.e. convert this from call by reference
+                to call by copy-return (or whatever it's called).
+                However, this does not work because it is not the
+                same: the method being called could stash a copy of
+                the address, and then future uses through that address
+                (after the method returns) would be expected to
+                use the variable itself, not some copy of it.  */
              arg2 = evaluate_subexp_for_address (exp, pos, noside);
            }
          else
@@ -1041,14 +1056,14 @@ evaluate_subexp_for_address (exp, pos, noside)
                         evaluate_subexp (NULL_TYPE, exp, pos, noside));
 
     case OP_VAR_VALUE:
-      var = exp->elts[pc + 1].symbol;
+      var = exp->elts[pc + 2].symbol;
 
       /* C++: The "address" of a reference should yield the address
        * of the object pointed to. Let value_addr() deal with it. */
       if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_REF)
         goto default_case;
 
-      (*pos) += 3;
+      (*pos) += 4;
       if (noside == EVAL_AVOID_SIDE_EFFECTS)
        {
          struct type *type =
@@ -1065,7 +1080,10 @@ evaluate_subexp_for_address (exp, pos, noside)
          value_zero (type, not_lval);
        }
       else
-       return locate_var_value (var, (FRAME) 0);
+       return
+         locate_var_value
+           (var,
+            block_innermost_frame (exp->elts[pc + 1].block));
 
     default:
     default_case:
@@ -1085,14 +1103,15 @@ evaluate_subexp_for_address (exp, pos, noside)
 /* Evaluate like `evaluate_subexp' except coercing arrays to pointers.
    When used in contexts where arrays will be coerced anyway, this is
    equivalent to `evaluate_subexp' but much faster because it avoids
-   actually fetching array contents.
+   actually fetching array contents (perhaps obsolete now that we have
+   VALUE_LAZY).
 
    Note that we currently only do the coercion for C expressions, where
    arrays are zero based and the coercion is correct.  For other languages,
    with nonzero based arrays, coercion loses.  Use CAST_IS_CONVERSION
    to decide if coercion is appropriate.
 
-  */
+   */
 
 static value
 evaluate_subexp_with_coercion (exp, pos, noside)
@@ -1111,17 +1130,21 @@ evaluate_subexp_with_coercion (exp, pos, noside)
   switch (op)
     {
     case OP_VAR_VALUE:
-      var = exp->elts[pc + 1].symbol;
+      var = exp->elts[pc + 2].symbol;
       if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_ARRAY
          && CAST_IS_CONVERSION)
        {
-         (*pos) += 3;
-         val = locate_var_value (var, (FRAME) 0);
+         (*pos) += 4;
+         val =
+           locate_var_value
+             (var, block_innermost_frame (exp->elts[pc + 1].block));
          return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (SYMBOL_TYPE (var))),
                             val);
        }
-      default:
-       return evaluate_subexp (NULL_TYPE, exp, pos, noside);
+      /* FALLTHROUGH */
+
+    default:
+      return evaluate_subexp (NULL_TYPE, exp, pos, noside);
     }
 }
 
@@ -1159,9 +1182,11 @@ evaluate_subexp_for_sizeof (exp, pos)
                              (LONGEST) TYPE_LENGTH (exp->elts[pc + 1].type));
 
     case OP_VAR_VALUE:
-      (*pos) += 3;
-      return value_from_longest (builtin_type_int,
-        (LONGEST) TYPE_LENGTH (SYMBOL_TYPE (exp->elts[pc + 1].symbol)));
+      (*pos) += 4;
+      return
+       value_from_longest
+         (builtin_type_int,
+          (LONGEST) TYPE_LENGTH (SYMBOL_TYPE (exp->elts[pc + 2].symbol)));
 
     default:
       val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
index 89df84313d3b6fc8c1104f7f24c5ae8ac4caf5b3..042eb0b89a6ca7d49e75cd123fd5c2d676df38fd 100644 (file)
@@ -223,34 +223,27 @@ get_frame_pc PARAMS ((FRAME));
 extern CORE_ADDR
 get_pc_function_start PARAMS ((CORE_ADDR));
 
-extern struct block *
-block_for_pc PARAMS ((CORE_ADDR));
+extern struct block * block_for_pc PARAMS ((CORE_ADDR));
 
-extern int
-frameless_look_for_prologue PARAMS ((FRAME));
+extern int frameless_look_for_prologue PARAMS ((FRAME));
 
-extern void
-print_frame_args PARAMS ((struct symbol *, struct frame_info *, int, FILE *));
+extern void print_frame_args PARAMS ((struct symbol *, struct frame_info *,
+                                     int, FILE *));
 
-extern FRAME
-find_relative_frame PARAMS ((FRAME, int*));
+extern FRAME find_relative_frame PARAMS ((FRAME, int*));
 
-extern void
-print_stack_frame PARAMS ((FRAME, int, int));
+extern void print_stack_frame PARAMS ((FRAME, int, int));
 
-extern void
-select_frame PARAMS ((FRAME, int));
+extern void select_frame PARAMS ((FRAME, int));
 
-extern void
-record_selected_frame PARAMS ((FRAME_ADDR *, int *));
+extern void record_selected_frame PARAMS ((FRAME_ADDR *, int *));
 
-extern void
-print_frame_info PARAMS ((struct frame_info *, int, int, int));
+extern void print_frame_info PARAMS ((struct frame_info *, int, int, int));
 
-extern CORE_ADDR
-find_saved_register PARAMS ((FRAME, int));
+extern CORE_ADDR find_saved_register PARAMS ((FRAME, int));
 
-extern CORE_ADDR
-sigtramp_saved_pc PARAMS ((FRAME));
+extern FRAME block_innermost_frame PARAMS ((struct block *));
+
+extern CORE_ADDR sigtramp_saved_pc PARAMS ((FRAME));
 
 #endif /* !defined (FRAME_H)  */
index 56ed6e675e296682aef92e255e1413c1f1595058..b00af97d503c7a40eebadd9c21eabf5915cffbf7 100644 (file)
@@ -559,6 +559,7 @@ fblock      :       block COLONCOLON BLOCKNAME
 /* Useful for assigning to PROCEDURE variables */
 variable:      fblock
                        { write_exp_elt_opcode(OP_VAR_VALUE);
+                         write_exp_elt_block (NULL);
                          write_exp_elt_sym ($1);
                          write_exp_elt_opcode (OP_VAR_VALUE); }
        ;
@@ -580,6 +581,8 @@ variable:   block COLONCOLON NAME
                                   copy_name ($3));
 
                          write_exp_elt_opcode (OP_VAR_VALUE);
+                         /* block_found is set by lookup_symbol.  */
+                         write_exp_elt_block (block_found);
                          write_exp_elt_sym (sym);
                          write_exp_elt_opcode (OP_VAR_VALUE); }
        ;
@@ -623,6 +626,10 @@ variable:  NAME
                                  break;
                                }
                              write_exp_elt_opcode (OP_VAR_VALUE);
+                             /* We want to use the selected frame, not
+                                another more inner frame which happens to
+                                be in the same block.  */
+                             write_exp_elt_block (NULL);
                              write_exp_elt_sym (sym);
                              write_exp_elt_opcode (OP_VAR_VALUE);
                            }
index 4cec13b38b72a67a275d4bdb5ad9cbeea06d69ef..94e467e3d220e8f46487f9baf89d958c3dbeb4d6 100644 (file)
@@ -178,6 +178,15 @@ write_exp_elt_sym (expelt)
   write_exp_elt (tmp);
 }
 
+void
+write_exp_elt_block (b)
+     struct block *b;
+{
+  union exp_element tmp;
+  tmp.block = b;
+  write_exp_elt (tmp);
+}
+
 void
 write_exp_elt_longcst (expelt)
      LONGEST expelt;
@@ -389,12 +398,12 @@ length_of_subexp (expr, endpos)
 
     case OP_LONG:
     case OP_DOUBLE:
+    case OP_VAR_VALUE:
       oplen = 4;
       break;
 
     case OP_TYPE:
     case OP_BOOL:
-    case OP_VAR_VALUE:
     case OP_LAST:
     case OP_REGISTER:
     case OP_INTERNALVAR:
@@ -518,12 +527,12 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg)
 
     case OP_LONG:
     case OP_DOUBLE:
+    case OP_VAR_VALUE:
       oplen = 4;
       break;
 
     case OP_TYPE:
     case OP_BOOL:
-    case OP_VAR_VALUE:
     case OP_LAST:
     case OP_REGISTER:
     case OP_INTERNALVAR:
index 24eefcadee11d8a7b6b9cb4381ff2c4f157e3ac4..1b409ff82af0bcd9872b6676640328df9d23dc15 100644 (file)
@@ -81,7 +81,7 @@ allocate_space_in_inferior (len)
        {
          error ("\"malloc\" exists in this program but is not a function.");
        }
-      val = value_of_variable (sym);
+      val = value_of_variable (sym, NULL);
     }
   else
     {
@@ -332,7 +332,7 @@ value_assign (toval, fromval)
          int v;                /* FIXME, this won't work for large bitfields */
          read_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
                       (char *) &v, sizeof v);
-         modify_field ((char *) &v, (int) value_as_long (fromval),
+         modify_field ((char *) &v, value_as_long (fromval),
                        VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
          write_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
                        (char *)&v, sizeof v);
@@ -352,7 +352,7 @@ value_assign (toval, fromval)
 
          read_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
                               (char *) &v, sizeof v);
-         modify_field ((char *) &v, (int) value_as_long (fromval),
+         modify_field ((char *) &v, value_as_long (fromval),
                        VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
          write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
                                (char *) &v, sizeof v);
@@ -415,7 +415,7 @@ value_assign (toval, fromval)
        /* Modify what needs to be modified.  */
        if (VALUE_BITSIZE (toval))
          modify_field (buffer + byte_offset,
-                       (int) value_as_long (fromval),
+                       value_as_long (fromval),
                        VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
        else if (use_buffer)
          memcpy (buffer + byte_offset, raw_buffer, use_buffer);
@@ -498,12 +498,30 @@ value_repeat (arg1, count)
 }
 
 value
-value_of_variable (var)
+value_of_variable (var, b)
      struct symbol *var;
+     struct block *b;
 {
   value val;
+  FRAME fr;
 
-  val = read_var_value (var, (FRAME) 0);
+  if (b == NULL)
+    /* Use selected frame.  */
+    fr = NULL;
+  else
+    {
+      fr = block_innermost_frame (b);
+      if (fr == NULL)
+       {
+         if (BLOCK_FUNCTION (b) != NULL
+             && SYMBOL_NAME (BLOCK_FUNCTION (b)) != NULL)
+           error ("No frame is currently executing in block %s.",
+                  SYMBOL_NAME (BLOCK_FUNCTION (b)));
+         else
+           error ("No frame is currently executing in specified block");
+       }
+    }
+  val = read_var_value (var, fr);
   if (val == 0)
     error ("Address of symbol \"%s\" is unknown.", SYMBOL_SOURCE_NAME (var));
   return val;
@@ -632,14 +650,14 @@ push_word (sp, word)
      REGISTER_TYPE word;
 {
   register int len = sizeof (REGISTER_TYPE);
-  REGISTER_TYPE buffer;
+  char buffer[MAX_REGISTER_RAW_SIZE];
 
-  store_unsigned_integer (&buffer, len, word);
+  store_unsigned_integer (buffer, len, word);
 #if 1 INNER_THAN 2
   sp -= len;
-  write_memory (sp, (char *)&buffer, len);
+  write_memory (sp, buffer, len);
 #else /* stack grows upward */
-  write_memory (sp, (char *)&buffer, len);
+  write_memory (sp, buffer, len);
   sp += len;
 #endif /* stack grows upward */
 
@@ -694,7 +712,15 @@ value_arg_coerce (arg)
 {
   register struct type *type;
 
-  COERCE_ENUM (arg);
+  /* FIXME: We should coerce this according to the prototype (if we have
+     one).  Right now we do a little bit of this in typecmp(), but that
+     doesn't always get called.  For example, if passing a ref to a function
+     without a prototype, we probably should de-reference it.  Currently
+     we don't.  */
+
+  if (TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_ENUM)
+    arg = value_cast (builtin_type_unsigned_int, arg);
+
 #if 1  /* FIXME:  This is only a temporary patch.  -fnf */
   if (VALUE_REPEATED (arg)
       || TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_ARRAY)
@@ -1153,8 +1179,11 @@ value_string (ptr, len)
   return (val);
 }
 \f
-/* Compare two argument lists and return the position in which they differ,
-   or zero if equal.
+/* See if we can pass arguments in T2 to a function which takes arguments
+   of types T1.  Both t1 and t2 are NULL-terminated vectors.  If some
+   arguments need coercion of some sort, then the coerced values are written
+   into T2.  Return value is 0 if the arguments could be matched, or the
+   position at which they differ if not.
 
    STATICP is nonzero if the T1 argument list came from a
    static member function.
@@ -1186,8 +1215,22 @@ typecmp (staticp, t1, t2)
       if (! t2[i])
        return i+1;
       if (TYPE_CODE (t1[i]) == TYPE_CODE_REF
-         && TYPE_TARGET_TYPE (t1[i]) == VALUE_TYPE (t2[i]))
+         /* We should be doing hairy argument matching, as below.  */
+         && (TYPE_CODE (TYPE_TARGET_TYPE (t1[i]))
+             == TYPE_CODE (VALUE_TYPE (t2[i]))))
+       {
+         t2[i] = value_addr (t2[i]);
+         continue;
+       }
+
+      if (TYPE_CODE (t1[i]) == TYPE_CODE_PTR
+         && TYPE_CODE (VALUE_TYPE (t2[i])) == TYPE_CODE_ARRAY)
+       /* Array to pointer is a `trivial conversion' according to the ARM.  */
        continue;
+
+      /* We should be doing much hairier argument matching (see section 13.2
+        of the ARM), but as a quick kludge, just check for the same type
+        code.  */
       if (TYPE_CODE (t1[i]) != TYPE_CODE (VALUE_TYPE (t2[i])))
        return i+1;
     }