X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fvalops.c;h=502fb0d1f07112a2b68a75216be5ae0cf7b5c697;hb=63375b7438a788834187519e033e01cfdbd8d373;hp=32d71cdf86f61754bfee8f8871405a300c975d73;hpb=8afd712c6f6c36b80754178aae94d74aa48ffcd5;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/valops.c b/gdb/valops.c index 32d71cdf86..502fb0d1f0 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -1,8 +1,6 @@ /* Perform non-arithmetic operations on values, for GDB. - Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, - 2008, 2009, 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 1986-2012 Free Software Foundation, Inc. This file is part of GDB. @@ -48,7 +46,7 @@ #include "symtab.h" #include "exceptions.h" -extern int overload_debug; +extern unsigned int overload_debug; /* Local functions. */ static int typecmp (int staticp, int varargs, int nargs, @@ -61,20 +59,20 @@ static struct value *search_struct_method (const char *, struct value **, struct value **, int, int *, struct type *); -static int find_oload_champ_namespace (struct type **, int, +static int find_oload_champ_namespace (struct value **, int, const char *, const char *, struct symbol ***, struct badness_vector **, const int no_adl); static -int find_oload_champ_namespace_loop (struct type **, int, +int find_oload_champ_namespace_loop (struct value **, int, const char *, const char *, int, struct symbol ***, struct badness_vector **, int *, const int no_adl); -static int find_oload_champ (struct type **, int, int, int, +static int find_oload_champ (struct value **, int, int, int, struct fn_field *, struct symbol **, struct badness_vector **); @@ -303,10 +301,14 @@ value_cast_structs (struct type *type, struct value *v2) /* Cast one pointer or reference type to another. Both TYPE and the type of ARG2 should be pointer types, or else both should be - reference types. Returns the new pointer or reference. */ + reference types. If SUBCLASS_CHECK is non-zero, this will force a + check to see whether TYPE is a superclass of ARG2's type. If + SUBCLASS_CHECK is zero, then the subclass check is done only when + ARG2 is itself non-zero. Returns the new pointer or reference. */ struct value * -value_cast_pointers (struct type *type, struct value *arg2) +value_cast_pointers (struct type *type, struct value *arg2, + int subclass_check) { struct type *type1 = check_typedef (type); struct type *type2 = check_typedef (value_type (arg2)); @@ -315,7 +317,7 @@ value_cast_pointers (struct type *type, struct value *arg2) if (TYPE_CODE (t1) == TYPE_CODE_STRUCT && TYPE_CODE (t2) == TYPE_CODE_STRUCT - && !value_logical_not (arg2)) + && (subclass_check || !value_logical_not (arg2))) { struct value *v2; @@ -570,7 +572,7 @@ value_cast (struct type *type, struct value *arg2) else if (TYPE_LENGTH (type) == TYPE_LENGTH (type2)) { if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR) - return value_cast_pointers (type, arg2); + return value_cast_pointers (type, arg2, 0); arg2 = value_copy (arg2); deprecated_set_value_type (arg2, type); @@ -992,7 +994,6 @@ value_fetch_lazy (struct value *val) struct value *parent = value_parent (val); LONGEST offset = value_offset (val); LONGEST num; - int length = TYPE_LENGTH (type); if (!value_bits_valid (val, TARGET_CHAR_BIT * offset + value_bitpos (val), @@ -1006,19 +1007,20 @@ value_fetch_lazy (struct value *val) value_bitsize (val), parent, &num)) mark_value_bytes_unavailable (val, value_embedded_offset (val), - length); + TYPE_LENGTH (type)); else - store_signed_integer (value_contents_raw (val), length, + store_signed_integer (value_contents_raw (val), TYPE_LENGTH (type), byte_order, num); } else if (VALUE_LVAL (val) == lval_memory) { CORE_ADDR addr = value_address (val); - int length = TYPE_LENGTH (check_typedef (value_enclosing_type (val))); + struct type *type = check_typedef (value_enclosing_type (val)); - if (length) + if (TYPE_LENGTH (type)) read_value_memory (val, 0, value_stack (val), - addr, value_contents_all_raw (val), length); + addr, value_contents_all_raw (val), + TYPE_LENGTH (type)); } else if (VALUE_LVAL (val) == lval_register) { @@ -1110,7 +1112,8 @@ value_fetch_lazy (struct value *val) watchpoints from trying to watch the saved frame pointer. */ value_free_to_mark (mark); } - else if (VALUE_LVAL (val) == lval_computed) + else if (VALUE_LVAL (val) == lval_computed + && value_computed_funcs (val)->read != NULL) value_computed_funcs (val)->read (val); else if (value_optimized_out (val)) /* Keep it optimized out. */; @@ -1296,9 +1299,7 @@ value_assign (struct value *toval, struct value *fromval) dest_buffer = value_contents (fromval); } - write_memory (changed_addr, dest_buffer, changed_len); - observer_notify_memory_changed (changed_addr, changed_len, - dest_buffer); + write_memory_with_notification (changed_addr, dest_buffer, changed_len); } break; @@ -1373,7 +1374,6 @@ value_assign (struct value *toval, struct value *fromval) if (deprecated_register_changed_hook) deprecated_register_changed_hook (-1); - observer_notify_target_changed (¤t_target); break; } @@ -1381,9 +1381,13 @@ value_assign (struct value *toval, struct value *fromval) { const struct lval_funcs *funcs = value_computed_funcs (toval); - funcs->write (toval, fromval); + if (funcs->write != NULL) + { + funcs->write (toval, fromval); + break; + } } - break; + /* Fall through. */ default: error (_("Left operand of assignment is not an lvalue.")); @@ -1391,7 +1395,7 @@ value_assign (struct value *toval, struct value *fromval) /* Assigning to the stack pointer, frame pointer, and other (architecture and calling convention specific) registers may - cause the frame cache to be out of date. Assigning to memory + cause the frame cache and regcache to be out of date. Assigning to memory also can. We just do this on all assignments to registers or memory, for simplicity's sake; I doubt the slowdown matters. */ switch (VALUE_LVAL (toval)) @@ -1400,7 +1404,7 @@ value_assign (struct value *toval, struct value *fromval) case lval_register: case lval_computed: - reinit_frame_cache (); + observer_notify_target_changed (¤t_target); /* Having destroyed the frame cache, restore the selected frame. */ @@ -1486,7 +1490,7 @@ value_repeat (struct value *arg1, int count) } struct value * -value_of_variable (struct symbol *var, struct block *b) +value_of_variable (struct symbol *var, const struct block *b) { struct frame_info *frame; @@ -1769,15 +1773,7 @@ value_ind (struct value *arg1) (value_as_address (arg1) - value_pointed_to_offset (arg1))); - /* Re-adjust type. */ - deprecated_set_value_type (arg2, TYPE_TARGET_TYPE (base_type)); - /* Add embedding info. */ - set_value_enclosing_type (arg2, enc_type); - set_value_embedded_offset (arg2, value_pointed_to_offset (arg1)); - - /* We may be pointing to an object of some derived type. */ - arg2 = value_full_object (arg2, NULL, 0, 0, 0); - return arg2; + return readjust_indirect_value_type (arg2, enc_type, base_type, arg1); } error (_("Attempt to take contents of a non-pointer value.")); @@ -1842,11 +1838,11 @@ value_array (int lowbound, int highbound, struct value **elemvec) } struct value * -value_cstring (char *ptr, int len, struct type *char_type) +value_cstring (char *ptr, ssize_t len, struct type *char_type) { struct value *val; int lowbound = current_language->string_lower_bound; - int highbound = len / TYPE_LENGTH (char_type); + ssize_t highbound = len / TYPE_LENGTH (char_type); struct type *stringtype = lookup_array_range_type (char_type, lowbound, highbound + lowbound - 1); @@ -1865,11 +1861,11 @@ value_cstring (char *ptr, int len, struct type *char_type) string may contain embedded null bytes. */ struct value * -value_string (char *ptr, int len, struct type *char_type) +value_string (char *ptr, ssize_t len, struct type *char_type) { struct value *val; int lowbound = current_language->string_lower_bound; - int highbound = len / TYPE_LENGTH (char_type); + ssize_t highbound = len / TYPE_LENGTH (char_type); struct type *stringtype = lookup_string_range_type (char_type, lowbound, highbound + lowbound - 1); @@ -1878,19 +1874,6 @@ value_string (char *ptr, int len, struct type *char_type) return val; } -struct value * -value_bitstring (char *ptr, int len, struct type *index_type) -{ - struct value *val; - struct type *domain_type - = create_range_type (NULL, index_type, 0, len - 1); - struct type *type = create_set_type (NULL, domain_type); - - TYPE_CODE (type) = TYPE_CODE_BITSTRING; - val = allocate_value (type); - memcpy (value_contents_raw (val), ptr, TYPE_LENGTH (type)); - return val; -} /* See if we can pass arguments in T2 to a function which takes arguments of types T1. T1 is a list of NARGS arguments, and T2 is @@ -1981,17 +1964,41 @@ typecmp (int staticp, int varargs, int nargs, return i + 1; } -/* Helper function used by value_struct_elt to recurse through - baseclasses. Look for a field NAME in ARG1. Adjust the address of - ARG1 by OFFSET bytes, and search in it assuming it has (class) type - TYPE. If found, return value, else return NULL. +/* Helper class for do_search_struct_field that updates *RESULT_PTR + and *LAST_BOFFSET, and possibly throws an exception if the field + search has yielded ambiguous results. */ - If LOOKING_FOR_BASECLASS, then instead of looking for struct - fields, look for a baseclass named NAME. */ +static void +update_search_result (struct value **result_ptr, struct value *v, + int *last_boffset, int boffset, + const char *name, struct type *type) +{ + if (v != NULL) + { + if (*result_ptr != NULL + /* The result is not ambiguous if all the classes that are + found occupy the same space. */ + && *last_boffset != boffset) + error (_("base class '%s' is ambiguous in type '%s'"), + name, TYPE_SAFE_NAME (type)); + *result_ptr = v; + *last_boffset = boffset; + } +} -static struct value * -search_struct_field (const char *name, struct value *arg1, int offset, - struct type *type, int looking_for_baseclass) +/* A helper for search_struct_field. This does all the work; most + arguments are as passed to search_struct_field. The result is + stored in *RESULT_PTR, which must be initialized to NULL. + OUTERMOST_TYPE is the type of the initial type passed to + search_struct_field; this is used for error reporting when the + lookup is ambiguous. */ + +static void +do_search_struct_field (const char *name, struct value *arg1, int offset, + struct type *type, int looking_for_baseclass, + struct value **result_ptr, + int *last_boffset, + struct type *outermost_type) { int i; int nbases; @@ -2002,7 +2009,7 @@ search_struct_field (const char *name, struct value *arg1, int offset, if (!looking_for_baseclass) for (i = TYPE_NFIELDS (type) - 1; i >= nbases; i--) { - char *t_field_name = TYPE_FIELD_NAME (type, i); + const char *t_field_name = TYPE_FIELD_NAME (type, i); if (t_field_name && (strcmp_iw (t_field_name, name) == 0)) { @@ -2017,12 +2024,9 @@ search_struct_field (const char *name, struct value *arg1, int offset, name); } else - { - v = value_primitive_field (arg1, offset, i, type); - if (v == 0) - error (_("there is no field named %s"), name); - } - return v; + v = value_primitive_field (arg1, offset, i, type); + *result_ptr = v; + return; } if (t_field_name @@ -2047,7 +2051,7 @@ search_struct_field (const char *name, struct value *arg1, int offset, represented as a struct, with a member for each . */ - struct value *v; + struct value *v = NULL; int new_offset = offset; /* This is pretty gross. In G++, the offset in an @@ -2061,18 +2065,23 @@ search_struct_field (const char *name, struct value *arg1, int offset, && TYPE_FIELD_BITPOS (field_type, 0) == 0)) new_offset += TYPE_FIELD_BITPOS (type, i) / 8; - v = search_struct_field (name, arg1, new_offset, - field_type, - looking_for_baseclass); + do_search_struct_field (name, arg1, new_offset, + field_type, + looking_for_baseclass, &v, + last_boffset, + outermost_type); if (v) - return v; + { + *result_ptr = v; + return; + } } } } for (i = 0; i < nbases; i++) { - struct value *v; + struct value *v = NULL; struct type *basetype = check_typedef (TYPE_BASECLASS (type, i)); /* If we are looking for baseclasses, this is what we get when we hit them. But it could happen that the base part's member @@ -2082,10 +2091,10 @@ search_struct_field (const char *name, struct value *arg1, int offset, && (strcmp_iw (name, TYPE_BASECLASS_NAME (type, i)) == 0)); + int boffset = value_embedded_offset (arg1) + offset; if (BASETYPE_VIA_VIRTUAL (type, i)) { - int boffset; struct value *v2; boffset = baseclass_offset (type, i, @@ -2121,22 +2130,51 @@ search_struct_field (const char *name, struct value *arg1, int offset, } if (found_baseclass) - return v2; - v = search_struct_field (name, v2, 0, - TYPE_BASECLASS (type, i), - looking_for_baseclass); + v = v2; + else + { + do_search_struct_field (name, v2, 0, + TYPE_BASECLASS (type, i), + looking_for_baseclass, + result_ptr, last_boffset, + outermost_type); + } } else if (found_baseclass) v = value_primitive_field (arg1, offset, i, type); else - v = search_struct_field (name, arg1, - offset + TYPE_BASECLASS_BITPOS (type, - i) / 8, - basetype, looking_for_baseclass); - if (v) - return v; + { + do_search_struct_field (name, arg1, + offset + TYPE_BASECLASS_BITPOS (type, + i) / 8, + basetype, looking_for_baseclass, + result_ptr, last_boffset, + outermost_type); + } + + update_search_result (result_ptr, v, last_boffset, + boffset, name, outermost_type); } - return NULL; +} + +/* Helper function used by value_struct_elt to recurse through + baseclasses. Look for a field NAME in ARG1. Adjust the address of + ARG1 by OFFSET bytes, and search in it assuming it has (class) type + TYPE. If found, return value, else return NULL. + + If LOOKING_FOR_BASECLASS, then instead of looking for struct + fields, look for a baseclass named NAME. */ + +static struct value * +search_struct_field (const char *name, struct value *arg1, int offset, + struct type *type, int looking_for_baseclass) +{ + struct value *result = NULL; + int boffset = 0; + + do_search_struct_field (name, arg1, offset, type, looking_for_baseclass, + &result, &boffset, type); + return result; } /* Helper function used by value_struct_elt to recurse through @@ -2160,7 +2198,7 @@ search_struct_method (const char *name, struct value **arg1p, CHECK_TYPEDEF (type); for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; i--) { - char *t_field_name = TYPE_FN_FIELDLIST_NAME (type, i); + const char *t_field_name = TYPE_FN_FIELDLIST_NAME (type, i); /* FIXME! May need to check for ARM demangling here. */ if (strncmp (t_field_name, "__", 2) == 0 || @@ -2229,8 +2267,13 @@ search_struct_method (const char *name, struct value **arg1p, if (offset < 0 || offset >= TYPE_LENGTH (type)) { - gdb_byte *tmp = alloca (TYPE_LENGTH (baseclass)); - CORE_ADDR address = value_address (*arg1p); + gdb_byte *tmp; + struct cleanup *back_to; + CORE_ADDR address; + + tmp = xmalloc (TYPE_LENGTH (baseclass)); + back_to = make_cleanup (xfree, tmp); + address = value_address (*arg1p); if (target_read_memory (address + offset, tmp, TYPE_LENGTH (baseclass)) != 0) @@ -2241,6 +2284,7 @@ search_struct_method (const char *name, struct value **arg1p, address + offset); base_valaddr = value_contents_for_printing (base_val); this_offset = 0; + do_cleanups (back_to); } else { @@ -2404,7 +2448,7 @@ find_method_list (struct value **argp, const char *method, for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; i--) { /* pai: FIXME What about operators and type conversions? */ - char *fn_field_name = TYPE_FN_FIELDLIST_NAME (type, i); + const char *fn_field_name = TYPE_FN_FIELDLIST_NAME (type, i); if (fn_field_name && (strcmp_iw (fn_field_name, method) == 0)) { @@ -2458,7 +2502,7 @@ find_method_list (struct value **argp, const char *method, method. BOFFSET is the offset of the base subobject which defines the method. */ -struct fn_field * +static struct fn_field * value_find_oload_method_list (struct value **argp, const char *method, int offset, int *num_fns, struct type **basetype, int *boffset) @@ -2486,7 +2530,7 @@ value_find_oload_method_list (struct value **argp, const char *method, basetype, boffset); } -/* Given an array of argument types (ARGTYPES) (which includes an +/* Given an array of arguments (ARGS) (which includes an entry for "this" in the case of C++ methods), the number of arguments NARGS, the NAME of a function whether it's a method or not (METHOD), and the degree of laxness (LAX) in conforming to @@ -2529,13 +2573,14 @@ value_find_oload_method_list (struct value **argp, const char *method, resolution is permitted. */ int -find_overload_match (struct type **arg_types, int nargs, +find_overload_match (struct value **args, int nargs, const char *name, enum oload_search_type method, int lax, struct value **objp, struct symbol *fsym, struct value **valp, struct symbol **symp, int *staticp, const int no_adl) { struct value *obj = (objp ? *objp : NULL); + struct type *obj_type = obj ? value_type (obj) : NULL; /* Index of best overloaded function. */ int func_oload_champ = -1; int method_oload_champ = -1; @@ -2604,7 +2649,7 @@ find_overload_match (struct type **arg_types, int nargs, if (fns_ptr) { gdb_assert (TYPE_DOMAIN_TYPE (fns_ptr[0].type) != NULL); - method_oload_champ = find_oload_champ (arg_types, nargs, method, + method_oload_champ = find_oload_champ (args, nargs, method, num_fns, fns_ptr, oload_syms, &method_badness); @@ -2626,7 +2671,7 @@ find_overload_match (struct type **arg_types, int nargs, and non member function, the first argument must now be dereferenced. */ if (method == BOTH) - arg_types[0] = TYPE_TARGET_TYPE (arg_types[0]); + args[0] = value_ind (args[0]); if (fsym) { @@ -2672,7 +2717,7 @@ find_overload_match (struct type **arg_types, int nargs, return 0; } - func_oload_champ = find_oload_champ_namespace (arg_types, nargs, + func_oload_champ = find_oload_champ_namespace (args, nargs, func_name, qualified_name, &oload_syms, @@ -2776,11 +2821,11 @@ find_overload_match (struct type **arg_types, int nargs, if (objp) { struct type *temp_type = check_typedef (value_type (temp)); - struct type *obj_type = check_typedef (value_type (*objp)); + struct type *objtype = check_typedef (obj_type); if (TYPE_CODE (temp_type) != TYPE_CODE_PTR - && (TYPE_CODE (obj_type) == TYPE_CODE_PTR - || TYPE_CODE (obj_type) == TYPE_CODE_REF)) + && (TYPE_CODE (objtype) == TYPE_CODE_PTR + || TYPE_CODE (objtype) == TYPE_CODE_REF)) { temp = value_addr (temp); } @@ -2809,7 +2854,7 @@ find_overload_match (struct type **arg_types, int nargs, performned. */ static int -find_oload_champ_namespace (struct type **arg_types, int nargs, +find_oload_champ_namespace (struct value **args, int nargs, const char *func_name, const char *qualified_name, struct symbol ***oload_syms, @@ -2818,7 +2863,7 @@ find_oload_champ_namespace (struct type **arg_types, int nargs, { int oload_champ; - find_oload_champ_namespace_loop (arg_types, nargs, + find_oload_champ_namespace_loop (args, nargs, func_name, qualified_name, 0, oload_syms, oload_champ_bv, @@ -2838,7 +2883,7 @@ find_oload_champ_namespace (struct type **arg_types, int nargs, *OLOAD_CHAMP_BV. */ static int -find_oload_champ_namespace_loop (struct type **arg_types, int nargs, +find_oload_champ_namespace_loop (struct value **args, int nargs, const char *func_name, const char *qualified_name, int namespace_len, @@ -2875,7 +2920,7 @@ find_oload_champ_namespace_loop (struct type **arg_types, int nargs, { searched_deeper = 1; - if (find_oload_champ_namespace_loop (arg_types, nargs, + if (find_oload_champ_namespace_loop (args, nargs, func_name, qualified_name, next_namespace_len, oload_syms, oload_champ_bv, @@ -2904,12 +2949,22 @@ find_oload_champ_namespace_loop (struct type **arg_types, int nargs, /* If we have reached the deepest level perform argument determined lookup. */ if (!searched_deeper && !no_adl) - make_symbol_overload_list_adl (arg_types, nargs, func_name); + { + int ix; + struct type **arg_types; + + /* Prepare list of argument types for overload resolution. */ + arg_types = (struct type **) + alloca (nargs * (sizeof (struct type *))); + for (ix = 0; ix < nargs; ix++) + arg_types[ix] = value_type (args[ix]); + make_symbol_overload_list_adl (arg_types, nargs, func_name); + } while (new_oload_syms[num_fns]) ++num_fns; - new_oload_champ = find_oload_champ (arg_types, nargs, 0, num_fns, + new_oload_champ = find_oload_champ (args, nargs, 0, num_fns, NULL, new_oload_syms, &new_oload_champ_bv); @@ -2946,7 +3001,7 @@ find_oload_champ_namespace_loop (struct type **arg_types, int nargs, } } -/* Look for a function to take NARGS args of types ARG_TYPES. Find +/* Look for a function to take NARGS args of ARGS. 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. @@ -2956,7 +3011,7 @@ find_oload_champ_namespace_loop (struct type **arg_types, int nargs, It is the caller's responsibility to free *OLOAD_CHAMP_BV. */ static int -find_oload_champ (struct type **arg_types, int nargs, int method, +find_oload_champ (struct value **args, int nargs, int method, int num_fns, struct fn_field *fns_ptr, struct symbol **oload_syms, struct badness_vector **oload_champ_bv) @@ -3002,7 +3057,7 @@ find_oload_champ (struct type **arg_types, int nargs, int method, /* Compare parameter types to supplied argument types. Skip THIS for static methods. */ bv = rank_function (parm_types, nparms, - arg_types + static_offset, + args + static_offset, nargs - static_offset); if (!*oload_champ_bv) @@ -3076,6 +3131,7 @@ classify_oload_match (struct badness_vector *oload_champ_bv, int static_offset) { int ix; + enum oload_classification worst = STANDARD; for (ix = 1; ix <= nargs - static_offset; ix++) { @@ -3088,11 +3144,13 @@ classify_oload_match (struct badness_vector *oload_champ_bv, NS_POINTER_CONVERSION_BADNESS or worse return NON_STANDARD. */ else if (compare_ranks (oload_champ_bv->rank[ix], NS_POINTER_CONVERSION_BADNESS) <= 0) - return NON_STANDARD; /* Non-standard type conversions + worst = NON_STANDARD; /* Non-standard type conversions needed. */ } - return STANDARD; /* Only standard conversions needed. */ + /* If no INCOMPATIBLE classification was found, return the worst one + that was found (if any). */ + return worst; } /* C++: return 1 is NAME is a legitimate name for the destructor of @@ -3136,7 +3194,7 @@ check_field (struct type *type, const char *name) for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--) { - char *t_field_name = TYPE_FIELD_NAME (type, i); + const char *t_field_name = TYPE_FIELD_NAME (type, i); if (t_field_name && (strcmp_iw (t_field_name, name) == 0)) return 1; @@ -3226,7 +3284,7 @@ compare_parameters (struct type *t1, struct type *t2, int skip_artificial) for (i = 0; i < TYPE_NFIELDS (t2); ++i) { if (compare_ranks (rank_one_type (TYPE_FIELD_TYPE (t1, start + i), - TYPE_FIELD_TYPE (t2, i)), + TYPE_FIELD_TYPE (t2, i), NULL), EXACT_MATCH_BADNESS) != 0) return 0; } @@ -3262,7 +3320,7 @@ value_struct_elt_for_reference (struct type *domain, int offset, for (i = TYPE_NFIELDS (t) - 1; i >= TYPE_N_BASECLASSES (t); i--) { - char *t_field_name = TYPE_FIELD_NAME (t, i); + const char *t_field_name = TYPE_FIELD_NAME (t, i); if (t_field_name && strcmp (t_field_name, name) == 0) { @@ -3299,7 +3357,7 @@ value_struct_elt_for_reference (struct type *domain, int offset, for (i = TYPE_NFN_FIELDS (t) - 1; i >= 0; --i) { - char *t_field_name = TYPE_FN_FIELDLIST_NAME (t, i); + const char *t_field_name = TYPE_FN_FIELDLIST_NAME (t, i); char dem_opname[64]; if (strncmp (t_field_name, "__", 2) == 0 @@ -3508,21 +3566,48 @@ value_maybe_namespace_elt (const struct type *curtype, return result; } -/* Given a pointer value V, find the real (RTTI) type of the object it - points to. +/* Given a pointer or a reference value V, find its real (RTTI) type. Other parameters FULL, TOP, USING_ENC as with value_rtti_type() and refer to the values computed for the object pointed to. */ struct type * -value_rtti_target_type (struct value *v, int *full, - int *top, int *using_enc) +value_rtti_indirect_type (struct value *v, int *full, + int *top, int *using_enc) { struct value *target; + struct type *type, *real_type, *target_type; - target = value_ind (v); + type = value_type (v); + type = check_typedef (type); + if (TYPE_CODE (type) == TYPE_CODE_REF) + target = coerce_ref (v); + else if (TYPE_CODE (type) == TYPE_CODE_PTR) + target = value_ind (v); + else + return NULL; - return value_rtti_type (target, full, top, using_enc); + real_type = value_rtti_type (target, full, top, using_enc); + + if (real_type) + { + /* Copy qualifiers to the referenced object. */ + target_type = value_type (target); + real_type = make_cv_type (TYPE_CONST (target_type), + TYPE_VOLATILE (target_type), real_type, NULL); + if (TYPE_CODE (type) == TYPE_CODE_REF) + real_type = lookup_reference_type (real_type); + else if (TYPE_CODE (type) == TYPE_CODE_PTR) + real_type = lookup_pointer_type (real_type); + else + internal_error (__FILE__, __LINE__, _("Unexpected value type.")); + + /* Copy qualifiers to the pointer/reference. */ + real_type = make_cv_type (TYPE_CONST (type), TYPE_VOLATILE (type), + real_type, NULL); + } + + return real_type; } /* Given a value pointed to by ARGP, check its real run-time type, and @@ -3561,6 +3646,13 @@ value_full_object (struct value *argp, if (!real_type || real_type == value_enclosing_type (argp)) return argp; + /* In a destructor we might see a real type that is a superclass of + the object's type. In this case it is better to leave the object + as-is. */ + if (full + && TYPE_LENGTH (real_type) < TYPE_LENGTH (value_enclosing_type (argp))) + return argp; + /* If we have the full object, but for some reason the enclosing type is wrong, set it. */ /* pai: FIXME -- sounds iffy */ @@ -3651,8 +3743,7 @@ value_slice (struct value *array, int lowbound, int length) 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) + && TYPE_CODE (array_type) != TYPE_CODE_STRING) error (_("cannot take slice of non-array")); range_type = TYPE_INDEX_TYPE (array_type); @@ -3669,38 +3760,7 @@ value_slice (struct value *array, int lowbound, int length) TYPE_TARGET_TYPE (range_type), lowbound, lowbound + length - 1); - if (TYPE_CODE (array_type) == TYPE_CODE_BITSTRING) - { - int i; - - slice_type = create_set_type ((struct type *) NULL, - slice_range_type); - TYPE_CODE (slice_type) = TYPE_CODE_BITSTRING; - slice = value_zero (slice_type, not_lval); - for (i = 0; i < length; i++) - { - int element = value_bit_index (array_type, - value_contents (array), - lowbound + i); - - if (element < 0) - error (_("internal error accessing bitstring")); - else if (element > 0) - { - int j = i % TARGET_CHAR_BIT; - - if (gdbarch_bits_big_endian (get_type_arch (array_type))) - j = 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 - slice can be used on the LHS, but that may require extensions - to value_assign. For now, just leave as a non_lval. - FIXME. */ - } - else { struct type *element_type = TYPE_TARGET_TYPE (array_type); LONGEST offset =