X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fvalops.c;h=18be57eba32e2f58a3a8df0074ee0babb41b843a;hb=06987e6431adee88dcffb552d01162668efbf9f4;hp=d8261c822f0132957ed192f196ca509f3d65178e;hpb=04714b914fe6e2deaf384c77a286df8e95545a73;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/valops.c b/gdb/valops.c index d8261c822f..18be57eba3 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -1,6 +1,6 @@ /* 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 Free Software Foundation, Inc. This file is part of GDB. @@ -35,14 +35,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 +50,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 +57,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 +131,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,9 +200,9 @@ 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; @@ -208,7 +253,6 @@ value_cast (struct type *type, struct value *arg2) arg2 = value_coerce_function (arg2); type2 = check_typedef (VALUE_TYPE (arg2)); - COERCE_VARYING_ARRAY (arg2, type2); code2 = TYPE_CODE (type2); if (code1 == TYPE_CODE_COMPLEX) @@ -249,8 +293,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; @@ -366,10 +410,7 @@ value_cast (struct type *type, struct value *arg2) 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 +448,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; @@ -420,7 +461,6 @@ value_at (struct type *type, CORE_ADDR addr, asection *sect) VALUE_LVAL (val) = lval_memory; VALUE_ADDRESS (val) = addr; - VALUE_BFD_SECTION (val) = sect; return val; } @@ -428,7 +468,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,7 +480,6 @@ 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; } @@ -478,10 +517,8 @@ 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) @@ -496,22 +533,6 @@ value_assign (struct value *toval, struct value *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. */ @@ -540,10 +561,10 @@ 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)) { - 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) @@ -562,12 +583,6 @@ value_assign (struct value *toval, struct value *fromval) 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); @@ -576,26 +591,16 @@ value_assign (struct value *toval, struct value *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) @@ -605,102 +610,81 @@ value_assign (struct value *toval, struct value *fromval) } else { - for (frame = get_current_frame (); - frame && get_frame_base (frame) != VALUE_FRAME (toval); - frame = get_prev_frame (frame)) - ; + frame = frame_find_by_id (VALUE_FRAME_ID (toval)); value_reg = VALUE_FRAME_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_reg_frame_relative + && CONVERT_REGISTER_P (VALUE_FRAME_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_FRAME_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."); @@ -842,7 +826,7 @@ 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."); @@ -864,7 +848,6 @@ value_coerce_function (struct value *arg1) retval = value_from_pointer (lookup_pointer_type (VALUE_TYPE (arg1)), (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1))); - VALUE_BFD_SECTION (retval) = VALUE_BFD_SECTION (arg1); return retval; } @@ -902,7 +885,6 @@ value_addr (struct value *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; } @@ -927,8 +909,7 @@ 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; @@ -937,9 +918,8 @@ value_ind (struct value *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); /* Add embedding info */ @@ -962,8 +942,8 @@ value_ind (struct value *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)) @@ -1003,58 +983,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. @@ -1107,7 +1035,6 @@ value_array (int lowbound, int highbound, struct value **elemvec) VALUE_CONTENTS_ALL (elemvec[idx]), typelength); } - VALUE_BFD_SECTION (val) = VALUE_BFD_SECTION (elemvec[0]); return val; } @@ -1125,7 +1052,7 @@ value_array (int lowbound, int highbound, struct value **elemvec) /* 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); } @@ -1163,7 +1090,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); } @@ -1274,7 +1201,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); @@ -1497,7 +1424,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 +1441,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; @@ -1659,7 +1586,7 @@ 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); @@ -1919,19 +1846,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,13 +1858,13 @@ 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) @@ -1970,38 +1888,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); + } + + /* 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; + *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 +2171,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 +2206,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 +2262,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 +2275,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,7 +2318,7 @@ 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); @@ -2249,6 +2344,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 +2376,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 +2394,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 +2441,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 +2472,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 +2503,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. @@ -2460,8 +2631,7 @@ 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)); + (using_enc ? 0 : VALUE_EMBEDDED_OFFSET (argp))); VALUE_TYPE (new_val) = VALUE_TYPE (argp); VALUE_EMBEDDED_OFFSET (new_val) = using_enc ? top + VALUE_EMBEDDED_OFFSET (argp) : top; return new_val; @@ -2479,7 +2649,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 +2669,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 +2679,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) @@ -2551,7 +2719,6 @@ value_slice (struct value *array, int lowbound, int length) struct value *slice; struct type *array_type; array_type = check_typedef (VALUE_TYPE (array)); - COERCE_VARYING_ARRAY (array, array_type); if (TYPE_CODE (array_type) != TYPE_CODE_ARRAY && TYPE_CODE (array_type) != TYPE_CODE_STRING && TYPE_CODE (array_type) != TYPE_CODE_BITSTRING) @@ -2670,14 +2837,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),