public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: xgsa <xgsa@yandex.ru>
To: Tom Tromey <tromey@redhat.com>
Cc: gdb-patches@sourceware.org
Subject: Re: set print object on should affect MI varobjs (PR gdb/13393)
Date: Wed, 21 Dec 2011 19:01:00 -0000	[thread overview]
Message-ID: <4EF22A4D.80703@yandex.ru> (raw)
In-Reply-To: <m3mxanjiy0.fsf@fleche.redhat.com>

Here is the patch with the corrections after your review.

 >>>> +struct type *
 >>>> +actual_type (struct value *value, int resolve_simple_types)
 >>>> +{
 >>
 >>This should have an introductory comment saying to look at value.h.

It seems that none of neighboring functions (e.g. value_type() & value_enclosing_type()) has such comment. I think it is better to be consistent and not to add the comment, but if you insist I can add it.

 >>>> +      if (check_typedef (enclosing_type) != check_typedef (var->type))
 >>>> +        {
 >>>> +          var->type = enclosing_type;
 >>>> +          value = value_cast (enclosing_type, value);
 >>
 >>Will this always do the right thing?
 >>It seems questionable.

It works fine for me. Can you give an example when it works wrong?

 >>>> +      enclosing_type = actual_type(*value, 1);
 >>
 >>I don't understand why this one call has a '1' here.

The C++ references are treated as a simple values in many places of varobj. E.g. they are dereferenced in install_new_value():
 >  /* We are not interested in the address of references, and given
 >     that in C++ a reference is not rebindable, it cannot
 >     meaningfully change.  So, get hold of the real value.  */
 >  if (value)
 >    value = coerce_ref (value);
So I need to ask real type not only on references & pointers but also on the values.

I have also renamed actual_type() => value_actual_type() (to be consistent with value_type() & value_enclosing_type()).


Thanks,
Anton


gdb/ChangeLog:

2011-12-02  Anton Gorenkov <xgsa@yandex.ru>

     PR gdb/13393
     * gdb/valops.c (value_rtti_target_type): add support for references.
     Return also a reference or pointer type (because every caller do it after call that leads to code duplication)
     * gdb/c-valprint.c (c_value_print): updated for value_rtti_target_type() change.
     * gdb/eval.c (evaluate_subexp_standard): updated for value_rtti_target_type() change.
     * gdb/typeprint.c: updated for value_rtti_target_type() change.
     * gdb/value.c(value_actual_type): new function.
     (coerce_ref): support for enclosing type setting for references (as it is done for pointers in value_ind())
     * gdb/value.h(value_actual_type): add prototype.
     * 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): update 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 <xgsa@yandex.ru>

     PR gdb/13393
     * gdb.mi/mi-var-rtti.cc:: New file.
     * gdb.mi/mi-var-rtti.exp:: New file.


diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c
index 3461b08..bfb3227 100644
--- a/gdb/c-valprint.c
+++ b/gdb/c-valprint.c
@@ -702,18 +702,8 @@ c_value_print (struct value *val, struct ui_file *stream,
            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..7e6a6c5 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -1992,14 +1992,7 @@ evaluate_subexp_standard (struct type *expect_type,
            {
              real_type = value_rtti_target_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 <http://www.gnu.org/licenses/>.
+*/
+
+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..2999e87
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-var-rtti.exp
@@ -0,0 +1,108 @@
+# Copyright 2006, 2007, 2008, 2009, 2010, 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 <http://www.gnu.org/licenses/>.
+
+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..8170e14 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_target_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..6a914b0 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -3528,8 +3528,7 @@ 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.  */
@@ -3539,12 +3538,37 @@ value_rtti_target_type (struct value *v, int *full,
              int *top, int *using_enc)
  {
    struct value *target;
+  struct type *type, *real_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 0;

-  return value_rtti_type (target, full, top, using_enc);
+  real_type = value_rtti_type (target, full, top, using_enc);
+
+  if (real_type)
+    {
+      struct type *target_type = value_type (target);
+
+      /* Copy qualifiers to the referenced object.  */
+      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..7d9e5cc 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -821,6 +821,33 @@ value_enclosing_type (struct value *value)
    return value->enclosing_type;
  }

+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_target_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)
  {
@@ -3114,6 +3141,7 @@ 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 +3150,23 @@ 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),
+  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)));
+  /* Re-adjust type.  */
+  deprecated_set_value_type (retval, TYPE_TARGET_TYPE (value_type_arg_tmp));
+
+  /* Add embedding info.  */
+  set_value_enclosing_type (retval, enc_type);
+  set_value_embedded_offset (retval, value_pointed_to_offset (arg));
+
+  /* We may be pointing to an object of some derived type.  */
+  retval = value_full_object (retval, NULL, 0, 0, 0);
+
+  return retval;
  }

  struct value *
