#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 "block.h"
#include "gdbcmd.h"
#include "regcache.h"
#include "cp-abi.h"
#include "exceptions.h"
#include "gdbthread.h"
#include "gdb.h"
#include <errno.h>
#include "gdb_string.h"
#include "gdb_assert.h"
#include "cp-support.h"
#include "observer.h"
extern int overload_debug;
static int typecmp (int staticp, int varargs, int nargs,
struct field t1[], struct value *t2[]);
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 find_oload_champ_namespace (struct type **arg_types, int nargs,
const char *func_name,
const char *qualified_name,
struct symbol ***oload_syms,
struct badness_vector **oload_champ_bv);
static
int find_oload_champ_namespace_loop (struct type **arg_types, int nargs,
const char *func_name,
const char *qualified_name,
int namespace_len,
struct symbol ***oload_syms,
struct badness_vector **oload_champ_bv,
int *oload_champ);
static int find_oload_champ (struct type **arg_types, int nargs, int method,
int num_fns,
struct fn_field *fns_ptr,
struct symbol **oload_syms,
struct badness_vector **oload_champ_bv);
static int oload_method_static (int method, struct fn_field *fns_ptr,
int index);
enum oload_classification { STANDARD, NON_STANDARD, INCOMPATIBLE };
static enum
oload_classification classify_oload_match (struct badness_vector
* oload_champ_bv,
int nargs,
int static_offset);
static int check_field_in (struct type *, const char *);
static struct value *value_struct_elt_for_reference (struct type *domain,
int offset,
struct type *curtype,
char *name,
struct type *intype,
enum noside noside);
static struct value *value_namespace_elt (const struct type *curtype,
char *name,
enum noside noside);
static struct value *value_maybe_namespace_elt (const struct type *curtype,
char *name,
enum noside noside);
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;
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;
static void
show_overload_resolution (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
{
fprintf_filtered (file, _("\
Overload resolution in evaluating C++ functions is %s.\n"),
value);
}
struct value *
find_function_in_inferior (const char *name, struct type *type)
{
struct symbol *sym;
sym = lookup_symbol (name, 0, VAR_DOMAIN, 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);
}
}
}
CORE_ADDR
allocate_space_in_inferior_malloc (int len)
{
struct value *blocklen;
struct value *val;
static struct cached_value *fval = NULL;
struct cleanup *cleanup_chain;
int unwind;
if (target_check_safe_call () != 1)
error ("No memory available to program now: unsafe to call malloc");
if (fval == NULL)
fval = create_cached_function (NAME_OF_MALLOC, builtin_type_voidptrfuncptr);
blocklen = value_from_longest (builtin_type_int, (LONGEST) len);
unwind = set_unwind_on_signal (1);
cleanup_chain = make_cleanup (set_unwind_on_signal, unwind);
val = call_function_by_hand (lookup_cached_function (fval), 1, &blocklen);
do_cleanups (cleanup_chain);
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 value_as_long (val);
}
static CORE_ADDR
allocate_space_in_inferior (int len)
{
return target_allocate_memory (len);
}
struct value *
value_allocate_space_in_inferior (int len)
{
return value_from_longest (builtin_type_void_data_ptr, target_allocate_memory (len));
}
struct value *
value_cast_1 (struct type *type, struct value *arg2)
{
enum type_code code1;
enum type_code code2;
int scalar;
struct type *type2;
int convert_to_boolean = 0;
if (value_type (arg2) == type)
return arg2;
CHECK_TYPEDEF (type);
code1 = TYPE_CODE (type);
if (code1 != TYPE_CODE_REF)
arg2 = 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);
deprecated_set_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));
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)
{
deprecated_set_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 (deprecated_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);
deprecated_set_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);
}
}
}
}
deprecated_set_value_type (arg2, type);
arg2 = value_change_enclosing_type (arg2, type);
set_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));
else if (code1 == TYPE_CODE_VOID)
{
return value_zero (builtin_type_void, not_lval);
}
else
{
error (_("Invalid cast."));
return 0;
}
}
struct value *
value_cast (struct type *type, struct value *arg2)
{
struct value *ret_val = value_cast_1 (type, arg2);
if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
deprecated_set_value_type (ret_val, type);
return ret_val;
}
struct value *
value_zero (struct type *type, enum lval_type lv)
{
struct value *val = allocate_value (type);
VALUE_LVAL (val) = lv;
return val;
}
struct value *
value_at (struct type *type, CORE_ADDR addr)
{
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;
return val;
}
struct value *
value_at_lazy (struct type *type, CORE_ADDR addr)
{
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;
set_value_lazy (val, 1);
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);
set_value_lazy (val, 0);
return 0;
}
struct value *
value_assign (struct value *toval, struct value *fromval)
{
struct type *type;
struct value *val;
struct frame_id old_frame;
int old_frame_level;
if (!deprecated_value_modifiable (toval))
error (_("Left operand of assignment is not a modifiable lvalue."));
toval = coerce_ref (toval);
type = value_type (toval);
if (VALUE_LVAL (toval) != lval_internalvar)
fromval = value_cast (type, fromval);
else
fromval = coerce_array (fromval);
CHECK_TYPEDEF (type);
old_frame_level = frame_relative_level (deprecated_selected_frame);
if (old_frame_level > 0)
old_frame = get_frame_id (deprecated_selected_frame);
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));
set_value_embedded_offset (val, value_embedded_offset (fromval));
set_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:
{
const gdb_byte *dest_buffer;
CORE_ADDR changed_addr;
int changed_len;
gdb_byte buffer[sizeof (LONGEST)];
if (value_bitsize (toval))
{
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
{
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 (deprecated_memory_changed_hook)
deprecated_memory_changed_hook (changed_addr, changed_len);
}
break;
case lval_register:
case lval_register_literal:
{
struct frame_info *frame;
int value_reg;
frame = frame_find_by_id (VALUE_FRAME_ID (toval));
value_reg = VALUE_REGNUM (toval);
if (!frame)
error (_("Value being assigned to is no longer active."));
if (VALUE_LVAL (toval) != lval_register_literal
&& CONVERT_REGISTER_P (VALUE_REGNUM (toval), type))
{
VALUE_TO_REGISTER (frame, VALUE_REGNUM (toval),
type, value_contents (fromval));
}
else
{
int amount_copied;
int amount_to_copy;
gdb_byte *buffer;
int reg_offset;
int byte_offset;
int regno;
{
int offset;
for (reg_offset = value_reg, offset = 0;
offset + register_size (current_gdbarch, reg_offset) <= value_offset (toval);
reg_offset++);
byte_offset = value_offset (toval) - offset;
}
if (value_bitsize (toval))
amount_to_copy = byte_offset + 1;
else
amount_to_copy = byte_offset + TYPE_LENGTH (type);
buffer = alloca (amount_to_copy + MAX_REGISTER_SIZE);
for (regno = reg_offset, amount_copied = 0;
amount_copied < amount_to_copy;
amount_copied += register_size (current_gdbarch, regno), regno++)
frame_register_read (frame, regno, buffer + amount_copied);
if (value_bitsize (toval))
modify_field (buffer + byte_offset,
value_as_long (fromval),
value_bitpos (toval), value_bitsize (toval));
else
memcpy (buffer + byte_offset, value_contents (fromval),
TYPE_LENGTH (type));
for (regno = reg_offset, amount_copied = 0;
amount_copied < amount_to_copy;
amount_copied += register_size (current_gdbarch, regno), regno++)
put_frame_register (frame, regno, buffer + amount_copied);
}
if (deprecated_register_changed_hook)
deprecated_register_changed_hook (-1);
observer_notify_target_changed (¤t_target);
break;
}
default:
error (_("Left operand of assignment is not an lvalue."));
}
switch (VALUE_LVAL (toval))
{
case lval_memory:
case lval_register:
case lval_register_literal:
reinit_frame_cache ();
if (old_frame_level > 0)
{
volatile struct gdb_exception e;
TRY_CATCH (e, RETURN_MASK_ERROR)
{
struct frame_info *fi = frame_find_by_id (old_frame);
if (fi != NULL)
select_frame (fi);
}
if (e.reason == RETURN_ERROR)
{
if (e.message != NULL)
warning (_("Couldn't restore restore the previous frame: %s"), e.message);
else
warning (_("Couldn't restore restore the previous frame."));
}
}
break;
default:
break;
}
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));
deprecated_set_value_type (val, type);
val = value_change_enclosing_type (val, value_enclosing_type (fromval));
set_value_embedded_offset (val, value_embedded_offset (fromval));
set_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_PRINT_NAME (BLOCK_FUNCTION (b)))
error (_("No frame is currently executing in block %s."),
SYMBOL_PRINT_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_PRINT_NAME (var));
return val;
}
struct value *
value_coerce_array (struct value *arg1)
{
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)));
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);
deprecated_set_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)));
set_value_pointed_to_offset (arg2, value_embedded_offset (arg1));
return arg2;
}
struct value *
value_ind (struct value *arg1)
{
struct type *base_type;
struct value *arg2;
arg1 = 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_address (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)));
deprecated_set_value_type (arg2, TYPE_TARGET_TYPE (base_type));
arg2 = value_change_enclosing_type (arg2, enc_type);
set_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;
}
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);
}
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);
return (val);
}
struct string_in_child
{
char *str;
int len;
CORE_ADDR addr;
struct string_in_child *next;
};
#define STRING_HASH_TABLE_SIZE 2039
static struct string_in_child *string_table[STRING_HASH_TABLE_SIZE];
unsigned int
inferior_string_hash (const char *string, int len)
{
unsigned int hash = 0;
int i;
for (i = 0; i < len; i++)
hash = hash * 67 + string[i] - 113;
return hash;
}
static CORE_ADDR
allocate_string_in_inferior (char *str, int len)
{
struct string_in_child *ptr;
unsigned int hash = inferior_string_hash (str, len) % STRING_HASH_TABLE_SIZE;
if (string_table[hash] != NULL)
{
for (ptr = string_table[hash]; ptr != NULL; ptr = ptr->next)
{
if (len == ptr->len)
{
if (memcmp (str, ptr->str, len) == 0)
return ptr->addr;
}
}
}
ptr = (struct string_in_child *) xmalloc (sizeof (struct string_in_child));
ptr->len = len;
ptr->str = xmalloc (len);
memcpy (ptr->str, str, len);
ptr->addr = allocate_space_in_inferior (len);
write_memory (ptr->addr, (gdb_byte *) ptr->str, len);
if (string_table[hash] == NULL)
{
string_table[hash] = ptr;
ptr->next = NULL;
}
else
{
ptr->next = string_table[hash];
string_table[hash] = ptr;
}
return ptr->addr;
}
void
value_clear_inferior_string_pool ()
{
struct string_in_child *free_me, *ptr;
int i;
for (i = 0; i < STRING_HASH_TABLE_SIZE; i++)
{
if (string_table[i] != NULL)
{
ptr = string_table[i];
while (ptr != NULL)
{
free_me = ptr;
ptr = ptr->next;
xfree (free_me->str);
xfree (free_me);
}
string_table[i] = NULL;
}
}
}
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_string_in_inferior (ptr, len);
val = value_at_lazy (stringtype, addr);
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,
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_FRAME_ID (v2) = VALUE_FRAME_ID (arg1);
set_value_offset (v2, value_offset (arg1) + boffset);
if (value_lazy (arg1))
set_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,
const gdb_byte *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));
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, 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));
const gdb_byte *base_valaddr;
if (offset < 0 || offset >= TYPE_LENGTH (type))
{
gdb_byte *tmp = alloca (TYPE_LENGTH (baseclass));
if (target_read_memory (VALUE_ADDRESS (*arg1p)
+ value_offset (*arg1p) + offset,
tmp, TYPE_LENGTH (baseclass)) != 0)
error (_("virtual baseclass botch"));
base_valaddr = tmp;
}
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)
{
struct type *t;
struct value *v;
*argp = 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)
*argp = 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)
*argp = 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)
{
struct value *obj = (objp ? *objp : NULL);
int oload_champ;
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;
int ix;
int static_offset;
struct cleanup *old_cleanups = NULL;
const char *obj_type_name = NULL;
char *func_name = NULL;
enum oload_classification match_quality;
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);
oload_champ = find_oload_champ (arg_types, nargs, method, num_fns,
fns_ptr, oload_syms, &oload_champ_bv);
}
else
{
const char *qualified_name = SYMBOL_CPLUS_DEMANGLED_NAME (fsym);
func_name = cp_func_name (qualified_name);
if (func_name == NULL)
{
*symp = fsym;
return 0;
}
old_cleanups = make_cleanup (xfree, func_name);
make_cleanup (xfree, oload_syms);
make_cleanup (xfree, oload_champ_bv);
oload_champ = find_oload_champ_namespace (arg_types, nargs,
func_name,
qualified_name,
&oload_syms,
&oload_champ_bv);
}
match_quality
= classify_oload_match (oload_champ_bv, nargs,
oload_method_static (method, fns_ptr,
oload_champ));
if (match_quality == 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 (match_quality == 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 != NULL)
*staticp = oload_method_static (method, fns_ptr, oload_champ);
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];
}
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 (old_cleanups != NULL)
do_cleanups (old_cleanups);
switch (match_quality)
{
case INCOMPATIBLE:
return 100;
case NON_STANDARD:
return 10;
default:
return 0;
}
}
static int
find_oload_champ_namespace (struct type **arg_types, int nargs,
const char *func_name,
const char *qualified_name,
struct symbol ***oload_syms,
struct badness_vector **oload_champ_bv)
{
int oload_champ;
find_oload_champ_namespace_loop (arg_types, nargs,
func_name,
qualified_name, 0,
oload_syms, oload_champ_bv,
&oload_champ);
return oload_champ;
}
static int
find_oload_champ_namespace_loop (struct type **arg_types, int nargs,
const char *func_name,
const char *qualified_name,
int namespace_len,
struct symbol ***oload_syms,
struct badness_vector **oload_champ_bv,
int *oload_champ)
{
int next_namespace_len = namespace_len;
int searched_deeper = 0;
int num_fns = 0;
struct cleanup *old_cleanups;
int new_oload_champ;
struct symbol **new_oload_syms;
struct badness_vector *new_oload_champ_bv;
char *new_namespace;
if (next_namespace_len != 0)
{
gdb_assert (qualified_name[next_namespace_len] == ':');
next_namespace_len += 2;
}
next_namespace_len
+= cp_find_first_component (qualified_name + next_namespace_len);
*oload_syms = NULL;
*oload_champ_bv = NULL;
if (qualified_name[next_namespace_len] == ':')
{
searched_deeper = 1;
if (find_oload_champ_namespace_loop (arg_types, nargs,
func_name, qualified_name,
next_namespace_len,
oload_syms, oload_champ_bv,
oload_champ))
{
return 1;
}
};
old_cleanups = make_cleanup (xfree, *oload_syms);
old_cleanups = make_cleanup (xfree, *oload_champ_bv);
new_namespace = alloca (namespace_len + 1);
strncpy (new_namespace, qualified_name, namespace_len);
new_namespace[namespace_len] = '\0';
new_oload_syms = make_symbol_overload_list (func_name,
new_namespace);
while (new_oload_syms[num_fns])
++num_fns;
new_oload_champ = find_oload_champ (arg_types, nargs, 0, num_fns,
NULL, new_oload_syms,
&new_oload_champ_bv);
if (new_oload_champ != -1
&& classify_oload_match (new_oload_champ_bv, nargs, 0) == STANDARD)
{
*oload_syms = new_oload_syms;
*oload_champ = new_oload_champ;
*oload_champ_bv = new_oload_champ_bv;
do_cleanups (old_cleanups);
return 1;
}
else if (searched_deeper)
{
xfree (new_oload_syms);
xfree (new_oload_champ_bv);
discard_cleanups (old_cleanups);
return 0;
}
else
{
gdb_assert (new_oload_champ != -1);
*oload_syms = new_oload_syms;
*oload_champ = new_oload_champ;
*oload_champ_bv = new_oload_champ_bv;
discard_cleanups (old_cleanups);
return 0;
}
}
static int
find_oload_champ (struct type **arg_types, int nargs, int method,
int num_fns, struct fn_field *fns_ptr,
struct symbol **oload_syms,
struct badness_vector **oload_champ_bv)
{
int ix;
struct badness_vector *bv;
int oload_champ = -1;
int oload_ambiguous = 0;
*oload_champ_bv = NULL;
for (ix = 0; ix < num_fns; ix++)
{
int jj;
int static_offset = oload_method_static (method, fns_ptr, ix);
int nparms;
struct type **parm_types;
if (method)
{
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);
if (!*oload_champ_bv)
{
*oload_champ_bv = bv;
oload_champ = 0;
}
else
switch (compare_badness (bv, *oload_champ_bv))
{
case 0:
oload_ambiguous = 1;
break;
case 1:
oload_ambiguous = 2;
break;
case 2:
*oload_champ_bv = bv;
oload_ambiguous = 0;
oload_champ = ix;
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);
}
}
return oload_champ;
}
static int
oload_method_static (int method, struct fn_field *fns_ptr, int index)
{
if (method && TYPE_FN_FIELD_STATIC_P (fns_ptr, index))
return 1;
else
return 0;
}
static enum oload_classification
classify_oload_match (struct badness_vector *oload_champ_bv,
int nargs,
int static_offset)
{
int ix;
for (ix = 1; ix <= nargs - static_offset; ix++)
{
if (oload_champ_bv->rank[ix] >= 100)
return INCOMPATIBLE;
else if (oload_champ_bv->rank[ix] >= 10)
return NON_STANDARD;
}
return STANDARD;
}
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 || strncmp (dname, name + 1, len) != 0)
error (_("name of destructor must equal name of class"));
else
return 1;
}
return 0;
}
static int
check_field_in (struct type *type, const char *name)
{
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--)
{
struct type *baseclass = TYPE_BASECLASS (type, i);
if (TYPE_STUB (baseclass) || TYPE_IS_OPAQUE (baseclass))
CHECK_TYPEDEF (baseclass);
if (check_field_in (baseclass, name))
return 1;
}
return 0;
}
int
check_field (struct value *arg1, const char *name)
{
struct type *t;
arg1 = 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)
{
warning ("Trying to look up \"%s\" in 'this' but "
"'this' is not an aggregate", name);
return 0;
}
return check_field_in (t, name);
}
struct value *
value_aggregate_elt (struct type *curtype,
char *name,
enum noside noside)
{
switch (TYPE_CODE (curtype))
{
case TYPE_CODE_STRUCT:
case TYPE_CODE_UNION:
return value_struct_elt_for_reference (curtype, 0, curtype, name, NULL,
noside);
case TYPE_CODE_NAMESPACE:
return value_namespace_elt (curtype, name, noside);
default:
internal_error (__FILE__, __LINE__,
_("non-aggregate type in value_aggregate_elt"));
}
}
static struct value *
value_struct_elt_for_reference (struct type *domain, int offset,
struct type *curtype, char *name,
struct type *intype,
enum noside noside)
{
struct type *t = curtype;
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 && strcmp (t_field_name, name) == 0)
{
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 && strcmp (t_field_name, name) == 0)
{
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_DOMAIN, 0, NULL);
if (s == NULL)
{
v = 0;
}
else
{
v = read_var_value (s, 0);
#if 0
deprecated_set_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,
noside);
if (v)
return v;
}
return value_maybe_namespace_elt (curtype, name, noside);
}
static struct value *
value_namespace_elt (const struct type *curtype,
char *name,
enum noside noside)
{
struct value *retval = value_maybe_namespace_elt (curtype, name,
noside);
if (retval == NULL)
error (_("No symbol \"%s\" in namespace \"%s\"."), name,
TYPE_TAG_NAME (curtype));
return retval;
}
static struct value *
value_maybe_namespace_elt (const struct type *curtype,
char *name,
enum noside noside)
{
const char *namespace_name = TYPE_TAG_NAME (curtype);
struct symbol *sym;
sym = cp_lookup_symbol_namespace (namespace_name, name, NULL,
get_selected_block (0), VAR_DOMAIN,
NULL);
if (sym == NULL)
return NULL;
else if ((noside == EVAL_AVOID_SIDE_EFFECTS)
&& (SYMBOL_CLASS (sym) == LOC_TYPEDEF))
return allocate_value (SYMBOL_TYPE (sym));
else
return value_of_variable (sym, get_selected_block (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)));
deprecated_set_value_type (new_val, value_type (argp));
set_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;
struct value * ret;
if (deprecated_selected_frame == 0)
{
if (complain)
error (_("no frame selected"));
else
return 0;
}
func = get_frame_function (deprecated_selected_frame);
if (!func)
{
if (complain)
error (_("no `%s' in nameless context"), name);
else
return 0;
}
b = SYMBOL_BLOCK_VALUE (func);
if (dict_empty (BLOCK_DICT (b)))
{
if (complain)
error (_("no args, no `%s'"), name);
else
return 0;
}
sym = lookup_block_symbol (b, name, NULL, VAR_DOMAIN);
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, deprecated_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 if (current_language->la_language == language_objcplus)
{
struct symbol *sym =
get_frame_function (get_selected_frame (NULL));
if (sym)
if (SYMBOL_LANGUAGE (sym) == language_cplus)
return value_of_local ("this", complain);
else
return value_of_local ("self", complain);
else
if (complain)
error ("Couldn't find symbol for current pc.");
else
return NULL;
}
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;
struct value *slice;
struct type *array_type;
array_type = check_typedef (value_type (array));
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);
LONGEST 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))
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;
else
VALUE_LVAL (slice) = VALUE_LVAL (array);
VALUE_ADDRESS (slice) = VALUE_ADDRESS (array);
VALUE_FRAME_ID (slice) = VALUE_FRAME_ID (array);
set_value_offset (slice, value_offset (array) + offset);
}
return slice;
}
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"));
}
struct thread_is_safe_args
{
struct thread_info *tp;
struct re_pattern_buffer *unsafe_functions;
int npatterns;
int stack_depth;
int unsafe_p;
};
static int
do_check_is_thread_unsafe (void *argptr)
{
struct thread_is_safe_args *args = (struct thread_is_safe_args *) argptr;
struct frame_info *fi;
struct thread_info *tp = args->tp;
if (tp != NULL)
switch_to_thread (tp->ptid);
fi = get_current_frame ();
if (!fi)
return -1;
while (frame_relative_level (fi) < args->stack_depth)
{
CORE_ADDR pc;
char *sym_name;
pc = get_frame_pc (fi);
if (find_pc_partial_function (pc, &sym_name, NULL, NULL))
{
int i;
int len;
if (sym_name == NULL)
continue;
len = strlen (sym_name);
for (i = 0; i < args->npatterns ; i++)
{
if (regexec (&args->unsafe_functions[i], sym_name, 0, 0, 0) == 0)
{
struct cleanup *list_cleanup;
list_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, "bad_thread");
ui_out_text (uiout, "Unsafe to call functions on thread ");
ui_out_field_int (uiout, "thread", pid_to_thread_id (inferior_ptid));
ui_out_text (uiout, ": ");
ui_out_field_fmt (uiout, "reason", "function: %s on stack",
sym_name);
ui_out_text (uiout, "\n");
(args->unsafe_p)++;
do_cleanups (list_cleanup);
goto found_it;
}
}
}
fi = get_prev_frame (fi);
if (!fi)
break;
}
found_it:
return 1;
}
static int
safe_check_is_thread_unsafe (struct thread_info *tp, void *data)
{
struct thread_is_safe_args *args = (struct thread_is_safe_args *) data;
args->tp = tp;
struct cleanup *old_chain;
old_chain = make_cleanup_restore_current_thread (inferior_ptid, 0);
catch_errors ((catch_errors_ftype *) do_check_is_thread_unsafe, args,
"", RETURN_MASK_ERROR);
do_cleanups (old_chain);
return 0;
}
int
check_safe_call (regex_t unsafe_functions[],
int npatterns,
int stack_depth,
enum check_which_threads which_threads)
{
struct thread_is_safe_args args;
struct frame_id old_frame_id = get_frame_id (deprecated_safe_get_selected_frame ());
args.unsafe_p = 0;
args.unsafe_functions = unsafe_functions;
args.npatterns = npatterns;
if (which_threads == CHECK_CURRENT_THREAD
|| (which_threads == CHECK_SCHEDULER_VALUE && !scheduler_lock_on_p ()))
safe_check_is_thread_unsafe (NULL, &args);
else
{
struct cleanup *old_cleanups;
old_cleanups = make_cleanup_restore_current_thread (inferior_ptid, 0);
#ifdef NM_NEXTSTEP
extern void macosx_prune_threads (thread_array_t, unsigned int);
macosx_prune_threads (NULL, 0);
#else
prune_threads ();
#endif
iterate_over_threads (safe_check_is_thread_unsafe, &args);
do_cleanups (old_cleanups);
}
if (!frame_id_eq (old_frame_id, null_frame_id))
{
struct frame_info *old_frame = frame_find_by_id (old_frame_id);
if (old_frame == NULL)
warning ("check_safe_call: could not restore current frame\n");
else
select_frame (old_frame);
}
return !args.unsafe_p;
}
void
_initialize_valops (void)
{
add_setshow_boolean_cmd ("overload-resolution", class_support,
&overload_resolution, _("\
Set overload resolution in evaluating C++ functions."), _("\
Show overload resolution in evaluating C++ functions."), NULL,
NULL,
show_overload_resolution,
&setlist, &showlist);
overload_resolution = 1;
}