diff options
author | Anton Gorenkov <xgsa@sourceware.org> | 2012-04-14 12:18:50 +0000 |
---|---|---|
committer | Anton Gorenkov <xgsa@sourceware.org> | 2012-04-14 12:18:50 +0000 |
commit | 8264ba82b71a186e10fddc298c5eb6e68742a94a (patch) | |
tree | 6a127bac3d88db9846b9b2db0a98a21fd31b7f0c /gdb/testsuite | |
parent | 5f18041e78f879768645b113054261313517234a (diff) | |
download | gdb-8264ba82b71a186e10fddc298c5eb6e68742a94a.zip gdb-8264ba82b71a186e10fddc298c5eb6e68742a94a.tar.gz gdb-8264ba82b71a186e10fddc298c5eb6e68742a94a.tar.bz2 |
gdb/doc/ChangeLog:
2012-04-14 Anton Gorenkov <xgsa@yandex.ru>
PR mi/13393
* gdb.texinfo (Print Settings): Extend the description for "set print
object".
(GDB/MI Variable Objects): Extend the description for -var-create and
-var-list-children.
gdb/testsuite/ChangeLog:
2012-04-14 Anton Gorenkov <xgsa@yandex.ru>
PR mi/13393
* gdb.mi/mi-var-rtti.cc: New file.
* gdb.mi/mi-var-rtti.exp: New file.
* lib/mi-support.exp (mi_varobj_update_with_child_type_change): New
function.
(mi_varobj_update_with_type_change): updated to avoid code duplication.
gdb/ChangeLog:
2012-04-14 Anton Gorenkov <xgsa@yandex.ru>
PR mi/13393
* value.c (value_actual_type): New function.
* value.h (value_actual_type): New declaration.
* varobj.c (update_type_if_necessary): New function.
(varobj_create): Call value_actual_type instead of
value_type.
(install_dynamic_child): distinct changed and type changed MI variable
objects.
(update_dynamic_varobj_children): Updated for install_dynamic_child
change. All callers updated.
(varobj_update): Support for MI variable object type change if
the value changed and RTTI is used to determine the type.
(create_child_with_value): Call value_actual_type instead of
value_type.
(adjust_value_for_child_access): Extended with a new parameter which
specify whether the given value should be casted to enclosing type.
All callers updated.
Diffstat (limited to 'gdb/testsuite')
-rw-r--r-- | gdb/testsuite/ChangeLog | 9 | ||||
-rw-r--r-- | gdb/testsuite/gdb.mi/mi-var-rtti.cc | 360 | ||||
-rw-r--r-- | gdb/testsuite/gdb.mi/mi-var-rtti.exp | 124 | ||||
-rw-r--r-- | gdb/testsuite/lib/mi-support.exp | 8 |
4 files changed, 499 insertions, 2 deletions
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index bfcc42d..92ddbe8 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2012-04-14 Anton Gorenkov <xgsa@yandex.ru> + + PR mi/13393 + * gdb.mi/mi-var-rtti.cc: New file. + * gdb.mi/mi-var-rtti.exp: New file. + * lib/mi-support.exp (mi_varobj_update_with_child_type_change): New + function. + (mi_varobj_update_with_type_change): updated to avoid code duplication. + 2012-04-11 Siva Chandra Reddy <sivachandra@google.com> * gdb.python/Makefile.in: Add py-explore and py-explore-cc to 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..d05f660 --- /dev/null +++ b/gdb/testsuite/gdb.mi/mi-var-rtti.cc @@ -0,0 +1,360 @@ +/* Copyright 2012 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; + /*: + set testname use_rtti_for_ptr + set_print_object off $testname + check_new_derived_without_rtti ptr {Base \*} $testname + check_new_derived_without_rtti constPtr {const Base \*} $testname + check_new_derived_without_rtti ptrConst {Base \* const} $testname + check_new_derived_without_rtti constPtrConst {const Base \* const} \ + $testname + + set_print_object on $testname + check_new_derived_with_rtti ptr {Derived \*} $testname + check_new_derived_with_rtti constPtr {const Derived \*} $testname + check_new_derived_with_rtti ptrConst {Derived \* const} $testname + check_new_derived_with_rtti constPtrConst {const Derived \* const} \ + $testname + :*/ + 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; + /*: + set testname use_rtti_for_ref + set_print_object off $testname + check_new_derived_without_rtti ref {Base \&} $testname + check_new_derived_without_rtti constRef {const Base \&} $testname + + set_print_object on $testname + check_new_derived_with_rtti ref {Derived \&} $testname + check_new_derived_with_rtti constRef {const Derived \&} $testname + :*/ + 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 ); + /*: + set testname use_rtti_for_ptr_child + + set_print_object off $testname + mi_create_varobj VAR s "create varobj for s (without RTTI) in $testname" + mi_list_varobj_children VAR { + { VAR.public public 4 } + } "list children of s (without RTTI) in $testname" + mi_list_varobj_children VAR.public { + { VAR.public.ptr ptr 1 {Base \*} } + { VAR.public.constPtr constPtr 1 {const Base \*} } + { VAR.public.ptrConst ptrConst 1 {Base \* const} } + { VAR.public.constPtrConst constPtrConst 1 {const Base \* const} } + } "list children of s.public (without RTTI) in $testname" + check_derived_without_rtti VAR.public.ptr s.ptr $testname + check_derived_without_rtti VAR.public.constPtr s.constPtr $testname + check_derived_without_rtti VAR.public.ptrConst s.ptrConst $testname + check_derived_without_rtti VAR.public.constPtrConst s.constPtrConst \ + $testname + mi_delete_varobj VAR "delete varobj for s (without RTTI) in $testname" + + set_print_object on $testname + mi_create_varobj VAR s "create varobj for s (with RTTI) in $testname" + mi_list_varobj_children VAR { + { VAR.public public 4 } + } "list children of s (with RTTI) in $testname" + mi_list_varobj_children VAR.public { + { VAR.public.ptr ptr 2 {Derived \*} } + { VAR.public.constPtr constPtr 2 {const Derived \*} } + { VAR.public.ptrConst ptrConst 2 {Derived \* const} } + { VAR.public.constPtrConst constPtrConst 2 {const Derived \* const}} + } "list children of s.public (with RTTI) in $testname" + check_derived_with_rtti VAR.public.ptr s.ptr $testname + check_derived_with_rtti VAR.public.constPtr s.constPtr $testname + check_derived_with_rtti VAR.public.ptrConst s.ptrConst $testname + check_derived_with_rtti VAR.public.constPtrConst s.constPtrConst \ + $testname + mi_delete_varobj VAR "delete varobj for s (with RTTI) in $testname" + :*/ + 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 ); + /*: + set testname use_rtti_for_ref_child + + set_print_object off $testname + mi_create_varobj VAR s "create varobj for s (without RTTI) in $testname" + mi_list_varobj_children VAR { + { VAR.public public 2 } + } "list children of s (without RTTI) in $testname" + mi_list_varobj_children VAR.public { + { VAR.public.ref ref 1 {Base \&} } + { VAR.public.constRef constRef 1 {const Base \&} } + } "list children of s.public (without RTTI) in $testname" + check_derived_without_rtti VAR.public.ref s.ref $testname + check_derived_without_rtti VAR.public.constRef s.constRef $testname + mi_delete_varobj VAR "delete varobj for s (without RTTI) in $testname" + + set_print_object on $testname + mi_create_varobj VAR s "create varobj for s (with RTTI) in $testname" + mi_list_varobj_children VAR { + { VAR.public public 2 } + } "list children of s (with RTTI) in $testname" + mi_list_varobj_children VAR.public { + { VAR.public.ref ref 2 {Derived \&} } + { VAR.public.constRef constRef 2 {const Derived \&} } + } "list children of s.public (with RTTI) in $testname" + check_derived_with_rtti VAR.public.ref s.ref $testname + check_derived_with_rtti VAR.public.constRef s.constRef $testname + mi_delete_varobj VAR "delete varobj for s (with RTTI) in $testname" + :*/ + return; + /*: END: use_rtti_for_ref_child :*/ +} + + +struct First { + First() : F(-1) {} + int F; +}; + + +struct MultipleDerived : public First, Base { + MultipleDerived() : B(2), C(3) {} + int B; + int C; +}; + + +void use_rtti_with_multiple_inheritence_test () +{ + /*: BEGIN: use_rtti_with_multiple_inheritence :*/ + MultipleDerived d; + Base* ptr = &d; + Base& ref = d; + /*: + set testname use_rtti_with_multiple_inheritence + set_print_object off $testname + check_new_derived_without_rtti ptr {Base \*} $testname + check_new_derived_without_rtti ref {Base \&} $testname + + set_print_object on $testname + mi_create_varobj_checked VAR ptr {MultipleDerived \*} \ + "create varobj for ptr (with RTTI) in $testname" + mi_list_varobj_children VAR { + { VAR.First First 1 First } + { VAR.Base Base 1 Base } + { VAR.public public 2 } + } "list children of ptr (with RTTI) in $testname" + mi_list_varobj_children "VAR.First" { + { VAR.First.public public 1 } + } "list children of ptr.First (with RTTI) in $testname" + mi_list_varobj_children "VAR.First.public" { + { VAR.First.public.F F 0 int } + } "list children of ptr.Base.public (with RTTI) in $testname" + mi_list_varobj_children "VAR.Base" { + { VAR.Base.public public 1 } + } "list children of ptr.Base (with RTTI) in $testname" + mi_list_varobj_children "VAR.Base.public" { + { VAR.Base.public.A A 0 int } + } "list children of ptr.Base.public (with RTTI) in $testname" + mi_list_varobj_children "VAR.public" { + { VAR.public.B B 0 int } + { VAR.public.C C 0 int } + } "list children of ptr.public (with RTTI) in $testname" + + mi_delete_varobj VAR \ + "delete varobj for ptr (with RTTI) in $testname" + :*/ + return; + /*: END: use_rtti_with_multiple_inheritence :*/ +} + + +void type_update_when_use_rtti_test () +{ + /*: BEGIN: type_update_when_use_rtti :*/ + Derived d; + /*: + set testname type_update_when_use_rtti + + set_print_object on $testname + mi_create_varobj_checked PTR ptr {Base \*} \ + "create varobj for ptr in $testname" + check_derived_children_without_rtti PTR ptr $testname + + mi_create_varobj S s "create varobj for S in $testname" + mi_list_varobj_children S { + { S.public public 1 } + } "list children of s in $testname" + mi_list_varobj_children S.public { + { S.public.ptr ptr 1 {Base \*} } + } "list children of s.public in $testname" + check_derived_children_without_rtti S.public.ptr s.ptr $testname + :*/ + + Base* ptr = &d; + struct S { + Base* ptr; + S ( Base* v ) : + ptr ( v ) {} + } s ( &d ); + /*: + mi_varobj_update_with_type_change PTR {Derived \*} 2 \ + "update ptr to derived in $testname" + check_derived_with_rtti PTR ptr $testname + + mi_varobj_update_with_child_type_change S S.public.ptr {Derived \*} 2 \ + "update s.ptr to derived in $testname" + check_derived_with_rtti S.public.ptr s.ptr $testname + :*/ + + ptr = 0; + s.ptr = 0; + /*: + mi_varobj_update_with_type_change PTR {Base \*} 1 \ + "update ptr back to base type in $testname" + mi_delete_varobj PTR "delete varobj for ptr in $testname" + + mi_varobj_update_with_child_type_change S S.public.ptr {Base \*} 1 \ + "update s.ptr back to base type in $testname" + mi_delete_varobj S "delete varobj for s in $testname" + :*/ + 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; + /*: + set testname skip_type_update_when_not_use_rtti + + set_print_object off $testname + mi_create_varobj_checked PTR ptr {Base \*} \ + "create varobj for ptr in $testname" + check_derived_children_without_rtti PTR ptr $testname + + mi_create_varobj S s "create varobj for S in $testname" + mi_list_varobj_children S { + { S.public public 1 } + } "list children of s in $testname" + mi_list_varobj_children S.public { + { S.public.ptr ptr 1 {Base \*} } + } "list children of s.public in $testname" + check_derived_children_without_rtti S.public.ptr s.ptr $testname + :*/ + + Base* ptr = &d; + struct S { + Base* ptr; + S ( Base* v ) : + ptr ( v ) {} + } s ( &d ); + /*: + mi_varobj_update PTR {PTR PTR.public.A} \ + "update ptr to derived type in $testname" + check_derived_without_rtti PTR ptr $testname + + mi_varobj_update S {S.public.ptr S.public.ptr.public.A} \ + "update s to derived type in $testname" + check_derived_without_rtti S.public.ptr s.ptr $testname + :*/ + + ptr = 0; + s.ptr = 0; + /*: + mi_varobj_update PTR {PTR PTR.public.A} \ + "update ptr back to base type in $testname" + mi_delete_varobj PTR "delete varobj for ptr in $testname" + + mi_varobj_update S {S.public.ptr S.public.ptr.public.A} \ + "update s back to base type in $testname" + mi_delete_varobj S "delete varobj for s in $testname" + :*/ + 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(); + use_rtti_with_multiple_inheritence_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..5e43bae --- /dev/null +++ b/gdb/testsuite/gdb.mi/mi-var-rtti.exp @@ -0,0 +1,124 @@ +# Copyright 2012 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 executable ${testfile} +set binfile $objdir/$subdir/$testfile +set opts {debug c++} + +if [build_executable $testfile.exp $executable $srcfile $opts] { + return -1; +} + +mi_gdb_load ${binfile} + +mi_prepare_inline_tests $srcfile + +# Enable using RTTI to determine real types of the objects +proc set_print_object {state testname} { + mi_gdb_test "-interpreter-exec console \"set print object ${state}\"" \ + {\^done} \ + "-interpreter-exec console \"set print object ${state}\" in $testname" +} + +proc check_derived_children_without_rtti {varobj_name var_name testname} { + mi_list_varobj_children ${varobj_name} " + { ${varobj_name}.public public 1 } + " "list children of ${var_name} (without RTTI) in $testname" + mi_list_varobj_children "${varobj_name}.public" " + { ${varobj_name}.public.A A 0 int } + " "list children of ${var_name}.public (without RTTI) in $testname" +} + +proc check_derived_content_without_rtti {varobj_name var_name testname} { + mi_check_varobj_value ${varobj_name}.public.A 1 \ + "check ${var_name}->A (without RTTI) in $testname" +} + +proc check_derived_without_rtti {varobj_name var_name testname} { + check_derived_children_without_rtti ${varobj_name} ${var_name} ${testname} + check_derived_content_without_rtti ${varobj_name} ${var_name} ${testname} +} + +proc check_new_derived_without_rtti {var_name var_type testname} { + set varobj_name VAR + mi_create_varobj_checked ${varobj_name} ${var_name} ${var_type} \ + "create varobj for ${var_name} (without RTTI) in ${testname}" + check_derived_without_rtti ${varobj_name} ${var_name} ${testname} + mi_delete_varobj ${varobj_name} \ + "delete varobj for ${var_name} (without RTTI) in ${testname}" +} + +proc check_derived_children_with_rtti {varobj_name var_name testname} { + mi_list_varobj_children ${varobj_name} " + { ${varobj_name}.Base Base 1 Base } + { ${varobj_name}.public public 2 } + " "list children of ${var_name} (with RTTI) in $testname" + mi_list_varobj_children "${varobj_name}.Base" " + { ${varobj_name}.Base.public public 1 } + " "list children of ${var_name}.Base (with RTTI) in $testname" + mi_list_varobj_children "${varobj_name}.Base.public" " + { ${varobj_name}.Base.public.A A 0 int } + " "list children of ${var_name}.Base.public (with RTTI) in $testname" + mi_list_varobj_children "${varobj_name}.public" " + { ${varobj_name}.public.B B 0 int } + { ${varobj_name}.public.C C 0 int } + " "list children of ${var_name}.public (with RTTI) in $testname" +} + +proc check_derived_content_with_rtti {varobj_name var_name testname} { + mi_check_varobj_value ${varobj_name}.Base.public.A 1 \ + "check ${var_name}->A (with RTTI) in $testname" + mi_check_varobj_value ${varobj_name}.public.B 2 \ + "check ${var_name}->B (with RTTI) in $testname" + mi_check_varobj_value ${varobj_name}.public.C 3 \ + "check ${var_name}->C (with RTTI) in $testname" +} + +proc check_derived_with_rtti {varobj_name var_name testname} { + check_derived_children_with_rtti ${varobj_name} ${var_name} $testname + check_derived_content_with_rtti ${varobj_name} ${var_name} $testname +} + +proc check_new_derived_with_rtti {var_name var_type testname} { + set varobj_name VAR + mi_create_varobj_checked ${varobj_name} ${var_name} ${var_type} \ + "create varobj for ${var_name} (with RTTI) in $testname" + check_derived_with_rtti ${varobj_name} ${var_name} $testname + mi_delete_varobj ${varobj_name} \ + "delete varobj for ${var_name} (with RTTI) in $testname" +} + +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 use_rtti_with_multiple_inheritence +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/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp index 7f8642f..401565d 100644 --- a/gdb/testsuite/lib/mi-support.exp +++ b/gdb/testsuite/lib/mi-support.exp @@ -1298,13 +1298,17 @@ proc mi_varobj_update { name expected testname } { mi_gdb_test "-var-update $name" $er $testname } -proc mi_varobj_update_with_type_change { name new_type new_children testname } { - set v "{name=\"$name\",in_scope=\"true\",type_changed=\"true\",new_type=\"$new_type\",new_num_children=\"$new_children\",has_more=\".\"}" +proc mi_varobj_update_with_child_type_change { name child_name new_type new_children testname } { + set v "{name=\"$child_name\",in_scope=\"true\",type_changed=\"true\",new_type=\"$new_type\",new_num_children=\"$new_children\",has_more=\".\"}" set er "\\^done,changelist=\\\[$v\\\]" verbose -log "Expecting: $er" mi_gdb_test "-var-update $name" $er $testname } +proc mi_varobj_update_with_type_change { name new_type new_children testname } { + mi_varobj_update_with_child_type_change $name $name $new_type $new_children $testname +} + # A helper that turns a key/value list into a regular expression # matching some MI output. proc mi_varobj_update_kv_helper {list} { |