/* 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
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GDB.
#include "gdbcmd.h"
#include "regcache.h"
#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 find_function_addr (struct value *, struct type **);
-static struct value *value_arg_coerce (struct value *, struct type *, int);
-
-
-static CORE_ADDR value_push (CORE_ADDR, struct value *);
-
static struct value *search_struct_field (char *, struct value *, int,
struct type *, int);
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 *);
int overload_resolution = 0;
-/* This boolean tells what gdb should do if a signal is received while in
- a function called from gdb (call dummy). If set, gdb unwinds the stack
- and restore the context to what as it was before the call.
- The default is to stop in the frame where the signal was received. */
-
-int unwind_on_signal_p = 0;
-\f
-
-
/* Find the address of function name NAME in the inferior. */
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);
+ arg2->type = 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;
+ v->type = 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;
if (v)
{
v = value_addr (v);
- VALUE_TYPE (v) = type;
+ v->type = type;
return v;
}
}
{
CORE_ADDR addr2 = value_as_address (arg2);
addr2 -= (VALUE_ADDRESS (v)
- + VALUE_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;
+ arg2->type = type;
arg2 = value_change_enclosing_type (arg2, type);
VALUE_POINTED_TO_OFFSET (arg2) = 0; /* pai: chk_val */
return arg2;
}
- /* OBSOLETE else if (chill_varying_type (type)) */
- /* OBSOLETE { */
- /* OBSOLETE struct type *range1, *range2, *eltype1, *eltype2; */
- /* OBSOLETE struct value *val; */
- /* OBSOLETE int count1, count2; */
- /* OBSOLETE LONGEST low_bound, high_bound; */
- /* OBSOLETE char *valaddr, *valaddr_data; */
- /* OBSOLETE *//* For lint warning about eltype2 possibly uninitialized: */
- /* OBSOLETE eltype2 = NULL; */
- /* OBSOLETE if (code2 == TYPE_CODE_BITSTRING) */
- /* OBSOLETE error ("not implemented: converting bitstring to varying type"); */
- /* OBSOLETE if ((code2 != TYPE_CODE_ARRAY && code2 != TYPE_CODE_STRING) */
- /* OBSOLETE || (eltype1 = check_typedef (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 1))), */
- /* OBSOLETE eltype2 = check_typedef (TYPE_TARGET_TYPE (type2)), */
- /* OBSOLETE (TYPE_LENGTH (eltype1) != TYPE_LENGTH (eltype2) */
- /* OBSOLETE *//*|| TYPE_CODE (eltype1) != TYPE_CODE (eltype2) *//* ))) */
- /* OBSOLETE error ("Invalid conversion to varying type"); */
- /* OBSOLETE range1 = TYPE_FIELD_TYPE (TYPE_FIELD_TYPE (type, 1), 0); */
- /* OBSOLETE range2 = TYPE_FIELD_TYPE (type2, 0); */
- /* OBSOLETE if (get_discrete_bounds (range1, &low_bound, &high_bound) < 0) */
- /* OBSOLETE count1 = -1; */
- /* OBSOLETE else */
- /* OBSOLETE count1 = high_bound - low_bound + 1; */
- /* OBSOLETE if (get_discrete_bounds (range2, &low_bound, &high_bound) < 0) */
- /* OBSOLETE count1 = -1, count2 = 0; *//* To force error before */
- /* OBSOLETE else */
- /* OBSOLETE count2 = high_bound - low_bound + 1; */
- /* OBSOLETE if (count2 > count1) */
- /* OBSOLETE error ("target varying type is too small"); */
- /* OBSOLETE val = allocate_value (type); */
- /* OBSOLETE valaddr = VALUE_CONTENTS_RAW (val); */
- /* OBSOLETE valaddr_data = valaddr + TYPE_FIELD_BITPOS (type, 1) / 8; */
- /* OBSOLETE *//* Set val's __var_length field to count2. */
- /* OBSOLETE store_signed_integer (valaddr, TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)), */
- /* OBSOLETE count2); */
- /* OBSOLETE *//* Set the __var_data field to count2 elements copied from arg2. */
- /* OBSOLETE memcpy (valaddr_data, VALUE_CONTENTS (arg2), */
- /* OBSOLETE count2 * TYPE_LENGTH (eltype2)); */
- /* OBSOLETE *//* Zero the rest of the __var_data field of val. */
- /* OBSOLETE memset (valaddr_data + count2 * TYPE_LENGTH (eltype2), '\0', */
- /* OBSOLETE (count1 - count2) * TYPE_LENGTH (eltype2)); */
- /* OBSOLETE return val; */
- /* OBSOLETE } */
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);
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;
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;
return val;
}
int
value_fetch_lazy (struct value *val)
{
- CORE_ADDR addr = VALUE_ADDRESS (val) + VALUE_OFFSET (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);
struct value *
value_assign (struct value *toval, struct value *fromval)
{
- register struct type *type;
+ struct type *type;
struct value *val;
- char *raw_buffer = (char*) alloca (MAX_REGISTER_RAW_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. */
+ old_frame = get_frame_id (deprecated_selected_frame);
switch (VALUE_LVAL (toval))
{
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;
char *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);
}
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:
{
- struct frame_id old_frame;
- /* 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;
-
- /* Since modifying a register can trash the frame chain, we
- save the old frame and then restore the new frame
- afterwards. */
- old_frame = get_frame_id (deprecated_selected_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);
+ value_reg = VALUE_REGNUM (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_RAW_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 ();
-
- /* Assigning to the stack pointer, frame pointer, and other
- (architecture and calling convention specific) registers
- may cause the frame cache to be out of date. We just do
- this on all assignments to registers for simplicity; I
- doubt the slowdown matters. */
- reinit_frame_cache ();
-
- /* Having destoroyed the frame cache, restore the selected
- frame. */
- /* FIXME: cagney/2002-11-02: There has to be a better way of
- doing this. Instead of constantly saving/restoring the
- frame. Why not create a get_selected_frame() function
- that, having saved the selected frame's ID can
- automatically re-find the previously selected frame
- automatically. */
- {
- struct frame_info *fi = frame_find_by_id (old_frame);
- if (fi != NULL)
- select_frame (fi);
- }
+ /* 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.");
}
+ /* Assigning to the stack pointer, frame pointer, and other
+ (architecture and calling convention specific) registers may
+ cause the frame cache to be out of date. Assigning to memory
+ also can. We just do this on all assignments to registers or
+ memory, for simplicity's sake; I doubt the slowdown matters. */
+ switch (VALUE_LVAL (toval))
+ {
+ case lval_memory:
+ case lval_register:
+
+ reinit_frame_cache ();
+
+ /* Having destoroyed the frame cache, restore the selected frame. */
+
+ /* FIXME: cagney/2002-11-02: There has to be a better way of
+ doing this. Instead of constantly saving/restoring the
+ frame. Why not create a get_selected_frame() function that,
+ having saved the selected frame's ID can automatically
+ re-find the previously selected frame automatically. */
+
+ {
+ struct frame_info *fi = frame_find_by_id (old_frame);
+ if (fi != NULL)
+ select_frame (fi);
+ }
+
+ break;
+ default:
+ break;
+ }
+
/* 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),
TYPE_LENGTH (type));
- VALUE_TYPE (val) = type;
+ val->type = 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);
val = allocate_repeat_value (VALUE_ENCLOSING_TYPE (arg1), count);
- read_memory (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1),
+ 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;
}
if (!frame)
{
if (BLOCK_FUNCTION (b)
- && SYMBOL_SOURCE_NAME (BLOCK_FUNCTION (b)))
+ && SYMBOL_PRINT_NAME (BLOCK_FUNCTION (b)))
error ("No frame is currently executing in block %s.",
- SYMBOL_SOURCE_NAME (BLOCK_FUNCTION (b)));
+ 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_SOURCE_NAME (var));
+ error ("Address of symbol \"%s\" is unknown.", SYMBOL_PRINT_NAME (var));
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));
+ arg2->type = 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_offset (arg1)
+ VALUE_EMBEDDED_OFFSET (arg1)));
/* This may be a pointer to a base subobject; so remember the
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);
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;
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);
+ arg2->type = 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);
CORE_ADDR
push_word (CORE_ADDR sp, ULONGEST word)
{
- register int len = REGISTER_SIZE;
- char *buffer = alloca (MAX_REGISTER_RAW_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
-default_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;
-}
-
-
-/* Functions to use for the COERCE_FLOAT_TO_DOUBLE gdbarch method.
-
- How you should pass arguments to a function depends on whether it
- was defined in K&R style or prototype style. If you define a
- function using the K&R syntax that takes a `float' argument, then
- callers must pass that argument as a `double'. If you define the
- function using the prototype syntax, then you must pass the
- argument as a `float', with no promotion.
-
- Unfortunately, on certain older platforms, the debug info doesn't
- indicate reliably how each function was defined. A function type's
- TYPE_FLAG_PROTOTYPED flag may be clear, even if the function was
- defined in prototype style. When calling a function whose
- TYPE_FLAG_PROTOTYPED flag is clear, GDB consults the
- COERCE_FLOAT_TO_DOUBLE gdbarch method to decide what to do.
-
- For modern targets, it is proper to assume that, if the prototype
- flag is clear, that can be trusted: `float' arguments should be
- promoted to `double'. You should register the function
- `standard_coerce_float_to_double' to get this behavior.
-
- For some older targets, if the prototype flag is clear, that
- doesn't tell us anything. So we guess that, if we don't have a
- type for the formal parameter (i.e., the first argument to
- COERCE_FLOAT_TO_DOUBLE is null), then we should promote it;
- otherwise, we should leave it alone. The function
- `default_coerce_float_to_double' provides this behavior; it is the
- default value, for compatibility with older configurations. */
-int
-default_coerce_float_to_double (struct type *formal, struct type *actual)
-{
- return formal == NULL;
-}
-
-
-int
-standard_coerce_float_to_double (struct type *formal, struct type *actual)
-{
- return 1;
-}
-
-
-/* Perform the standard coercions that are specified
- for arguments to be passed to C functions.
-
- If PARAM_TYPE is non-NULL, it is the expected parameter type.
- IS_PROTOTYPED is non-zero if the function declaration is prototyped. */
-
-static struct value *
-value_arg_coerce (struct value *arg, struct type *param_type,
- int is_prototyped)
-{
- register struct type *arg_type = check_typedef (VALUE_TYPE (arg));
- register struct type *type
- = param_type ? check_typedef (param_type) : arg_type;
-
- switch (TYPE_CODE (type))
- {
- case TYPE_CODE_REF:
- if (TYPE_CODE (arg_type) != TYPE_CODE_REF
- && TYPE_CODE (arg_type) != TYPE_CODE_PTR)
- {
- arg = value_addr (arg);
- VALUE_TYPE (arg) = param_type;
- return arg;
- }
- break;
- case TYPE_CODE_INT:
- case TYPE_CODE_CHAR:
- case TYPE_CODE_BOOL:
- case TYPE_CODE_ENUM:
- /* If we don't have a prototype, coerce to integer type if necessary. */
- if (!is_prototyped)
- {
- if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int))
- type = builtin_type_int;
- }
- /* Currently all target ABIs require at least the width of an integer
- type for an argument. We may have to conditionalize the following
- type coercion for future targets. */
- if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int))
- type = builtin_type_int;
- break;
- case TYPE_CODE_FLT:
- /* FIXME: We should always convert floats to doubles in the
- non-prototyped case. As many debugging formats include
- no information about prototyping, we have to live with
- COERCE_FLOAT_TO_DOUBLE for now. */
- if (!is_prototyped && COERCE_FLOAT_TO_DOUBLE (param_type, arg_type))
- {
- if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double))
- type = builtin_type_double;
- else if (TYPE_LENGTH (type) > TYPE_LENGTH (builtin_type_double))
- type = builtin_type_long_double;
- }
- break;
- case TYPE_CODE_FUNC:
- type = lookup_pointer_type (type);
- break;
- case TYPE_CODE_ARRAY:
- /* Arrays are coerced to pointers to their first element, unless
- they are vectors, in which case we want to leave them alone,
- because they are passed by value. */
- if (current_language->c_style_arrays)
- if (!TYPE_VECTOR (type))
- type = lookup_pointer_type (TYPE_TARGET_TYPE (type));
- break;
- case TYPE_CODE_UNDEF:
- case TYPE_CODE_PTR:
- case TYPE_CODE_STRUCT:
- case TYPE_CODE_UNION:
- case TYPE_CODE_VOID:
- case TYPE_CODE_SET:
- case TYPE_CODE_RANGE:
- case TYPE_CODE_STRING:
- case TYPE_CODE_BITSTRING:
- case TYPE_CODE_ERROR:
- case TYPE_CODE_MEMBER:
- case TYPE_CODE_METHOD:
- case TYPE_CODE_COMPLEX:
- default:
- break;
- }
-
- return value_cast (type, arg);
-}
-
-/* Determine a function's address and its return type from its value.
- Calls error() if the function is not valid for calling. */
-
-static CORE_ADDR
-find_function_addr (struct value *function, struct type **retval_type)
-{
- register struct type *ftype = check_typedef (VALUE_TYPE (function));
- register enum type_code code = TYPE_CODE (ftype);
- struct type *value_type;
- CORE_ADDR funaddr;
-
- /* If it's a member function, just look at the function
- part of it. */
-
- /* Determine address to call. */
- if (code == TYPE_CODE_FUNC || code == TYPE_CODE_METHOD)
- {
- funaddr = VALUE_ADDRESS (function);
- value_type = TYPE_TARGET_TYPE (ftype);
- }
- else if (code == TYPE_CODE_PTR)
- {
- funaddr = value_as_address (function);
- ftype = check_typedef (TYPE_TARGET_TYPE (ftype));
- if (TYPE_CODE (ftype) == TYPE_CODE_FUNC
- || TYPE_CODE (ftype) == TYPE_CODE_METHOD)
- {
- funaddr = CONVERT_FROM_FUNC_PTR_ADDR (funaddr);
- value_type = TYPE_TARGET_TYPE (ftype);
- }
- else
- value_type = builtin_type_int;
- }
- else if (code == TYPE_CODE_INT)
- {
- /* Handle the case of functions lacking debugging info.
- Their values are characters since their addresses are char */
- if (TYPE_LENGTH (ftype) == 1)
- funaddr = value_as_address (value_addr (function));
- else
- /* Handle integer used as address of a function. */
- funaddr = (CORE_ADDR) value_as_long (function);
-
- value_type = builtin_type_int;
- }
- else
- error ("Invalid data type for function to be called.");
-
- *retval_type = value_type;
- return funaddr;
-}
-
-/* All this stuff with a dummy frame may seem unnecessarily complicated
- (why not just save registers in GDB?). The purpose of pushing a dummy
- frame which looks just like a real frame is so that if you call a
- function and then hit a breakpoint (get a signal, etc), "backtrace"
- will look right. Whether the backtrace needs to actually show the
- stack at the time the inferior function was called is debatable, but
- it certainly needs to not display garbage. So if you are contemplating
- making dummy frames be different from normal frames, consider that. */
-
-/* Perform a function call in the inferior.
- ARGS is a vector of values of arguments (NARGS of them).
- FUNCTION is a value, the function to be called.
- Returns a value representing what the function returned.
- May fail to return, if a breakpoint or signal is hit
- during the execution of the function.
-
- ARGS is modified to contain coerced values. */
-
-static struct value *
-hand_function_call (struct value *function, int nargs, struct value **args)
-{
- register CORE_ADDR sp;
- register int i;
- int rc;
- CORE_ADDR start_sp;
- /* CALL_DUMMY is an array of words (REGISTER_SIZE), but each word
- is in host byte order. Before calling FIX_CALL_DUMMY, we byteswap it
- and remove any extra bytes which might exist because ULONGEST is
- bigger than REGISTER_SIZE.
-
- NOTE: This is pretty wierd, as the call dummy is actually a
- sequence of instructions. But CISC machines will have
- to pack the instructions into REGISTER_SIZE units (and
- so will RISC machines for which INSTRUCTION_SIZE is not
- REGISTER_SIZE).
-
- NOTE: This is pretty stupid. CALL_DUMMY should be in strict
- target byte order. */
-
- static ULONGEST *dummy;
- int sizeof_dummy1;
- char *dummy1;
- CORE_ADDR old_sp;
- struct type *value_type;
- unsigned char struct_return;
- CORE_ADDR struct_addr = 0;
- struct regcache *retbuf;
- struct cleanup *retbuf_cleanup;
- struct inferior_status *inf_status;
- struct cleanup *inf_status_cleanup;
- CORE_ADDR funaddr;
- int using_gcc; /* Set to version of gcc in use, or zero if not gcc */
- CORE_ADDR real_pc;
- struct type *param_type = NULL;
- struct type *ftype = check_typedef (SYMBOL_TYPE (function));
- int n_method_args = 0;
-
- dummy = alloca (SIZEOF_CALL_DUMMY_WORDS);
- sizeof_dummy1 = REGISTER_SIZE * SIZEOF_CALL_DUMMY_WORDS / sizeof (ULONGEST);
- dummy1 = alloca (sizeof_dummy1);
- memcpy (dummy, CALL_DUMMY_WORDS, SIZEOF_CALL_DUMMY_WORDS);
-
- if (!target_has_execution)
- noprocess ();
-
- /* Create a cleanup chain that contains the retbuf (buffer
- containing the register values). This chain is create BEFORE the
- inf_status chain so that the inferior status can cleaned up
- (restored or discarded) without having the retbuf freed. */
- retbuf = regcache_xmalloc (current_gdbarch);
- retbuf_cleanup = make_cleanup_regcache_xfree (retbuf);
-
- /* A cleanup for the inferior status. Create this AFTER the retbuf
- so that this can be discarded or applied without interfering with
- the regbuf. */
- inf_status = save_inferior_status (1);
- inf_status_cleanup = make_cleanup_restore_inferior_status (inf_status);
-
- /* PUSH_DUMMY_FRAME is responsible for saving the inferior registers
- (and POP_FRAME for restoring them). (At least on most machines)
- they are saved on the stack in the inferior. */
- PUSH_DUMMY_FRAME;
-
- old_sp = read_sp ();
-
- /* Ensure that the initial SP is correctly aligned. */
- if (gdbarch_frame_align_p (current_gdbarch))
- {
- /* NOTE: cagney/2002-09-18:
-
- On a RISC architecture, a void parameterless generic dummy
- frame (i.e., no parameters, no result) typically does not
- need to push anything the stack and hence can leave SP and
- FP. Similarly, a framelss (possibly leaf) function does not
- push anything on the stack and, hence, that too can leave FP
- and SP unchanged. As a consequence, a sequence of void
- parameterless generic dummy frame calls to frameless
- functions will create a sequence of effectively identical
- frames (SP, FP and TOS and PC the same). This, not
- suprisingly, results in what appears to be a stack in an
- infinite loop --- when GDB tries to find a generic dummy
- frame on the internal dummy frame stack, it will always find
- the first one.
-
- To avoid this problem, the code below always grows the stack.
- That way, two dummy frames can never be identical. It does
- burn a few bytes of stack but that is a small price to pay
- :-). */
- sp = gdbarch_frame_align (current_gdbarch, old_sp);
- if (sp == old_sp)
- {
- if (INNER_THAN (1, 2))
- /* Stack grows down. */
- sp = gdbarch_frame_align (current_gdbarch, old_sp - 1);
- else
- /* Stack grows up. */
- sp = gdbarch_frame_align (current_gdbarch, old_sp + 1);
- }
- gdb_assert ((INNER_THAN (1, 2) && sp <= old_sp)
- || (INNER_THAN (2, 1) && sp >= old_sp));
- }
- else
- /* FIXME: cagney/2002-09-18: Hey, you loose! Who knows how badly
- aligned the SP is! Further, per comment above, if the generic
- dummy frame ends up empty (because nothing is pushed) GDB won't
- be able to correctly perform back traces. If a target is
- having trouble with backtraces, first thing to do is add
- FRAME_ALIGN() to its architecture vector. After that, try
- adding SAVE_DUMMY_FRAME_TOS() and modifying FRAME_CHAIN so that
- when the next outer frame is a generic dummy, it returns the
- current frame's base. */
- sp = old_sp;
-
- if (INNER_THAN (1, 2))
- {
- /* Stack grows down */
- sp -= sizeof_dummy1;
- start_sp = sp;
- }
- else
- {
- /* Stack grows up */
- start_sp = sp;
- sp += sizeof_dummy1;
- }
-
- /* NOTE: cagney/2002-09-10: Don't bother re-adjusting the stack
- after allocating space for the call dummy. A target can specify
- a SIZEOF_DUMMY1 (via SIZEOF_CALL_DUMMY_WORDS) such that all local
- alignment requirements are met. */
-
- funaddr = find_function_addr (function, &value_type);
- CHECK_TYPEDEF (value_type);
-
- {
- struct block *b = block_for_pc (funaddr);
- /* If compiled without -g, assume GCC 2. */
- using_gcc = (b == NULL ? 2 : BLOCK_GCC_COMPILED (b));
- }
-
- /* Are we returning a value using a structure return or a normal
- value return? */
-
- struct_return = using_struct_return (function, funaddr, value_type,
- using_gcc);
-
- /* Create a call sequence customized for this function
- and the number of arguments for it. */
- for (i = 0; i < (int) (SIZEOF_CALL_DUMMY_WORDS / sizeof (dummy[0])); i++)
- store_unsigned_integer (&dummy1[i * REGISTER_SIZE],
- REGISTER_SIZE,
- (ULONGEST) dummy[i]);
-
-#ifdef GDB_TARGET_IS_HPPA
- real_pc = FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args,
- value_type, using_gcc);
-#else
- FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args,
- value_type, using_gcc);
- real_pc = start_sp;
-#endif
-
- if (CALL_DUMMY_LOCATION == ON_STACK)
- {
- write_memory (start_sp, (char *) dummy1, sizeof_dummy1);
- if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES)
- generic_save_call_dummy_addr (start_sp, start_sp + sizeof_dummy1);
- }
-
- if (CALL_DUMMY_LOCATION == BEFORE_TEXT_END)
- {
- /* Convex Unix prohibits executing in the stack segment. */
- /* Hope there is empty room at the top of the text segment. */
- extern CORE_ADDR text_end;
- static int checked = 0;
- if (!checked)
- for (start_sp = text_end - sizeof_dummy1; start_sp < text_end; ++start_sp)
- if (read_memory_integer (start_sp, 1) != 0)
- error ("text segment full -- no place to put call");
- checked = 1;
- sp = old_sp;
- real_pc = text_end - sizeof_dummy1;
- write_memory (real_pc, (char *) dummy1, sizeof_dummy1);
- if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES)
- generic_save_call_dummy_addr (real_pc, real_pc + sizeof_dummy1);
- }
-
- if (CALL_DUMMY_LOCATION == AFTER_TEXT_END)
- {
- extern CORE_ADDR text_end;
- int errcode;
- sp = old_sp;
- real_pc = text_end;
- errcode = target_write_memory (real_pc, (char *) dummy1, sizeof_dummy1);
- if (errcode != 0)
- error ("Cannot write text segment -- call_function failed");
- if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES)
- generic_save_call_dummy_addr (real_pc, real_pc + sizeof_dummy1);
- }
-
- if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT)
- {
- real_pc = funaddr;
- if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES)
- /* NOTE: cagney/2002-04-13: The entry point is going to be
- modified with a single breakpoint. */
- generic_save_call_dummy_addr (CALL_DUMMY_ADDRESS (),
- CALL_DUMMY_ADDRESS () + 1);
- }
-
-#ifdef lint
- sp = old_sp; /* It really is used, for some ifdef's... */
-#endif
-
- if (nargs < TYPE_NFIELDS (ftype))
- error ("too few arguments in function call");
-
- for (i = nargs - 1; i >= 0; i--)
- {
- int prototyped;
-
- /* FIXME drow/2002-05-31: Should just always mark methods as
- prototyped. Can we respect TYPE_VARARGS? Probably not. */
- if (TYPE_CODE (ftype) == TYPE_CODE_METHOD)
- prototyped = 1;
- else
- prototyped = TYPE_PROTOTYPED (ftype);
-
- if (i < TYPE_NFIELDS (ftype))
- args[i] = value_arg_coerce (args[i], TYPE_FIELD_TYPE (ftype, i),
- prototyped);
- else
- args[i] = value_arg_coerce (args[i], NULL, 0);
-
- /*elz: this code is to handle the case in which the function to be called
- has a pointer to function as parameter and the corresponding actual argument
- is the address of a function and not a pointer to function variable.
- In aCC compiled code, the calls through pointers to functions (in the body
- of the function called by hand) are made via $$dyncall_external which
- requires some registers setting, this is taken care of if we call
- via a function pointer variable, but not via a function address.
- In cc this is not a problem. */
-
- if (using_gcc == 0)
- if (param_type && TYPE_CODE (ftype) != TYPE_CODE_METHOD)
- /* if this parameter is a pointer to function */
- if (TYPE_CODE (param_type) == TYPE_CODE_PTR)
- if (TYPE_CODE (TYPE_TARGET_TYPE (param_type)) == TYPE_CODE_FUNC)
- /* elz: FIXME here should go the test about the compiler used
- to compile the target. We want to issue the error
- message only if the compiler used was HP's aCC.
- If we used HP's cc, then there is no problem and no need
- to return at this point */
- if (using_gcc == 0) /* && compiler == aCC */
- /* go see if the actual parameter is a variable of type
- pointer to function or just a function */
- if (args[i]->lval == not_lval)
- {
- char *arg_name;
- if (find_pc_partial_function ((CORE_ADDR) args[i]->aligner.contents[0], &arg_name, NULL, NULL))
- error ("\
-You cannot use function <%s> as argument. \n\
-You must use a pointer to function type variable. Command ignored.", arg_name);
- }
- }
-
- if (REG_STRUCT_HAS_ADDR_P ())
- {
- /* This is a machine like the sparc, where we may need to pass a
- pointer to the structure, not the structure itself. */
- for (i = nargs - 1; i >= 0; i--)
- {
- struct type *arg_type = check_typedef (VALUE_TYPE (args[i]));
- if ((TYPE_CODE (arg_type) == TYPE_CODE_STRUCT
- || TYPE_CODE (arg_type) == TYPE_CODE_UNION
- || TYPE_CODE (arg_type) == TYPE_CODE_ARRAY
- || TYPE_CODE (arg_type) == TYPE_CODE_STRING
- || TYPE_CODE (arg_type) == TYPE_CODE_BITSTRING
- || TYPE_CODE (arg_type) == TYPE_CODE_SET
- || (TYPE_CODE (arg_type) == TYPE_CODE_FLT
- && TYPE_LENGTH (arg_type) > 8)
- )
- && REG_STRUCT_HAS_ADDR (using_gcc, arg_type))
- {
- CORE_ADDR addr;
- int len; /* = TYPE_LENGTH (arg_type); */
- int aligned_len;
- arg_type = check_typedef (VALUE_ENCLOSING_TYPE (args[i]));
- len = TYPE_LENGTH (arg_type);
-
- if (STACK_ALIGN_P ())
- /* MVS 11/22/96: I think at least some of this
- stack_align code is really broken. Better to let
- PUSH_ARGUMENTS adjust the stack in a target-defined
- manner. */
- aligned_len = STACK_ALIGN (len);
- else
- aligned_len = len;
- if (INNER_THAN (1, 2))
- {
- /* stack grows downward */
- sp -= aligned_len;
- /* ... so the address of the thing we push is the
- stack pointer after we push it. */
- addr = sp;
- }
- else
- {
- /* The stack grows up, so the address of the thing
- we push is the stack pointer before we push it. */
- addr = sp;
- sp += aligned_len;
- }
- /* Push the structure. */
- write_memory (addr, VALUE_CONTENTS_ALL (args[i]), len);
- /* The value we're going to pass is the address of the
- thing we just pushed. */
- /*args[i] = value_from_longest (lookup_pointer_type (value_type),
- (LONGEST) addr); */
- args[i] = value_from_pointer (lookup_pointer_type (arg_type),
- addr);
- }
- }
- }
-
-
- /* Reserve space for the return structure to be written on the
- stack, if necessary. Make certain that the value is correctly
- aligned. */
-
- if (struct_return)
- {
- int len = TYPE_LENGTH (value_type);
- if (STACK_ALIGN_P ())
- /* MVS 11/22/96: I think at least some of this stack_align
- code is really broken. Better to let PUSH_ARGUMENTS adjust
- the stack in a target-defined manner. */
- len = STACK_ALIGN (len);
- if (INNER_THAN (1, 2))
- {
- /* Stack grows downward. Align STRUCT_ADDR and SP after
- making space for the return value. */
- sp -= len;
- if (gdbarch_frame_align_p (current_gdbarch))
- sp = gdbarch_frame_align (current_gdbarch, sp);
- struct_addr = sp;
- }
- else
- {
- /* Stack grows upward. Align the frame, allocate space, and
- then again, re-align the frame??? */
- if (gdbarch_frame_align_p (current_gdbarch))
- sp = gdbarch_frame_align (current_gdbarch, sp);
- struct_addr = sp;
- sp += len;
- if (gdbarch_frame_align_p (current_gdbarch))
- sp = gdbarch_frame_align (current_gdbarch, sp);
- }
- }
-
- /* elz: on HPPA no need for this extra alignment, maybe it is needed
- on other architectures. This is because all the alignment is
- taken care of in the above code (ifdef REG_STRUCT_HAS_ADDR) and
- in hppa_push_arguments */
- if (EXTRA_STACK_ALIGNMENT_NEEDED)
- {
- /* MVS 11/22/96: I think at least some of this stack_align code
- is really broken. Better to let PUSH_ARGUMENTS adjust the
- stack in a target-defined manner. */
- if (STACK_ALIGN_P () && INNER_THAN (1, 2))
- {
- /* If stack grows down, we must leave a hole at the top. */
- int len = 0;
-
- for (i = nargs - 1; i >= 0; i--)
- len += TYPE_LENGTH (VALUE_ENCLOSING_TYPE (args[i]));
- if (CALL_DUMMY_STACK_ADJUST_P)
- len += CALL_DUMMY_STACK_ADJUST;
- sp -= STACK_ALIGN (len) - len;
- }
- }
-
- sp = PUSH_ARGUMENTS (nargs, args, sp, struct_return, struct_addr);
-
- if (PUSH_RETURN_ADDRESS_P ())
- /* for targets that use no CALL_DUMMY */
- /* There are a number of targets now which actually don't write
- any CALL_DUMMY instructions into the target, but instead just
- save the machine state, push the arguments, and jump directly
- to the callee function. Since this doesn't actually involve
- executing a JSR/BSR instruction, the return address must be set
- up by hand, either by pushing onto the stack or copying into a
- return-address register as appropriate. Formerly this has been
- done in PUSH_ARGUMENTS, but that's overloading its
- functionality a bit, so I'm making it explicit to do it here. */
- sp = PUSH_RETURN_ADDRESS (real_pc, sp);
-
- if (STACK_ALIGN_P () && !INNER_THAN (1, 2))
- {
- /* If stack grows up, we must leave a hole at the bottom, note
- that sp already has been advanced for the arguments! */
- if (CALL_DUMMY_STACK_ADJUST_P)
- sp += CALL_DUMMY_STACK_ADJUST;
- sp = STACK_ALIGN (sp);
- }
-
-/* XXX This seems wrong. For stacks that grow down we shouldn't do
- anything here! */
- /* MVS 11/22/96: I think at least some of this stack_align code is
- really broken. Better to let PUSH_ARGUMENTS adjust the stack in
- a target-defined manner. */
- if (CALL_DUMMY_STACK_ADJUST_P)
- if (INNER_THAN (1, 2))
- {
- /* stack grows downward */
- sp -= CALL_DUMMY_STACK_ADJUST;
- }
-
- /* Store the address at which the structure is supposed to be
- written. Note that this (and the code which reserved the space
- above) assumes that gcc was used to compile this function. Since
- it doesn't cost us anything but space and if the function is pcc
- it will ignore this value, we will make that assumption.
-
- Also note that on some machines (like the sparc) pcc uses a
- convention like gcc's. */
-
- if (struct_return)
- STORE_STRUCT_RETURN (struct_addr, sp);
-
- /* Write the stack pointer. This is here because the statements above
- might fool with it. On SPARC, this write also stores the register
- window into the right place in the new stack frame, which otherwise
- wouldn't happen. (See store_inferior_registers in sparc-nat.c.) */
- write_sp (sp);
-
- if (SAVE_DUMMY_FRAME_TOS_P ())
- SAVE_DUMMY_FRAME_TOS (sp);
-
- {
- char *name;
- struct symbol *symbol;
-
- name = NULL;
- symbol = find_pc_function (funaddr);
- if (symbol)
- {
- name = SYMBOL_SOURCE_NAME (symbol);
- }
- else
- {
- /* Try the minimal symbols. */
- struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (funaddr);
-
- if (msymbol)
- {
- name = SYMBOL_SOURCE_NAME (msymbol);
- }
- }
- if (name == NULL)
- {
- char format[80];
- sprintf (format, "at %s", local_hex_format ());
- name = alloca (80);
- /* FIXME-32x64: assumes funaddr fits in a long. */
- sprintf (name, format, (unsigned long) funaddr);
- }
-
- /* Execute the stack dummy routine, calling FUNCTION.
- When it is done, discard the empty frame
- after storing the contents of all regs into retbuf. */
- rc = run_stack_dummy (real_pc + CALL_DUMMY_START_OFFSET, retbuf);
-
- if (rc == 1)
- {
- /* We stopped inside the FUNCTION because of a random signal.
- Further execution of the FUNCTION is not allowed. */
-
- if (unwind_on_signal_p)
- {
- /* The user wants the context restored. */
-
- /* We must get back to the frame we were before the dummy call. */
- POP_FRAME;
-
- /* FIXME: Insert a bunch of wrap_here; name can be very long if it's
- a C++ name with arguments and stuff. */
- error ("\
-The program being debugged was signaled while in a function called from GDB.\n\
-GDB has restored the context to what it was before the call.\n\
-To change this behavior use \"set unwindonsignal off\"\n\
-Evaluation of the expression containing the function (%s) will be abandoned.",
- name);
- }
- else
- {
- /* The user wants to stay in the frame where we stopped (default).*/
-
- /* If we restored the inferior status (via the cleanup),
- we would print a spurious error message (Unable to
- restore previously selected frame), would write the
- registers from the inf_status (which is wrong), and
- would do other wrong things. */
- discard_cleanups (inf_status_cleanup);
- discard_inferior_status (inf_status);
-
- /* FIXME: Insert a bunch of wrap_here; name can be very long if it's
- a C++ name with arguments and stuff. */
- error ("\
-The program being debugged was signaled while in a function called from GDB.\n\
-GDB remains in the frame where the signal was received.\n\
-To change this behavior use \"set unwindonsignal on\"\n\
-Evaluation of the expression containing the function (%s) will be abandoned.",
- name);
- }
- }
-
- if (rc == 2)
- {
- /* We hit a breakpoint inside the FUNCTION. */
-
- /* If we restored the inferior status (via the cleanup), we
- would print a spurious error message (Unable to restore
- previously selected frame), would write the registers from
- the inf_status (which is wrong), and would do other wrong
- things. */
- discard_cleanups (inf_status_cleanup);
- discard_inferior_status (inf_status);
-
- /* The following error message used to say "The expression
- which contained the function call has been discarded." It
- is a hard concept to explain in a few words. Ideally, GDB
- would be able to resume evaluation of the expression when
- the function finally is done executing. Perhaps someday
- this will be implemented (it would not be easy). */
-
- /* FIXME: Insert a bunch of wrap_here; name can be very long if it's
- a C++ name with arguments and stuff. */
- error ("\
-The program being debugged stopped while in a function called from GDB.\n\
-When the function (%s) is done executing, GDB will silently\n\
-stop (instead of continuing to evaluate the expression containing\n\
-the function call).", name);
- }
-
- /* If we get here the called FUNCTION run to completion. */
-
- /* Restore the inferior status, via its cleanup. At this stage,
- leave the RETBUF alone. */
- do_cleanups (inf_status_cleanup);
-
- /* Figure out the value returned by the function. */
- /* elz: I defined this new macro for the hppa architecture only.
- this gives us a way to get the value returned by the function
- from the stack, at the same address we told the function to put
- it. We cannot assume on the pa that r28 still contains the
- address of the returned structure. Usually this will be
- overwritten by the callee. I don't know about other
- architectures, so I defined this macro */
-#ifdef VALUE_RETURNED_FROM_STACK
- if (struct_return)
- {
- do_cleanups (retbuf_cleanup);
- return VALUE_RETURNED_FROM_STACK (value_type, struct_addr);
- }
-#endif
- /* NOTE: cagney/2002-09-10: Only when the stack has been correctly
- aligned (using frame_align()) do we can trust STRUCT_ADDR and
- fetch the return value direct from the stack. This lack of
- trust comes about because legacy targets have a nasty habit of
- silently, and local to PUSH_ARGUMENTS(), moving STRUCT_ADDR.
- For such targets, just hope that value_being_returned() can
- find the adjusted value. */
- if (struct_return && gdbarch_frame_align_p (current_gdbarch))
- {
- struct value *retval = value_at (value_type, struct_addr, NULL);
- do_cleanups (retbuf_cleanup);
- return retval;
- }
- else
- {
- struct value *retval = value_being_returned (value_type, retbuf,
- struct_return);
- do_cleanups (retbuf_cleanup);
- return retval;
- }
- }
-}
-
-struct value *
-call_function_by_hand (struct value *function, int nargs, struct value **args)
-{
- if (CALL_DUMMY_P)
- {
- return hand_function_call (function, nargs, args);
- }
- else
- {
- error ("Cannot invoke functions on this machine.");
- }
-}
-\f
-
-
/* 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.
VALUE_CONTENTS_ALL (elemvec[idx]),
typelength);
}
- VALUE_BFD_SECTION (val) = VALUE_BFD_SECTION (elemvec[0]);
return val;
}
/* 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);
}
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);
}
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);
/* Look for a match through the fields of an anonymous union,
or anonymous struct. C++ provides anonymous unions.
- In the GNU Chill (OBSOLETE) implementation of
- variant record types, each <alternative field> has
- an (anonymous) union type, each member of the union
- represents a <variant alternative>. Each <variant
- alternative> is represented as a struct, with a
- member for each <variant field>. */
+ In the GNU Chill (now deleted from GDB)
+ implementation of variant record types, each
+ <alternative field> has an (anonymous) union type,
+ each member of the union represents a <variant
+ alternative>. Each <variant alternative> is
+ represented as a struct, with a member for each
+ <variant field>. */
struct value *v;
int new_offset = offset;
/* This is pretty gross. In G++, the offset in an
anonymous union is relative to the beginning of the
- enclosing struct. In the GNU Chill (OBSOLETE)
- implementation of variant records, the bitpos is
- zero in an anonymous union field, so we have to add
- the offset of the union here. */
+ enclosing struct. In the GNU Chill (now deleted
+ from GDB) implementation of variant records, the
+ bitpos is zero in an anonymous union field, so we
+ have to add the offset of the union here. */
if (TYPE_CODE (field_type) == TYPE_CODE_STRUCT
|| (TYPE_NFIELDS (field_type) > 0
&& TYPE_FIELD_BITPOS (field_type, 0) == 0))
boffset = baseclass_offset (type, i,
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;
+ 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) = VALUE_LVAL (arg1);
VALUE_ADDRESS (v2) = VALUE_ADDRESS (arg1);
- VALUE_OFFSET (v2) = VALUE_OFFSET (arg1) + boffset;
+ v2->offset = value_offset (arg1) + boffset;
if (VALUE_LAZY (arg1))
VALUE_LAZY (v2) = 1;
else
& 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;
{
base_valaddr = (char *) alloca (TYPE_LENGTH (baseclass));
if (target_read_memory (VALUE_ADDRESS (*arg1p)
- + VALUE_OFFSET (*arg1p) + offset,
+ + value_offset (*arg1p) + offset,
base_valaddr,
TYPE_LENGTH (baseclass)) != 0)
error ("virtual baseclass botch");
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)
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,
{
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 (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;
+
+ 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;
}
+}
- oload_champ_bv = NULL;
+/* 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. */
}
/* 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
of the member we are looking for. This will help us resolve
"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.
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);
+ (using_enc ? 0 : VALUE_EMBEDDED_OFFSET (argp)));
+ new_val->type = value_type (argp);
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)
error ("slice from bad array or bitstring");
if (lowbound < lowerbound || length < 0
|| lowbound + length - 1 > upperbound)
- /* OBSOLETE Chill allows zero-length strings but not arrays. */
- /* OBSOLETE || (current_language->la_language == language_chill */
- /* OBSOLETE && length == 0 && TYPE_CODE (array_type) == TYPE_CODE_ARRAY)) */
error ("slice out of range");
/* FIXME-type-allocation: need a way to free this type when we are
done with it. */
else
VALUE_LVAL (slice) = VALUE_LVAL (array);
VALUE_ADDRESS (slice) = VALUE_ADDRESS (array);
- VALUE_OFFSET (slice) = VALUE_OFFSET (array) + offset;
+ slice->offset = value_offset (array) + offset;
}
return slice;
}
-/* Assuming OBSOLETE chill_varying_type (VARRAY) is true, return an
- equivalent value as a fixed-length array. */
-
-struct value *
-varying_to_slice (struct value *varray)
-{
- struct type *vtype = check_typedef (VALUE_TYPE (varray));
- LONGEST length = unpack_long (TYPE_FIELD_TYPE (vtype, 0),
- VALUE_CONTENTS (varray)
- + TYPE_FIELD_BITPOS (vtype, 0) / 8);
- return value_slice (value_primitive_field (varray, 0, 1, vtype), 0, length);
-}
-
/* Create a value for a FORTRAN complex number. Currently most of
the time values are coerced to COMPLEX*16 (i.e. a complex number
composed of 2 doubles. This really should be a smarter routine
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);
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),
&showlist);
overload_resolution = 1;
-
- add_show_from_set (
- add_set_cmd ("unwindonsignal", no_class, var_boolean,
- (char *) &unwind_on_signal_p,
-"Set unwinding of stack if a signal is received while in a call dummy.\n\
-The unwindonsignal lets the user determine what gdb should do if a signal\n\
-is received while in a function called from gdb (call dummy). If set, gdb\n\
-unwinds the stack and restore the context to what as it was before the call.\n\
-The default is to stop in the frame where the signal was received.", &setlist),
- &showlist);
}