aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite
diff options
context:
space:
mode:
authorAnton Gorenkov <xgsa@sourceware.org>2012-04-14 12:18:50 +0000
committerAnton Gorenkov <xgsa@sourceware.org>2012-04-14 12:18:50 +0000
commit8264ba82b71a186e10fddc298c5eb6e68742a94a (patch)
tree6a127bac3d88db9846b9b2db0a98a21fd31b7f0c /gdb/testsuite
parent5f18041e78f879768645b113054261313517234a (diff)
downloadgdb-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/ChangeLog9
-rw-r--r--gdb/testsuite/gdb.mi/mi-var-rtti.cc360
-rw-r--r--gdb/testsuite/gdb.mi/mi-var-rtti.exp124
-rw-r--r--gdb/testsuite/lib/mi-support.exp8
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} {