#include "defs.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "value.h"
#include "frame.h"
#include "inferior.h"
#include "gdbcore.h"
#include "target.h"
#include "demangle.h"
#include "language.h"
#include "gdbcmd.h"
#include "regcache.h"
#include "cp-abi.h"
#include <errno.h>
#include "gdb_string.h"
#include "gdb_assert.h"
extern int hp_som_som_object_present;
extern int overload_debug;
static int typecmp (int staticp, int varargs, int nargs,
struct field t1[], struct value *t2[]);
static struct value *value_arg_coerce (struct value *, struct type *, int);
static CORE_ADDR value_push (CORE_ADDR, struct value *);
static struct value *search_struct_field (char *, struct value *, int,
struct type *, int);
static struct value *search_struct_method (char *, struct value **,
struct value **,
int, int *, struct type *);
static int check_field_in (struct type *, const char *);
static CORE_ADDR allocate_space_in_inferior (int);
static struct value *cast_into_complex (struct type *, struct value *);
static struct fn_field *find_method_list (struct value ** argp, char *method,
int offset,
struct type *type, int *num_fns,
struct type **basetype,
int *boffset);
void _initialize_valops (void);
#if 0
static int auto_abandon = 0;
#endif
int overload_resolution = 0;
int unwind_on_signal_p = 0;
extern struct type *msym_text_symbol_type;
extern struct type *msym_data_symbol_type;
extern struct type *msym_unknown_symbol_type;
extern unsigned int symbol_generation;
struct cached_value *
create_cached_function (name, type)
char *name;
struct type *type;
{
struct cached_value *ptr;
ptr = (struct cached_value *) xmalloc (sizeof (struct cached_value));
ptr->name = xstrdup (name);
ptr->type = type;
ptr->bound = 0;
memset (&ptr->val, 0, sizeof (struct value));
ptr->generation = (unsigned int) -1;
return ptr;
}
int
set_unwind_on_signal (int new_val)
{
int old_val = unwind_on_signal_p;
unwind_on_signal_p = new_val;
return old_val;
}
struct value *
lookup_cached_function (struct cached_value *cval)
{
struct value *val = NULL;
struct value *next = NULL;
if (cval->generation != symbol_generation)
{
val = find_function_in_inferior (cval->name, cval->type);
cval->val = *val;
cval->val.next = NULL;
cval->bound = 0;
cval->generation = symbol_generation;
}
if (!cval->bound)
{
if (!target_bind_function (cval->name))
error ("Could not bind function \"%s\".", cval->name);
else
cval->bound = 1;
}
val = allocate_value (cval->val.type);
next = val->next;
*val = cval->val;
val->next = next;
return val;
}
struct value *
find_function_in_inferior (const char *name, struct type *type)
{
register struct symbol *sym;
sym = lookup_symbol (name, 0, VAR_NAMESPACE, 0, NULL);
if (sym != NULL)
{
if (SYMBOL_CLASS (sym) != LOC_BLOCK)
{
error ("\"%s\" exists in this program but is not a function.",
name);
}
return value_of_variable (sym, NULL);
}
else
{
struct minimal_symbol *msymbol = lookup_minimal_symbol (name, NULL, NULL);
if (msymbol != NULL)
{
if (type != NULL)
return value_from_longest (type, (LONGEST) SYMBOL_VALUE_ADDRESS (msymbol));
else
return value_from_longest (lookup_pointer_type (msym_text_symbol_type),
(LONGEST) SYMBOL_VALUE_ADDRESS (msymbol));
}
else
{
if (!target_has_execution)
error ("evaluation of this expression requires the target program to be active");
else
error ("evaluation of this expression requires the program to have a function named \"%s\".", name);
}
}
}
struct value *
value_allocate_space_in_inferior (int len)
{
struct value *blocklen;
struct value *val;
static struct cached_value *fval = NULL;
if (fval == NULL)
fval = create_cached_function (NAME_OF_MALLOC, builtin_type_voidptrfuncptr);
blocklen = value_from_longest (builtin_type_int, (LONGEST) len);
val = call_function_by_hand (lookup_cached_function (fval), 1, &blocklen);
if (value_logical_not (val))
{
if (!target_has_execution)
error ("No memory available to program now: you need to start the target first");
else
error ("No memory available to program: call to malloc failed");
}
return val;
}
static CORE_ADDR
allocate_space_in_inferior (int len)
{
return value_as_long (value_allocate_space_in_inferior (len));
}
struct value *
value_cast (struct type *type, struct value *arg2)
{
register enum type_code code1;
register enum type_code code2;
register int scalar;
struct type *type2;
int convert_to_boolean = 0;
if (VALUE_TYPE (arg2) == type)
return arg2;
CHECK_TYPEDEF (type);
code1 = TYPE_CODE (type);
COERCE_REF (arg2);
type2 = check_typedef (VALUE_TYPE (arg2));
if (code1 == TYPE_CODE_ARRAY)
{
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)
{
struct type *range_type = TYPE_INDEX_TYPE (type);
int val_length = TYPE_LENGTH (type2);
LONGEST low_bound, high_bound, new_length;
if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
low_bound = 0, high_bound = 0;
new_length = val_length / element_length;
if (val_length % element_length != 0)
warning ("array element type size does not divide object size in cast");
range_type = create_range_type ((struct type *) NULL,
TYPE_TARGET_TYPE (range_type),
low_bound,
new_length + low_bound - 1);
VALUE_TYPE (arg2) = create_array_type ((struct type *) NULL,
element_type, range_type);
return arg2;
}
}
if (current_language->c_style_arrays &&
(TYPE_CODE (type2) == TYPE_CODE_ARRAY ||
TYPE_CODE (type2) == TYPE_CODE_STRING))
arg2 = value_coerce_array (arg2);
if (TYPE_CODE (type2) == TYPE_CODE_FUNC)
arg2 = value_coerce_function (arg2);
type2 = check_typedef (VALUE_TYPE (arg2));
COERCE_VARYING_ARRAY (arg2, type2);
code2 = TYPE_CODE (type2);
if (code1 == TYPE_CODE_COMPLEX)
return cast_into_complex (type, arg2);
if (code1 == TYPE_CODE_BOOL)
{
code1 = TYPE_CODE_INT;
convert_to_boolean = 1;
}
if (code1 == TYPE_CODE_CHAR)
code1 = TYPE_CODE_INT;
if (code2 == TYPE_CODE_BOOL || code2 == TYPE_CODE_CHAR)
code2 = TYPE_CODE_INT;
scalar = (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_FLT
|| code2 == TYPE_CODE_ENUM || code2 == TYPE_CODE_RANGE);
if (code1 == TYPE_CODE_STRUCT
&& code2 == TYPE_CODE_STRUCT
&& TYPE_NAME (type) != 0)
{
struct value *v = search_struct_field (type_name_no_tag (type),
arg2, 0, type2, 1);
if (v)
{
VALUE_TYPE (v) = type;
return v;
}
}
if (code1 == TYPE_CODE_FLT && scalar)
return value_from_double (type, value_as_double (arg2));
else if ((code1 == TYPE_CODE_INT || code1 == TYPE_CODE_ENUM
|| code1 == TYPE_CODE_RANGE)
&& (scalar || code2 == TYPE_CODE_PTR))
{
LONGEST longest;
if (hp_som_som_object_present &&
(code2 == TYPE_CODE_PTR))
{
unsigned int *ptr;
struct value *retvalp;
switch (TYPE_CODE (TYPE_TARGET_TYPE (type2)))
{
case TYPE_CODE_MEMBER:
retvalp = value_from_longest (type, value_as_long (arg2));
ptr = (unsigned int *) VALUE_CONTENTS (retvalp);
*ptr &= ~0x20000000;
return retvalp;
case TYPE_CODE_METHOD:
error ("Pointers to methods not supported with HP aCC");
default:
break;
}
}
if (code2 == TYPE_CODE_PTR)
longest = extract_unsigned_integer (VALUE_CONTENTS (arg2),
TYPE_LENGTH (type2));
else
longest = value_as_long (arg2);
return value_from_longest (type, convert_to_boolean ?
(LONGEST) (longest ? 1 : 0) : longest);
}
else if (code1 == TYPE_CODE_PTR && (code2 == TYPE_CODE_INT ||
code2 == TYPE_CODE_ENUM ||
code2 == TYPE_CODE_RANGE))
{
int addr_bit = TARGET_ADDR_BIT;
LONGEST longest = value_as_long (arg2);
if (addr_bit < sizeof (LONGEST) * HOST_CHAR_BIT)
{
if (longest >= ((LONGEST) 1 << addr_bit)
|| longest <= -((LONGEST) 1 << addr_bit))
warning ("value truncated");
}
return value_from_longest (type, longest);
}
else if (TYPE_LENGTH (type) == TYPE_LENGTH (type2))
{
if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR)
{
struct type *t1 = check_typedef (TYPE_TARGET_TYPE (type));
struct type *t2 = check_typedef (TYPE_TARGET_TYPE (type2));
if (TYPE_CODE (t1) == TYPE_CODE_STRUCT
&& TYPE_CODE (t2) == TYPE_CODE_STRUCT
&& !value_logical_not (arg2))
{
struct value *v;
if (TYPE_NAME (t1) != NULL)
{
v = search_struct_field (type_name_no_tag (t1),
value_ind (arg2), 0, t2, 1);
if (v)
{
v = value_addr (v);
VALUE_TYPE (v) = type;
return v;
}
}
if (TYPE_NAME (t2) != NULL)
{
v = search_struct_field (type_name_no_tag (t2),
value_zero (t1, not_lval), 0, t1, 1);
if (v)
{
CORE_ADDR addr2 = value_as_address (arg2);
addr2 -= (VALUE_ADDRESS (v)
+ VALUE_OFFSET (v)
+ VALUE_EMBEDDED_OFFSET (v));
return value_from_pointer (type, addr2);
}
}
}
}
VALUE_TYPE (arg2) = type;
arg2 = value_change_enclosing_type (arg2, type);
VALUE_POINTED_TO_OFFSET (arg2) = 0;
return arg2;
}
else if (VALUE_LVAL (arg2) == lval_memory)
{
return value_at_lazy (type, VALUE_ADDRESS (arg2) + VALUE_OFFSET (arg2),
VALUE_BFD_SECTION (arg2));
}
else if (code1 == TYPE_CODE_VOID)
{
return value_zero (builtin_type_void, not_lval);
}
else
{
error ("Invalid cast.");
return 0;
}
}
struct value *
value_zero (struct type *type, enum lval_type lv)
{
struct value *val = allocate_value (type);
memset (VALUE_CONTENTS (val), 0, TYPE_LENGTH (check_typedef (type)));
VALUE_LVAL (val) = lv;
return val;
}
struct value *
value_at (struct type *type, CORE_ADDR addr, asection *sect)
{
struct value *val;
if (TYPE_CODE (check_typedef (type)) == TYPE_CODE_VOID)
error ("Attempt to dereference a generic pointer.");
val = allocate_value (type);
read_memory (addr, VALUE_CONTENTS_ALL_RAW (val), TYPE_LENGTH (type));
VALUE_LVAL (val) = lval_memory;
VALUE_ADDRESS (val) = addr;
VALUE_BFD_SECTION (val) = sect;
return val;
}
struct value *
value_at_lazy (struct type *type, CORE_ADDR addr, asection *sect)
{
struct value *val;
if (TYPE_CODE (check_typedef (type)) == TYPE_CODE_VOID)
error ("Attempt to dereference a generic pointer.");
val = allocate_value (type);
VALUE_LVAL (val) = lval_memory;
VALUE_ADDRESS (val) = addr;
VALUE_LAZY (val) = 1;
VALUE_BFD_SECTION (val) = sect;
return val;
}
int
value_fetch_lazy (struct value *val)
{
CORE_ADDR addr = VALUE_ADDRESS (val) + VALUE_OFFSET (val);
int length = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (val));
struct type *type = VALUE_TYPE (val);
if (length)
read_memory (addr, VALUE_CONTENTS_ALL_RAW (val), length);
VALUE_LAZY (val) = 0;
return 0;
}
struct value *
value_assign (struct value *toval, struct value *fromval)
{
register struct type *type;
struct value *val;
char *raw_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE);
int use_buffer = 0;
if (!toval->modifiable)
error ("Left operand of assignment is not a modifiable lvalue.");
COERCE_REF (toval);
type = VALUE_TYPE (toval);
if (VALUE_LVAL (toval) != lval_internalvar)
fromval = value_cast (type, fromval);
else
COERCE_ARRAY (fromval);
CHECK_TYPEDEF (type);
if (VALUE_REGNO (toval) >= 0)
{
int regno = VALUE_REGNO (toval);
if (CONVERT_REGISTER_P (regno))
{
struct type *fromtype = check_typedef (VALUE_TYPE (fromval));
VALUE_TO_REGISTER (fromtype, regno, VALUE_CONTENTS (fromval), raw_buffer);
use_buffer = REGISTER_RAW_SIZE (regno);
}
}
switch (VALUE_LVAL (toval))
{
case lval_internalvar:
set_internalvar (VALUE_INTERNALVAR (toval), fromval);
val = value_copy (VALUE_INTERNALVAR (toval)->value);
val = value_change_enclosing_type (val, VALUE_ENCLOSING_TYPE (fromval));
VALUE_EMBEDDED_OFFSET (val) = VALUE_EMBEDDED_OFFSET (fromval);
VALUE_POINTED_TO_OFFSET (val) = VALUE_POINTED_TO_OFFSET (fromval);
return val;
case lval_internalvar_component:
set_internalvar_component (VALUE_INTERNALVAR (toval),
VALUE_OFFSET (toval),
VALUE_BITPOS (toval),
VALUE_BITSIZE (toval),
fromval);
break;
case lval_memory:
{
char *dest_buffer;
CORE_ADDR changed_addr;
int changed_len;
if (VALUE_BITSIZE (toval))
{
char buffer[sizeof (LONGEST)];
changed_len = (VALUE_BITPOS (toval)
+ VALUE_BITSIZE (toval)
+ HOST_CHAR_BIT - 1)
/ HOST_CHAR_BIT;
if (changed_len > (int) sizeof (LONGEST))
error ("Can't handle bitfields which don't fit in a %d bit word.",
(int) sizeof (LONGEST) * HOST_CHAR_BIT);
read_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
buffer, changed_len);
modify_field (buffer, value_as_long (fromval),
VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
changed_addr = VALUE_ADDRESS (toval) + VALUE_OFFSET (toval);
dest_buffer = buffer;
}
else if (use_buffer)
{
changed_addr = VALUE_ADDRESS (toval) + VALUE_OFFSET (toval);
changed_len = use_buffer;
dest_buffer = raw_buffer;
}
else
{
changed_addr = VALUE_ADDRESS (toval) + VALUE_OFFSET (toval);
changed_len = TYPE_LENGTH (type);
dest_buffer = VALUE_CONTENTS (fromval);
}
write_memory (changed_addr, dest_buffer, changed_len);
if (memory_changed_hook)
memory_changed_hook (changed_addr, changed_len);
target_changed_event ();
}
break;
case lval_register:
if (VALUE_BITSIZE (toval))
{
char buffer[sizeof (LONGEST)];
int len =
REGISTER_RAW_SIZE (VALUE_REGNO (toval)) - VALUE_OFFSET (toval);
if (len > (int) sizeof (LONGEST))
error ("Can't handle bitfields in registers larger than %d bits.",
(int) sizeof (LONGEST) * HOST_CHAR_BIT);
if (VALUE_BITPOS (toval) + VALUE_BITSIZE (toval)
> len * HOST_CHAR_BIT)
error ("Can't assign to bitfields that cross register "
"boundaries.");
read_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
buffer, len);
modify_field (buffer, value_as_long (fromval),
VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
buffer, len);
}
else if (use_buffer)
write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
raw_buffer, use_buffer);
else
{
#ifdef REGISTER_CONVERT_FROM_TYPE
memcpy (raw_buffer, VALUE_CONTENTS (fromval), TYPE_LENGTH (type));
REGISTER_CONVERT_FROM_TYPE (VALUE_REGNO (toval), type, raw_buffer);
write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
raw_buffer, TYPE_LENGTH (type));
#else
write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
VALUE_CONTENTS (fromval), TYPE_LENGTH (type));
#endif
}
target_changed_event ();
reinit_frame_cache ();
break;
case lval_reg_frame_relative:
{
int amount_to_copy = (VALUE_BITSIZE (toval) ? 1 : TYPE_LENGTH (type));
int reg_size = REGISTER_RAW_SIZE (VALUE_FRAME_REGNUM (toval));
int byte_offset = VALUE_OFFSET (toval) % reg_size;
int reg_offset = VALUE_OFFSET (toval) / reg_size;
int amount_copied;
char *buffer = (char *) alloca (amount_to_copy
+ sizeof (LONGEST)
+ MAX_REGISTER_RAW_SIZE);
int regno;
struct frame_info *frame;
for (frame = get_current_frame ();
frame && FRAME_FP (frame) != VALUE_FRAME (toval);
frame = get_prev_frame (frame))
;
if (!frame)
error ("Value being assigned to is no longer active.");
amount_to_copy += (reg_size - amount_to_copy % reg_size);
for ((regno = VALUE_FRAME_REGNUM (toval) + reg_offset,
amount_copied = 0);
amount_copied < amount_to_copy;
amount_copied += reg_size, regno++)
{
get_saved_register (buffer + amount_copied,
(int *) NULL, (CORE_ADDR *) NULL,
frame, regno, (enum lval_type *) NULL);
}
if (VALUE_BITSIZE (toval))
modify_field (buffer + byte_offset,
value_as_long (fromval),
VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
else if (use_buffer)
memcpy (buffer + byte_offset, raw_buffer, use_buffer);
else
memcpy (buffer + byte_offset, VALUE_CONTENTS (fromval),
TYPE_LENGTH (type));
for ((regno = VALUE_FRAME_REGNUM (toval) + reg_offset,
amount_copied = 0);
amount_copied < amount_to_copy;
amount_copied += reg_size, regno++)
{
enum lval_type lval;
CORE_ADDR addr;
int optim;
get_saved_register ((char *) NULL,
&optim, &addr, frame, regno, &lval);
if (optim)
error ("Attempt to assign to a value that was optimized out.");
if (lval == lval_memory)
write_memory (addr, buffer + amount_copied, reg_size);
else if (lval == lval_register)
write_register_bytes (addr, buffer + amount_copied, reg_size);
else
error ("Attempt to assign to an unmodifiable value.");
}
if (register_changed_hook)
register_changed_hook (-1);
target_changed_event ();
}
break;
default:
error ("Left operand of assignment is not an lvalue.");
}
if ((VALUE_BITSIZE (toval) > 0)
&& (VALUE_BITSIZE (toval) < 8 * (int) sizeof (LONGEST)))
{
LONGEST fieldval = value_as_long (fromval);
LONGEST valmask = (((ULONGEST) 1) << VALUE_BITSIZE (toval)) - 1;
fieldval &= valmask;
if (!TYPE_UNSIGNED (type) && (fieldval & (valmask ^ (valmask >> 1))))
fieldval |= ~valmask;
fromval = value_from_longest (type, fieldval);
}
val = value_copy (toval);
memcpy (VALUE_CONTENTS_RAW (val), VALUE_CONTENTS (fromval),
TYPE_LENGTH (type));
VALUE_TYPE (val) = type;
val = value_change_enclosing_type (val, VALUE_ENCLOSING_TYPE (fromval));
VALUE_EMBEDDED_OFFSET (val) = VALUE_EMBEDDED_OFFSET (fromval);
VALUE_POINTED_TO_OFFSET (val) = VALUE_POINTED_TO_OFFSET (fromval);
return val;
}
struct value *
value_repeat (struct value *arg1, int count)
{
struct value *val;
if (VALUE_LVAL (arg1) != lval_memory)
error ("Only values in memory can be extended with '@'.");
if (count < 1)
error ("Invalid number %d of repetitions.", count);
val = allocate_repeat_value (VALUE_ENCLOSING_TYPE (arg1), count);
read_memory (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1),
VALUE_CONTENTS_ALL_RAW (val),
TYPE_LENGTH (VALUE_ENCLOSING_TYPE (val)));
VALUE_LVAL (val) = lval_memory;
VALUE_ADDRESS (val) = VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1);
return val;
}
struct value *
value_of_variable (struct symbol *var, struct block *b)
{
struct value *val;
struct frame_info *frame = NULL;
if (!b)
frame = NULL;
else if (symbol_read_needs_frame (var))
{
frame = block_innermost_frame (b);
if (!frame)
{
if (BLOCK_FUNCTION (b)
&& SYMBOL_SOURCE_NAME (BLOCK_FUNCTION (b)))
error ("No frame is currently executing in block %s.",
SYMBOL_SOURCE_NAME (BLOCK_FUNCTION (b)));
else
error ("No frame is currently executing in specified block");
}
}
val = read_var_value (var, frame);
if (!val)
error ("Address of symbol \"%s\" is unknown.", SYMBOL_SOURCE_NAME (var));
return val;
}
struct value *
value_coerce_array (struct value *arg1)
{
register struct type *type = check_typedef (VALUE_TYPE (arg1));
if (VALUE_LVAL (arg1) != lval_memory)
error ("Attempt to take address of value not located in memory.");
return value_from_pointer (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
(VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1)));
}
struct value *
value_coerce_function (struct value *arg1)
{
struct value *retval;
if (VALUE_LVAL (arg1) != lval_memory)
error ("Attempt to take address of value not located in memory.");
retval = value_from_pointer (lookup_pointer_type (VALUE_TYPE (arg1)),
(VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1)));
VALUE_BFD_SECTION (retval) = VALUE_BFD_SECTION (arg1);
return retval;
}
struct value *
value_addr (struct value *arg1)
{
struct value *arg2;
struct type *type = check_typedef (VALUE_TYPE (arg1));
if (TYPE_CODE (type) == TYPE_CODE_REF)
{
arg2 = value_copy (arg1);
VALUE_TYPE (arg2) = lookup_pointer_type (TYPE_TARGET_TYPE (type));
return arg2;
}
if (TYPE_CODE (type) == TYPE_CODE_FUNC)
return value_coerce_function (arg1);
if (VALUE_LVAL (arg1) != lval_memory)
error ("Attempt to take address of value not located in memory.");
arg2 = value_from_pointer (lookup_pointer_type (VALUE_TYPE (arg1)),
(VALUE_ADDRESS (arg1)
+ VALUE_OFFSET (arg1)
+ VALUE_EMBEDDED_OFFSET (arg1)));
arg2 = value_change_enclosing_type (arg2, lookup_pointer_type (VALUE_ENCLOSING_TYPE (arg1)));
VALUE_POINTED_TO_OFFSET (arg2) = VALUE_EMBEDDED_OFFSET (arg1);
VALUE_BFD_SECTION (arg2) = VALUE_BFD_SECTION (arg1);
return arg2;
}
struct value *
value_ind (struct value *arg1)
{
struct type *base_type;
struct value *arg2;
COERCE_ARRAY (arg1);
base_type = check_typedef (VALUE_TYPE (arg1));
if (TYPE_CODE (base_type) == TYPE_CODE_MEMBER)
error ("not implemented: member types in value_ind");
if (TYPE_CODE (base_type) == TYPE_CODE_INT)
return value_at_lazy (builtin_type_int,
(CORE_ADDR) value_as_long (arg1),
VALUE_BFD_SECTION (arg1));
else if (TYPE_CODE (base_type) == TYPE_CODE_PTR)
{
struct type *enc_type;
enc_type = check_typedef (VALUE_ENCLOSING_TYPE (arg1));
enc_type = TYPE_TARGET_TYPE (enc_type);
arg2 = value_at_lazy (enc_type,
value_as_address (arg1) - VALUE_POINTED_TO_OFFSET (arg1),
VALUE_BFD_SECTION (arg1));
VALUE_TYPE (arg2) = TYPE_TARGET_TYPE (base_type);
arg2 = value_change_enclosing_type (arg2, enc_type);
VALUE_EMBEDDED_OFFSET (arg2) = VALUE_POINTED_TO_OFFSET (arg1);
arg2 = value_full_object (arg2, NULL, 0, 0, 0);
return arg2;
}
error ("Attempt to take contents of a non-pointer value.");
return 0;
}
CORE_ADDR
push_word (CORE_ADDR sp, ULONGEST word)
{
register int len = REGISTER_SIZE;
char *buffer = alloca (MAX_REGISTER_RAW_SIZE);
store_unsigned_integer (buffer, len, word);
if (INNER_THAN (1, 2))
{
sp -= len;
write_memory (sp, buffer, len);
}
else
{
write_memory (sp, buffer, len);
sp += len;
}
return sp;
}
CORE_ADDR
push_bytes (CORE_ADDR sp, char *buffer, int len)
{
if (INNER_THAN (1, 2))
{
sp -= len;
write_memory (sp, buffer, len);
}
else
{
write_memory (sp, buffer, len);
sp += len;
}
return sp;
}
#ifndef PARM_BOUNDARY
#define PARM_BOUNDARY (0)
#endif
static CORE_ADDR
value_push (register CORE_ADDR sp, struct value *arg)
{
register int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg));
register int container_len = len;
register int offset;
if (PARM_BOUNDARY)
container_len = ((len + PARM_BOUNDARY / TARGET_CHAR_BIT - 1)
& ~(PARM_BOUNDARY / TARGET_CHAR_BIT - 1));
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
offset = container_len - len;
else
offset = 0;
if (INNER_THAN (1, 2))
{
sp -= container_len;
write_memory (sp + offset, VALUE_CONTENTS_ALL (arg), len);
}
else
{
write_memory (sp + offset, VALUE_CONTENTS_ALL (arg), len);
sp += container_len;
}
return sp;
}
CORE_ADDR
default_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
int struct_return, CORE_ADDR struct_addr)
{
int i;
for (i = nargs - 1; i >= 0; i--)
sp = value_push (sp, args[i]);
return sp;
}
int
default_coerce_float_to_double (struct type *formal, struct type *actual)
{
return formal == NULL;
}
int
standard_coerce_float_to_double (struct type *formal, struct type *actual)
{
return 1;
}
static struct value *
value_arg_coerce (struct value *arg, struct type *param_type,
int is_prototyped)
{
register struct type *arg_type = check_typedef (VALUE_TYPE (arg));
register struct type *type
= param_type ? check_typedef (param_type) : arg_type;
switch (TYPE_CODE (type))
{
case TYPE_CODE_REF:
if (TYPE_CODE (arg_type) != TYPE_CODE_REF
&& TYPE_CODE (arg_type) != TYPE_CODE_PTR)
{
arg = value_addr (arg);
VALUE_TYPE (arg) = param_type;
return arg;
}
break;
case TYPE_CODE_INT:
case TYPE_CODE_CHAR:
case TYPE_CODE_BOOL:
case TYPE_CODE_ENUM:
if (!is_prototyped)
{
if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int))
type = builtin_type_int;
}
if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int))
type = builtin_type_int;
break;
case TYPE_CODE_FLT:
if (!is_prototyped && COERCE_FLOAT_TO_DOUBLE (param_type, arg_type))
{
if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double))
type = builtin_type_double;
else if (TYPE_LENGTH (type) > TYPE_LENGTH (builtin_type_double))
type = builtin_type_long_double;
}
break;
case TYPE_CODE_FUNC:
type = lookup_pointer_type (type);
break;
case TYPE_CODE_ARRAY:
if (current_language->c_style_arrays)
if (!TYPE_VECTOR (type))
type = lookup_pointer_type (TYPE_TARGET_TYPE (type));
break;
case TYPE_CODE_UNDEF:
case TYPE_CODE_PTR:
case TYPE_CODE_STRUCT:
case TYPE_CODE_UNION:
case TYPE_CODE_VOID:
case TYPE_CODE_SET:
case TYPE_CODE_RANGE:
case TYPE_CODE_STRING:
case TYPE_CODE_BITSTRING:
case TYPE_CODE_ERROR:
case TYPE_CODE_MEMBER:
case TYPE_CODE_METHOD:
case TYPE_CODE_COMPLEX:
default:
break;
}
return value_cast (type, arg);
}
CORE_ADDR
find_function_addr (struct value *function, struct type **retval_type)
{
register struct type *ftype = check_typedef (VALUE_TYPE (function));
register enum type_code code = TYPE_CODE (ftype);
struct type *value_type;
CORE_ADDR funaddr;
if (code == TYPE_CODE_FUNC || code == TYPE_CODE_METHOD)
{
funaddr = VALUE_ADDRESS (function);
value_type = TYPE_TARGET_TYPE (ftype);
}
else if (code == TYPE_CODE_PTR)
{
funaddr = value_as_address (function);
ftype = check_typedef (TYPE_TARGET_TYPE (ftype));
if (TYPE_CODE (ftype) == TYPE_CODE_FUNC
|| TYPE_CODE (ftype) == TYPE_CODE_METHOD)
{
funaddr = CONVERT_FROM_FUNC_PTR_ADDR (funaddr);
value_type = TYPE_TARGET_TYPE (ftype);
}
else
value_type = builtin_type_int;
}
else if (code == TYPE_CODE_INT)
{
if (TYPE_LENGTH (ftype) == 1)
funaddr = value_as_address (value_addr (function));
else
funaddr = (CORE_ADDR) value_as_long (function);
value_type = builtin_type_int;
}
else if (code == TYPE_CODE_ERROR)
{
value_type = builtin_type_error;
}
else
error ("Invalid data type for function to be called.");
*retval_type = value_type;
return funaddr;
}
static struct value *
hand_function_call (struct value *function, struct type *expect_type,
int nargs, struct value **args, int restore_frame)
{
register CORE_ADDR sp;
register int i;
int rc;
CORE_ADDR start_sp;
static ULONGEST *dummy;
int sizeof_dummy1;
char *dummy1;
CORE_ADDR old_sp;
struct type *value_type;
unsigned char struct_return;
CORE_ADDR struct_addr = 0;
struct regcache *retbuf;
struct cleanup *retbuf_cleanup;
struct inferior_status *inf_status;
struct cleanup *inf_status_cleanup;
CORE_ADDR funaddr;
int using_gcc;
CORE_ADDR real_pc;
struct type *param_type = NULL;
struct type *ftype = check_typedef (SYMBOL_TYPE (function));
int n_method_args = 0;
dummy = alloca (SIZEOF_CALL_DUMMY_WORDS);
sizeof_dummy1 = REGISTER_SIZE * SIZEOF_CALL_DUMMY_WORDS / sizeof (ULONGEST);
dummy1 = alloca (sizeof_dummy1);
memcpy (dummy, CALL_DUMMY_WORDS, SIZEOF_CALL_DUMMY_WORDS);
if (!target_has_execution)
noprocess ();
funaddr = find_function_addr (function, &value_type);
CHECK_TYPEDEF (value_type);
if ((value_type == NULL) || (TYPE_CODE (value_type) == TYPE_CODE_ERROR))
value_type = expect_type;
if ((value_type == NULL) || (TYPE_CODE (value_type) == TYPE_CODE_ERROR))
error ("Unable to call function at 0x%lx: no return type information available.\n"
"To call this function anyway, you can cast the return type explicitly (e.g. 'print (float) fabs (3.0)')",
(unsigned long) funaddr);
retbuf = regcache_xmalloc (current_gdbarch);
retbuf_cleanup = make_cleanup_regcache_xfree (retbuf);
inf_status = save_inferior_status (1);
inf_status_cleanup = make_cleanup_restore_inferior_status (inf_status);
PUSH_DUMMY_FRAME;
old_sp = read_sp ();
if (gdbarch_frame_align_p (current_gdbarch))
{
sp = gdbarch_frame_align (current_gdbarch, old_sp);
if (sp == old_sp)
{
if (INNER_THAN (1, 2))
sp = gdbarch_frame_align (current_gdbarch, old_sp - 1);
else
sp = gdbarch_frame_align (current_gdbarch, old_sp + 1);
}
gdb_assert ((INNER_THAN (1, 2) && sp <= old_sp)
|| (INNER_THAN (2, 1) && sp >= old_sp));
}
else
sp = old_sp;
if (INNER_THAN (1, 2))
{
sp -= sizeof_dummy1;
start_sp = sp;
}
else
{
start_sp = sp;
sp += sizeof_dummy1;
}
{
struct block *b = block_for_pc (funaddr);
using_gcc = (b == NULL ? 2 : BLOCK_GCC_COMPILED (b));
}
struct_return = using_struct_return (function, funaddr, value_type,
using_gcc);
for (i = 0; i < (int) (SIZEOF_CALL_DUMMY_WORDS / sizeof (dummy[0])); i++)
store_unsigned_integer (&dummy1[i * REGISTER_SIZE],
REGISTER_SIZE,
(ULONGEST) dummy[i]);
#ifdef GDB_TARGET_IS_HPPA
real_pc = FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args,
value_type, using_gcc);
#else
FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args,
value_type, using_gcc);
real_pc = start_sp;
#endif
if (CALL_DUMMY_LOCATION == ON_STACK)
{
write_memory (start_sp, (char *) dummy1, sizeof_dummy1);
if (USE_GENERIC_DUMMY_FRAMES)
generic_save_call_dummy_addr (start_sp, start_sp + sizeof_dummy1);
}
if (CALL_DUMMY_LOCATION == BEFORE_TEXT_END)
{
extern CORE_ADDR text_end;
static int checked = 0;
if (!checked)
for (start_sp = text_end - sizeof_dummy1; start_sp < text_end; ++start_sp)
if (read_memory_integer (start_sp, 1) != 0)
error ("text segment full -- no place to put call");
checked = 1;
sp = old_sp;
real_pc = text_end - sizeof_dummy1;
write_memory (real_pc, (char *) dummy1, sizeof_dummy1);
if (USE_GENERIC_DUMMY_FRAMES)
generic_save_call_dummy_addr (real_pc, real_pc + sizeof_dummy1);
}
if (CALL_DUMMY_LOCATION == AFTER_TEXT_END)
{
extern CORE_ADDR text_end;
int errcode;
sp = old_sp;
real_pc = text_end;
errcode = target_write_memory (real_pc, (char *) dummy1, sizeof_dummy1);
if (errcode != 0)
error ("Cannot write text segment -- call_function failed");
if (USE_GENERIC_DUMMY_FRAMES)
generic_save_call_dummy_addr (real_pc, real_pc + sizeof_dummy1);
}
if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT)
{
real_pc = funaddr;
if (USE_GENERIC_DUMMY_FRAMES)
generic_save_call_dummy_addr (CALL_DUMMY_ADDRESS (),
CALL_DUMMY_ADDRESS () + 1);
}
#ifdef lint
sp = old_sp;
#endif
if (nargs < TYPE_NFIELDS (ftype))
error ("too few arguments in function call");
for (i = nargs - 1; i >= 0; i--)
{
int prototyped;
if (TYPE_CODE (ftype) == TYPE_CODE_METHOD)
prototyped = 1;
else
prototyped = TYPE_PROTOTYPED (ftype);
if (i < TYPE_NFIELDS (ftype))
args[i] = value_arg_coerce (args[i], TYPE_FIELD_TYPE (ftype, i),
prototyped);
else
args[i] = value_arg_coerce (args[i], NULL, 0);
if (using_gcc == 0)
if (param_type && TYPE_CODE (ftype) != TYPE_CODE_METHOD)
if (TYPE_CODE (param_type) == TYPE_CODE_PTR)
if (TYPE_CODE (TYPE_TARGET_TYPE (param_type)) == TYPE_CODE_FUNC)
if (using_gcc == 0)
if (args[i]->lval == not_lval)
{
char *arg_name;
if (find_pc_partial_function ((CORE_ADDR) args[i]->aligner.contents[0], &arg_name, NULL, NULL))
error ("\
You cannot use function <%s> as argument. \n\
You must use a pointer to function type variable. Command ignored.", arg_name);
}
}
if (REG_STRUCT_HAS_ADDR_P ())
{
for (i = nargs - 1; i >= 0; i--)
{
struct type *arg_type = check_typedef (VALUE_TYPE (args[i]));
if ((TYPE_CODE (arg_type) == TYPE_CODE_STRUCT
|| TYPE_CODE (arg_type) == TYPE_CODE_UNION
|| TYPE_CODE (arg_type) == TYPE_CODE_ARRAY
|| TYPE_CODE (arg_type) == TYPE_CODE_STRING
|| TYPE_CODE (arg_type) == TYPE_CODE_BITSTRING
|| TYPE_CODE (arg_type) == TYPE_CODE_SET
|| (TYPE_CODE (arg_type) == TYPE_CODE_FLT
&& TYPE_LENGTH (arg_type) > 8)
)
&& REG_STRUCT_HAS_ADDR (using_gcc, arg_type))
{
CORE_ADDR addr;
int len;
int aligned_len;
arg_type = check_typedef (VALUE_ENCLOSING_TYPE (args[i]));
len = TYPE_LENGTH (arg_type);
if (STACK_ALIGN_P ())
aligned_len = STACK_ALIGN (len);
else
aligned_len = len;
if (INNER_THAN (1, 2))
{
sp -= aligned_len;
addr = sp;
}
else
{
addr = sp;
sp += aligned_len;
}
write_memory (addr, VALUE_CONTENTS_ALL (args[i]), len);
args[i] = value_from_pointer (lookup_pointer_type (arg_type),
addr);
}
}
}
if (struct_return)
{
int len = TYPE_LENGTH (value_type);
if (STACK_ALIGN_P ())
len = STACK_ALIGN (len);
if (INNER_THAN (1, 2))
{
sp -= len;
if (gdbarch_frame_align_p (current_gdbarch))
sp = gdbarch_frame_align (current_gdbarch, sp);
struct_addr = sp;
}
else
{
if (gdbarch_frame_align_p (current_gdbarch))
sp = gdbarch_frame_align (current_gdbarch, sp);
struct_addr = sp;
sp += len;
if (gdbarch_frame_align_p (current_gdbarch))
sp = gdbarch_frame_align (current_gdbarch, sp);
}
}
if (EXTRA_STACK_ALIGNMENT_NEEDED)
{
if (STACK_ALIGN_P () && INNER_THAN (1, 2))
{
int len = 0;
for (i = nargs - 1; i >= 0; i--)
len += TYPE_LENGTH (VALUE_ENCLOSING_TYPE (args[i]));
if (CALL_DUMMY_STACK_ADJUST_P)
len += CALL_DUMMY_STACK_ADJUST;
sp -= STACK_ALIGN (len) - len;
}
}
sp = PUSH_ARGUMENTS (nargs, args, sp, struct_return, struct_addr);
if (PUSH_RETURN_ADDRESS_P ())
sp = PUSH_RETURN_ADDRESS (real_pc, sp);
if (STACK_ALIGN_P () && !INNER_THAN (1, 2))
{
if (CALL_DUMMY_STACK_ADJUST_P)
sp += CALL_DUMMY_STACK_ADJUST;
sp = STACK_ALIGN (sp);
}
if (CALL_DUMMY_STACK_ADJUST_P)
if (INNER_THAN (1, 2))
{
sp -= CALL_DUMMY_STACK_ADJUST;
}
if (struct_return)
STORE_STRUCT_RETURN (struct_addr, sp);
write_sp (sp);
if (SAVE_DUMMY_FRAME_TOS_P ())
SAVE_DUMMY_FRAME_TOS (sp);
{
char *name;
struct symbol *symbol;
name = NULL;
symbol = find_pc_function (funaddr);
if (symbol)
{
name = SYMBOL_SOURCE_NAME (symbol);
}
else
{
struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (funaddr);
if (msymbol)
{
name = SYMBOL_SOURCE_NAME (msymbol);
}
}
if (name == NULL)
{
char format[80];
sprintf (format, "at %s", local_hex_format ());
name = alloca (80);
sprintf (name, format, (unsigned long) funaddr);
}
rc = run_stack_dummy (real_pc + CALL_DUMMY_START_OFFSET, retbuf);
if (rc == 1)
{
if (unwind_on_signal_p)
{
POP_FRAME;
error ("\
The program being debugged was signaled while in a function called from GDB.\n\
GDB has restored the context to what it was before the call.\n\
To change this behavior use \"set unwindonsignal off\"\n\
Evaluation of the expression containing the function (%s) will be abandoned.",
name);
}
else
{
discard_cleanups (inf_status_cleanup);
discard_inferior_status (inf_status);
error ("\
The program being debugged was signaled while in a function called from GDB.\n\
GDB remains in the frame where the signal was received.\n\
To change this behavior use \"set unwindonsignal on\"\n\
Evaluation of the expression containing the function (%s) will be abandoned.",
name);
}
}
if (rc == 2)
{
discard_cleanups (inf_status_cleanup);
discard_inferior_status (inf_status);
error ("\
The program being debugged stopped while in a function called from GDB.\n\
When the function (%s) is done executing, GDB will silently\n\
stop (instead of continuing to evaluate the expression containing\n\
the function call).", name);
}
do_cleanups (inf_status_cleanup);
#ifdef VALUE_RETURNED_FROM_STACK
if (struct_return)
{
do_cleanups (retbuf_cleanup);
return VALUE_RETURNED_FROM_STACK (value_type, struct_addr);
}
#endif
if (struct_return && gdbarch_frame_align_p (current_gdbarch))
{
struct value *retval = value_at (value_type, struct_addr, NULL);
do_cleanups (retbuf_cleanup);
return retval;
}
else
{
struct value *retval = value_being_returned (value_type, retbuf,
struct_return);
do_cleanups (retbuf_cleanup);
return retval;
}
}
}
struct value *
call_function_by_hand (struct value *function, int nargs, struct value **args)
{
if (CALL_DUMMY_P)
{
return hand_function_call (function, NULL, nargs, args, 1);
}
else
{
error ("Cannot invoke functions on this machine.");
}
}
struct value *
call_function_by_hand_expecting_type (struct value *function, struct type *expect_type,
int nargs, struct value **args, int restore_frame)
{
if (CALL_DUMMY_P)
{
return hand_function_call (function, expect_type, nargs, args, restore_frame);
}
else
{
error ("Cannot invoke functions on this machine.");
}
}
struct value *
value_array (int lowbound, int highbound, struct value **elemvec)
{
int nelem;
int idx;
unsigned int typelength;
struct value *val;
struct type *rangetype;
struct type *arraytype;
CORE_ADDR addr;
nelem = highbound - lowbound + 1;
if (nelem <= 0)
{
error ("bad array bounds (%d, %d)", lowbound, highbound);
}
typelength = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (elemvec[0]));
for (idx = 1; idx < nelem; idx++)
{
if (TYPE_LENGTH (VALUE_ENCLOSING_TYPE (elemvec[idx])) != typelength)
{
error ("array elements must all be the same size");
}
}
rangetype = create_range_type ((struct type *) NULL, builtin_type_int,
lowbound, highbound);
arraytype = create_array_type ((struct type *) NULL,
VALUE_ENCLOSING_TYPE (elemvec[0]), rangetype);
if (!current_language->c_style_arrays)
{
val = allocate_value (arraytype);
for (idx = 0; idx < nelem; idx++)
{
memcpy (VALUE_CONTENTS_ALL_RAW (val) + (idx * typelength),
VALUE_CONTENTS_ALL (elemvec[idx]),
typelength);
}
VALUE_BFD_SECTION (val) = VALUE_BFD_SECTION (elemvec[0]);
return val;
}
addr = allocate_space_in_inferior (nelem * typelength);
for (idx = 0; idx < nelem; idx++)
{
write_memory (addr + (idx * typelength), VALUE_CONTENTS_ALL (elemvec[idx]),
typelength);
}
val = value_at_lazy (arraytype, addr, VALUE_BFD_SECTION (elemvec[0]));
return (val);
}
struct value *
value_string (char *ptr, int len)
{
struct value *val;
int lowbound = current_language->string_lower_bound;
struct type *rangetype = create_range_type ((struct type *) NULL,
builtin_type_int,
lowbound, len + lowbound - 1);
struct type *stringtype
= create_string_type ((struct type *) NULL, rangetype);
CORE_ADDR addr;
if (current_language->c_style_arrays == 0)
{
val = allocate_value (stringtype);
memcpy (VALUE_CONTENTS_RAW (val), ptr, len);
return val;
}
addr = allocate_space_in_inferior (len);
write_memory (addr, ptr, len);
val = value_at_lazy (stringtype, addr, NULL);
return (val);
}
struct value *
value_bitstring (char *ptr, int len)
{
struct value *val;
struct type *domain_type = create_range_type (NULL, builtin_type_int,
0, len - 1);
struct type *type = create_set_type ((struct type *) NULL, domain_type);
TYPE_CODE (type) = TYPE_CODE_BITSTRING;
val = allocate_value (type);
memcpy (VALUE_CONTENTS_RAW (val), ptr, TYPE_LENGTH (type));
return val;
}
static int
typecmp (int staticp, int varargs, int nargs,
struct field t1[], struct value *t2[])
{
int i;
if (t2 == 0)
internal_error (__FILE__, __LINE__, "typecmp: no argument list");
if (staticp)
t2 ++;
for (i = 0;
(i < nargs) && TYPE_CODE (t1[i].type) != TYPE_CODE_VOID;
i++)
{
struct type *tt1, *tt2;
if (!t2[i])
return i + 1;
tt1 = check_typedef (t1[i].type);
tt2 = check_typedef (VALUE_TYPE (t2[i]));
if (TYPE_CODE (tt1) == TYPE_CODE_REF
&& (TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (tt1))) == TYPE_CODE (tt2)))
{
if (TYPE_CODE (tt2) == TYPE_CODE_ARRAY)
t2[i] = value_coerce_array (t2[i]);
else
t2[i] = value_addr (t2[i]);
continue;
}
while ( TYPE_CODE(tt1) == TYPE_CODE_REF ||
TYPE_CODE (tt1) == TYPE_CODE_PTR)
{
tt1 = check_typedef( TYPE_TARGET_TYPE(tt1) );
}
while ( TYPE_CODE(tt2) == TYPE_CODE_ARRAY ||
TYPE_CODE(tt2) == TYPE_CODE_PTR ||
TYPE_CODE(tt2) == TYPE_CODE_REF)
{
tt2 = check_typedef( TYPE_TARGET_TYPE(tt2) );
}
if (TYPE_CODE (tt1) == TYPE_CODE (tt2))
continue;
if (TYPE_CODE (t1[i].type) != TYPE_CODE (VALUE_TYPE (t2[i])))
return i + 1;
}
if (varargs || t2[i] == NULL)
return 0;
return i + 1;
}
static struct value *
search_struct_field (char *name, struct value *arg1, int offset,
register struct type *type, int looking_for_baseclass)
{
int i;
int nbases = TYPE_N_BASECLASSES (type);
CHECK_TYPEDEF (type);
if (!looking_for_baseclass)
for (i = TYPE_NFIELDS (type) - 1; i >= nbases; i--)
{
char *t_field_name = TYPE_FIELD_NAME (type, i);
if (t_field_name && (strcmp_iw (t_field_name, name) == 0))
{
struct value *v;
if (TYPE_FIELD_STATIC (type, i))
{
v = value_static_field (type, i);
if (v == 0)
error ("field %s is nonexistent or has been optimised out",
name);
}
else
{
v = value_primitive_field (arg1, offset, i, type);
if (v == 0)
error ("there is no field named %s", name);
}
return v;
}
if (t_field_name
&& (t_field_name[0] == '\0'
|| (TYPE_CODE (type) == TYPE_CODE_UNION
&& (strcmp_iw (t_field_name, "else") == 0))))
{
struct type *field_type = TYPE_FIELD_TYPE (type, i);
if (TYPE_CODE (field_type) == TYPE_CODE_UNION
|| TYPE_CODE (field_type) == TYPE_CODE_STRUCT)
{
struct value *v;
int new_offset = offset;
if (TYPE_CODE (field_type) == TYPE_CODE_STRUCT
|| (TYPE_NFIELDS (field_type) > 0
&& TYPE_FIELD_BITPOS (field_type, 0) == 0))
new_offset += TYPE_FIELD_BITPOS (type, i) / 8;
v = search_struct_field (name, arg1, new_offset, field_type,
looking_for_baseclass);
if (v)
return v;
}
}
}
for (i = 0; i < nbases; i++)
{
struct value *v;
struct type *basetype = check_typedef (TYPE_BASECLASS (type, i));
int found_baseclass = (looking_for_baseclass
&& TYPE_BASECLASS_NAME (type, i) != NULL
&& (strcmp_iw (name, TYPE_BASECLASS_NAME (type, i)) == 0));
if (BASETYPE_VIA_VIRTUAL (type, i))
{
int boffset;
struct value *v2 = allocate_value (basetype);
boffset = baseclass_offset (type, i,
VALUE_CONTENTS (arg1) + offset,
VALUE_ADDRESS (arg1)
+ VALUE_OFFSET (arg1) + offset);
if (boffset == -1)
error ("virtual baseclass botch");
boffset += offset;
if (boffset < 0 || boffset >= TYPE_LENGTH (type))
{
CORE_ADDR base_addr;
base_addr = VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1) + boffset;
if (target_read_memory (base_addr, VALUE_CONTENTS_RAW (v2),
TYPE_LENGTH (basetype)) != 0)
error ("virtual baseclass botch");
VALUE_LVAL (v2) = lval_memory;
VALUE_ADDRESS (v2) = base_addr;
}
else
{
VALUE_LVAL (v2) = VALUE_LVAL (arg1);
VALUE_ADDRESS (v2) = VALUE_ADDRESS (arg1);
VALUE_OFFSET (v2) = VALUE_OFFSET (arg1) + boffset;
if (VALUE_LAZY (arg1))
VALUE_LAZY (v2) = 1;
else
memcpy (VALUE_CONTENTS_RAW (v2),
VALUE_CONTENTS_RAW (arg1) + boffset,
TYPE_LENGTH (basetype));
}
if (found_baseclass)
return v2;
v = search_struct_field (name, v2, 0, TYPE_BASECLASS (type, i),
looking_for_baseclass);
}
else if (found_baseclass)
v = value_primitive_field (arg1, offset, i, type);
else
v = search_struct_field (name, arg1,
offset + TYPE_BASECLASS_BITPOS (type, i) / 8,
basetype, looking_for_baseclass);
if (v)
return v;
}
return NULL;
}
void
find_rt_vbase_offset (struct type *type, struct type *basetype, char *valaddr,
int offset, int *boffset_p, int *skip_p)
{
int boffset;
int index;
int skip;
struct value *vp;
CORE_ADDR vtbl;
struct type *pbc;
boffset = 0;
pbc = TYPE_PRIMARY_BASE (type);
if (pbc)
{
find_rt_vbase_offset (pbc, basetype, valaddr, offset, &boffset, &skip);
if (skip < 0)
{
*boffset_p = boffset;
*skip_p = -1;
return;
}
}
else
skip = 0;
index = virtual_base_index_skip_primaries (basetype, type);
if (index < 0)
{
*skip_p = skip + virtual_base_list_length_skip_primaries (type);
*boffset_p = 0;
return;
}
vtbl = *(CORE_ADDR *) (valaddr + offset);
if (vtbl == 0)
error ("Couldn't find virtual table -- object may not be constructed yet.");
vp = value_at (builtin_type_int, vtbl + 4 * (-skip - index - HP_ACC_VBASE_START), NULL);
boffset = value_as_long (vp);
*skip_p = -1;
*boffset_p = boffset;
return;
}
static struct value *
search_struct_method (char *name, struct value **arg1p,
struct value **args, int offset,
int *static_memfuncp, register struct type *type)
{
int i;
struct value *v;
int name_matched = 0;
char dem_opname[64];
CHECK_TYPEDEF (type);
for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; i--)
{
char *t_field_name = TYPE_FN_FIELDLIST_NAME (type, i);
if (strncmp (t_field_name, "__", 2) == 0 ||
strncmp (t_field_name, "op", 2) == 0 ||
strncmp (t_field_name, "type", 4) == 0)
{
if (cplus_demangle_opname (t_field_name, dem_opname, DMGL_ANSI))
t_field_name = dem_opname;
else if (cplus_demangle_opname (t_field_name, dem_opname, 0))
t_field_name = dem_opname;
}
if (t_field_name && (strcmp_iw (t_field_name, name) == 0))
{
int j = TYPE_FN_FIELDLIST_LENGTH (type, i) - 1;
struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
name_matched = 1;
check_stub_method_group (type, i);
if (j > 0 && args == 0)
error ("cannot resolve overloaded method `%s': no arguments supplied", name);
else if (j == 0 && args == 0)
{
v = value_fn_field (arg1p, f, j, type, offset);
if (v != NULL)
return v;
}
else
while (j >= 0)
{
if (!typecmp (TYPE_FN_FIELD_STATIC_P (f, j),
TYPE_VARARGS (TYPE_FN_FIELD_TYPE (f, j)),
TYPE_NFIELDS (TYPE_FN_FIELD_TYPE (f, j)),
TYPE_FN_FIELD_ARGS (f, j), args))
{
if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
return value_virtual_fn_field (arg1p, f, j, type, offset);
if (TYPE_FN_FIELD_STATIC_P (f, j) && static_memfuncp)
*static_memfuncp = 1;
v = value_fn_field (arg1p, f, j, type, offset);
if (v != NULL)
return v;
}
j--;
}
}
}
for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
{
int base_offset;
if (BASETYPE_VIA_VIRTUAL (type, i))
{
if (TYPE_HAS_VTABLE (type))
{
int skip;
find_rt_vbase_offset (type, TYPE_BASECLASS (type, i),
VALUE_CONTENTS_ALL (*arg1p),
offset + VALUE_EMBEDDED_OFFSET (*arg1p),
&base_offset, &skip);
if (skip >= 0)
error ("Virtual base class offset not found in vtable");
}
else
{
struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
char *base_valaddr;
if (offset < 0 || offset >= TYPE_LENGTH (type))
{
base_valaddr = (char *) alloca (TYPE_LENGTH (baseclass));
if (target_read_memory (VALUE_ADDRESS (*arg1p)
+ VALUE_OFFSET (*arg1p) + offset,
base_valaddr,
TYPE_LENGTH (baseclass)) != 0)
error ("virtual baseclass botch");
}
else
base_valaddr = VALUE_CONTENTS (*arg1p) + offset;
base_offset =
baseclass_offset (type, i, base_valaddr,
VALUE_ADDRESS (*arg1p)
+ VALUE_OFFSET (*arg1p) + offset);
if (base_offset == -1)
error ("virtual baseclass botch");
}
}
else
{
base_offset = TYPE_BASECLASS_BITPOS (type, i) / 8;
}
v = search_struct_method (name, arg1p, args, base_offset + offset,
static_memfuncp, TYPE_BASECLASS (type, i));
if (v == (struct value *) - 1)
{
name_matched = 1;
}
else if (v)
{
return v;
}
}
if (name_matched)
return (struct value *) - 1;
else
return NULL;
}
struct value *
value_struct_elt (struct value **argp, struct value **args,
char *name, int *static_memfuncp, char *err)
{
register struct type *t;
struct value *v;
COERCE_ARRAY (*argp);
t = check_typedef (VALUE_TYPE (*argp));
while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
{
*argp = value_ind (*argp);
if (TYPE_CODE (VALUE_TYPE (*argp)) != TYPE_CODE_FUNC)
COERCE_ARRAY (*argp);
t = check_typedef (VALUE_TYPE (*argp));
}
if (TYPE_CODE (t) == TYPE_CODE_MEMBER)
error ("not implemented: member type in value_struct_elt");
if (TYPE_CODE (t) != TYPE_CODE_STRUCT
&& TYPE_CODE (t) != TYPE_CODE_UNION)
error ("Attempt to extract a component of a value that is not a %s.", err);
if (static_memfuncp)
*static_memfuncp = 0;
if (!args)
{
v = search_struct_field (name, *argp, 0, t, 0);
if (v)
return v;
if (destructor_name_p (name, t))
error ("Cannot get value of destructor");
v = search_struct_method (name, argp, args, 0, static_memfuncp, t);
if (v == (struct value *) - 1)
error ("Cannot take address of a method");
else if (v == 0)
{
if (TYPE_NFN_FIELDS (t))
error ("There is no member or method named %s.", name);
else
error ("There is no member named %s.", name);
}
return v;
}
if (destructor_name_p (name, t))
{
if (!args[1])
{
int m_index, f_index;
v = NULL;
if (get_destructor_fn_field (t, &m_index, &f_index))
{
v = value_fn_field (NULL, TYPE_FN_FIELDLIST1 (t, m_index),
f_index, NULL, 0);
}
if (v == NULL)
error ("could not find destructor function named %s.", name);
else
return v;
}
else
{
error ("destructor should not have any argument");
}
}
else
v = search_struct_method (name, argp, args, 0, static_memfuncp, t);
if (v == (struct value *) - 1)
{
error ("One of the arguments you tried to pass to %s could not be converted to what the function wants.", name);
}
else if (v == 0)
{
v = search_struct_field (name, *argp, 0, t, 0);
}
if (!v)
error ("Structure has no component named %s.", name);
return v;
}
static struct fn_field *
find_method_list (struct value **argp, char *method, int offset,
struct type *type, int *num_fns,
struct type **basetype, int *boffset)
{
int i;
struct fn_field *f;
CHECK_TYPEDEF (type);
*num_fns = 0;
for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; i--)
{
char *fn_field_name = TYPE_FN_FIELDLIST_NAME (type, i);
if (fn_field_name && (strcmp_iw (fn_field_name, method) == 0))
{
int len = TYPE_FN_FIELDLIST_LENGTH (type, i);
struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
*num_fns = len;
*basetype = type;
*boffset = offset;
check_stub_method_group (type, i);
return f;
}
}
for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
{
int base_offset;
if (BASETYPE_VIA_VIRTUAL (type, i))
{
if (TYPE_HAS_VTABLE (type))
{
int skip;
find_rt_vbase_offset (type, TYPE_BASECLASS (type, i),
VALUE_CONTENTS_ALL (*argp),
offset + VALUE_EMBEDDED_OFFSET (*argp),
&base_offset, &skip);
if (skip >= 0)
error ("Virtual base class offset not found in vtable");
}
else
{
base_offset = VALUE_OFFSET (*argp) + offset;
base_offset =
baseclass_offset (type, i,
VALUE_CONTENTS (*argp) + base_offset,
VALUE_ADDRESS (*argp) + base_offset);
if (base_offset == -1)
error ("virtual baseclass botch");
}
}
else
{
base_offset = TYPE_BASECLASS_BITPOS (type, i) / 8;
}
f = find_method_list (argp, method, base_offset + offset,
TYPE_BASECLASS (type, i), num_fns, basetype,
boffset);
if (f)
return f;
}
return NULL;
}
struct fn_field *
value_find_oload_method_list (struct value **argp, char *method, int offset,
int *num_fns, struct type **basetype,
int *boffset)
{
struct type *t;
t = check_typedef (VALUE_TYPE (*argp));
while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
{
*argp = value_ind (*argp);
if (TYPE_CODE (VALUE_TYPE (*argp)) != TYPE_CODE_FUNC)
COERCE_ARRAY (*argp);
t = check_typedef (VALUE_TYPE (*argp));
}
if (TYPE_CODE (t) == TYPE_CODE_MEMBER)
error ("Not implemented: member type in value_find_oload_lis");
if (TYPE_CODE (t) != TYPE_CODE_STRUCT
&& TYPE_CODE (t) != TYPE_CODE_UNION)
error ("Attempt to extract a component of a value that is not a struct or union");
return find_method_list (argp, method, 0, t, num_fns, basetype, boffset);
}
int
find_overload_match (struct type **arg_types, int nargs, char *name, int method,
int lax, struct value **objp, struct symbol *fsym,
struct value **valp, struct symbol **symp, int *staticp)
{
int nparms;
struct type **parm_types;
int champ_nparms = 0;
struct value *obj = (objp ? *objp : NULL);
short oload_champ = -1;
short oload_ambiguous = 0;
short oload_ambig_champ = -1;
short oload_non_standard = 0;
short oload_incompatible = 0;
struct badness_vector *bv;
struct badness_vector *oload_champ_bv = NULL;
struct value *temp = obj;
struct fn_field *fns_ptr = NULL;
struct symbol **oload_syms = NULL;
int num_fns = 0;
struct type *basetype = NULL;
int boffset;
register int jj;
register int ix;
int static_offset;
struct cleanup *cleanups = NULL;
char *obj_type_name = NULL;
char *func_name = NULL;
if (method)
{
obj_type_name = TYPE_NAME (VALUE_TYPE (obj));
if ((!obj_type_name || !*obj_type_name) &&
(TYPE_CODE (VALUE_TYPE (obj)) == TYPE_CODE_PTR))
obj_type_name = TYPE_NAME (TYPE_TARGET_TYPE (VALUE_TYPE (obj)));
if ((!obj_type_name || !*obj_type_name) &&
(TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (obj))) == TYPE_CODE_PTR))
obj_type_name = TYPE_NAME (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (VALUE_TYPE (obj))));
fns_ptr = value_find_oload_method_list (&temp, name, 0,
&num_fns,
&basetype, &boffset);
if (!fns_ptr || !num_fns)
error ("Couldn't find method %s%s%s",
obj_type_name ? obj_type_name : "",
(obj_type_name && *obj_type_name) ? "::" : "",
name);
gdb_assert (TYPE_DOMAIN_TYPE (fns_ptr[0].type) != NULL);
}
else
{
int i = -1;
func_name = cplus_demangle (SYMBOL_NAME (fsym), DMGL_NO_OPTS);
if (!func_name)
{
*symp = fsym;
return 0;
}
oload_syms = make_symbol_overload_list (fsym);
cleanups = make_cleanup (xfree, oload_syms);
while (oload_syms[++i])
num_fns++;
if (!num_fns)
error ("Couldn't find function %s", func_name);
}
oload_champ_bv = NULL;
for (ix = 0; ix < num_fns; ix++)
{
static_offset = 0;
if (method)
{
if (TYPE_FN_FIELD_STATIC_P (fns_ptr, ix))
static_offset = 1;
nparms = TYPE_NFIELDS (TYPE_FN_FIELD_TYPE (fns_ptr, ix));
}
else
{
nparms=TYPE_NFIELDS(SYMBOL_TYPE(oload_syms[ix]));
}
parm_types = (struct type **) xmalloc (nparms * (sizeof (struct type *)));
for (jj = 0; jj < nparms; jj++)
parm_types[jj] = (method
? (TYPE_FN_FIELD_ARGS (fns_ptr, ix)[jj].type)
: TYPE_FIELD_TYPE (SYMBOL_TYPE (oload_syms[ix]), jj));
bv = rank_function (parm_types, nparms, arg_types + static_offset,
nargs - static_offset);
bv = rank_function (parm_types, nparms, arg_types, nargs);
if (!oload_champ_bv)
{
oload_champ_bv = bv;
oload_champ = 0;
champ_nparms = nparms;
}
else
switch (compare_badness (bv, oload_champ_bv))
{
case 0:
oload_ambiguous = 1;
oload_ambig_champ = ix;
break;
case 1:
oload_ambiguous = 2;
oload_ambig_champ = ix;
break;
case 2:
oload_champ_bv = bv;
oload_ambiguous = 0;
oload_champ = ix;
oload_ambig_champ = -1;
champ_nparms = nparms;
break;
case 3:
default:
break;
}
xfree (parm_types);
if (overload_debug)
{
if (method)
fprintf_filtered (gdb_stderr,"Overloaded method instance %s, # of parms %d\n", fns_ptr[ix].physname, nparms);
else
fprintf_filtered (gdb_stderr,"Overloaded function instance %s # of parms %d\n", SYMBOL_DEMANGLED_NAME (oload_syms[ix]), nparms);
for (jj = 0; jj < nargs - static_offset; jj++)
fprintf_filtered (gdb_stderr,"...Badness @ %d : %d\n", jj, bv->rank[jj]);
fprintf_filtered (gdb_stderr,"Overload resolution champion is %d, ambiguous? %d\n", oload_champ, oload_ambiguous);
}
}
#if 0
if (oload_ambiguous)
{
if (method)
error ("Cannot resolve overloaded method %s%s%s to unique instance; disambiguate by specifying function signature",
obj_type_name ? obj_type_name : "",
(obj_type_name && *obj_type_name) ? "::" : "",
name);
else
error ("Cannot resolve overloaded function %s to unique instance; disambiguate by specifying function signature",
func_name);
}
#endif
static_offset = 0;
if (method && TYPE_FN_FIELD_STATIC_P (fns_ptr, oload_champ))
static_offset = 1;
for (ix = 1; ix <= nargs - static_offset; ix++)
{
if (oload_champ_bv->rank[ix] >= 100)
oload_incompatible = 1;
else if (oload_champ_bv->rank[ix] >= 10)
oload_non_standard = 1;
}
if (oload_incompatible)
{
if (method)
error ("Cannot resolve method %s%s%s to any overloaded instance",
obj_type_name ? obj_type_name : "",
(obj_type_name && *obj_type_name) ? "::" : "",
name);
else
error ("Cannot resolve function %s to any overloaded instance",
func_name);
}
else if (oload_non_standard)
{
if (method)
warning ("Using non-standard conversion to match method %s%s%s to supplied arguments",
obj_type_name ? obj_type_name : "",
(obj_type_name && *obj_type_name) ? "::" : "",
name);
else
warning ("Using non-standard conversion to match function %s to supplied arguments",
func_name);
}
if (method)
{
if (staticp && TYPE_FN_FIELD_STATIC_P (fns_ptr, oload_champ))
*staticp = 1;
else if (staticp)
*staticp = 0;
if (TYPE_FN_FIELD_VIRTUAL_P (fns_ptr, oload_champ))
*valp = value_virtual_fn_field (&temp, fns_ptr, oload_champ, basetype, boffset);
else
*valp = value_fn_field (&temp, fns_ptr, oload_champ, basetype, boffset);
}
else
{
*symp = oload_syms[oload_champ];
xfree (func_name);
}
if (objp)
{
if (TYPE_CODE (VALUE_TYPE (temp)) != TYPE_CODE_PTR
&& TYPE_CODE (VALUE_TYPE (*objp)) == TYPE_CODE_PTR)
{
temp = value_addr (temp);
}
*objp = temp;
}
if (cleanups != NULL)
do_cleanups (cleanups);
return oload_incompatible ? 100 : (oload_non_standard ? 10 : 0);
}
int
destructor_name_p (const char *name, const struct type *type)
{
if (name[0] == '~')
{
char *dname = type_name_no_tag (type);
char *cp = strchr (dname, '<');
unsigned int len;
if (cp == NULL)
len = strlen (dname);
else
len = cp - dname;
if (strlen (name + 1) != len || !STREQN (dname, name + 1, len))
error ("name of destructor must equal name of class");
else
return 1;
}
return 0;
}
static int
check_field_in (register struct type *type, const char *name)
{
register int i;
for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--)
{
char *t_field_name = TYPE_FIELD_NAME (type, i);
if (t_field_name && (strcmp_iw (t_field_name, name) == 0))
return 1;
}
if (destructor_name_p (name, type))
{
int m_index, f_index;
return get_destructor_fn_field (type, &m_index, &f_index);
}
for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; --i)
{
if (strcmp_iw (TYPE_FN_FIELDLIST_NAME (type, i), name) == 0)
return 1;
}
for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
if (check_field_in (TYPE_BASECLASS (type, i), name))
return 1;
return 0;
}
int
check_field (struct value *arg1, const char *name)
{
register struct type *t;
COERCE_ARRAY (arg1);
t = VALUE_TYPE (arg1);
for (;;)
{
CHECK_TYPEDEF (t);
if (TYPE_CODE (t) != TYPE_CODE_PTR && TYPE_CODE (t) != TYPE_CODE_REF)
break;
t = TYPE_TARGET_TYPE (t);
}
if (TYPE_CODE (t) == TYPE_CODE_MEMBER)
error ("not implemented: member type in check_field");
if (TYPE_CODE (t) != TYPE_CODE_STRUCT
&& TYPE_CODE (t) != TYPE_CODE_UNION)
error ("Internal error: `this' is not an aggregate");
return check_field_in (t, name);
}
struct value *
value_struct_elt_for_reference (struct type *domain, int offset,
struct type *curtype, char *name,
struct type *intype)
{
register struct type *t = curtype;
register int i;
struct value *v;
if (TYPE_CODE (t) != TYPE_CODE_STRUCT
&& TYPE_CODE (t) != TYPE_CODE_UNION)
error ("Internal error: non-aggregate type to value_struct_elt_for_reference");
for (i = TYPE_NFIELDS (t) - 1; i >= TYPE_N_BASECLASSES (t); i--)
{
char *t_field_name = TYPE_FIELD_NAME (t, i);
if (t_field_name && STREQ (t_field_name, name))
{
if (TYPE_FIELD_STATIC (t, i))
{
v = value_static_field (t, i);
if (v == NULL)
error ("static field %s has been optimized out",
name);
return v;
}
if (TYPE_FIELD_PACKED (t, i))
error ("pointers to bitfield members not allowed");
return value_from_longest
(lookup_reference_type (lookup_member_type (TYPE_FIELD_TYPE (t, i),
domain)),
offset + (LONGEST) (TYPE_FIELD_BITPOS (t, i) >> 3));
}
}
if (destructor_name_p (name, t))
{
error ("member pointers to destructors not implemented yet");
}
while (intype && TYPE_CODE (intype) == TYPE_CODE_PTR)
intype = TYPE_TARGET_TYPE (intype);
for (i = TYPE_NFN_FIELDS (t) - 1; i >= 0; --i)
{
char *t_field_name = TYPE_FN_FIELDLIST_NAME (t, i);
char dem_opname[64];
if (strncmp (t_field_name, "__", 2) == 0 ||
strncmp (t_field_name, "op", 2) == 0 ||
strncmp (t_field_name, "type", 4) == 0)
{
if (cplus_demangle_opname (t_field_name, dem_opname, DMGL_ANSI))
t_field_name = dem_opname;
else if (cplus_demangle_opname (t_field_name, dem_opname, 0))
t_field_name = dem_opname;
}
if (t_field_name && STREQ (t_field_name, name))
{
int j = TYPE_FN_FIELDLIST_LENGTH (t, i);
struct fn_field *f = TYPE_FN_FIELDLIST1 (t, i);
check_stub_method_group (t, i);
if (intype == 0 && j > 1)
error ("non-unique member `%s' requires type instantiation", name);
if (intype)
{
while (j--)
if (TYPE_FN_FIELD_TYPE (f, j) == intype)
break;
if (j < 0)
error ("no member function matches that type instantiation");
}
else
j = 0;
if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
{
return value_from_longest
(lookup_reference_type
(lookup_member_type (TYPE_FN_FIELD_TYPE (f, j),
domain)),
(LONGEST) METHOD_PTR_FROM_VOFFSET (TYPE_FN_FIELD_VOFFSET (f, j)));
}
else
{
struct symbol *s = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, j),
0, VAR_NAMESPACE, 0, NULL);
if (s == NULL)
{
v = 0;
}
else
{
v = read_var_value (s, 0);
#if 0
VALUE_TYPE (v) = lookup_reference_type
(lookup_member_type (TYPE_FN_FIELD_TYPE (f, j),
domain));
#endif
}
return v;
}
}
}
for (i = TYPE_N_BASECLASSES (t) - 1; i >= 0; i--)
{
struct value *v;
int base_offset;
if (BASETYPE_VIA_VIRTUAL (t, i))
base_offset = 0;
else
base_offset = TYPE_BASECLASS_BITPOS (t, i) / 8;
v = value_struct_elt_for_reference (domain,
offset + base_offset,
TYPE_BASECLASS (t, i),
name,
intype);
if (v)
return v;
}
return 0;
}
struct type *
value_rtti_target_type (struct value *v, int *full, int *top, int *using_enc)
{
struct value *target;
target = value_ind (v);
return value_rtti_type (target, full, top, using_enc);
}
struct value *
value_full_object (struct value *argp, struct type *rtype, int xfull, int xtop,
int xusing_enc)
{
struct type *real_type;
int full = 0;
int top = -1;
int using_enc = 0;
struct value *new_val;
if (rtype)
{
real_type = rtype;
full = xfull;
top = xtop;
using_enc = xusing_enc;
}
else
real_type = value_rtti_type (argp, &full, &top, &using_enc);
if (!real_type || real_type == VALUE_ENCLOSING_TYPE (argp))
return argp;
if (full)
{
argp = value_change_enclosing_type (argp, real_type);
return argp;
}
if (VALUE_LVAL (argp) != lval_memory)
{
warning ("Couldn't retrieve complete object of RTTI type %s; object may be in register(s).", TYPE_NAME (real_type));
return argp;
}
new_val = value_at_lazy (real_type, VALUE_ADDRESS (argp) - top +
(using_enc ? 0 : VALUE_EMBEDDED_OFFSET (argp)),
VALUE_BFD_SECTION (argp));
VALUE_TYPE (new_val) = VALUE_TYPE (argp);
VALUE_EMBEDDED_OFFSET (new_val) = using_enc ? top + VALUE_EMBEDDED_OFFSET (argp) : top;
return new_val;
}
struct value *
value_of_local (const char *name, int complain)
{
struct symbol *func, *sym;
struct block *b;
int i;
struct value * ret;
if (selected_frame == 0)
{
if (complain)
error ("no frame selected");
else
return 0;
}
func = get_frame_function (selected_frame);
if (!func)
{
if (complain)
error ("no %s in nameless context", name);
else
return 0;
}
b = SYMBOL_BLOCK_VALUE (func);
i = BLOCK_NSYMS (b);
if (i <= 0)
{
if (complain)
error ("no args, no %s", name);
else
return 0;
}
sym = lookup_block_symbol (b, name, NULL, VAR_NAMESPACE);
if (sym == NULL)
{
if (complain)
error ("current stack frame does not contain a variable named \"%s\"", name);
else
return NULL;
}
ret = read_var_value (sym, selected_frame);
if (ret == 0 && complain)
error ("%s argument unreadable", name);
return ret;
}
struct value *
value_of_this (int complain)
{
if (current_language->la_language == language_objc)
return value_of_local ("self", complain);
else
return value_of_local ("this", complain);
}
struct value *
value_slice (struct value *array, int lowbound, int length)
{
struct type *slice_range_type, *slice_type, *range_type;
LONGEST lowerbound, upperbound, offset;
struct value *slice;
struct type *array_type;
array_type = check_typedef (VALUE_TYPE (array));
COERCE_VARYING_ARRAY (array, array_type);
if (TYPE_CODE (array_type) != TYPE_CODE_ARRAY
&& TYPE_CODE (array_type) != TYPE_CODE_STRING
&& TYPE_CODE (array_type) != TYPE_CODE_BITSTRING)
error ("cannot take slice of non-array");
range_type = TYPE_INDEX_TYPE (array_type);
if (get_discrete_bounds (range_type, &lowerbound, &upperbound) < 0)
error ("slice from bad array or bitstring");
if (lowbound < lowerbound || length < 0
|| lowbound + length - 1 > upperbound)
error ("slice out of range");
slice_range_type = create_range_type ((struct type *) NULL,
TYPE_TARGET_TYPE (range_type),
lowbound, lowbound + length - 1);
if (TYPE_CODE (array_type) == TYPE_CODE_BITSTRING)
{
int i;
slice_type = create_set_type ((struct type *) NULL, slice_range_type);
TYPE_CODE (slice_type) = TYPE_CODE_BITSTRING;
slice = value_zero (slice_type, not_lval);
for (i = 0; i < length; i++)
{
int element = value_bit_index (array_type,
VALUE_CONTENTS (array),
lowbound + i);
if (element < 0)
error ("internal error accessing bitstring");
else if (element > 0)
{
int j = i % TARGET_CHAR_BIT;
if (BITS_BIG_ENDIAN)
j = TARGET_CHAR_BIT - 1 - j;
VALUE_CONTENTS_RAW (slice)[i / TARGET_CHAR_BIT] |= (1 << j);
}
}
}
else
{
struct type *element_type = TYPE_TARGET_TYPE (array_type);
offset
= (lowbound - lowerbound) * TYPE_LENGTH (check_typedef (element_type));
slice_type = create_array_type ((struct type *) NULL, element_type,
slice_range_type);
TYPE_CODE (slice_type) = TYPE_CODE (array_type);
slice = allocate_value (slice_type);
if (VALUE_LAZY (array))
VALUE_LAZY (slice) = 1;
else
memcpy (VALUE_CONTENTS (slice), VALUE_CONTENTS (array) + offset,
TYPE_LENGTH (slice_type));
if (VALUE_LVAL (array) == lval_internalvar)
VALUE_LVAL (slice) = lval_internalvar_component;
else
VALUE_LVAL (slice) = VALUE_LVAL (array);
VALUE_ADDRESS (slice) = VALUE_ADDRESS (array);
VALUE_OFFSET (slice) = VALUE_OFFSET (array) + offset;
}
return slice;
}
struct value *
varying_to_slice (struct value *varray)
{
struct type *vtype = check_typedef (VALUE_TYPE (varray));
LONGEST length = unpack_long (TYPE_FIELD_TYPE (vtype, 0),
VALUE_CONTENTS (varray)
+ TYPE_FIELD_BITPOS (vtype, 0) / 8);
return value_slice (value_primitive_field (varray, 0, 1, vtype), 0, length);
}
struct value *
value_literal_complex (struct value *arg1, struct value *arg2, struct type *type)
{
struct value *val;
struct type *real_type = TYPE_TARGET_TYPE (type);
val = allocate_value (type);
arg1 = value_cast (real_type, arg1);
arg2 = value_cast (real_type, arg2);
memcpy (VALUE_CONTENTS_RAW (val),
VALUE_CONTENTS (arg1), TYPE_LENGTH (real_type));
memcpy (VALUE_CONTENTS_RAW (val) + TYPE_LENGTH (real_type),
VALUE_CONTENTS (arg2), TYPE_LENGTH (real_type));
return val;
}
static struct value *
cast_into_complex (struct type *type, struct value *val)
{
struct type *real_type = TYPE_TARGET_TYPE (type);
if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_COMPLEX)
{
struct type *val_real_type = TYPE_TARGET_TYPE (VALUE_TYPE (val));
struct value *re_val = allocate_value (val_real_type);
struct value *im_val = allocate_value (val_real_type);
memcpy (VALUE_CONTENTS_RAW (re_val),
VALUE_CONTENTS (val), TYPE_LENGTH (val_real_type));
memcpy (VALUE_CONTENTS_RAW (im_val),
VALUE_CONTENTS (val) + TYPE_LENGTH (val_real_type),
TYPE_LENGTH (val_real_type));
return value_literal_complex (re_val, im_val, type);
}
else if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FLT
|| TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_INT)
return value_literal_complex (val, value_zero (real_type, not_lval), type);
else
error ("cannot cast non-number to complex");
}
void
_initialize_valops (void)
{
#if 0
add_show_from_set
(add_set_cmd ("abandon", class_support, var_boolean, (char *) &auto_abandon,
"Set automatic abandonment of expressions upon failure.",
&setlist),
&showlist);
#endif
add_show_from_set
(add_set_cmd ("overload-resolution", class_support, var_boolean, (char *) &overload_resolution,
"Set overload resolution in evaluating C++ functions.",
&setlist),
&showlist);
overload_resolution = 1;
add_show_from_set (
add_set_cmd ("unwindonsignal", no_class, var_boolean,
(char *) &unwind_on_signal_p,
"Set unwinding of stack if a signal is received while in a call dummy.\n\
The unwindonsignal lets the user determine what gdb should do if a signal\n\
is received while in a function called from gdb (call dummy). If set, gdb\n\
unwinds the stack and restore the context to what as it was before the call.\n\
The default is to stop in the frame where the signal was received.", &setlist),
&showlist);
}