aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog11
-rw-r--r--gdb/blockframe.c11
-rw-r--r--gdb/c-exp.y7
-rw-r--r--gdb/ch-exp.y2
-rw-r--r--gdb/eval.c55
-rw-r--r--gdb/frame.h33
-rw-r--r--gdb/m2-exp.y7
-rw-r--r--gdb/parse.c13
-rw-r--r--gdb/valops.c71
9 files changed, 153 insertions, 57 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index ecea9be..c85a369 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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.
diff --git a/gdb/blockframe.c b/gdb/blockframe.c
index 0e5dc1a..6430cba 100644
--- a/gdb/blockframe.c
+++ b/gdb/blockframe.c
@@ -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. */
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index b841498..42e482b 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -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);
}
diff --git a/gdb/ch-exp.y b/gdb/ch-exp.y
index 166d01a..58b82ea 100644
--- a/gdb/ch-exp.y
+++ b/gdb/ch-exp.y
@@ -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);
}
diff --git a/gdb/eval.c b/gdb/eval.c
index 98774bf..4aba99f 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -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);
diff --git a/gdb/frame.h b/gdb/frame.h
index 89df843..042eb0b 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -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) */
diff --git a/gdb/m2-exp.y b/gdb/m2-exp.y
index 56ed6e6..b00af97 100644
--- a/gdb/m2-exp.y
+++ b/gdb/m2-exp.y
@@ -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);
}
diff --git a/gdb/parse.c b/gdb/parse.c
index 4cec13b..94e467e 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -179,6 +179,15 @@ write_exp_elt_sym (expelt)
}
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:
diff --git a/gdb/valops.c b/gdb/valops.c
index 24eefca..1b409ff 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -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);
}
-/* 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;
}