Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- 2008 Free Software Foundation, Inc.
+ 2008, 2009 Free Software Foundation, Inc.
This file is part of GDB.
#include "gdb_assert.h"
#include "cp-support.h"
#include "observer.h"
+#include "objfiles.h"
+#include "symtab.h"
extern int overload_debug;
/* Local functions. */
value);
}
-/* Find the address of function name NAME in the inferior. */
+/* Find the address of function name NAME in the inferior. If OBJF_P
+ is non-NULL, *OBJF_P will be set to the OBJFILE where the function
+ is defined. */
struct value *
-find_function_in_inferior (const char *name)
+find_function_in_inferior (const char *name, struct objfile **objf_p)
{
struct symbol *sym;
sym = lookup_symbol (name, 0, VAR_DOMAIN, 0);
error (_("\"%s\" exists in this program but is not a function."),
name);
}
+
+ if (objf_p)
+ *objf_p = SYMBOL_SYMTAB (sym)->objfile;
+
return value_of_variable (sym, NULL);
}
else
lookup_minimal_symbol (name, NULL, NULL);
if (msymbol != NULL)
{
+ struct objfile *objfile = msymbol_objfile (msymbol);
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
+
struct type *type;
CORE_ADDR maddr;
- type = lookup_pointer_type (builtin_type_char);
+ type = lookup_pointer_type (builtin_type (gdbarch)->builtin_char);
type = lookup_function_type (type);
type = lookup_pointer_type (type);
maddr = SYMBOL_VALUE_ADDRESS (msymbol);
+
+ if (objf_p)
+ *objf_p = objfile;
+
return value_from_pointer (type, maddr);
}
else
struct value *
value_allocate_space_in_inferior (int len)
{
+ struct objfile *objf;
+ struct value *val = find_function_in_inferior ("malloc", &objf);
+ struct gdbarch *gdbarch = get_objfile_arch (objf);
struct value *blocklen;
- struct value *val =
- find_function_in_inferior (gdbarch_name_of_malloc (current_gdbarch));
- blocklen = value_from_longest (builtin_type_int, (LONGEST) len);
+ blocklen = value_from_longest (builtin_type (gdbarch)->builtin_int, len);
val = call_function_by_hand (val, 1, &blocklen);
if (value_logical_not (val))
{
{
struct type *element_type = TYPE_TARGET_TYPE (type);
unsigned element_length = TYPE_LENGTH (check_typedef (element_type));
- if (element_length > 0
- && TYPE_ARRAY_UPPER_BOUND_TYPE (type) == BOUND_CANNOT_BE_DETERMINED)
+ if (element_length > 0 && TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type))
{
struct type *range_type = TYPE_INDEX_TYPE (type);
int val_length = TYPE_LENGTH (type2);
if (TYPE_CODE (check_typedef (type)) == TYPE_CODE_VOID)
error (_("Attempt to dereference a generic pointer."));
- val = allocate_value (type);
+ val = allocate_value_lazy (type);
VALUE_LVAL (val) = lval_memory;
VALUE_ADDRESS (val) = addr;
- set_value_lazy (val, 1);
return val;
}
int
value_fetch_lazy (struct value *val)
{
+ gdb_assert (value_lazy (val));
+ allocate_value_contents (val);
if (VALUE_LVAL (val) == lval_memory)
{
CORE_ADDR addr = VALUE_ADDRESS (val) + value_offset (val);
watchpoints from trying to watch the saved frame pointer. */
value_free_to_mark (mark);
}
+ else if (VALUE_LVAL (val) == lval_computed)
+ value_computed_funcs (val)->read (val);
else
internal_error (__FILE__, __LINE__, "Unexpected lazy value type.");
observer_notify_target_changed (¤t_target);
break;
}
-
+
+ case lval_computed:
+ {
+ struct lval_funcs *funcs = value_computed_funcs (toval);
+
+ funcs->write (toval, fromval);
+ }
+ break;
+
default:
error (_("Left operand of assignment is not an lvalue."));
}
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)
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. */
if (t_field_name && (strcmp_iw (t_field_name, name) == 0))
{
struct value *v;
- if (TYPE_FIELD_STATIC (type, i))
+ if (field_is_static (&TYPE_FIELD (type, i)))
{
v = value_static_field (type, i);
if (v == 0)
if (BASETYPE_VIA_VIRTUAL (type, i))
{
int boffset;
- struct value *v2 = allocate_value (basetype);
+ struct value *v2;
boffset = baseclass_offset (type, i,
value_contents (arg1) + offset,
{
CORE_ADDR base_addr;
+ v2 = allocate_value (basetype);
base_addr =
VALUE_ADDRESS (arg1) + value_offset (arg1) + boffset;
if (target_read_memory (base_addr,
}
else
{
- VALUE_LVAL (v2) = VALUE_LVAL (arg1);
- VALUE_ADDRESS (v2) = VALUE_ADDRESS (arg1);
- VALUE_FRAME_ID (v2) = VALUE_FRAME_ID (arg1);
- set_value_offset (v2, value_offset (arg1) + boffset);
if (VALUE_LVAL (arg1) == lval_memory && value_lazy (arg1))
- set_value_lazy (v2, 1);
+ v2 = allocate_value_lazy (basetype);
else
- memcpy (value_contents_raw (v2),
- value_contents_raw (arg1) + boffset,
- TYPE_LENGTH (basetype));
+ {
+ v2 = allocate_value (basetype);
+ memcpy (value_contents_raw (v2),
+ value_contents_raw (arg1) + boffset,
+ TYPE_LENGTH (basetype));
+ }
+ set_value_component_location (v2, arg1);
+ VALUE_FRAME_ID (v2) = VALUE_FRAME_ID (arg1);
+ set_value_offset (v2, value_offset (arg1) + boffset);
}
if (found_baseclass)
}
/* Search through the methods of an object (and its bases) to find a
- specified method. Return the pointer to the fn_field list of
+ specified method. Return the pointer to the fn_field list of
overloaded instances.
Helper function for value_find_oload_list.
if (objp)
{
- if (TYPE_CODE (value_type (temp)) != TYPE_CODE_PTR
- && (TYPE_CODE (value_type (*objp)) == TYPE_CODE_PTR
- || TYPE_CODE (value_type (*objp)) == TYPE_CODE_REF))
+ struct type *temp_type = check_typedef (value_type (temp));
+ struct type *obj_type = check_typedef (value_type (*objp));
+ if (TYPE_CODE (temp_type) != TYPE_CODE_PTR
+ && (TYPE_CODE (obj_type) == TYPE_CODE_PTR
+ || TYPE_CODE (obj_type) == TYPE_CODE_REF))
{
temp = value_addr (temp);
}
if (t_field_name && strcmp (t_field_name, name) == 0)
{
- if (TYPE_FIELD_STATIC (t, i))
+ if (field_is_static (&TYPE_FIELD (t, i)))
{
v = value_static_field (t, i);
if (v == NULL)
slice_range_type);
TYPE_CODE (slice_type) = TYPE_CODE (array_type);
- slice = allocate_value (slice_type);
if (VALUE_LVAL (array) == lval_memory && value_lazy (array))
- set_value_lazy (slice, 1);
- else
- memcpy (value_contents_writeable (slice),
- value_contents (array) + offset,
- TYPE_LENGTH (slice_type));
-
- if (VALUE_LVAL (array) == lval_internalvar)
- VALUE_LVAL (slice) = lval_internalvar_component;
+ slice = allocate_value_lazy (slice_type);
else
- VALUE_LVAL (slice) = VALUE_LVAL (array);
+ {
+ slice = allocate_value (slice_type);
+ memcpy (value_contents_writeable (slice),
+ value_contents (array) + offset,
+ TYPE_LENGTH (slice_type));
+ }
- VALUE_ADDRESS (slice) = VALUE_ADDRESS (array);
+ set_value_component_location (slice, array);
VALUE_FRAME_ID (slice) = VALUE_FRAME_ID (array);
set_value_offset (slice, value_offset (array) + offset);
}