/* Perform non-arithmetic operations on values, for GDB.
+
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
- 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
This file is part of GDB.
#include "cp-abi.h"
#include "block.h"
#include "infcall.h"
+#include "dictionary.h"
+#include "cp-support.h"
#include <errno.h>
#include "gdb_string.h"
#include "gdb_assert.h"
-
-/* Flag indicating HP compilers were used; needed to correctly handle some
- value operations with HP aCC code/runtime. */
-extern int hp_som_som_object_present;
+#include "cp-support.h"
+#include "observer.h"
extern int overload_debug;
/* Local functions. */
static int typecmp (int staticp, int varargs, int nargs,
struct field t1[], struct value *t2[]);
-static CORE_ADDR value_push (CORE_ADDR, struct value *);
-
static struct value *search_struct_field (char *, struct value *, int,
struct type *, int);
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 *);
struct value *
find_function_in_inferior (const char *name)
{
- register struct symbol *sym;
- sym = lookup_symbol (name, 0, VAR_NAMESPACE, 0, NULL);
+ struct symbol *sym;
+ sym = lookup_symbol (name, 0, VAR_DOMAIN, 0, NULL);
if (sym != NULL)
{
if (SYMBOL_CLASS (sym) != LOC_BLOCK)
struct value *
value_cast (struct type *type, struct value *arg2)
{
- register enum type_code code1;
- register enum type_code code2;
- register int scalar;
+ enum type_code code1;
+ enum type_code code2;
+ int scalar;
struct type *type2;
int convert_to_boolean = 0;
- if (VALUE_TYPE (arg2) == type)
+ if (value_type (arg2) == type)
return arg2;
CHECK_TYPEDEF (type);
code1 = TYPE_CODE (type);
- COERCE_REF (arg2);
- type2 = check_typedef (VALUE_TYPE (arg2));
+ arg2 = coerce_ref (arg2);
+ type2 = check_typedef (value_type (arg2));
/* A cast to an undetermined-length array_type, such as (TYPE [])OBJECT,
is treated like a cast to (TYPE [N])OBJECT,
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);
+ deprecated_set_value_type (arg2, create_array_type ((struct type *) NULL,
+ element_type, range_type));
return arg2;
}
}
if (TYPE_CODE (type2) == TYPE_CODE_FUNC)
arg2 = value_coerce_function (arg2);
- type2 = check_typedef (VALUE_TYPE (arg2));
- COERCE_VARYING_ARRAY (arg2, type2);
+ type2 = check_typedef (value_type (arg2));
code2 = TYPE_CODE (type2);
if (code1 == TYPE_CODE_COMPLEX)
arg2, 0, type2, 1);
if (v)
{
- VALUE_TYPE (v) = type;
+ deprecated_set_value_type (v, type);
return v;
}
}
{
LONGEST longest;
- if (hp_som_som_object_present && /* if target compiled by HP aCC */
- (code2 == TYPE_CODE_PTR))
+ if (deprecated_hp_som_som_object_present /* if target compiled by HP aCC */
+ && (code2 == TYPE_CODE_PTR))
{
unsigned int *ptr;
struct value *retvalp;
case TYPE_CODE_MEMBER:
retvalp = value_from_longest (type, value_as_long (arg2));
/* force evaluation */
- ptr = (unsigned int *) VALUE_CONTENTS (retvalp);
+ ptr = (unsigned int *) value_contents (retvalp);
*ptr &= ~0x20000000; /* zap 29th bit to remove bias */
return retvalp;
sees a cast as a simple reinterpretation of the pointer's
bits. */
if (code2 == TYPE_CODE_PTR)
- longest = extract_unsigned_integer (VALUE_CONTENTS (arg2),
+ longest = extract_unsigned_integer (value_contents (arg2),
TYPE_LENGTH (type2));
else
longest = value_as_long (arg2);
if (v)
{
v = value_addr (v);
- VALUE_TYPE (v) = type;
+ deprecated_set_value_type (v, type);
return v;
}
}
{
CORE_ADDR addr2 = value_as_address (arg2);
addr2 -= (VALUE_ADDRESS (v)
- + VALUE_OFFSET (v)
- + VALUE_EMBEDDED_OFFSET (v));
+ + value_offset (v)
+ + value_embedded_offset (v));
return value_from_pointer (type, addr2);
}
}
}
/* No superclass found, just fall through to change ptr type. */
}
- VALUE_TYPE (arg2) = type;
+ deprecated_set_value_type (arg2, type);
arg2 = value_change_enclosing_type (arg2, type);
- VALUE_POINTED_TO_OFFSET (arg2) = 0; /* pai: chk_val */
+ set_value_pointed_to_offset (arg2, 0); /* pai: chk_val */
return arg2;
}
else if (VALUE_LVAL (arg2) == lval_memory)
- {
- return value_at_lazy (type, VALUE_ADDRESS (arg2) + VALUE_OFFSET (arg2),
- VALUE_BFD_SECTION (arg2));
- }
+ 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);
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;
if we can be 'lazy' and defer the fetch, perhaps indefinately, call
value_at_lazy instead. value_at_lazy simply records the address of
the data and sets the lazy-evaluation-required flag. The lazy flag
- is tested in the VALUE_CONTENTS macro, which is used if and when
+ is tested in the value_contents macro, which is used if and when
the contents are actually required.
Note: value_at does *NOT* handle embedded offsets; perform such
adjustments before or after calling it. */
struct value *
-value_at (struct type *type, CORE_ADDR addr, asection *sect)
+value_at (struct type *type, CORE_ADDR addr)
{
struct value *val;
val = allocate_value (type);
- read_memory (addr, VALUE_CONTENTS_ALL_RAW (val), TYPE_LENGTH (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;
}
/* Return a lazy value with type TYPE located at ADDR (cf. value_at). */
struct value *
-value_at_lazy (struct type *type, CORE_ADDR addr, asection *sect)
+value_at_lazy (struct type *type, CORE_ADDR addr)
{
struct value *val;
VALUE_LVAL (val) = lval_memory;
VALUE_ADDRESS (val) = addr;
- VALUE_LAZY (val) = 1;
- VALUE_BFD_SECTION (val) = sect;
+ set_value_lazy (val, 1);
return val;
}
-/* Called only from the VALUE_CONTENTS and VALUE_CONTENTS_ALL macros,
- if the current data for a variable needs to be loaded into
- VALUE_CONTENTS(VAL). Fetches the data from the user's process, and
- clears the lazy flag to indicate that the data in the buffer is valid.
+/* Called only from the value_contents and value_contents_all()
+ macros, if the current data for a variable needs to be loaded into
+ value_contents(VAL). Fetches the data from the user's process, and
+ clears the lazy flag to indicate that the data in the buffer is
+ valid.
If the value is zero-length, we avoid calling read_memory, which would
abort. We mark the value as fetched anyway -- all 0 bytes of it.
- This function returns a value because it is used in the VALUE_CONTENTS
+ This function returns a value because it is used in the value_contents
macro as part of an expression, where a void would not work. The
value is ignored. */
int
value_fetch_lazy (struct value *val)
{
- CORE_ADDR addr = VALUE_ADDRESS (val) + VALUE_OFFSET (val);
- int length = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (val));
+ CORE_ADDR addr = VALUE_ADDRESS (val) + value_offset (val);
+ int length = TYPE_LENGTH (value_enclosing_type (val));
- struct type *type = VALUE_TYPE (val);
+ struct type *type = value_type (val);
if (length)
- read_memory (addr, VALUE_CONTENTS_ALL_RAW (val), length);
+ read_memory (addr, value_contents_all_raw (val), length);
- VALUE_LAZY (val) = 0;
+ set_value_lazy (val, 0);
return 0;
}
struct value *
value_assign (struct value *toval, struct value *fromval)
{
- register struct type *type;
+ struct type *type;
struct value *val;
- char raw_buffer[MAX_REGISTER_SIZE];
- int use_buffer = 0;
struct frame_id old_frame;
if (!toval->modifiable)
error ("Left operand of assignment is not a modifiable lvalue.");
- COERCE_REF (toval);
+ toval = coerce_ref (toval);
- type = VALUE_TYPE (toval);
+ type = value_type (toval);
if (VALUE_LVAL (toval) != lval_internalvar)
fromval = value_cast (type, fromval);
else
- COERCE_ARRAY (fromval);
+ fromval = coerce_array (fromval);
CHECK_TYPEDEF (type);
- /* If TOVAL is a special machine register requiring conversion
- of program values to a special raw format,
- convert FROMVAL's contents now, with result in `raw_buffer',
- and set USE_BUFFER to the number of bytes to write. */
-
- 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);
- }
- }
-
/* Since modifying a register can trash the frame chain, and modifying memory
can trash the frame cache, we save the old frame and then restore the new
frame afterwards. */
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);
+ 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),
+ value_offset (toval),
+ value_bitpos (toval),
+ value_bitsize (toval),
fromval);
break;
case lval_memory:
{
- char *dest_buffer;
+ const bfd_byte *dest_buffer;
CORE_ADDR changed_addr;
int changed_len;
+ char buffer[sizeof (LONGEST)];
- if (VALUE_BITSIZE (toval))
+ if (value_bitsize (toval))
{
- char buffer[sizeof (LONGEST)];
/* We assume that the argument to read_memory is in units of
host chars. FIXME: Is that correct? */
- changed_len = (VALUE_BITPOS (toval)
- + VALUE_BITSIZE (toval)
+ changed_len = (value_bitpos (toval)
+ + value_bitsize (toval)
+ HOST_CHAR_BIT - 1)
/ HOST_CHAR_BIT;
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),
+ 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);
+ 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_addr = VALUE_ADDRESS (toval) + value_offset (toval);
changed_len = TYPE_LENGTH (type);
- dest_buffer = VALUE_CONTENTS (fromval);
+ 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 ();
+ if (deprecated_memory_changed_hook)
+ deprecated_memory_changed_hook (changed_addr, changed_len);
}
break;
- case lval_reg_frame_relative:
case lval_register:
{
- /* value is stored in a series of registers in the frame
- specified by the structure. Copy that value out, modify
- it, and copy it back in. */
- int amount_copied;
- int amount_to_copy;
- char *buffer;
- int value_reg;
- int reg_offset;
- int byte_offset;
- int regno;
struct frame_info *frame;
+ int value_reg;
/* Figure out which frame this is in currently. */
- if (VALUE_LVAL (toval) == lval_register)
- {
- frame = get_current_frame ();
- value_reg = VALUE_REGNO (toval);
- }
- else
- {
- for (frame = get_current_frame ();
- frame && get_frame_base (frame) != VALUE_FRAME (toval);
- frame = get_prev_frame (frame))
- ;
- value_reg = VALUE_FRAME_REGNUM (toval);
- }
+ 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.");
-
- /* Locate the first register that falls in the value that
- needs to be transfered. Compute the offset of the value in
- that register. */
- {
- int offset;
- for (reg_offset = value_reg, offset = 0;
- offset + REGISTER_RAW_SIZE (reg_offset) <= VALUE_OFFSET (toval);
- reg_offset++);
- byte_offset = VALUE_OFFSET (toval) - offset;
- }
-
- /* Compute the number of register aligned values that need to
- be copied. */
- if (VALUE_BITSIZE (toval))
- amount_to_copy = byte_offset + 1;
- else
- amount_to_copy = byte_offset + TYPE_LENGTH (type);
-
- /* And a bounce buffer. Be slightly over generous. */
- buffer = (char *) alloca (amount_to_copy + MAX_REGISTER_SIZE);
-
- /* Copy it in. */
- for (regno = reg_offset, amount_copied = 0;
- amount_copied < amount_to_copy;
- amount_copied += REGISTER_RAW_SIZE (regno), regno++)
- {
- frame_register_read (frame, regno, buffer + amount_copied);
- }
- /* Modify what needs to be modified. */
- if (VALUE_BITSIZE (toval))
- {
- modify_field (buffer + byte_offset,
- value_as_long (fromval),
- VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
- }
- else if (use_buffer)
+ if (VALUE_LVAL (toval) == lval_register
+ && CONVERT_REGISTER_P (VALUE_REGNUM (toval), type))
{
- memcpy (buffer + VALUE_OFFSET (toval), raw_buffer, use_buffer);
+ /* If TOVAL is a special machine register requiring
+ conversion of program values to a special raw format. */
+ VALUE_TO_REGISTER (frame, VALUE_REGNUM (toval),
+ type, value_contents (fromval));
}
else
{
- memcpy (buffer + byte_offset, VALUE_CONTENTS (fromval),
- TYPE_LENGTH (type));
- /* Do any conversion necessary when storing this type to
- more than one register. */
-#ifdef REGISTER_CONVERT_FROM_TYPE
- REGISTER_CONVERT_FROM_TYPE (value_reg, type,
- (buffer + byte_offset));
-#endif
- }
+ /* TOVAL is stored in a series of registers in the frame
+ specified by the structure. Copy that value out,
+ modify it, and copy it back in. */
+ int amount_copied;
+ int amount_to_copy;
+ char *buffer;
+ int reg_offset;
+ int byte_offset;
+ int regno;
+
+ /* Locate the first register that falls in the value that
+ needs to be transfered. Compute the offset of the
+ value in that register. */
+ {
+ 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;
+ }
- /* Copy it out. */
- for (regno = reg_offset, amount_copied = 0;
- amount_copied < amount_to_copy;
- amount_copied += REGISTER_RAW_SIZE (regno), regno++)
- {
- enum lval_type lval;
- CORE_ADDR addr;
- int optim;
- int realnum;
+ /* Compute the number of register aligned values that need
+ to be copied. */
+ if (value_bitsize (toval))
+ amount_to_copy = byte_offset + 1;
+ else
+ amount_to_copy = byte_offset + TYPE_LENGTH (type);
- /* Just find out where to put it. */
- frame_register (frame, regno, &optim, &lval, &addr, &realnum,
- NULL);
+ /* And a bounce buffer. Be slightly over generous. */
+ buffer = (char *) alloca (amount_to_copy + MAX_REGISTER_SIZE);
+
+ /* Copy it in. */
+ 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 (optim)
- error ("Attempt to assign to a value that was optimized out.");
- if (lval == lval_memory)
- write_memory (addr, buffer + amount_copied,
- REGISTER_RAW_SIZE (regno));
- else if (lval == lval_register)
- regcache_cooked_write (current_regcache, realnum,
- (buffer + amount_copied));
+ /* Modify what needs to be modified. */
+ if (value_bitsize (toval))
+ modify_field (buffer + byte_offset,
+ value_as_long (fromval),
+ value_bitpos (toval), value_bitsize (toval));
else
- error ("Attempt to assign to an unmodifiable value.");
- }
+ memcpy (buffer + byte_offset, value_contents (fromval),
+ TYPE_LENGTH (type));
- if (register_changed_hook)
- register_changed_hook (-1);
- target_changed_event ();
+ /* Copy it out. */
+ 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;
}
- break;
-
default:
error ("Left operand of assignment is not an lvalue.");
{
case lval_memory:
case lval_register:
- case lval_reg_frame_relative:
reinit_frame_cache ();
/* If the field does not entirely fill a LONGEST, then zero the sign bits.
If the field is signed, and is negative, then sign extend. */
- if ((VALUE_BITSIZE (toval) > 0)
- && (VALUE_BITSIZE (toval) < 8 * (int) sizeof (LONGEST)))
+ 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;
+ LONGEST valmask = (((ULONGEST) 1) << value_bitsize (toval)) - 1;
fieldval &= valmask;
if (!TYPE_UNSIGNED (type) && (fieldval & (valmask ^ (valmask >> 1))))
}
val = value_copy (toval);
- memcpy (VALUE_CONTENTS_RAW (val), VALUE_CONTENTS (fromval),
+ 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);
+ 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;
}
if (count < 1)
error ("Invalid number %d of repetitions.", count);
- val = allocate_repeat_value (VALUE_ENCLOSING_TYPE (arg1), 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)));
+ 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);
+ VALUE_ADDRESS (val) = VALUE_ADDRESS (arg1) + value_offset (arg1);
return val;
}
struct value *
value_coerce_array (struct value *arg1)
{
- register struct type *type = check_typedef (VALUE_TYPE (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)));
+ (VALUE_ADDRESS (arg1) + value_offset (arg1)));
}
/* Given a value which is a function, return a value which is a pointer
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);
+ retval = value_from_pointer (lookup_pointer_type (value_type (arg1)),
+ (VALUE_ADDRESS (arg1) + value_offset (arg1)));
return retval;
}
{
struct value *arg2;
- struct type *type = check_typedef (VALUE_TYPE (arg1));
+ struct type *type = check_typedef (value_type (arg1));
if (TYPE_CODE (type) == TYPE_CODE_REF)
{
/* Copy the value, but change the type from (T&) to (T*).
We keep the same location information, which is efficient,
and allows &(&X) to get the location containing the reference. */
arg2 = value_copy (arg1);
- VALUE_TYPE (arg2) = lookup_pointer_type (TYPE_TARGET_TYPE (type));
+ deprecated_set_value_type (arg2, lookup_pointer_type (TYPE_TARGET_TYPE (type)));
return arg2;
}
if (TYPE_CODE (type) == TYPE_CODE_FUNC)
error ("Attempt to take address of value not located in memory.");
/* Get target memory address */
- arg2 = value_from_pointer (lookup_pointer_type (VALUE_TYPE (arg1)),
+ arg2 = value_from_pointer (lookup_pointer_type (value_type (arg1)),
(VALUE_ADDRESS (arg1)
- + VALUE_OFFSET (arg1)
- + VALUE_EMBEDDED_OFFSET (arg1)));
+ + value_offset (arg1)
+ + value_embedded_offset (arg1)));
/* This may be a pointer to a base subobject; so remember the
full derived object's type ... */
- arg2 = value_change_enclosing_type (arg2, lookup_pointer_type (VALUE_ENCLOSING_TYPE (arg1)));
+ arg2 = value_change_enclosing_type (arg2, lookup_pointer_type (value_enclosing_type (arg1)));
/* ... and also the relative position of the subobject in the full object */
- VALUE_POINTED_TO_OFFSET (arg2) = VALUE_EMBEDDED_OFFSET (arg1);
- VALUE_BFD_SECTION (arg2) = VALUE_BFD_SECTION (arg1);
+ set_value_pointed_to_offset (arg2, value_embedded_offset (arg1));
return arg2;
}
struct type *base_type;
struct value *arg2;
- COERCE_ARRAY (arg1);
+ arg1 = coerce_array (arg1);
- base_type = check_typedef (VALUE_TYPE (arg1));
+ base_type = check_typedef (value_type (arg1));
if (TYPE_CODE (base_type) == TYPE_CODE_MEMBER)
error ("not implemented: member types in value_ind");
BUILTIN_TYPE_LONGEST would seem to be a mistake. */
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));
+ (CORE_ADDR) value_as_long (arg1));
else if (TYPE_CODE (base_type) == TYPE_CODE_PTR)
{
struct type *enc_type;
/* We may be pointing to something embedded in a larger object */
/* Get the real type of the enclosing object */
- enc_type = check_typedef (VALUE_ENCLOSING_TYPE (arg1));
+ enc_type = check_typedef (value_enclosing_type (arg1));
enc_type = TYPE_TARGET_TYPE (enc_type);
/* Retrieve the enclosing object pointed to */
- arg2 = value_at_lazy (enc_type,
- value_as_address (arg1) - VALUE_POINTED_TO_OFFSET (arg1),
- VALUE_BFD_SECTION (arg1));
+ arg2 = value_at_lazy (enc_type, (value_as_address (arg1)
+ - value_pointed_to_offset (arg1)));
/* Re-adjust type */
- VALUE_TYPE (arg2) = TYPE_TARGET_TYPE (base_type);
+ deprecated_set_value_type (arg2, TYPE_TARGET_TYPE (base_type));
/* Add embedding info */
arg2 = value_change_enclosing_type (arg2, enc_type);
- VALUE_EMBEDDED_OFFSET (arg2) = VALUE_POINTED_TO_OFFSET (arg1);
+ set_value_embedded_offset (arg2, value_pointed_to_offset (arg1));
/* We may be pointing to an object of some derived type */
arg2 = value_full_object (arg2, NULL, 0, 0, 0);
CORE_ADDR
push_word (CORE_ADDR sp, ULONGEST word)
{
- register int len = DEPRECATED_REGISTER_SIZE;
- char buffer[MAX_REGISTER_SIZE]);
+ int len = DEPRECATED_REGISTER_SIZE;
+ char buffer[MAX_REGISTER_SIZE];
store_unsigned_integer (buffer, len, word);
if (INNER_THAN (1, 2))
return sp;
}
-#ifndef PARM_BOUNDARY
-#define PARM_BOUNDARY (0)
-#endif
-
-/* Push onto the stack the specified value VALUE. Pad it correctly for
- it to be an argument to a function. */
-
-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;
-
- /* How big is the container we're going to put this value in? */
- if (PARM_BOUNDARY)
- container_len = ((len + PARM_BOUNDARY / TARGET_CHAR_BIT - 1)
- & ~(PARM_BOUNDARY / TARGET_CHAR_BIT - 1));
-
- /* Are we going to put it at the high or low end of the container? */
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
- offset = container_len - len;
- else
- offset = 0;
-
- if (INNER_THAN (1, 2))
- {
- /* stack grows downward */
- sp -= container_len;
- write_memory (sp + offset, VALUE_CONTENTS_ALL (arg), len);
- }
- else
- {
- /* stack grows upward */
- write_memory (sp + offset, VALUE_CONTENTS_ALL (arg), len);
- sp += container_len;
- }
-
- return sp;
-}
-
-CORE_ADDR
-legacy_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
- int struct_return, CORE_ADDR struct_addr)
-{
- /* ASSERT ( !struct_return); */
- int i;
- for (i = nargs - 1; i >= 0; i--)
- sp = value_push (sp, args[i]);
- return sp;
-}
-
/* Create a value for an array by allocating space in the inferior, copying
the data into that space, and then setting up an array value.
{
error ("bad array bounds (%d, %d)", lowbound, highbound);
}
- typelength = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (elemvec[0]));
+ typelength = TYPE_LENGTH (value_enclosing_type (elemvec[0]));
for (idx = 1; idx < nelem; idx++)
{
- if (TYPE_LENGTH (VALUE_ENCLOSING_TYPE (elemvec[idx])) != typelength)
+ 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);
+ 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]),
+ 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]),
+ write_memory (addr + (idx * typelength),
+ value_contents_all (elemvec[idx]),
typelength);
}
/* Create the array type and set up an array value to be evaluated lazily. */
- val = value_at_lazy (arraytype, addr, VALUE_BFD_SECTION (elemvec[0]));
+ val = value_at_lazy (arraytype, addr);
return (val);
}
if (current_language->c_style_arrays == 0)
{
val = allocate_value (stringtype);
- memcpy (VALUE_CONTENTS_RAW (val), ptr, len);
+ 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);
+ val = value_at_lazy (stringtype, addr);
return (val);
}
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));
+ memcpy (value_contents_raw (val), ptr, TYPE_LENGTH (type));
return val;
}
\f
return i + 1;
tt1 = check_typedef (t1[i].type);
- tt2 = check_typedef (VALUE_TYPE (t2[i]));
+ tt2 = check_typedef (value_type (t2[i]));
if (TYPE_CODE (tt1) == TYPE_CODE_REF
/* We should be doing hairy argument matching, as below. */
/* We should be doing much hairier argument matching (see section 13.2
of the ARM), but as a quick kludge, just check for the same type
code. */
- if (TYPE_CODE (t1[i].type) != TYPE_CODE (VALUE_TYPE (t2[i])))
+ if (TYPE_CODE (t1[i].type) != TYPE_CODE (value_type (t2[i])))
return i + 1;
}
if (varargs || t2[i] == NULL)
static struct value *
search_struct_field (char *name, struct value *arg1, int offset,
- register struct type *type, int looking_for_baseclass)
+ struct type *type, int looking_for_baseclass)
{
int i;
int nbases = TYPE_N_BASECLASSES (type);
struct value *v2 = allocate_value (basetype);
boffset = baseclass_offset (type, i,
- VALUE_CONTENTS (arg1) + offset,
+ value_contents (arg1) + offset,
VALUE_ADDRESS (arg1)
- + VALUE_OFFSET (arg1) + offset);
+ + value_offset (arg1) + offset);
if (boffset == -1)
error ("virtual baseclass botch");
{
CORE_ADDR base_addr;
- base_addr = VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1) + boffset;
- if (target_read_memory (base_addr, VALUE_CONTENTS_RAW (v2),
+ 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_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;
+ VALUE_FRAME_ID (v2) = VALUE_FRAME_ID (arg1);
+ v2->offset = value_offset (arg1) + boffset;
+ if (value_lazy (arg1))
+ set_value_lazy (v2, 1);
else
- memcpy (VALUE_CONTENTS_RAW (v2),
- VALUE_CONTENTS_RAW (arg1) + boffset,
+ memcpy (value_contents_raw (v2),
+ value_contents_raw (arg1) + boffset,
TYPE_LENGTH (basetype));
}
* conventions. */
void
-find_rt_vbase_offset (struct type *type, struct type *basetype, char *valaddr,
- int offset, int *boffset_p, int *skip_p)
+find_rt_vbase_offset (struct type *type, struct type *basetype,
+ const bfd_byte *valaddr, int offset, int *boffset_p,
+ int *skip_p)
{
int boffset; /* offset of virtual base */
int index; /* displacement to use in virtual table */
& use long type */
/* epstein : FIXME -- added param for overlay section. May not be correct */
- vp = value_at (builtin_type_int, vtbl + 4 * (-skip - index - HP_ACC_VBASE_START), NULL);
+ 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;
static struct value *
search_struct_method (char *name, struct value **arg1p,
struct value **args, int offset,
- int *static_memfuncp, register struct type *type)
+ int *static_memfuncp, struct type *type)
{
int i;
struct value *v;
according to HP/Taligent runtime spec. */
int skip;
find_rt_vbase_offset (type, TYPE_BASECLASS (type, i),
- VALUE_CONTENTS_ALL (*arg1p),
- offset + VALUE_EMBEDDED_OFFSET (*arg1p),
+ 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;
+ const bfd_byte *base_valaddr;
/* The virtual base class pointer might have been clobbered by the
user program. Make sure that it still points to a valid memory
if (offset < 0 || offset >= TYPE_LENGTH (type))
{
- base_valaddr = (char *) alloca (TYPE_LENGTH (baseclass));
+ bfd_byte *tmp = alloca (TYPE_LENGTH (baseclass));
if (target_read_memory (VALUE_ADDRESS (*arg1p)
- + VALUE_OFFSET (*arg1p) + offset,
- base_valaddr,
- TYPE_LENGTH (baseclass)) != 0)
+ + value_offset (*arg1p) + offset,
+ tmp, TYPE_LENGTH (baseclass)) != 0)
error ("virtual baseclass botch");
+ base_valaddr = tmp;
}
else
- base_valaddr = VALUE_CONTENTS (*arg1p) + offset;
+ base_valaddr = value_contents (*arg1p) + offset;
base_offset =
baseclass_offset (type, i, base_valaddr,
VALUE_ADDRESS (*arg1p)
- + VALUE_OFFSET (*arg1p) + offset);
+ + value_offset (*arg1p) + offset);
if (base_offset == -1)
error ("virtual baseclass botch");
}
value_struct_elt (struct value **argp, struct value **args,
char *name, int *static_memfuncp, char *err)
{
- register struct type *t;
+ struct type *t;
struct value *v;
- COERCE_ARRAY (*argp);
+ *argp = coerce_array (*argp);
- t = check_typedef (VALUE_TYPE (*argp));
+ t = check_typedef (value_type (*argp));
/* Follow pointers until we get to a non-pointer. */
{
*argp = value_ind (*argp);
/* Don't coerce fn pointer to fn and then back again! */
- if (TYPE_CODE (VALUE_TYPE (*argp)) != TYPE_CODE_FUNC)
- COERCE_ARRAY (*argp);
- t = check_typedef (VALUE_TYPE (*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)
* according to HP/Taligent runtime spec. */
int skip;
find_rt_vbase_offset (type, TYPE_BASECLASS (type, i),
- VALUE_CONTENTS_ALL (*argp),
- offset + VALUE_EMBEDDED_OFFSET (*argp),
+ 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
{
/* probably g++ runtime model */
- base_offset = VALUE_OFFSET (*argp) + offset;
+ base_offset = value_offset (*argp) + offset;
base_offset =
baseclass_offset (type, i,
- VALUE_CONTENTS (*argp) + base_offset,
+ value_contents (*argp) + base_offset,
VALUE_ADDRESS (*argp) + base_offset);
if (base_offset == -1)
error ("virtual baseclass botch");
{
struct type *t;
- t = check_typedef (VALUE_TYPE (*argp));
+ t = check_typedef (value_type (*argp));
/* code snarfed from value_struct_elt */
while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
{
*argp = value_ind (*argp);
/* Don't coerce fn pointer to fn and then back again! */
- if (TYPE_CODE (VALUE_TYPE (*argp)) != TYPE_CODE_FUNC)
- COERCE_ARRAY (*argp);
- t = check_typedef (VALUE_TYPE (*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)
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; /* Index of best overloaded function */
- short oload_ambiguous = 0; /* Current ambiguity state for overload resolution */
- /* 0 => no ambiguity, 1 => two good funcs, 2 => incomparable funcs */
- short oload_ambig_champ = -1; /* 2nd contender for best match */
- short oload_non_standard = 0; /* did we have to use non-standard conversions? */
- short oload_incompatible = 0; /* are args supplied incompatible with any function? */
+ int oload_champ; /* Index of best overloaded function */
- struct badness_vector *bv; /* A measure of how good an overloaded instance is */
struct badness_vector *oload_champ_bv = NULL; /* The measure for the current best match */
struct value *temp = obj;
int num_fns = 0; /* Number of overloaded instances being considered */
struct type *basetype = NULL;
int boffset;
- register int jj;
- register int ix;
+ int ix;
int static_offset;
- struct cleanup *cleanups = NULL;
+ struct cleanup *old_cleanups = NULL;
- char *obj_type_name = NULL;
+ const char *obj_type_name = NULL;
char *func_name = NULL;
+ enum oload_classification match_quality;
/* Get the list of overloaded methods or functions */
if (method)
{
- obj_type_name = TYPE_NAME (VALUE_TYPE (obj));
+ obj_type_name = TYPE_NAME (value_type (obj));
/* Hack: evaluate_subexp_standard often passes in a pointer
value rather than the object itself, so try again */
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)));
+ (TYPE_CODE (value_type (obj)) == TYPE_CODE_PTR))
+ obj_type_name = TYPE_NAME (TYPE_TARGET_TYPE (value_type (obj)));
fns_ptr = value_find_oload_method_list (&temp, name, 0,
&num_fns,
been resolved by find_method_list via value_find_oload_method_list
above. */
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
{
- int i = -1;
- func_name = cplus_demangle (DEPRECATED_SYMBOL_NAME (fsym), DMGL_NO_OPTS);
+ const char *qualified_name = SYMBOL_CPLUS_DEMANGLED_NAME (fsym);
+ func_name = cp_func_name (qualified_name);
/* If the name is NULL this must be a C-style function.
Just return the same symbol. */
- if (!func_name)
+ if (func_name == NULL)
{
*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);
+ 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);
+ }
+
+ /* Check how bad the best match is. */
+
+ 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) ? "::" : "",
+ 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) ? "::" : "",
+ 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: /* STANDARD */
+ return 0;
+ }
+}
+
+/* Find the best overload match, searching for FUNC_NAME in namespaces
+ contained in QUALIFIED_NAME until it either finds a good match or
+ runs out of namespaces. It stores the overloaded functions in
+ *OLOAD_SYMS, and the badness vector in *OLOAD_CHAMP_BV. The
+ calling function is responsible for freeing *OLOAD_SYMS and
+ *OLOAD_CHAMP_BV. */
+
+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;
+}
+
+/* Helper function for find_oload_champ_namespace; NAMESPACE_LEN is
+ how deep we've looked for namespaces, and the champ is stored in
+ OLOAD_CHAMP. The return value is 1 if the champ is a good one, 0
+ if it isn't.
+
+ It is the caller's responsibility to free *OLOAD_SYMS and
+ *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)
+{
+ 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);
+
+ /* Initialize these to values that can safely be xfree'd. */
+ *oload_syms = NULL;
+ *oload_champ_bv = NULL;
+
+ /* First, see if we have a deeper namespace we can search in. If we
+ get a good match there, use it. */
+
+ if (qualified_name[next_namespace_len] == ':')
+ {
+ searched_deeper = 1;
- oload_champ_bv = NULL;
+ 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;
+ }
+ };
+
+ /* If we reach here, either we're in the deepest namespace or we
+ didn't find a good match in a deeper namespace. But, in the
+ latter case, we still have a bad match in a deeper namespace;
+ note that we might not find any match at all in the current
+ namespace. (There's always a match in the deepest namespace,
+ because this overload mechanism only gets called if there's a
+ function symbol to start off with.) */
+
+ 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);
+
+ /* Case 1: We found a good match. Free earlier matches (if any),
+ and return it. Case 2: We didn't find a good match, but we're
+ not the deepest function. Then go with the bad match that the
+ deeper function found. Case 3: We found a bad match, and we're
+ the deepest function. Then return what we found, even though
+ it's a bad match. */
+
+ 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;
+ }
+}
+
+/* Look for a function to take NARGS args of types ARG_TYPES. Find
+ the best match from among the overloaded methods or functions
+ (depending on METHOD) given by FNS_PTR or OLOAD_SYMS, respectively.
+ The number of methods/functions in the list is given by NUM_FNS.
+ Return the index of the best match; store an indication of the
+ quality of the match in OLOAD_CHAMP_BV.
+
+ It is the caller's responsibility to free *OLOAD_CHAMP_BV. */
+
+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; /* A measure of how good an overloaded instance is */
+ int oload_champ = -1; /* Index of best overloaded function */
+ int oload_ambiguous = 0; /* Current ambiguity state for overload resolution */
+ /* 0 => no ambiguity, 1 => two good funcs, 2 => incomparable funcs */
+
+ *oload_champ_bv = NULL;
/* Consider each candidate in turn */
for (ix = 0; ix < num_fns; ix++)
{
- static_offset = 0;
+ int jj;
+ int static_offset = oload_method_static (method, fns_ptr, ix);
+ int nparms;
+ struct type **parm_types;
+
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
bv = rank_function (parm_types, nparms, arg_types + static_offset,
nargs - static_offset);
- if (!oload_champ_bv)
+ if (!*oload_champ_bv)
{
- oload_champ_bv = bv;
+ *oload_champ_bv = bv;
oload_champ = 0;
- champ_nparms = nparms;
}
else
/* See whether current candidate is better or worse than previous best */
- switch (compare_badness (bv, oload_champ_bv))
+ switch (compare_badness (bv, *oload_champ_bv))
{
case 0:
oload_ambiguous = 1; /* top two contenders are equally good */
- oload_ambig_champ = ix;
break;
case 1:
oload_ambiguous = 2; /* incomparable top contenders */
- oload_ambig_champ = ix;
break;
case 2:
- oload_champ_bv = bv; /* new champion, record details */
+ *oload_champ_bv = bv; /* new champion, record details */
oload_ambiguous = 0;
oload_champ = ix;
- oload_ambig_champ = -1;
- champ_nparms = nparms;
break;
case 3:
default:
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);
}
- } /* end loop over all candidates */
- /* NOTE: dan/2000-03-10: Seems to be a better idea to just pick one
- if they have the exact same goodness. This is because there is no
- way to differentiate based on return type, which we need to in
- cases like overloads of .begin() <It's both const and non-const> */
-#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) ? "::" : "",
- name);
- else
- error ("Cannot resolve overloaded function %s to unique instance; disambiguate by specifying function signature",
- func_name);
}
-#endif
- /* Check how bad the best match is. */
- 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; /* truly mismatched types */
+ return oload_champ;
+}
- else if (oload_champ_bv->rank[ix] >= 10)
- oload_non_standard = 1; /* non-standard type conversions needed */
- }
- 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) ? "::" : "",
- 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) ? "::" : "",
- name);
- else
- warning ("Using non-standard conversion to match function %s to supplied arguments",
- func_name);
- }
+/* Return 1 if we're looking at a static method, 0 if we're looking at
+ a non-static method or a function that isn't a method. */
- 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);
- }
+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
- {
- *symp = oload_syms[oload_champ];
- xfree (func_name);
- }
+ return 0;
+}
- if (objp)
+/* Check how good an overload match OLOAD_CHAMP_BV represents. */
+
+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 (TYPE_CODE (VALUE_TYPE (temp)) != TYPE_CODE_PTR
- && TYPE_CODE (VALUE_TYPE (*objp)) == TYPE_CODE_PTR)
- {
- temp = value_addr (temp);
- }
- *objp = temp;
+ if (oload_champ_bv->rank[ix] >= 100)
+ return INCOMPATIBLE; /* truly mismatched types */
+ else if (oload_champ_bv->rank[ix] >= 10)
+ return NON_STANDARD; /* non-standard type conversions needed */
}
- if (cleanups != NULL)
- do_cleanups (cleanups);
- return oload_incompatible ? 100 : (oload_non_standard ? 10 : 0);
+ return STANDARD; /* Only standard conversions needed. */
}
/* C++: return 1 is NAME is a legitimate name for the destructor
len = strlen (dname);
else
len = cp - dname;
- if (strlen (name + 1) != len || !STREQN (dname, name + 1, len))
+ if (strlen (name + 1) != len || strncmp (dname, name + 1, len) != 0)
error ("name of destructor must equal name of class");
else
return 1;
target structure/union is defined, otherwise, return 0. */
static int
-check_field_in (register struct type *type, const char *name)
+check_field_in (struct type *type, const char *name)
{
- register int i;
+ int i;
for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--)
{
int
check_field (struct value *arg1, const char *name)
{
- register struct type *t;
+ struct type *t;
- COERCE_ARRAY (arg1);
+ arg1 = coerce_array (arg1);
- t = VALUE_TYPE (arg1);
+ t = value_type (arg1);
/* Follow pointers until we get to a non-pointer. */
return check_field_in (t, name);
}
+/* C++: Given an aggregate type CURTYPE, and a member name NAME,
+ return the appropriate member. This function is used to resolve
+ user expressions of the form "DOMAIN::NAME". For more details on
+ what happens, see the comment before
+ value_struct_elt_for_reference. */
+
+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");
+ }
+}
+
/* C++: Given an aggregate type CURTYPE, and a member name NAME,
return the address of this member as a "pointer to member"
type. If INTYPE is non-null, then it will be the type
"pointers to member functions". This function is used
to resolve user expressions of the form "DOMAIN::NAME". */
-struct value *
+static struct value *
value_struct_elt_for_reference (struct type *domain, int offset,
struct type *curtype, char *name,
- struct type *intype)
+ struct type *intype,
+ enum noside noside)
{
- register struct type *t = curtype;
- register int i;
+ struct type *t = curtype;
+ int i;
struct value *v;
if (TYPE_CODE (t) != TYPE_CODE_STRUCT
{
char *t_field_name = TYPE_FIELD_NAME (t, i);
- if (t_field_name && STREQ (t_field_name, name))
+ if (t_field_name && strcmp (t_field_name, name) == 0)
{
if (TYPE_FIELD_STATIC (t, i))
{
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))
+ 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);
else
{
struct symbol *s = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, j),
- 0, VAR_NAMESPACE, 0, NULL);
+ 0, VAR_DOMAIN, 0, NULL);
if (s == NULL)
{
v = 0;
offset + base_offset,
TYPE_BASECLASS (t, i),
name,
- intype);
+ intype,
+ noside);
if (v)
return v;
}
- return 0;
+
+ /* As a last chance, pretend that CURTYPE is a namespace, and look
+ it up that way; this (frequently) works for types nested inside
+ classes. */
+
+ return value_maybe_namespace_elt (curtype, name, noside);
+}
+
+/* C++: Return the member NAME of the namespace given by the type
+ CURTYPE. */
+
+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;
}
+/* A helper function used by value_namespace_elt and
+ value_struct_elt_for_reference. It looks up NAME inside the
+ context CURTYPE; this works if CURTYPE is a namespace or if CURTYPE
+ is a class and NAME refers to a type in CURTYPE itself (as opposed
+ to, say, some base class of CURTYPE). */
+
+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));
+}
/* Given a pointer value V, find the real (RTTI) type
of the object it points to.
real_type = value_rtti_type (argp, &full, &top, &using_enc);
/* If no RTTI data, or if object is already complete, do nothing */
- if (!real_type || real_type == VALUE_ENCLOSING_TYPE (argp))
+ if (!real_type || real_type == value_enclosing_type (argp))
return argp;
/* If we have the full object, but for some reason the enclosing
adjusting for the embedded offset of argp if that's what value_rtti_type
used for its computation. */
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;
+ (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 symbol *func, *sym;
struct block *b;
- int i;
struct value * ret;
if (deprecated_selected_frame == 0)
}
b = SYMBOL_BLOCK_VALUE (func);
- i = BLOCK_NSYMS (b);
- if (i <= 0)
+ if (dict_empty (BLOCK_DICT (b)))
{
if (complain)
error ("no args, no `%s'", name);
/* Calling lookup_block_symbol is necessary to get the LOC_REGISTER
symbol instead of the LOC_ARG one (if both exist). */
- sym = lookup_block_symbol (b, name, NULL, VAR_NAMESPACE);
+ sym = lookup_block_symbol (b, name, NULL, VAR_DOMAIN);
if (sym == NULL)
{
if (complain)
LONGEST lowerbound, upperbound;
struct value *slice;
struct type *array_type;
- array_type = check_typedef (VALUE_TYPE (array));
- COERCE_VARYING_ARRAY (array, 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)
for (i = 0; i < length; i++)
{
int element = value_bit_index (array_type,
- VALUE_CONTENTS (array),
+ value_contents (array),
lowbound + i);
if (element < 0)
error ("internal error accessing bitstring");
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);
+ value_contents_raw (slice)[i / TARGET_CHAR_BIT] |= (1 << j);
}
}
/* We should set the address, bitssize, and bitspos, so the clice
slice_range_type);
TYPE_CODE (slice_type) = TYPE_CODE (array_type);
slice = allocate_value (slice_type);
- if (VALUE_LAZY (array))
- VALUE_LAZY (slice) = 1;
+ if (value_lazy (array))
+ set_value_lazy (slice, 1);
else
- memcpy (VALUE_CONTENTS (slice), VALUE_CONTENTS (array) + offset,
+ 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_OFFSET (slice) = VALUE_OFFSET (array) + offset;
+ VALUE_FRAME_ID (slice) = VALUE_FRAME_ID (array);
+ slice->offset = value_offset (array) + offset;
}
return slice;
}
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));
+ 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;
}
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)
+ if (TYPE_CODE (value_type (val)) == TYPE_CODE_COMPLEX)
{
- struct type *val_real_type = TYPE_TARGET_TYPE (VALUE_TYPE (val));
+ 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),
+ 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)
+ 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");
_initialize_valops (void)
{
#if 0
- add_show_from_set
+ deprecated_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
+ deprecated_add_show_from_set
(add_set_cmd ("overload-resolution", class_support, var_boolean, (char *) &overload_resolution,
"Set overload resolution in evaluating C++ functions.",
&setlist),