X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fvalops.c;h=29d1fbdd8be182251b9e9a430eb745fc79c494d8;hb=a7860e76c92d8aea95640ce1a75822efeaed4f32;hp=5465abaac90cb669e26909fc5e48c2ac3b3a3ef0;hpb=8af8e3bc815c464731924d121681ac73cae1ab1d;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/valops.c b/gdb/valops.c index 5465abaac9..29d1fbdd8b 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -61,20 +61,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 **); @@ -860,14 +860,14 @@ value_zero (struct type *type, enum lval_type lv) { struct value *val = allocate_value (type); - VALUE_LVAL (val) = lv; + VALUE_LVAL (val) = (lv == lval_computed ? not_lval : lv); return val; } -/* Create a value of numeric type TYPE that is one, and return it. */ +/* Create a not_lval value of numeric type TYPE that is one, and return it. */ struct value * -value_one (struct type *type, enum lval_type lv) +value_one (struct type *type) { struct type *type1 = check_typedef (type); struct value *val; @@ -901,7 +901,7 @@ value_one (struct type *type, enum lval_type lv) val = allocate_value (type); for (i = 0; i < high_bound - low_bound + 1; i++) { - tmp = value_one (eltype, lv); + tmp = value_one (eltype); memcpy (value_contents_writeable (val) + i * TYPE_LENGTH (eltype), value_contents_all (tmp), TYPE_LENGTH (eltype)); } @@ -911,7 +911,9 @@ value_one (struct type *type, enum lval_type lv) error (_("Not a numeric type.")); } - VALUE_LVAL (val) = lv; + /* value_one result is never used for assignments to. */ + gdb_assert (VALUE_LVAL (val) == not_lval); + return val; } @@ -1108,7 +1110,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. */; @@ -1343,8 +1346,16 @@ value_assign (struct value *toval, struct value *fromval) "don't fit in a %d bit word."), (int) sizeof (LONGEST) * HOST_CHAR_BIT); - get_frame_register_bytes (frame, value_reg, offset, - changed_len, buffer); + if (!get_frame_register_bytes (frame, value_reg, offset, + changed_len, buffer, + &optim, &unavail)) + { + if (optim) + error (_("value has been optimized out")); + if (unavail) + throw_error (NOT_AVAILABLE_ERROR, + _("value is not available")); + } modify_field (type, buffer, value_as_long (fromval), value_bitpos (toval), value_bitsize (toval)); @@ -1369,11 +1380,15 @@ value_assign (struct value *toval, struct value *fromval) case lval_computed: { - struct lval_funcs *funcs = value_computed_funcs (toval); + 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.")); @@ -1476,9 +1491,8 @@ 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 value *val; struct frame_info *frame; if (!symbol_read_needs_frame (var)) @@ -1499,11 +1513,7 @@ value_of_variable (struct symbol *var, struct block *b) } } - val = read_var_value (var, frame); - if (!val) - error (_("Address of symbol \"%s\" is unknown."), SYMBOL_PRINT_NAME (var)); - - return val; + return read_var_value (var, frame); } struct value * @@ -1732,7 +1742,7 @@ value_ind (struct value *arg1) if (VALUE_LVAL (arg1) == lval_computed) { - struct lval_funcs *funcs = value_computed_funcs (arg1); + const struct lval_funcs *funcs = value_computed_funcs (arg1); if (funcs->indirect) { @@ -2481,7 +2491,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 @@ -2524,13 +2534,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; @@ -2577,6 +2588,7 @@ find_overload_match (struct type **arg_types, int nargs, if (*valp) { *staticp = 1; + do_cleanups (all_cleanups); return 0; } } @@ -2598,7 +2610,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); @@ -2616,11 +2628,12 @@ find_overload_match (struct type **arg_types, int nargs, { const char *qualified_name = NULL; - /* If the the overload match is being search for both - as a method and non member function, the first argument - must now be dereferenced. */ + /* If the overload match is being search for both as a method + and non member function, the first argument must now be + dereferenced. */ if (method == BOTH) - arg_types[0] = TYPE_TARGET_TYPE (arg_types[0]); + deprecated_set_value_type (args[0], + TYPE_TARGET_TYPE (value_type (args[0]))); if (fsym) { @@ -2662,10 +2675,11 @@ find_overload_match (struct type **arg_types, int nargs, if (func_name == NULL) { *symp = fsym; + do_cleanups (all_cleanups); 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, @@ -2693,9 +2707,9 @@ find_overload_match (struct type **arg_types, int nargs, switch (compare_badness (func_badness, method_badness)) { case 0: /* Top two contenders are equally good. */ - /* FIXME: GDB does not support the general ambiguous - case. All candidates should be collected and presented - the the user. */ + /* FIXME: GDB does not support the general ambiguous case. + All candidates should be collected and presented the + user. */ error (_("Ambiguous overload resolution")); break; case 1: /* Incomparable top contenders. */ @@ -2769,11 +2783,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); } @@ -2802,7 +2816,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, @@ -2811,7 +2825,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, @@ -2831,7 +2845,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, @@ -2868,7 +2882,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, @@ -2897,12 +2911,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); @@ -2939,7 +2963,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. @@ -2949,7 +2973,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) @@ -2995,7 +3019,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) @@ -3069,6 +3093,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++) { @@ -3081,23 +3106,27 @@ 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 type TYPE. If TYPE does not have a destructor, or if NAME is - inappropriate for TYPE, an error is signaled. */ + inappropriate for TYPE, an error is signaled. Parameter TYPE should not yet + have CHECK_TYPEDEF applied, this function will apply it itself. */ + int -destructor_name_p (const char *name, const struct type *type) +destructor_name_p (const char *name, struct type *type) { if (name[0] == '~') { - char *dname = type_name_no_tag (type); - char *cp = strchr (dname, '<'); + const char *dname = type_name_no_tag_or_error (type); + const char *cp = strchr (dname, '<'); unsigned int len; /* Do not compare the template part for template classes. */ @@ -3177,7 +3206,7 @@ value_aggregate_elt (struct type *curtype, char *name, } /* Compares the two method/function types T1 and T2 for "equality" - with respect to the the methods' parameters. If the types of the + with respect to the methods' parameters. If the types of the two parameter lists are the same, returns 1; 0 otherwise. This comparison may ignore any artificial parameters in T1 if SKIP_ARTIFICIAL is non-zero. This function will ALWAYS skip @@ -3217,7 +3246,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; } @@ -3331,25 +3360,32 @@ value_struct_elt_for_reference (struct type *domain, int offset, int ii; j = -1; - for (ii = 0; ii < TYPE_FN_FIELDLIST_LENGTH (t, i); - ++ii) + for (ii = 0; ii < len; ++ii) { /* Skip artificial methods. This is necessary if, for example, the user wants to "print subclass::subclass" with only one user-defined - constructor. There is no ambiguity in this - case. */ + constructor. There is no ambiguity in this case. + We are careful here to allow artificial methods + if they are the unique result. */ if (TYPE_FN_FIELD_ARTIFICIAL (f, ii)) - continue; + { + if (j == -1) + j = ii; + continue; + } /* Desired method is ambiguous if more than one method is defined. */ - if (j != -1) + if (j != -1 && !TYPE_FN_FIELD_ARTIFICIAL (f, j)) error (_("non-unique member `%s' requires " "type instantiation"), name); j = ii; } + + if (j == -1) + error (_("no matching member function")); } if (TYPE_FN_FIELD_STATIC_P (f, j)) @@ -3545,6 +3581,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 */ @@ -3579,73 +3622,46 @@ value_full_object (struct value *argp, } -/* Return the value of the local variable, if one exists. - Flag COMPLAIN signals an error if the request is made in an - inappropriate context. */ +/* Return the value of the local variable, if one exists. Throw error + otherwise, such as if the request is made in an inappropriate context. */ struct value * -value_of_local (const char *name, int complain) +value_of_this (const struct language_defn *lang) { - struct symbol *func, *sym; + struct symbol *sym; struct block *b; - struct value * ret; struct frame_info *frame; - if (complain) - frame = get_selected_frame (_("no frame selected")); - else - { - frame = deprecated_safe_get_selected_frame (); - if (frame == 0) - return 0; - } + if (!lang->la_name_of_this) + error (_("no `this' in current language")); - func = get_frame_function (frame); - if (!func) - { - if (complain) - error (_("no `%s' in nameless context"), name); - else - return 0; - } + frame = get_selected_frame (_("no frame selected")); - b = SYMBOL_BLOCK_VALUE (func); - if (dict_empty (BLOCK_DICT (b))) - { - if (complain) - error (_("no args, no `%s'"), name); - else - return 0; - } + b = get_frame_block (frame, NULL); - /* 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, VAR_DOMAIN); + sym = lookup_language_this (lang, b); if (sym == NULL) - { - if (complain) - error (_("current stack frame does not contain a variable named `%s'"), - name); - else - return NULL; - } + error (_("current stack frame does not contain a variable named `%s'"), + lang->la_name_of_this); - ret = read_var_value (sym, frame); - if (ret == 0 && complain) - error (_("`%s' argument unreadable"), name); - return ret; + return read_var_value (sym, frame); } -/* C++/Objective-C: return the value of the class instance variable, - if one exists. Flag COMPLAIN signals an error if the request is - made in an inappropriate context. */ +/* Return the value of the local variable, if one exists. Return NULL + otherwise. Never throw error. */ struct value * -value_of_this (int complain) +value_of_this_silent (const struct language_defn *lang) { - if (!current_language->la_name_of_this) - return 0; - return value_of_local (current_language->la_name_of_this, complain); + struct value *ret = NULL; + volatile struct gdb_exception except; + + TRY_CATCH (except, RETURN_MASK_ERROR) + { + ret = value_of_this (lang); + } + + return ret; } /* Create a slice (sub-string, sub-array) of ARRAY, that is LENGTH