From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11138 invoked by alias); 24 Dec 2011 13:21:22 -0000 Received: (qmail 11125 invoked by uid 22791); 24 Dec 2011 13:21:18 -0000 X-SWARE-Spam-Status: No, hits=0.0 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,RCVD_IN_SORBS_WEB X-Spam-Check-By: sourceware.org Received: from forward15.mail.yandex.net (HELO forward15.mail.yandex.net) (95.108.130.119) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 24 Dec 2011 13:20:59 +0000 Received: from smtp13.mail.yandex.net (smtp13.mail.yandex.net [95.108.130.68]) by forward15.mail.yandex.net (Yandex) with ESMTP id 5CABA9E2326; Sat, 24 Dec 2011 17:20:56 +0400 (MSK) Received: from smtp13.mail.yandex.net (localhost [127.0.0.1]) by smtp13.mail.yandex.net (Yandex) with ESMTP id 29C9AE40447; Sat, 24 Dec 2011 17:20:56 +0400 (MSK) Received: from kts.bestnet.kharkov.ua (kts.bestnet.kharkov.ua [80.92.226.138]) by smtp13.mail.yandex.net (nwsmtp/Yandex) with ESMTP id Kt2iRt8t-Kt28LNwV; Sat, 24 Dec 2011 17:20:55 +0400 X-Yandex-Spam: 1 Message-ID: <4EF5D1C5.5010902@yandex.ru> Date: Sat, 24 Dec 2011 13:56:00 -0000 From: xgsa User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.23) Gecko/20110921 Thunderbird/3.1.15 MIME-Version: 1.0 To: Jan Kratochvil CC: Tom Tromey , gdb-patches@sourceware.org Subject: Re: set print object on should affect MI varobjs (PR mi/13393) References: <4ED92C05.9080803@yandex.ru> <4EF22A4D.80703@yandex.ru> <20111221193630.GA28985@host2.jankratochvil.net> <4EF30389.5010008@yandex.ru> <20111223200951.GA19581@host2.jankratochvil.net> In-Reply-To: <20111223200951.GA19581@host2.jankratochvil.net> Content-Type: multipart/mixed; boundary="------------000605040206050807070102" X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-12/txt/msg00819.txt.bz2 This is a multi-part message in MIME format. --------------000605040206050807070102 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 2133 I have used 4 spaces for tabs in ChangeLog, sorry. Fixed. Thanks, Anton gdb/ChangeLog: 2011-12-02 Anton Gorenkov PR mi/13393 * gdb/valops.c (value_rtti_target_type): Replaced with value_rtti_indirect_type. (value_rtti_indirect_type): New function. The same as value_rtti_target_type, but return a reference or pointer type (because every caller do it after call that leads to code duplication). * gdb/c-valprint.c (c_value_print): Use value_rtti_indirect_type instead of value_rtti_target_type. * gdb/eval.c (evaluate_subexp_standard): Use value_rtti_indirect_type instead of value_rtti_target_type. * gdb/typeprint.c: Use value_rtti_indirect_type instead of value_rtti_target_type. * gdb/value.c (value_actual_type): New function. (value_rtti_indirect_type): New function. (coerce_ref): Support for enclosing type setting for references with readjust_value_type. * gdb/value.h (value_actual_type): Add prototype. (readjust_value_type): Add prototype. * gdb/valops.c (value_ind): Extract value type and enclosing type setting to a separate function readjust_value_type. * gdb/varobj.c (varobj_create): Call value_actual_type if necessary. (create_child_with_value): Call value_actual_type. (value_of_root): Support for type change if the value changed and RTTI is used to determine type. (adjust_value_for_child_access): Extended with a new parameter and cast given value to enclosing type is necessary. (c_number_of_children): Updated for extended adjust_value_for_child_access. (cplus_number_of_children): Send a value as parameter if RTTI should be used to determine type. (cplus_describe_child): Determine whether RTTI type should be used. gdb/testsuite/ChangeLog: 2011-12-02 Anton Gorenkov PR mi/13393 * gdb.mi/mi-var-rtti.cc: New file. * gdb.mi/mi-var-rtti.exp: New file. --------------000605040206050807070102 Content-Type: text/x-diff; name="gdb_mi4.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="gdb_mi4.patch" Content-length: 26366 diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c index 3461b08..d81d07d 100644 --- a/gdb/c-valprint.c +++ b/gdb/c-valprint.c @@ -698,22 +698,12 @@ c_value_print (struct value *val, struct ui_file *stream, if (value_entirely_available (val)) { - real_type = value_rtti_target_type (val, &full, &top, &using_enc); + real_type = value_rtti_indirect_type (val, &full, &top, &using_enc); if (real_type) { /* RTTI entry found. */ - if (TYPE_CODE (type) == TYPE_CODE_PTR) - { - /* Create a pointer type pointing to the real - type. */ - type = lookup_pointer_type (real_type); - } - else - { - /* Create a reference type referencing the real - type. */ - type = lookup_reference_type (real_type); - } + type = real_type; + /* Need to adjust pointer value. */ val = value_from_pointer (type, value_as_address (val) - top); diff --git a/gdb/eval.c b/gdb/eval.c index 5d758d1..3d23d0f 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -1990,16 +1990,9 @@ evaluate_subexp_standard (struct type *expect_type, if (opts.objectprint && TYPE_TARGET_TYPE(type) && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CLASS)) { - real_type = value_rtti_target_type (arg1, &full, &top, &using_enc); + real_type = value_rtti_indirect_type (arg1, &full, &top, &using_enc); if (real_type) - { - if (TYPE_CODE (type) == TYPE_CODE_PTR) - real_type = lookup_pointer_type (real_type); - else - real_type = lookup_reference_type (real_type); - arg1 = value_cast (real_type, arg1); - } } } diff --git a/gdb/testsuite/gdb.mi/mi-var-rtti.cc b/gdb/testsuite/gdb.mi/mi-var-rtti.cc new file mode 100644 index 0000000..3622f3b --- /dev/null +++ b/gdb/testsuite/gdb.mi/mi-var-rtti.cc @@ -0,0 +1,184 @@ +/* Copyright 2011 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +struct Base { + Base() : A(1) {} + virtual ~Base() {} // Enforce type to have vtable + int A; +}; + +struct Derived : public Base { + Derived() : B(2), C(3) {} + int B; + int C; +}; + + +void use_rtti_for_ptr_test () +{ + /*: BEGIN: use_rtti_for_ptr :*/ + Derived d; + Base* ptr = &d; + const Base* constPtr = &d; + Base* const ptrConst = &d; + Base const* const constPtrConst = &d; + /*: + mi_var_rtti__set_print_object off + mi_var_rtti__check_derived_class_without_rtti ptr {Base \*} + mi_var_rtti__check_derived_class_without_rtti constPtr {const Base \*} + mi_var_rtti__check_derived_class_without_rtti ptrConst {Base \* const} + mi_var_rtti__check_derived_class_without_rtti constPtrConst {const Base \* const} + + mi_var_rtti__set_print_object on + mi_var_rtti__check_derived_class_with_rtti ptr {Derived \*} + mi_var_rtti__check_derived_class_with_rtti constPtr {const Derived \*} + mi_var_rtti__check_derived_class_with_rtti ptrConst {Derived \* const} + mi_var_rtti__check_derived_class_with_rtti constPtrConst {const Derived \* const} + :*/ + return; + /*: END: use_rtti_for_ptr :*/ +} + + +void use_rtti_for_ref_test () +{ + /*: BEGIN: use_rtti_for_ref :*/ + Derived d; + Base& ref = d; + const Base& constRef = d; + /*: + mi_var_rtti__set_print_object off + mi_var_rtti__check_derived_class_without_rtti ref {Base \&} + mi_var_rtti__check_derived_class_without_rtti constRef {const Base \&} + + mi_var_rtti__set_print_object on + mi_var_rtti__check_derived_class_with_rtti ref {Derived \&} + mi_var_rtti__check_derived_class_with_rtti constRef {const Derived \&} + :*/ + return; + /*: END: use_rtti_for_ref :*/ +} + + +void use_rtti_for_ptr_child_test () +{ + /*: BEGIN: use_rtti_for_ptr_child :*/ + Derived d; + struct S { + Base* ptr; + const Base* constPtr; + Base* const ptrConst; + Base const* const constPtrConst; + S ( Base* v ) : + ptr ( v ), + constPtr ( v ), + ptrConst ( v ), + constPtrConst ( v ) {} + } s ( &d ); + /*: + mi_var_rtti__set_print_object off + mi_var_rtti__check_derived_class_without_rtti s.ptr {Base \*} + mi_var_rtti__check_derived_class_without_rtti s.constPtr {const Base \*} + mi_var_rtti__check_derived_class_without_rtti s.ptrConst {Base \* const} + mi_var_rtti__check_derived_class_without_rtti s.constPtrConst {const Base \* const} + + mi_var_rtti__set_print_object on + mi_var_rtti__check_derived_class_with_rtti s.ptr {Derived \*} + mi_var_rtti__check_derived_class_with_rtti s.constPtr {const Derived \*} + mi_var_rtti__check_derived_class_with_rtti s.ptrConst {Derived \* const} + mi_var_rtti__check_derived_class_with_rtti s.constPtrConst {const Derived \* const} + :*/ + return; + /*: END: use_rtti_for_ptr_child :*/ +} + + +void use_rtti_for_ref_child_test () +{ + /*: BEGIN: use_rtti_for_ref_child :*/ + Derived d; + struct S { + Base& ref; + const Base& constRef; + S ( Base& v ) : + ref ( v ), + constRef ( v ) {} + } s ( d ); + /*: + mi_var_rtti__set_print_object off + mi_var_rtti__check_derived_class_without_rtti s.ref {Base \&} + mi_var_rtti__check_derived_class_without_rtti s.constRef {const Base \&} + + mi_var_rtti__set_print_object on + mi_var_rtti__check_derived_class_with_rtti s.ref {Derived \&} + mi_var_rtti__check_derived_class_with_rtti s.constRef {const Derived \&} + :*/ + return; + /*: END: use_rtti_for_ref_child :*/ +} + +void type_update_when_use_rtti_test () +{ + /*: BEGIN: type_update_when_use_rtti :*/ + Derived d; + /*: + mi_var_rtti__set_print_object on + mi_create_varobj_checked VAR ptr {Base \*} "create varobj for ptr" + mi_var_rtti__check_derived_children_without_rtti ptr + :*/ + + Base* ptr = &d; + /*: + mi_varobj_update_with_type_change VAR {Derived \*} 2 "update ptr" + mi_var_rtti__check_derived_children_with_rtti ptr + mi_var_rtti__check_derived_content_with_rtti ptr + mi_delete_varobj VAR "delete varobj for ptr" + :*/ + return; + /*: END: type_update_when_use_rtti :*/ +} + +void skip_type_update_when_not_use_rtti_test () +{ + /*: BEGIN: skip_type_update_when_not_use_rtti :*/ + Derived d; + /*: + mi_var_rtti__set_print_object off + mi_create_varobj_checked VAR ptr {Base \*} "create varobj for ptr" + mi_var_rtti__check_derived_children_without_rtti ptr + :*/ + + Base* ptr = &d; + /*: + mi_varobj_update VAR {} "update ptr" + mi_var_rtti__check_derived_children_without_rtti ptr + mi_var_rtti__check_derived_content_without_rtti ptr + mi_delete_varobj VAR "delete varobj for ptr" + :*/ + return; + /*: END: skip_type_update_when_not_use_rtti :*/ +} + +int main () +{ + use_rtti_for_ptr_test(); + use_rtti_for_ref_test(); + use_rtti_for_ptr_child_test(); + use_rtti_for_ref_child_test(); + type_update_when_use_rtti_test(); + skip_type_update_when_not_use_rtti_test(); + return 0; +} diff --git a/gdb/testsuite/gdb.mi/mi-var-rtti.exp b/gdb/testsuite/gdb.mi/mi-var-rtti.exp new file mode 100644 index 0000000..177b63c --- /dev/null +++ b/gdb/testsuite/gdb.mi/mi-var-rtti.exp @@ -0,0 +1,108 @@ +# Copyright 2011 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +if { [skip_cplus_tests] } { continue } + +load_lib mi-support.exp +set MIFLAGS "-i=mi" + +gdb_exit +if [mi_gdb_start] { + continue +} + +set testfile mi-var-rtti +set srcfile "$testfile.cc" +set binfile $objdir/$subdir/$testfile + +if [get_compiler_info ${binfile} "c++"] { + return -1; +} + +if {[gdb_compile $srcdir/$subdir/$srcfile $binfile executable {debug c++}] != ""} { + untested $testfile.exp + return -1 +} + +mi_gdb_load ${binfile} + +mi_prepare_inline_tests $srcfile + +# Enable using RTTI to determine real types of the objects +proc mi_var_rtti__set_print_object {state} { + mi_gdb_test "-interpreter-exec console \"set print object ${state}\"" \ + {\^done} \ + "-interpreter-exec console \"set print object ${state}\"" +} + +proc mi_var_rtti__check_derived_children_without_rtti {var_name} { + mi_list_varobj_children VAR { + { VAR.public public 1 } + } "list children of ${var_name} (without RTTI)" + mi_list_varobj_children "VAR.public" { + { VAR.public.A A 0 int } + } "list children of ${var_name}.public (without RTTI)" +} + +proc mi_var_rtti__check_derived_content_without_rtti {var_name} { + mi_check_varobj_value VAR.public.A 1 "check ${var_name}->A (without RTTI)" +} + +proc mi_var_rtti__check_derived_class_without_rtti {var_name var_type} { + mi_create_varobj_checked VAR ${var_name} ${var_type} "create varobj for ${var_name} (without RTTI)" + mi_var_rtti__check_derived_children_without_rtti ${var_name} + mi_var_rtti__check_derived_content_without_rtti ${var_name} + mi_delete_varobj VAR "delete varobj for ${var_name} (without RTTI)" +} + +proc mi_var_rtti__check_derived_children_with_rtti {var_name} { + mi_list_varobj_children VAR { + { VAR.Base Base 1 Base } + { VAR.public public 2 } + } "list children of ${var_name} (with RTTI)" + mi_list_varobj_children "VAR.Base" { + { VAR.Base.public public 1 } + } "list children of ${var_name}.Base (with RTTI)" + mi_list_varobj_children "VAR.Base.public" { + { VAR.Base.public.A A 0 int } + } "list children of ${var_name}.Base.public (with RTTI)" + mi_list_varobj_children "VAR.public" { + { VAR.public.B B 0 int } + { VAR.public.C C 0 int } + } "list children of ${var_name}.public (with RTTI)" +} + +proc mi_var_rtti__check_derived_content_with_rtti {var_name} { + mi_check_varobj_value VAR.Base.public.A 1 "check ${var_name}->A (with RTTI)" + mi_check_varobj_value VAR.public.B 2 "check ${var_name}->B (with RTTI)" + mi_check_varobj_value VAR.public.C 3 "check ${var_name}->C (with RTTI)" +} + +proc mi_var_rtti__check_derived_class_with_rtti {var_name var_type} { + mi_create_varobj_checked VAR ${var_name} ${var_type} "create varobj for ${var_name} (with RTTI)" + mi_var_rtti__check_derived_children_with_rtti ${var_name} + mi_var_rtti__check_derived_content_with_rtti ${var_name} + mi_delete_varobj VAR "delete varobj for ${var_name} (with RTTI)" +} + +mi_run_inline_test use_rtti_for_ptr +mi_run_inline_test use_rtti_for_ref +mi_run_inline_test use_rtti_for_ptr_child +mi_run_inline_test use_rtti_for_ref_child +mi_run_inline_test type_update_when_use_rtti +mi_run_inline_test skip_type_update_when_not_use_rtti + +mi_gdb_exit +return 0 diff --git a/gdb/typeprint.c b/gdb/typeprint.c index cf4158d..6546c98 100644 --- a/gdb/typeprint.c +++ b/gdb/typeprint.c @@ -140,16 +140,7 @@ whatis_exp (char *exp, int show) if (((TYPE_CODE (type) == TYPE_CODE_PTR) || (TYPE_CODE (type) == TYPE_CODE_REF)) && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CLASS)) - { - real_type = value_rtti_target_type (val, &full, &top, &using_enc); - if (real_type) - { - if (TYPE_CODE (type) == TYPE_CODE_PTR) - real_type = lookup_pointer_type (real_type); - else - real_type = lookup_reference_type (real_type); - } - } + real_type = value_rtti_indirect_type (val, &full, &top, &using_enc); else if (TYPE_CODE (type) == TYPE_CODE_CLASS) real_type = value_rtti_type (val, &full, &top, &using_enc); } diff --git a/gdb/valops.c b/gdb/valops.c index cb39677..b4ebe36 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -1774,15 +1774,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_value_type (arg2, enc_type, base_type, arg1); } error (_("Attempt to take contents of a non-pointer value.")); @@ -3528,23 +3520,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; + + 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; - target = value_ind (v); + real_type = value_rtti_type (target, full, top, using_enc); - return 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); + /* 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 if that is different from the enclosing type, create a new value using the real run-time type as the enclosing type (and of the same diff --git a/gdb/value.c b/gdb/value.c index d263d0c..15726c0 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -821,6 +821,35 @@ value_enclosing_type (struct value *value) return value->enclosing_type; } +/* Look at value.h for description. */ +struct type * +value_actual_type (struct value *value, int resolve_simple_types) +{ + struct value_print_options opts; + struct value *target; + struct type *result; + + get_user_print_options (&opts); + + result = value_type (value); + if (opts.objectprint) + { + if (TYPE_CODE (result) == TYPE_CODE_PTR + || TYPE_CODE (result) == TYPE_CODE_REF) + { + struct type *real_type; + + real_type = value_rtti_indirect_type (value, 0, 0, 0); + if (real_type) + result = real_type; + } + else if (resolve_simple_types) + result = value_enclosing_type (value); + } + + return result; +} + static void require_not_optimized_out (const struct value *value) { @@ -3110,10 +3139,26 @@ coerce_ref_if_computed (const struct value *arg) } struct value * +readjust_value_type (struct value *value, struct type *enc_type, + struct type *original_type, struct value *original_value) +{ + /* Re-adjust type. */ + deprecated_set_value_type (value, TYPE_TARGET_TYPE (original_type)); + + /* Add embedding info. */ + set_value_enclosing_type (value, enc_type); + set_value_embedded_offset (value, value_pointed_to_offset (original_value)); + + /* We may be pointing to an object of some derived type. */ + return value_full_object (value, NULL, 0, 0, 0); +} + +struct value * coerce_ref (struct value *arg) { struct type *value_type_arg_tmp = check_typedef (value_type (arg)); struct value *retval; + struct type *enc_type; retval = coerce_ref_if_computed (arg); if (retval) @@ -3122,9 +3167,13 @@ coerce_ref (struct value *arg) if (TYPE_CODE (value_type_arg_tmp) != TYPE_CODE_REF) return arg; - return value_at_lazy (TYPE_TARGET_TYPE (value_type_arg_tmp), - unpack_pointer (value_type (arg), - value_contents (arg))); + enc_type = check_typedef (value_enclosing_type (arg)); + enc_type = TYPE_TARGET_TYPE (enc_type); + + retval = value_at_lazy (enc_type, + unpack_pointer (value_type (arg), + value_contents (arg))); + return readjust_value_type (retval, enc_type, value_type_arg_tmp, arg); } struct value * diff --git a/gdb/value.h b/gdb/value.h index d2c58ec..7345c71 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -139,6 +139,16 @@ extern struct type *value_enclosing_type (struct value *); extern void set_value_enclosing_type (struct value *val, struct type *new_type); +/* Returns value_type or value_enclosing_type depending on + value_print_options.objectprint. + + If RESOLVE_SIMPLE_TYPES is 0 the enclosing type will be resolved + only for pointers and references, else it will be returned + for all the types (e.g. structures). This option is useful + to prevent retrieving enclosing type for the base classes fields. */ + +extern struct type *value_actual_type (struct value *value, int resolve_simple_types); + extern int value_pointed_to_offset (struct value *value); extern void set_value_pointed_to_offset (struct value *value, int val); extern int value_embedded_offset (struct value *value); @@ -353,6 +363,13 @@ extern short *deprecated_value_regnum_hack (struct value *); extern struct value *coerce_ref_if_computed (const struct value *arg); +/* Setup a new value type and enclosing value type for dereferenced value. + It is a common implementation for coerce_ref and value_ind. */ + +extern struct value * +readjust_value_type (struct value *value, struct type *enc_type, + struct type *original_type, struct value *original_value); + /* Convert a REF to the object referenced. */ extern struct value *coerce_ref (struct value *value); @@ -617,8 +634,8 @@ extern struct value *value_primitive_field (struct value *arg1, int offset, struct type *arg_type); -extern struct type *value_rtti_target_type (struct value *, int *, int *, - int *); +extern struct type *value_rtti_indirect_type (struct value *, int *, int *, + int *); extern struct value *value_full_object (struct value *, struct type *, int, int, int); diff --git a/gdb/varobj.c b/gdb/varobj.c index 7c68a93..dfeb71b 100644 --- a/gdb/varobj.c +++ b/gdb/varobj.c @@ -659,8 +659,18 @@ varobj_create (char *objname, var->type = value_type (type_only_value); } - else - var->type = value_type (value); + else + { + struct type *enclosing_type; + + var->type = value_type (value); + enclosing_type = value_actual_type (value, 0); + if (check_typedef (enclosing_type) != check_typedef (var->type)) + { + var->type = enclosing_type; + value = value_cast (enclosing_type, value); + } + } install_new_value (var, value, 1 /* Initial assignment */); @@ -2194,7 +2204,7 @@ create_child_with_value (struct varobj *parent, int index, const char *name, if (value != NULL) /* If the child had no evaluation errors, var->value will be non-NULL and contain a valid type. */ - child->type = value_type (value); + child->type = value_actual_type (value, 0); else /* Otherwise, we must compute the type. */ child->type = (*child->root->lang->type_of_child) (child->parent, @@ -2480,6 +2490,7 @@ static struct value * value_of_root (struct varobj **var_handle, int *type_changed) { struct varobj *var; + struct value_print_options opts; if (var_handle == NULL) return NULL; @@ -2492,7 +2503,8 @@ value_of_root (struct varobj **var_handle, int *type_changed) if (!is_root_p (var)) return NULL; - if (var->root->floating) + get_user_print_options (&opts); + if (var->root->floating || opts.objectprint) { struct varobj *tmp_var; char *old_type, *new_type; @@ -2781,6 +2793,10 @@ varobj_floating_p (struct varobj *var) to all types and dereferencing pointers to structures. + If LOOKUP_ACTUAL_TYPE is set the enclosing type of the + value will be fetched and if it differs from static type + the value will be casted to it. + Both TYPE and *TYPE should be non-null. VALUE can be null if we want to only translate type. *VALUE can be null as well -- if the parent @@ -2792,7 +2808,8 @@ varobj_floating_p (struct varobj *var) static void adjust_value_for_child_access (struct value **value, struct type **type, - int *was_ptr) + int *was_ptr, + int lookup_actual_type) { gdb_assert (type && *type); @@ -2832,6 +2849,19 @@ adjust_value_for_child_access (struct value **value, /* The 'get_target_type' function calls check_typedef on result, so we can immediately check type code. No need to call check_typedef here. */ + + /* Access a real type of the value (if necessary and possible). */ + if (value && *value && lookup_actual_type) + { + struct type *enclosing_type; + + enclosing_type = value_actual_type (*value, 1); + if (check_typedef (enclosing_type) != check_typedef (*type)) + { + *type = enclosing_type; + *value = value_cast (enclosing_type, *value); + } + } } /* C */ @@ -2842,7 +2872,7 @@ c_number_of_children (struct varobj *var) int children = 0; struct type *target; - adjust_value_for_child_access (NULL, &type, NULL); + adjust_value_for_child_access (NULL, &type, NULL, 0); target = get_target_type (type); switch (TYPE_CODE (type)) @@ -2957,7 +2987,7 @@ c_describe_child (struct varobj *parent, int index, *cfull_expression = NULL; parent_expression = varobj_get_path_expr (parent); } - adjust_value_for_child_access (&value, &type, &was_ptr); + adjust_value_for_child_access (&value, &type, &was_ptr, 0); switch (TYPE_CODE (type)) { @@ -3223,16 +3253,28 @@ c_value_of_variable (struct varobj *var, enum varobj_display_formats format) static int cplus_number_of_children (struct varobj *var) { + struct value *value = 0; struct type *type; int children, dont_know; + int lookup_actual_type = 0; + struct value_print_options opts; dont_know = 1; children = 0; + get_user_print_options (&opts); + if (!CPLUS_FAKE_CHILD (var)) { type = get_value_type (var); - adjust_value_for_child_access (NULL, &type, NULL); + /* It is necessary to access a real type (via RTTI). */ + if (opts.objectprint) + { + value = var->value; + lookup_actual_type = (TYPE_CODE (var->type) == TYPE_CODE_REF + || TYPE_CODE (var->type) == TYPE_CODE_PTR); + } + adjust_value_for_child_access (&value, &type, NULL, lookup_actual_type); if (((TYPE_CODE (type)) == TYPE_CODE_STRUCT) || ((TYPE_CODE (type)) == TYPE_CODE_UNION)) @@ -3259,7 +3301,15 @@ cplus_number_of_children (struct varobj *var) int kids[3]; type = get_value_type (var->parent); - adjust_value_for_child_access (NULL, &type, NULL); + + /* It is necessary to access a real type (via RTTI). */ + if (opts.objectprint) + { + value = var->parent->value; + lookup_actual_type = (TYPE_CODE (var->parent->type) == TYPE_CODE_REF + || TYPE_CODE (var->parent->type) == TYPE_CODE_PTR); + } + adjust_value_for_child_access (&value, &type, NULL, lookup_actual_type); cplus_class_num_children (type, kids); if (strcmp (var->name, "public") == 0) @@ -3341,7 +3391,10 @@ cplus_describe_child (struct varobj *parent, int index, struct value *value; struct type *type; int was_ptr; + int lookup_actual_type = 0; char *parent_expression = NULL; + struct varobj *var; + struct value_print_options opts; if (cname) *cname = NULL; @@ -3352,22 +3405,18 @@ cplus_describe_child (struct varobj *parent, int index, if (cfull_expression) *cfull_expression = NULL; - if (CPLUS_FAKE_CHILD (parent)) - { - value = parent->parent->value; - type = get_value_type (parent->parent); - if (cfull_expression) - parent_expression = varobj_get_path_expr (parent->parent); - } - else - { - value = parent->value; - type = get_value_type (parent); - if (cfull_expression) - parent_expression = varobj_get_path_expr (parent); - } + get_user_print_options (&opts); + + var = (CPLUS_FAKE_CHILD (parent)) ? parent->parent : parent; + if (opts.objectprint) + lookup_actual_type = (TYPE_CODE (var->type) == TYPE_CODE_REF + || TYPE_CODE (var->type) == TYPE_CODE_PTR); + value = var->value; + type = get_value_type (var); + if (cfull_expression) + parent_expression = varobj_get_path_expr (var); - adjust_value_for_child_access (&value, &type, &was_ptr); + adjust_value_for_child_access (&value, &type, &was_ptr, lookup_actual_type); if (TYPE_CODE (type) == TYPE_CODE_STRUCT || TYPE_CODE (type) == TYPE_CODE_UNION) --------------000605040206050807070102--