aboutsummaryrefslogtreecommitdiff
path: root/gdb/valops.c
diff options
context:
space:
mode:
authorUlrich Weigand <uweigand@de.ibm.com>2009-01-15 15:38:07 +0000
committerUlrich Weigand <uweigand@de.ibm.com>2009-01-15 15:38:07 +0000
commit61212c0fb13d0a54f12748dcc56a41c15a91d12a (patch)
treed006b77357adb211693a534f9f5d25e962e128cb /gdb/valops.c
parentcc2420d5bbb6f8ebfc231b80e87e9987585a7549 (diff)
downloadbinutils-61212c0fb13d0a54f12748dcc56a41c15a91d12a.zip
binutils-61212c0fb13d0a54f12748dcc56a41c15a91d12a.tar.gz
binutils-61212c0fb13d0a54f12748dcc56a41c15a91d12a.tar.bz2
* value.h (address_of_variable): Add prototype.
(locate_var_value): Remove prototype. * findvar.c (read_var_value): Do not attempt to default frame to selected frame. (locate_var_value): Remove function. * valops.c (value_of_variable): Retrieve selected frame for symbols that require a frame when called with NULL block. * valops.c (address_of_variable): New function. * eval.c (evaluate_subexp_for_address): Call address_of_variable instead of calling locate_var_value. (evaluate_subexp_with_coercion): Likewise.
Diffstat (limited to 'gdb/valops.c')
-rw-r--r--gdb/valops.c58
1 files changed, 54 insertions, 4 deletions
diff --git a/gdb/valops.c b/gdb/valops.c
index 30e74fa..1c724d3 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -988,11 +988,13 @@ struct value *
value_of_variable (struct symbol *var, struct block *b)
{
struct value *val;
- struct frame_info *frame = NULL;
+ struct frame_info *frame;
- if (!b)
- frame = NULL; /* Use selected frame. */
- else if (symbol_read_needs_frame (var))
+ if (!symbol_read_needs_frame (var))
+ frame = NULL;
+ else if (!b)
+ frame = get_selected_frame (_("No frame selected."));
+ else
{
frame = block_innermost_frame (b);
if (!frame)
@@ -1013,6 +1015,54 @@ value_of_variable (struct symbol *var, struct block *b)
return val;
}
+struct value *
+address_of_variable (struct symbol *var, struct block *b)
+{
+ struct type *type = SYMBOL_TYPE (var);
+ struct value *val;
+
+ /* Evaluate it first; if the result is a memory address, we're fine.
+ Lazy evaluation pays off here. */
+
+ val = value_of_variable (var, b);
+
+ if ((VALUE_LVAL (val) == lval_memory && value_lazy (val))
+ || TYPE_CODE (type) == TYPE_CODE_FUNC)
+ {
+ CORE_ADDR addr = VALUE_ADDRESS (val);
+ return value_from_pointer (lookup_pointer_type (type), addr);
+ }
+
+ /* Not a memory address; check what the problem was. */
+ switch (VALUE_LVAL (val))
+ {
+ case lval_register:
+ {
+ struct frame_info *frame;
+ const char *regname;
+
+ frame = frame_find_by_id (VALUE_FRAME_ID (val));
+ gdb_assert (frame);
+
+ regname = gdbarch_register_name (get_frame_arch (frame),
+ VALUE_REGNUM (val));
+ gdb_assert (regname && *regname);
+
+ error (_("Address requested for identifier "
+ "\"%s\" which is in register $%s"),
+ SYMBOL_PRINT_NAME (var), regname);
+ break;
+ }
+
+ default:
+ error (_("Can't take address of \"%s\" which isn't an lvalue."),
+ SYMBOL_PRINT_NAME (var));
+ break;
+ }
+
+ return val;
+}
+
/* Return one if VAL does not live in target memory, but should in order
to operate on it. Otherwise return zero. */