diff --git a/gdb/value.h b/gdb/value.h
index d2c58ec..c01da3e 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -139,6 +139,15 @@ 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);
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 7c68a93..47390cb 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -660,7 +660,17 @@ varobj_create (char *objname,
        var->type = value_type (type_only_value);
      }
        else
-    var->type = value_type (value);
+    {
+      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,14 @@ 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 +3390,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 +3404,17 @@ 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)

  reply	other threads:[~2011-12-21 18:50 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-12-02 19:50 set print object on should affect MI varobjs (PR 13393) xgsa
2011-12-08  8:15 ` xgsa
2011-12-19 20:34   ` xgsa
2011-12-20 17:47 ` Tom Tromey
2011-12-21 19:01   ` xgsa [this message]
2011-12-21 19:37     ` set print object on should affect MI varobjs (PR gdb/13393) Jan Kratochvil
2011-12-22 10:17       ` set print object on should affect MI varobjs (PR mi/13393) xgsa
2011-12-24  1:55         ` Jan Kratochvil
2011-12-24 13:56           ` xgsa
2012-01-02  2:22             ` Jan Kratochvil
2012-01-06 15:47               ` RTTI type improvement for (was: "Re: set print object on should affect MI varobjs (PR mi/13393)") xgsa
2012-01-09 14:41                 ` Jan Kratochvil
2012-01-11 21:58                   ` RTTI type improvement for Tom Tromey
2012-01-12 11:25                     ` xgsa
2012-02-06 21:45                 ` Tom Tromey
2012-02-08 18:34                   ` xgsa
2012-02-10 20:13                     ` Tom Tromey
2012-02-19 18:46                       ` set print object on should affect MI varobjs (PR mi/13393) xgsa
2012-02-23  4:58                         ` xgsa
2012-03-18 16:28                         ` xgsa
2012-03-18 20:41                           ` Eli Zaretskii
2012-03-19  7:10                             ` xgsa
2012-03-19 17:41                               ` Eli Zaretskii
2012-03-23 17:09                                 ` xgsa
2012-03-26 19:08                                   ` xgsa
2012-03-30 17:51                                   ` Tom Tromey
2012-03-30 18:01                                     ` Eli Zaretskii
2012-03-30 20:11                                     ` xgsa
2012-03-30 18:01                                   ` Eli Zaretskii
2012-03-30 20:25                                     ` xgsa
2012-03-30 20:52                                       ` Eli Zaretskii
2012-03-30 21:26                                         ` xgsa
2012-03-31  5:54                                           ` Eli Zaretskii
2012-03-31  6:57                                             ` xgsa
2012-03-31  9:33                                               ` xgsa
2012-04-03  0:54                                                 ` Doug Evans
2012-04-03 13:27                                                   ` xgsa
2012-04-06 17:11                                                     ` xgsa
2012-04-13  8:07                                                       ` xgsa
2012-04-13 12:22                                                         ` Eli Zaretskii
2012-04-13 12:34                                                           ` xgsa
2012-04-13 17:23                                                             ` Tom Tromey
2012-04-14 23:35                                                               ` xgsa
2012-04-16 18:35                                                                 ` Jan Kratochvil
2012-07-23 17:21                                                                   ` Ulrich Weigand
2012-08-06  7:26                                                                     ` xgsa
2012-02-21 14:15                       ` RTTI type improvement for xgsa

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4EF22A4D.80703@yandex.ru \
    --to=xgsa@yandex.ru \
    --cc=gdb-patches@sourceware.org \
    --cc=tromey@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).