X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fvalops.c;h=4758b5cdfc6ab0c6cfe8c6ea59074fc400456287;hb=e71585ffe2e1394858f0fcf809e86f1b324fe4e6;hp=bf028fd7a3e38d39ca7805be2ca0f6bf645b8d5b;hpb=7c22600aabfd10e190e98fff0b7c2d69cd191325;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/valops.c b/gdb/valops.c index bf028fd7a3..4758b5cdfc 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -36,7 +36,7 @@ #include "cp-support.h" #include "target-float.h" #include "tracepoint.h" -#include "observer.h" +#include "observable.h" #include "objfiles.h" #include "extension.h" #include "byte-vector.h" @@ -102,13 +102,6 @@ static void find_method_list (struct value **, const char *, std::vector *, struct type **, LONGEST *); -#if 0 -/* Flag for whether we want to abandon failed expression evals by - default. */ - -static int auto_abandon = 0; -#endif - int overload_resolution = 0; static void show_overload_resolution (struct ui_file *file, int from_tty, @@ -191,7 +184,7 @@ value_allocate_space_in_inferior (int len) struct value *blocklen; blocklen = value_from_longest (builtin_type (gdbarch)->builtin_int, len); - val = call_function_by_hand (val, NULL, 1, &blocklen); + val = call_function_by_hand (val, NULL, blocklen); if (value_logical_not (val)) { if (!target_has_execution) @@ -244,7 +237,7 @@ value_cast_structs (struct type *type, struct value *v2) offset the pointer rather than just change its type. */ if (TYPE_NAME (t1) != NULL) { - v = search_struct_field (type_name_no_tag (t1), + v = search_struct_field (TYPE_NAME (t1), v2, t2, 1); if (v) return v; @@ -273,7 +266,7 @@ value_cast_structs (struct type *type, struct value *v2) && !strcmp (TYPE_NAME (real_type), TYPE_NAME (t1))) return v; - v = search_struct_field (type_name_no_tag (t2), v, real_type, 1); + v = search_struct_field (TYPE_NAME (t2), v, real_type, 1); if (v) return v; } @@ -281,7 +274,7 @@ value_cast_structs (struct type *type, struct value *v2) /* Try downcasting using information from the destination type T2. This wouldn't work properly for classes with virtual bases, but those were handled above. */ - v = search_struct_field (type_name_no_tag (t2), + v = search_struct_field (TYPE_NAME (t2), value_zero (t1, not_lval), t1, 1); if (v) { @@ -964,7 +957,7 @@ read_value_memory (struct value *val, LONGEST bit_offset, enum target_xfer_status status; ULONGEST xfered_partial; - status = target_xfer_partial (current_target.beneath, + status = target_xfer_partial (current_top_target (), object, NULL, buffer + xfered_total * unit_size, NULL, memaddr + xfered_total, @@ -1177,7 +1170,7 @@ value_assign (struct value *toval, struct value *fromval) } } - observer_notify_register_changed (frame, value_reg); + gdb::observers::register_changed.notify (frame, value_reg); break; } @@ -1208,7 +1201,7 @@ value_assign (struct value *toval, struct value *fromval) case lval_register: case lval_computed: - observer_notify_target_changed (¤t_target); + gdb::observers::target_changed.notify (current_top_target ()); /* Having destroyed the frame cache, restore the selected frame. */ @@ -1588,7 +1581,6 @@ value_ind (struct value *arg1) } error (_("Attempt to take contents of a non-pointer value.")); - return 0; /* For lint -- never reached. */ } /* Create a value for an array by allocating space in GDB, copying the @@ -2683,20 +2675,20 @@ find_overload_match (struct value **args, int nargs, && TYPE_CODE (check_typedef (SYMBOL_TYPE (fsym))) == TYPE_CODE_FUNC) { - char *temp; + char *temp_func; - temp = cp_func_name (qualified_name); + temp_func = cp_func_name (qualified_name); /* If cp_func_name did not remove anything, the name of the symbol did not include scope or argument types - it was probably a C-style function. */ - if (temp) + if (temp_func) { - make_cleanup (xfree, temp); - if (strcmp (temp, qualified_name) == 0) + make_cleanup (xfree, temp_func); + if (strcmp (temp_func, qualified_name) == 0) func_name = NULL; else - func_name = temp; + func_name = temp_func; } } } @@ -3193,7 +3185,7 @@ destructor_name_p (const char *name, struct type *type) { if (name[0] == '~') { - const char *dname = type_name_no_tag_or_error (type); + const char *dname = type_name_or_error (type); const char *cp = strchr (dname, '<'); unsigned int len; @@ -3243,7 +3235,7 @@ enum_constant_from_type (struct type *type, const char *name) } error (_("no constant named \"%s\" in enum \"%s\""), - name, TYPE_TAG_NAME (type)); + name, TYPE_NAME (type)); } /* C++: Given an aggregate type CURTYPE, and a member name NAME, @@ -3329,6 +3321,49 @@ compare_parameters (struct type *t1, struct type *t2, int skip_artificial) return 0; } +/* C++: Given an aggregate type VT, and a class type CLS, search + recursively for CLS using value V; If found, store the offset + which is either fetched from the virtual base pointer if CLS + is virtual or accumulated offset of its parent classes if + CLS is non-virtual in *BOFFS, set ISVIRT to indicate if CLS + is virtual, and return true. If not found, return false. */ + +static bool +get_baseclass_offset (struct type *vt, struct type *cls, + struct value *v, int *boffs, bool *isvirt) +{ + for (int i = 0; i < TYPE_N_BASECLASSES (vt); i++) + { + struct type *t = TYPE_FIELD_TYPE (vt, i); + if (types_equal (t, cls)) + { + if (BASETYPE_VIA_VIRTUAL (vt, i)) + { + const gdb_byte *adr = value_contents_for_printing (v); + *boffs = baseclass_offset (vt, i, adr, value_offset (v), + value_as_long (v), v); + *isvirt = true; + } + else + *isvirt = false; + return true; + } + + if (get_baseclass_offset (check_typedef (t), cls, v, boffs, isvirt)) + { + if (*isvirt == false) /* Add non-virtual base offset. */ + { + const gdb_byte *adr = value_contents_for_printing (v); + *boffs += baseclass_offset (vt, i, adr, value_offset (v), + value_as_long (v), v); + } + return true; + } + } + + return false; +} + /* C++: Given an aggregate type CURTYPE, and a member name NAME, return the address of this member as a "pointer to member" type. If INTYPE is non-null, then it will be the type of the member we @@ -3343,9 +3378,9 @@ value_struct_elt_for_reference (struct type *domain, int offset, int want_address, enum noside noside) { - struct type *t = curtype; + struct type *t = check_typedef (curtype); int i; - struct value *v, *result; + struct value *result; if (TYPE_CODE (t) != TYPE_CODE_STRUCT && TYPE_CODE (t) != TYPE_CODE_UNION) @@ -3360,7 +3395,7 @@ value_struct_elt_for_reference (struct type *domain, int offset, { if (field_is_static (&TYPE_FIELD (t, i))) { - v = value_static_field (t, i); + struct value *v = value_static_field (t, i); if (want_address) v = value_addr (v); return v; @@ -3379,10 +3414,10 @@ value_struct_elt_for_reference (struct type *domain, int offset, /* Try to evaluate NAME as a qualified name with implicit this pointer. In this case, attempt to return the equivalent to `this->*(&TYPE::NAME)'. */ - v = value_of_this_silent (current_language); + struct value *v = value_of_this_silent (current_language); if (v != NULL) { - struct value *ptr; + struct value *ptr, *this_v = v; long mem_offset; struct type *type, *tmp; @@ -3393,6 +3428,24 @@ value_struct_elt_for_reference (struct type *domain, int offset, tmp = lookup_pointer_type (TYPE_SELF_TYPE (type)); v = value_cast_pointers (tmp, v, 1); mem_offset = value_as_long (ptr); + if (domain != curtype) + { + /* Find class offset of type CURTYPE from either its + parent type DOMAIN or the type of implied this. */ + int boff = 0; + bool isvirt = false; + if (get_baseclass_offset (domain, curtype, v, &boff, + &isvirt)) + mem_offset += boff; + else + { + struct type *p = check_typedef (value_type (this_v)); + p = check_typedef (TYPE_TARGET_TYPE (p)); + if (get_baseclass_offset (p, curtype, this_v, + &boff, &isvirt)) + mem_offset += boff; + } + } tmp = lookup_pointer_type (TYPE_TARGET_TYPE (type)); result = value_from_pointer (tmp, value_as_long (v) + mem_offset); @@ -3527,7 +3580,7 @@ value_struct_elt_for_reference (struct type *domain, int offset, if (s == NULL) return NULL; - v = read_var_value (s, 0, 0); + struct value *v = read_var_value (s, 0, 0); if (!want_address) result = v; else @@ -3581,7 +3634,7 @@ value_namespace_elt (const struct type *curtype, if (retval == NULL) error (_("No symbol \"%s\" in namespace \"%s\"."), - name, TYPE_TAG_NAME (curtype)); + name, TYPE_NAME (curtype)); return retval; } @@ -3597,7 +3650,7 @@ value_maybe_namespace_elt (const struct type *curtype, const char *name, int want_address, enum noside noside) { - const char *namespace_name = TYPE_TAG_NAME (curtype); + const char *namespace_name = TYPE_NAME (curtype); struct block_symbol sym; struct value *result;