* 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.
This commit is contained in:
Jim Kingdon 1993-08-18 19:33:39 +00:00
parent e56ac0ba86
commit 479fdd26ee
9 changed files with 153 additions and 57 deletions

View 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.

View 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. */

View 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);
}

View 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);
}

View 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);

View 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) */

View 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);
}

View 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:

View 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);
}
/* 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;
}