X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fvalops.c;h=442bb51ddb9c9bed8b5c0e2cfb3960ef3392ee85;hb=d69fe07ead0b14603cb37fd9659bffc11afa37b1;hp=5523c5dbedbb9e56e0981455139aa528924c8715;hpb=b1e29e332aca04fd8b4b795d1c2ee1eb8fa7ba42;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/valops.c b/gdb/valops.c index 5523c5dbed..442bb51ddb 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -1,6 +1,7 @@ /* 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. @@ -35,14 +36,14 @@ #include "cp-abi.h" #include "block.h" #include "infcall.h" +#include "dictionary.h" +#include "cp-support.h" #include #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. */ @@ -50,8 +51,6 @@ extern int overload_debug; 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); @@ -59,8 +58,55 @@ static struct value *search_struct_method (char *, struct value **, struct value **, int, int *, struct type *); +static int find_oload_champ_namespace (struct type **arg_types, int nargs, + const char *func_name, + const char *qualified_name, + struct symbol ***oload_syms, + struct badness_vector **oload_champ_bv); + +static +int find_oload_champ_namespace_loop (struct type **arg_types, int nargs, + const char *func_name, + const char *qualified_name, + int namespace_len, + struct symbol ***oload_syms, + struct badness_vector **oload_champ_bv, + int *oload_champ); + +static int find_oload_champ (struct type **arg_types, int nargs, int method, + int num_fns, + struct fn_field *fns_ptr, + struct symbol **oload_syms, + struct badness_vector **oload_champ_bv); + +static int oload_method_static (int method, struct fn_field *fns_ptr, + int index); + +enum oload_classification { STANDARD, NON_STANDARD, INCOMPATIBLE }; + +static enum +oload_classification classify_oload_match (struct badness_vector + * oload_champ_bv, + int nargs, + int static_offset); + static int check_field_in (struct type *, const char *); +static struct value *value_struct_elt_for_reference (struct type *domain, + int offset, + struct type *curtype, + char *name, + struct type *intype, + enum noside noside); + +static struct value *value_namespace_elt (const struct type *curtype, + char *name, + enum noside noside); + +static struct value *value_maybe_namespace_elt (const struct type *curtype, + char *name, + enum noside noside); + static CORE_ADDR allocate_space_in_inferior (int); static struct value *cast_into_complex (struct type *, struct value *); @@ -86,8 +132,8 @@ int overload_resolution = 0; 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) @@ -155,20 +201,20 @@ allocate_space_in_inferior (int len) 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, @@ -194,8 +240,8 @@ value_cast (struct type *type, struct value *arg2) 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; } } @@ -207,8 +253,7 @@ value_cast (struct type *type, struct value *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) @@ -237,7 +282,7 @@ value_cast (struct type *type, struct value *arg2) arg2, 0, type2, 1); if (v) { - VALUE_TYPE (v) = type; + v->type = type; return v; } } @@ -249,8 +294,8 @@ value_cast (struct type *type, struct value *arg2) { 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; @@ -335,7 +380,7 @@ value_cast (struct type *type, struct value *arg2) if (v) { v = value_addr (v); - VALUE_TYPE (v) = type; + v->type = type; return v; } } @@ -352,7 +397,7 @@ value_cast (struct type *type, struct value *arg2) { 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); } @@ -360,16 +405,13 @@ value_cast (struct type *type, struct value *arg2) } /* 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; } 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); @@ -407,7 +449,7 @@ value_zero (struct type *type, enum lval_type lv) 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; @@ -416,11 +458,10 @@ value_at (struct type *type, CORE_ADDR addr, asection *sect) 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; } @@ -428,7 +469,7 @@ value_at (struct type *type, CORE_ADDR addr, asection *sect) /* 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; @@ -440,15 +481,15 @@ value_at_lazy (struct type *type, CORE_ADDR addr, asection *sect) VALUE_LVAL (val) = lval_memory; VALUE_ADDRESS (val) = addr; VALUE_LAZY (val) = 1; - VALUE_BFD_SECTION (val) = sect; 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 +/* 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. + 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. @@ -460,12 +501,12 @@ value_at_lazy (struct type *type, CORE_ADDR addr, asection *sect) 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; return 0; @@ -478,40 +519,22 @@ value_fetch_lazy (struct value *val) 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. */ @@ -522,16 +545,16 @@ value_assign (struct value *toval, struct value *fromval) 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)); + val = value_change_enclosing_type (val, value_enclosing_type (fromval)); VALUE_EMBEDDED_OFFSET (val) = VALUE_EMBEDDED_OFFSET (fromval); VALUE_POINTED_TO_OFFSET (val) = VALUE_POINTED_TO_OFFSET (fromval); return val; case lval_internalvar_component: set_internalvar_component (VALUE_INTERNALVAR (toval), - VALUE_OFFSET (toval), - VALUE_BITPOS (toval), - VALUE_BITSIZE (toval), + value_offset (toval), + value_bitpos (toval), + value_bitsize (toval), fromval); break; @@ -540,14 +563,14 @@ value_assign (struct value *toval, struct value *fromval) 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; @@ -555,152 +578,106 @@ value_assign (struct value *toval, struct value *fromval) 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: { - /* 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_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)) + if (VALUE_LVAL (toval) == lval_register + && CONVERT_REGISTER_P (VALUE_REGNUM (toval), type)) { - modify_field (buffer + byte_offset, - value_as_long (fromval), - VALUE_BITPOS (toval), VALUE_BITSIZE (toval)); - } - else if (use_buffer) - { - 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."); @@ -715,7 +692,6 @@ value_assign (struct value *toval, struct value *fromval) { case lval_memory: case lval_register: - case lval_reg_frame_relative: reinit_frame_cache (); @@ -740,11 +716,11 @@ value_assign (struct value *toval, struct value *fromval) /* 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)))) @@ -754,10 +730,10 @@ value_assign (struct value *toval, struct value *fromval) } 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)); + 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); @@ -776,13 +752,13 @@ value_repeat (struct value *arg1, int count) 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; } @@ -842,13 +818,13 @@ value_of_variable (struct symbol *var, struct block *b) 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 @@ -862,9 +838,8 @@ value_coerce_function (struct value *arg1) 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; } @@ -875,14 +850,14 @@ value_addr (struct value *arg1) { 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) @@ -892,17 +867,16 @@ value_addr (struct value *arg1) 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 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); return arg2; } @@ -914,9 +888,9 @@ value_ind (struct value *arg1) 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"); @@ -927,21 +901,19 @@ value_ind (struct value *arg1) 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); + 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); @@ -962,8 +934,8 @@ value_ind (struct value *arg1) CORE_ADDR push_word (CORE_ADDR sp, ULONGEST word) { - register int len = DEPRECATED_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)) @@ -1003,58 +975,6 @@ push_bytes (CORE_ADDR sp, char *buffer, int len) 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. @@ -1084,10 +1004,10 @@ value_array (int lowbound, int highbound, struct value **elemvec) { 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"); } @@ -1096,18 +1016,17 @@ value_array (int lowbound, int highbound, struct value **elemvec) 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; } @@ -1119,13 +1038,14 @@ value_array (int lowbound, int highbound, struct value **elemvec) 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); } @@ -1152,7 +1072,7 @@ value_string (char *ptr, int len) 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; } @@ -1163,7 +1083,7 @@ value_string (char *ptr, int len) 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); } @@ -1176,7 +1096,7 @@ value_bitstring (char *ptr, int len) 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; } @@ -1219,7 +1139,7 @@ typecmp (int staticp, int varargs, int nargs, 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. */ @@ -1256,7 +1176,7 @@ typecmp (int staticp, int varargs, int nargs, /* 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) @@ -1274,7 +1194,7 @@ typecmp (int staticp, int varargs, int nargs, 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); @@ -1366,7 +1286,7 @@ search_struct_field (char *name, struct value *arg1, int offset, 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"); @@ -1379,8 +1299,8 @@ search_struct_field (char *name, struct value *arg1, int offset, { 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; @@ -1390,12 +1310,13 @@ search_struct_field (char *name, struct value *arg1, int offset, { VALUE_LVAL (v2) = VALUE_LVAL (arg1); VALUE_ADDRESS (v2) = VALUE_ADDRESS (arg1); - VALUE_OFFSET (v2) = VALUE_OFFSET (arg1) + boffset; - if (VALUE_LAZY (arg1)) + VALUE_FRAME_ID (v2) = VALUE_FRAME_ID (arg1); + v2->offset = value_offset (arg1) + boffset; + if (value_lazy (arg1)) 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)); } @@ -1436,8 +1357,9 @@ search_struct_field (char *name, struct value *arg1, int offset, * 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 */ @@ -1497,7 +1419,7 @@ find_rt_vbase_offset (struct type *type, struct type *basetype, char *valaddr, & 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; @@ -1514,7 +1436,7 @@ find_rt_vbase_offset (struct type *type, struct type *basetype, char *valaddr, 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; @@ -1583,7 +1505,7 @@ search_struct_method (char *name, struct value **arg1p, according to HP/Taligent runtime spec. */ int skip; find_rt_vbase_offset (type, TYPE_BASECLASS (type, i), - VALUE_CONTENTS_ALL (*arg1p), + value_contents_all (*arg1p), offset + VALUE_EMBEDDED_OFFSET (*arg1p), &base_offset, &skip); if (skip >= 0) @@ -1602,7 +1524,7 @@ search_struct_method (char *name, struct value **arg1p, { 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"); @@ -1613,7 +1535,7 @@ search_struct_method (char *name, struct value **arg1p, 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"); } @@ -1659,12 +1581,12 @@ struct value * 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. */ @@ -1672,9 +1594,9 @@ value_struct_elt (struct value **argp, struct value **args, { *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) @@ -1817,7 +1739,7 @@ find_method_list (struct value **argp, char *method, int offset, * according to HP/Taligent runtime spec. */ int skip; find_rt_vbase_offset (type, TYPE_BASECLASS (type, i), - VALUE_CONTENTS_ALL (*argp), + value_contents_all (*argp), offset + VALUE_EMBEDDED_OFFSET (*argp), &base_offset, &skip); if (skip >= 0) @@ -1826,7 +1748,7 @@ find_method_list (struct value **argp, char *method, int offset, 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, @@ -1864,16 +1786,16 @@ value_find_oload_method_list (struct value **argp, char *method, int 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) @@ -1919,19 +1841,10 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method, int lax, struct value **objp, struct symbol *fsym, struct value **valp, struct symbol **symp, int *staticp) { - int nparms; - struct type **parm_types; - int champ_nparms = 0; struct value *obj = (objp ? *objp : NULL); - short oload_champ = -1; /* 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; @@ -1940,23 +1853,23 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method, 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, @@ -1970,38 +1883,269 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method, 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); } - oload_champ_bv = NULL; + /* 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; + } +} + +/* 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 @@ -2022,30 +2166,25 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method, 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: @@ -2062,90 +2201,41 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method, 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() */ -#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 @@ -2167,7 +2257,7 @@ destructor_name_p (const char *name, const struct type *type) 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; @@ -2180,9 +2270,9 @@ destructor_name_p (const char *name, const struct type *type) 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--) { @@ -2223,11 +2313,11 @@ check_field_in (register struct type *type, const char *name) 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. */ @@ -2249,6 +2339,31 @@ check_field (struct value *arg1, const char *name) 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 @@ -2256,13 +2371,14 @@ check_field (struct value *arg1, const char *name) "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 @@ -2273,7 +2389,7 @@ value_struct_elt_for_reference (struct type *domain, int offset, { 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)) { @@ -2320,7 +2436,7 @@ value_struct_elt_for_reference (struct type *domain, int offset, 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); @@ -2351,7 +2467,7 @@ value_struct_elt_for_reference (struct type *domain, int offset, 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; @@ -2382,13 +2498,63 @@ value_struct_elt_for_reference (struct type *domain, int offset, 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. @@ -2436,7 +2602,7 @@ value_full_object (struct value *argp, struct type *rtype, int xfull, int xtop, 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 @@ -2460,9 +2626,8 @@ value_full_object (struct value *argp, struct type *rtype, int xfull, int xtop, 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; } @@ -2479,7 +2644,6 @@ value_of_local (const char *name, int complain) { struct symbol *func, *sym; struct block *b; - int i; struct value * ret; if (deprecated_selected_frame == 0) @@ -2500,8 +2664,7 @@ value_of_local (const char *name, int complain) } 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); @@ -2511,7 +2674,7 @@ value_of_local (const char *name, int complain) /* 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) @@ -2550,8 +2713,7 @@ value_slice (struct value *array, int lowbound, int length) 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) @@ -2585,7 +2747,7 @@ value_slice (struct value *array, int lowbound, int length) 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 @@ -2601,7 +2763,7 @@ value_slice (struct value *array, int lowbound, int length) slice_range_type); TYPE_CODE (slice_type) = TYPE_CODE (array_type); slice = allocate_value (slice_type); - if (VALUE_LAZY (array)) + if (value_lazy (array)) VALUE_LAZY (slice) = 1; else memcpy (VALUE_CONTENTS (slice), VALUE_CONTENTS (array) + offset, @@ -2611,7 +2773,8 @@ value_slice (struct value *array, int lowbound, int length) 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; } @@ -2632,9 +2795,9 @@ value_literal_complex (struct value *arg1, struct value *arg2, struct type *type arg1 = value_cast (real_type, arg1); arg2 = value_cast (real_type, arg2); - memcpy (VALUE_CONTENTS_RAW (val), + memcpy (value_contents_raw (val), VALUE_CONTENTS (arg1), TYPE_LENGTH (real_type)); - memcpy (VALUE_CONTENTS_RAW (val) + TYPE_LENGTH (real_type), + memcpy (value_contents_raw (val) + TYPE_LENGTH (real_type), VALUE_CONTENTS (arg2), TYPE_LENGTH (real_type)); return val; } @@ -2645,22 +2808,22 @@ static struct value * cast_into_complex (struct type *type, struct value *val) { struct type *real_type = TYPE_TARGET_TYPE (type); - if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_COMPLEX) + 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), + memcpy (value_contents_raw (re_val), VALUE_CONTENTS (val), TYPE_LENGTH (val_real_type)); - memcpy (VALUE_CONTENTS_RAW (im_val), + 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"); @@ -2670,14 +2833,14 @@ void _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),