1# Copyright 1992-2023 Free Software Foundation, Inc. 2 3# This program is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published by 5# the Free Software Foundation; either version 3 of the License, or 6# (at your option) any later version. 7# 8# This program is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16# This file was written by Fred Fish. (fnf@cygnus.com) 17# And rewritten by Michael Chastain <mec.gnu@mindspring.com>. 18 19set nl "\[\r\n\]+" 20 21if { [skip_cplus_tests] } { continue } 22 23load_lib "cp-support.exp" 24 25standard_testfile .cc 26 27if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug c++}]} { 28 return -1 29} 30 31proc test_ptype_of_classes {} { 32 33 # class VA 34 35 cp_test_ptype_class \ 36 "VA" "" "class" "VA" \ 37 { 38 { field public "int va;" } 39 } 40 41 # class VB 42 43 cp_test_ptype_class \ 44 "VB" "" "class" "VB" \ 45 { 46 { field public "int vb;" } 47 { method public "int fvb();" } 48 { method public "virtual int vvb();" } 49 } 50 51 # class V 52 53 cp_test_ptype_class \ 54 "V" "" "class" "V" \ 55 { 56 { base "public VA" } 57 { base "public VB" } 58 { field public "int w;" } 59 { method public "int f();" } 60 { method public "virtual int vv();" } 61 } 62 63 # class A 64 65 cp_test_ptype_class \ 66 "A" "" "class" "A" \ 67 { 68 { base "public virtual V" } 69 { vbase "V" } 70 { field private "int a;" } 71 { method public "virtual int f();" } 72 } 73 74 # class B 75 76 cp_test_ptype_class \ 77 "B" "" "class" "B" \ 78 { 79 { base "public A" } 80 { field private "int b;" } 81 { method public "virtual int f();" } 82 } 83 84 # class C 85 86 cp_test_ptype_class \ 87 "C" "" "class" "C" \ 88 { 89 { base "public virtual V" } 90 { vbase "V" } 91 { field public "int c;" } 92 } 93 94 # class AD 95 96 cp_test_ptype_class \ 97 "AD" "" "class" "AD" \ 98 { 99 { method public "virtual int vg();" } 100 } 101 102 # class D 103 104 cp_test_ptype_class \ 105 "D" "" "class" "D" \ 106 { 107 { base "public AD" } 108 { base "public virtual V" } 109 { vbase "V" } 110 { method public "static void s();" } 111 { method public "virtual int vg();" } 112 { method public "virtual int vd();" } 113 { method public "int fd();" } 114 { field public "int d;" } 115 } 116 117 # class E 118 119 cp_test_ptype_class \ 120 "E" "" "class" "E" \ 121 { 122 { base "public B" } 123 { base "public virtual V" } 124 { base "public D" } 125 { base "public C" } 126 { vbase "V" } 127 { method public "virtual int f();" } 128 { method public "virtual int vg();" } 129 { method public "virtual int vv();" } 130 { field public "int e;" } 131 } 132 133 # An instance of D 134 135 cp_test_ptype_class "dd" "" "class" "D" ibid 136 137 # An instance of D * 138 139 cp_test_ptype_class "ppd" "" "class" "D" ibid "*" 140 141 # An instance of AD * 142 # TODO: this should be named pADd, not pAd. 143 144 cp_test_ptype_class "pAd" "" "class" "AD" ibid "*" 145 146 # Instances of these classes. 147 148 cp_test_ptype_class "a" "" "class" "A" ibid 149 cp_test_ptype_class "b" "" "class" "B" ibid 150 cp_test_ptype_class "c" "" "class" "C" ibid 151 cp_test_ptype_class "d" "" "class" "D" ibid 152 cp_test_ptype_class "e" "" "class" "E" ibid 153 cp_test_ptype_class "v" "" "class" "V" ibid 154 cp_test_ptype_class "vb" "" "class" "VB" ibid 155 156 # Instances of pointers to these classes. 157 158 cp_test_ptype_class "pAa" "" "class" "A" ibid "*" 159 cp_test_ptype_class "pAe" "" "class" "A" ibid "*" 160 cp_test_ptype_class "pBe" "" "class" "B" ibid "*" 161 cp_test_ptype_class "pDd" "" "class" "D" ibid "*" 162 cp_test_ptype_class "pDe" "" "class" "D" ibid "*" 163 cp_test_ptype_class "pVa" "" "class" "V" ibid "*" 164 cp_test_ptype_class "pVv" "" "class" "V" ibid "*" 165 cp_test_ptype_class "pVe" "" "class" "V" ibid "*" 166 cp_test_ptype_class "pVd" "" "class" "V" ibid "*" 167 cp_test_ptype_class "pADe" "" "class" "AD" ibid "*" 168 cp_test_ptype_class "pEe" "" "class" "E" ibid "*" 169 cp_test_ptype_class "pVB" "" "class" "VB" ibid "*" 170 171} 172 173# Call virtual functions. 174 175proc test_virtual_calls {} { 176 global gdb_prompt 177 global nl 178 179 if [target_info exists gdb,cannot_call_functions] { 180 unsupported "this target can not call functions" 181 return 0 182 } 183 184 gdb_test "print pAe->f()" "\\$\[0-9\]+ = 20" 185 gdb_test "print pAa->f()" "\\$\[0-9\]+ = 1" 186 gdb_test "print pDe->vg()" "\\$\[0-9\]+ = 202" 187 gdb_test "print pADe->vg()" "\\$\[0-9\]+ = 202" 188 gdb_test "print pDd->vg()" "\\$\[0-9\]+ = 101" 189 gdb_test "print pEe->vvb()" "\\$\[0-9\]+ = 411" 190 gdb_test "print pVB->vvb()" "\\$\[0-9\]+ = 407" 191 gdb_test "print pBe->vvb()" "\\$\[0-9\]+ = 411" 192 gdb_test "print pDe->vvb()" "\\$\[0-9\]+ = 411" 193 gdb_test "print pEe->vd()" "\\$\[0-9\]+ = 282" 194 gdb_test "print pEe->fvb()" "\\$\[0-9\]+ = 311" 195 196 # more recent results: 197 # wrong value "202" 198 # gcc 2.95.3 -gdwarf-2 199 # gcc 2.95.3 -gstabs+ 200 # attempt to take addres of value not located in memory 201 # gcc 3.3.2 -gdwarf-2 202 # gcc 3.3.2 -gstabs+ 203 # 204 # -- chastain 2003-12-31 205 206 gdb_test_multiple "print pEe->D::vg()" "print pEe->D::vg()" { 207 -re "\\$\[0-9]+ = 102$nl$gdb_prompt $" { 208 pass "print pEe->D::vg()" 209 } 210 -re "\\$\[0-9]+ = 202$nl$gdb_prompt $" { 211 # To get this result, we have called pEe->*(&D::vg) (). 212 # That's how GDB interprets this, but it's wrong; in fact 213 # the explicit D:: means to bypass virtual function lookup, 214 # and call D::vg as if it were non-virtual. We still have 215 # to e.g. adjust "this", though. 216 kfail "gdb/1064" "print pEe->D::vg()" 217 } 218 -re "Attempt to take address of value not located in memory.$nl$gdb_prompt $" { 219 kfail "gdb/1064" "print pEe->D::vg()" 220 } 221 } 222} 223 224# A helper proc that creates a regular expression matching a 225# particular vtable. NAME is the type name. Each element of ARGS is 226# the name of a function in the vtable. 227 228proc make_one_vtable_result {name args} { 229 global hex 230 231 set nls "\[\r\n\]+" 232 233 set result "vtable for '${name}' @ $hex .subobject @ $hex.:$nls" 234 set count 0 235 foreach func $args { 236 append result ".${count}.:( @$hex:)? $hex <(\.)?$func..>${nls}" 237 incr count 238 } 239 240 return $result 241} 242 243# Test "info vtbl". 244 245proc test_info_vtbl {} { 246 global hex 247 248 set nls "\[\r\n\]+" 249 250 set vt_A [make_one_vtable_result A A::f] 251 set vt_B [make_one_vtable_result B B::f] 252 set vt_V [make_one_vtable_result V VB::vvb V::vv] 253 set vt_V2 [make_one_vtable_result V VB::vvb "virtual thunk to E::vv"] 254 set vt_D [make_one_vtable_result D D::vg D::vd] 255 set vt_D2 [make_one_vtable_result D "non-virtual thunk to E::vg" D::vd] 256 set vt_E [make_one_vtable_result E E::f E::vg E::vv] 257 258 gdb_test "info vtbl a" "${vt_A}${vt_V}" 259 gdb_test "info vtbl b" "${vt_B}${vt_V}" 260 gdb_test "info vtbl c" "${vt_V}" 261 gdb_test "info vtbl d" "${vt_D}${vt_V}" 262 gdb_test "info vtbl e" "${vt_E}${vt_D2}${vt_V2}" 263 gdb_test "info vtbl pEe" "${vt_E}${vt_D2}${vt_V2}" 264 265 gdb_test "info vtbl" "Argument required.*" 266 gdb_test "info vtbl va" \ 267 "This object does not have a virtual function table.*" 268 gdb_test "info vtbl all_count" \ 269 "This object does not have a virtual function table.*" 270} 271 272proc do_tests {} { 273 gdb_test_no_output "set language c++" "" 274 gdb_test_no_output "set width 0" "" 275 276 if {![runto_main]} { 277 return 278 } 279 test_ptype_of_classes 280 test_info_vtbl 281 282 gdb_breakpoint test_calls 283 gdb_test "continue" ".*Breakpoint .* test_calls.*" "" 284 test_virtual_calls 285 286 gdb_test "next" ".*pAa->f.*" "next to pAa->f call" 287 gdb_test "next" ".*pDe->vg.*" "next to pDe->vg call" 288 gdb_test "step" ".*E::vg.*" "step through thunk into E::vg" 289} 290 291do_tests 292