diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2009-01-15 15:38:07 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@de.ibm.com> | 2009-01-15 15:38:07 +0000 |
commit | 61212c0fb13d0a54f12748dcc56a41c15a91d12a (patch) | |
tree | d006b77357adb211693a534f9f5d25e962e128cb /gdb/valops.c | |
parent | cc2420d5bbb6f8ebfc231b80e87e9987585a7549 (diff) | |
download | binutils-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.c | 58 |
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. */ |