| 1 | # Copyright 1992-2019 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 | |
| 19 | set nl "\[\r\n\]+" |
| 20 | |
| 21 | if { [skip_cplus_tests] } { continue } |
| 22 | |
| 23 | load_lib "cp-support.exp" |
| 24 | |
| 25 | standard_testfile .cc |
| 26 | |
| 27 | if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug c++}]} { |
| 28 | return -1 |
| 29 | } |
| 30 | |
| 31 | proc 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 | |
| 175 | proc 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 | |
| 228 | proc 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 | |
| 245 | proc 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 | |
| 272 | proc do_tests {} { |
| 273 | gdb_test_no_output "set language c++" "" |
| 274 | gdb_test_no_output "set width 0" "" |
| 275 | |
| 276 | if ![runto_main] then { |
| 277 | perror "couldn't run to breakpoint" |
| 278 | return |
| 279 | } |
| 280 | test_ptype_of_classes |
| 281 | test_info_vtbl |
| 282 | |
| 283 | gdb_breakpoint test_calls |
| 284 | gdb_test "continue" ".*Breakpoint .* test_calls.*" "" |
| 285 | test_virtual_calls |
| 286 | |
| 287 | gdb_test "next" ".*pAa->f.*" "next to pAa->f call" |
| 288 | gdb_test "next" ".*pDe->vg.*" "next to pDe->vg call" |
| 289 | gdb_test "step" ".*E::vg.*" "step through thunk into E::vg" |
| 290 | } |
| 291 | |
| 292 | do_tests |