diff options
-rw-r--r-- | gdb/ChangeLog | 16 | ||||
-rw-r--r-- | gdb/eval.c | 17 | ||||
-rw-r--r-- | gdb/findvar.c | 75 | ||||
-rw-r--r-- | gdb/valops.c | 58 | ||||
-rw-r--r-- | gdb/value.h | 5 |
5 files changed, 81 insertions, 90 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 04022f9..928e760 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,19 @@ +2009-01-15 Ulrich Weigand <uweigand@de.ibm.com> + + * 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. + 2009-01-14 Daniel Jacobowitz <dan@codesourcery.com> * NEWS: Document "define" for prefixed commands. @@ -2560,13 +2560,8 @@ evaluate_subexp_for_address (struct expression *exp, int *pos, return value_zero (type, not_lval); } - else if (symbol_read_needs_frame (var)) - return - locate_var_value - (var, - block_innermost_frame (exp->elts[pc + 1].block)); else - return locate_var_value (var, NULL); + return address_of_variable (var, exp->elts[pc + 1].block); case OP_SCOPE: tem = longest_to_int (exp->elts[pc + 2].longconst); @@ -2620,6 +2615,7 @@ evaluate_subexp_with_coercion (struct expression *exp, int pc; struct value *val; struct symbol *var; + struct type *type; pc = (*pos); op = exp->elts[pc].opcode; @@ -2628,14 +2624,13 @@ evaluate_subexp_with_coercion (struct expression *exp, { case OP_VAR_VALUE: var = exp->elts[pc + 2].symbol; - if (TYPE_CODE (check_typedef (SYMBOL_TYPE (var))) == TYPE_CODE_ARRAY + type = check_typedef (SYMBOL_TYPE (var)); + if (TYPE_CODE (type) == TYPE_CODE_ARRAY && CAST_IS_CONVERSION) { (*pos) += 4; - val = - locate_var_value - (var, block_innermost_frame (exp->elts[pc + 1].block)); - return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (check_typedef (SYMBOL_TYPE (var)))), + val = address_of_variable (var, exp->elts[pc + 1].block); + return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (type)), val); } /* FALLTHROUGH */ diff --git a/gdb/findvar.c b/gdb/findvar.c index a56650d..1048887 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -382,8 +382,7 @@ symbol_read_needs_frame (struct symbol *sym) /* Given a struct symbol for a variable, and a stack frame id, read the value of the variable and return a (pointer to a) struct value containing the value. - If the variable cannot be found, return a zero pointer. - If FRAME is NULL, use the selected frame. */ + If the variable cannot be found, return a zero pointer. */ struct value * read_var_value (struct symbol *var, struct frame_info *frame) @@ -405,10 +404,8 @@ read_var_value (struct symbol *var, struct frame_info *frame) len = TYPE_LENGTH (type); - /* FIXME drow/2003-09-06: this call to the selected frame should be - pushed upwards to the callers. */ - if (frame == NULL) - frame = deprecated_safe_get_selected_frame (); + if (symbol_read_needs_frame (var)) + gdb_assert (frame); switch (SYMBOL_CLASS (var)) { @@ -450,8 +447,6 @@ read_var_value (struct symbol *var, struct frame_info *frame) break; case LOC_ARG: - if (frame == NULL) - return 0; addr = get_frame_args_address (frame); if (!addr) return 0; @@ -462,8 +457,6 @@ read_var_value (struct symbol *var, struct frame_info *frame) { struct value *ref; CORE_ADDR argref; - if (frame == NULL) - return 0; argref = get_frame_args_address (frame); if (!argref) return 0; @@ -474,8 +467,6 @@ read_var_value (struct symbol *var, struct frame_info *frame) } case LOC_LOCAL: - if (frame == NULL) - return 0; addr = get_frame_locals_address (frame); addr += SYMBOL_VALUE (var); break; @@ -498,9 +489,6 @@ read_var_value (struct symbol *var, struct frame_info *frame) int regno = SYMBOL_VALUE (var); struct value *regval; - if (frame == NULL) - return 0; - if (SYMBOL_CLASS (var) == LOC_REGPARM_ADDR) { regval = value_from_register (lookup_pointer_type (type), @@ -530,8 +518,6 @@ read_var_value (struct symbol *var, struct frame_info *frame) Unfortunately DWARF 2 stores the frame-base (instead of the function) location in a function's symbol. Oops! For the moment enable this when/where applicable. */ - if (frame == 0 && SYMBOL_OPS (var)->read_needs_frame (var)) - return 0; return SYMBOL_OPS (var)->read_variable (var, frame); case LOC_UNRESOLVED: @@ -657,58 +643,3 @@ address_from_register (struct type *type, int regnum, struct frame_info *frame) return result; } - - -/* Given a struct symbol for a variable or function, - and a stack frame id, - return a (pointer to a) struct value containing the properly typed - address. */ - -struct value * -locate_var_value (struct symbol *var, struct frame_info *frame) -{ - struct gdbarch *gdbarch; - CORE_ADDR addr = 0; - struct type *type = SYMBOL_TYPE (var); - struct value *lazy_value; - - /* Evaluate it first; if the result is a memory address, we're fine. - Lazy evaluation pays off here. */ - - lazy_value = read_var_value (var, frame); - if (lazy_value == 0) - error (_("Address of \"%s\" is unknown."), SYMBOL_PRINT_NAME (var)); - - if ((VALUE_LVAL (lazy_value) == lval_memory && value_lazy (lazy_value)) - || TYPE_CODE (type) == TYPE_CODE_FUNC) - { - struct value *val; - - addr = VALUE_ADDRESS (lazy_value); - val = value_from_pointer (lookup_pointer_type (type), addr); - return val; - } - - /* Not a memory address; check what the problem was. */ - switch (VALUE_LVAL (lazy_value)) - { - case lval_register: - gdb_assert (frame); - gdbarch = get_frame_arch (frame); - gdb_assert (gdbarch_register_name - (gdbarch, VALUE_REGNUM (lazy_value)) != NULL - && *gdbarch_register_name - (gdbarch, VALUE_REGNUM (lazy_value)) != '\0'); - error (_("Address requested for identifier " - "\"%s\" which is in register $%s"), - SYMBOL_PRINT_NAME (var), - gdbarch_register_name (gdbarch, VALUE_REGNUM (lazy_value))); - break; - - default: - error (_("Can't take address of \"%s\" which isn't an lvalue."), - SYMBOL_PRINT_NAME (var)); - break; - } - return 0; /* For lint -- never reached */ -} 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. */ diff --git a/gdb/value.h b/gdb/value.h index ecdcf25..724aa5a 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -310,6 +310,8 @@ extern CORE_ADDR address_from_register (struct type *type, int regnum, extern struct value *value_of_variable (struct symbol *var, struct block *b); +extern struct value *address_of_variable (struct symbol *var, struct block *b); + extern struct value *value_of_register (int regnum, struct frame_info *frame); struct value *value_of_register_lazy (struct frame_info *frame, int regnum); @@ -319,9 +321,6 @@ extern int symbol_read_needs_frame (struct symbol *); extern struct value *read_var_value (struct symbol *var, struct frame_info *frame); -extern struct value *locate_var_value (struct symbol *var, - struct frame_info *frame); - extern struct value *allocate_value (struct type *type); extern struct value *allocate_value_lazy (struct type *type); extern void allocate_value_contents (struct value *value); |