| 1 | # Copyright 1992-2020 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 \ |
| 28 | {debug c++ additional_flags=-Wno-deprecated-register}]} { |
| 29 | return -1 |
| 30 | } |
| 31 | |
| 32 | # Test ptype of class objects. |
| 33 | |
| 34 | proc test_ptype_class_objects {} { |
| 35 | |
| 36 | # Simple type. |
| 37 | |
| 38 | cp_test_ptype_class \ |
| 39 | "struct default_public_struct" "" "struct" "default_public_struct" \ |
| 40 | { |
| 41 | { field public "int a;" } |
| 42 | { field public "int b;" } |
| 43 | } |
| 44 | |
| 45 | # Another simple type. |
| 46 | |
| 47 | cp_test_ptype_class \ |
| 48 | "struct explicit_public_struct" "" "struct" "explicit_public_struct" \ |
| 49 | { |
| 50 | { field public "int a;" } |
| 51 | { field public "int b;" } |
| 52 | } |
| 53 | |
| 54 | # Another simple type. |
| 55 | |
| 56 | cp_test_ptype_class \ |
| 57 | "struct protected_struct" "" "struct" "protected_struct" \ |
| 58 | { |
| 59 | { field protected "int a;" } |
| 60 | { field protected "int b;" } |
| 61 | } |
| 62 | |
| 63 | # Another simple type. |
| 64 | |
| 65 | cp_test_ptype_class \ |
| 66 | "struct private_struct" "" "struct" "private_struct" \ |
| 67 | { |
| 68 | { field private "int a;" } |
| 69 | { field private "int b;" } |
| 70 | } |
| 71 | |
| 72 | # A bigger type. |
| 73 | |
| 74 | cp_test_ptype_class \ |
| 75 | "struct mixed_protection_struct" "" "struct" "mixed_protection_struct" \ |
| 76 | { |
| 77 | { field public "int a;" } |
| 78 | { field public "int b;" } |
| 79 | { field private "int c;" } |
| 80 | { field private "int d;" } |
| 81 | { field protected "int e;" } |
| 82 | { field protected "int f;" } |
| 83 | { field public "int g;" } |
| 84 | { field private "int h;" } |
| 85 | { field protected "int i;" } |
| 86 | } |
| 87 | |
| 88 | # All that again with "class" instead of "struct". |
| 89 | # gdb does not care about the difference anyways. |
| 90 | |
| 91 | cp_test_ptype_class \ |
| 92 | "class public_class" "" "class" "public_class" \ |
| 93 | { |
| 94 | { field public "int a;" } |
| 95 | { field public "int b;" } |
| 96 | } |
| 97 | |
| 98 | # Another simple type. |
| 99 | |
| 100 | cp_test_ptype_class \ |
| 101 | "class protected_class" "" "class" "protected_class" \ |
| 102 | { |
| 103 | { field protected "int a;" } |
| 104 | { field protected "int b;" } |
| 105 | } |
| 106 | |
| 107 | # Another simple type. |
| 108 | |
| 109 | cp_test_ptype_class \ |
| 110 | "class default_private_class" "" "class" "default_private_class" \ |
| 111 | { |
| 112 | { field private "int a;" } |
| 113 | { field private "int b;" } |
| 114 | } |
| 115 | |
| 116 | # Another simple type. |
| 117 | |
| 118 | cp_test_ptype_class \ |
| 119 | "class explicit_private_class" "" "class" "explicit_private_class" \ |
| 120 | { |
| 121 | { field private "int a;" } |
| 122 | { field private "int b;" } |
| 123 | } |
| 124 | |
| 125 | # A bigger type. |
| 126 | |
| 127 | cp_test_ptype_class \ |
| 128 | "class mixed_protection_class" "" "class" "mixed_protection_class" \ |
| 129 | { |
| 130 | |
| 131 | { field public "int a;" } |
| 132 | { field public "int b;" } |
| 133 | { field private "int c;" } |
| 134 | { field private "int d;" } |
| 135 | { field protected "int e;" } |
| 136 | { field protected "int f;" } |
| 137 | { field public "int g;" } |
| 138 | { field private "int h;" } |
| 139 | { field protected "int i;" } |
| 140 | } |
| 141 | |
| 142 | # Here are some classes with inheritance. |
| 143 | |
| 144 | # Base class. |
| 145 | |
| 146 | cp_test_ptype_class \ |
| 147 | "class A" "" "class" "A" \ |
| 148 | { |
| 149 | { field public "int a;" } |
| 150 | { field public "int x;" } |
| 151 | } |
| 152 | |
| 153 | # Derived class. |
| 154 | |
| 155 | cp_test_ptype_class \ |
| 156 | "class B" "" "class" "B" \ |
| 157 | { |
| 158 | { base "public A" } |
| 159 | { field public "int b;" } |
| 160 | { field public "int x;" } |
| 161 | } |
| 162 | |
| 163 | # Derived class. |
| 164 | |
| 165 | cp_test_ptype_class \ |
| 166 | "class C" "" "class" "C" \ |
| 167 | { |
| 168 | { base "public A" } |
| 169 | { field public "int c;" } |
| 170 | { field public "int x;" } |
| 171 | } |
| 172 | |
| 173 | # Derived class, multiple inheritance. |
| 174 | |
| 175 | cp_test_ptype_class \ |
| 176 | "class D" "" "class" "D" \ |
| 177 | { |
| 178 | { base "public B" } |
| 179 | { base "public C" } |
| 180 | { field public "int d;" } |
| 181 | { field public "int x;" } |
| 182 | } |
| 183 | |
| 184 | # Derived class. |
| 185 | |
| 186 | cp_test_ptype_class \ |
| 187 | "class E" "" "class" "E" \ |
| 188 | { |
| 189 | { base "public D" } |
| 190 | { field public "int e;" } |
| 191 | { field public "int x;" } |
| 192 | } |
| 193 | |
| 194 | # This is a break from inheritance tests. |
| 195 | # |
| 196 | # gcc 2.X with stabs (stabs or stabs+?) used to have a problem with |
| 197 | # static methods whose name is the same as their argument mangling. |
| 198 | |
| 199 | cp_test_ptype_class \ |
| 200 | "class Static" "" "class" "Static" \ |
| 201 | { |
| 202 | { method public "static void ii(int, int);" } |
| 203 | } |
| 204 | |
| 205 | # Here are some virtual inheritance tests. |
| 206 | |
| 207 | # A virtual base class. |
| 208 | |
| 209 | cp_test_ptype_class \ |
| 210 | "class vA" "" "class" "vA" \ |
| 211 | { |
| 212 | { field public "int va;" } |
| 213 | { field public "int vx;" } |
| 214 | } |
| 215 | |
| 216 | # A derived class with a virtual base. |
| 217 | |
| 218 | cp_test_ptype_class \ |
| 219 | "class vB" "" "class" "vB" \ |
| 220 | { |
| 221 | { base "public virtual vA" } |
| 222 | { vbase "vA" } |
| 223 | { field public "int vb;" } |
| 224 | { field public "int vx;" } |
| 225 | } |
| 226 | |
| 227 | # Another derived class with a virtual base. |
| 228 | |
| 229 | cp_test_ptype_class \ |
| 230 | "class vC" "" "class" "vC" \ |
| 231 | { |
| 232 | { base "public virtual vA" } |
| 233 | { vbase "vA" } |
| 234 | { field public "int vc;" } |
| 235 | { field public "int vx;" } |
| 236 | } |
| 237 | |
| 238 | # A classic diamond class. |
| 239 | |
| 240 | cp_test_ptype_class \ |
| 241 | "class vD" "" "class" "vD" \ |
| 242 | { |
| 243 | { base "public virtual vB" } |
| 244 | { base "public virtual vC" } |
| 245 | { vbase "vC" } |
| 246 | { vbase "vB" } |
| 247 | { field public "int vd;" } |
| 248 | { field public "int vx;" } |
| 249 | } |
| 250 | |
| 251 | # A class derived from a diamond class. |
| 252 | |
| 253 | cp_test_ptype_class \ |
| 254 | "class vE" "" "class" "vE" \ |
| 255 | { |
| 256 | { base "public virtual vD" } |
| 257 | { vbase "vD" } |
| 258 | { field public "int ve;" } |
| 259 | { field public "int vx;" } |
| 260 | } |
| 261 | |
| 262 | # Another inheritance series. |
| 263 | |
| 264 | # A base class. |
| 265 | |
| 266 | cp_test_ptype_class \ |
| 267 | "class Base1" "" "class" "Base1" \ |
| 268 | { |
| 269 | { field public "int x;" } |
| 270 | { method public "Base1(int);" } |
| 271 | } |
| 272 | |
| 273 | # Another base class. |
| 274 | |
| 275 | cp_test_ptype_class \ |
| 276 | "class Foo" "" "class" "Foo" \ |
| 277 | { |
| 278 | { field public "int x;" } |
| 279 | { field public "int y;" } |
| 280 | { field public "static int st;" } |
| 281 | { method public "Foo(int, int);" } |
| 282 | { method public "int operator!();" } |
| 283 | { method public "operator int();" } |
| 284 | { method public "int times(int);" } |
| 285 | } \ |
| 286 | "" \ |
| 287 | { |
| 288 | { |
| 289 | "operator int();" |
| 290 | "int operator int();" |
| 291 | { setup_kfail "gdb/1497" "*-*-*" } |
| 292 | } |
| 293 | { |
| 294 | "operator int();" |
| 295 | "int operator int(void);" |
| 296 | { setup_kfail "gdb/1497" "*-*-*" } |
| 297 | } |
| 298 | } |
| 299 | |
| 300 | # A multiple inheritance derived class. |
| 301 | |
| 302 | cp_test_ptype_class \ |
| 303 | "class Bar" "" "class" "Bar" \ |
| 304 | { |
| 305 | { base "public Base1" } |
| 306 | { base "public Foo" } |
| 307 | { field public "int z;" } |
| 308 | { method public "Bar(int, int, int);" } |
| 309 | } |
| 310 | |
| 311 | # Derived class with typedef'd baseclass with virtual methods. |
| 312 | |
| 313 | cp_test_ptype_class \ |
| 314 | "class DynamicBar" "" "class" "DynamicBar" \ |
| 315 | { |
| 316 | { base "public DynamicBase2" } |
| 317 | { field public "int y;" } |
| 318 | { method public "DynamicBar(int, int);" } |
| 319 | } |
| 320 | |
| 321 | # Classes with typedefs of different access. |
| 322 | |
| 323 | cp_test_ptype_class \ |
| 324 | "class class_with_typedefs" "" "class" "class_with_typedefs" \ |
| 325 | { |
| 326 | { field protected \ |
| 327 | "class_with_typedefs::public_int public_int_;" } |
| 328 | { field protected \ |
| 329 | "class_with_typedefs::protected_int protected_int_;" } |
| 330 | { field protected \ |
| 331 | "class_with_typedefs::private_int private_int_;" } |
| 332 | { method public "class_with_typedefs(void);" } |
| 333 | { method public "class_with_typedefs::public_int add_public(class_with_typedefs::public_int);" } |
| 334 | { method public \ |
| 335 | "class_with_typedefs::public_int add_all(int);" } |
| 336 | { method protected "class_with_typedefs::protected_int add_protected(class_with_typedefs::protected_int);" } |
| 337 | { method private "class_with_typedefs::private_int add_private(class_with_typedefs::private_int);" } |
| 338 | { typedef public "typedef int public_int;" } |
| 339 | { typedef protected "typedef int protected_int;" } |
| 340 | { typedef private "typedef int private_int;" } |
| 341 | } |
| 342 | |
| 343 | cp_test_ptype_class \ |
| 344 | "class class_with_public_typedef" "" "class" \ |
| 345 | "class_with_public_typedef" { |
| 346 | { field private "int a;" } |
| 347 | { field public "class_with_public_typedef::INT b;" } |
| 348 | { typedef public "typedef int INT;" } |
| 349 | } |
| 350 | cp_test_ptype_class \ |
| 351 | "class class_with_protected_typedef" "" "class" \ |
| 352 | "class_with_protected_typedef" { |
| 353 | { field private "int a;" } |
| 354 | { field protected "class_with_protected_typedef::INT b;" } |
| 355 | { typedef protected "typedef int INT;" } |
| 356 | } |
| 357 | cp_test_ptype_class \ |
| 358 | "struct struct_with_protected_typedef" "" "struct" \ |
| 359 | "struct_with_protected_typedef" { |
| 360 | { field public "int a;" } |
| 361 | { field protected "struct_with_protected_typedef::INT b;" } |
| 362 | { typedef protected "typedef int INT;" } |
| 363 | } |
| 364 | cp_test_ptype_class \ |
| 365 | "struct struct_with_private_typedef" "" "struct" \ |
| 366 | "struct_with_private_typedef" { |
| 367 | { field public "int a;" } |
| 368 | { field private "struct_with_private_typedef::INT b;" } |
| 369 | { typedef private "typedef int INT;" } |
| 370 | } |
| 371 | |
| 372 | # For the following two cases, we cannot use cp_test_ptype_class. |
| 373 | # We need to explicitly check whether the access label was suppressed. |
| 374 | set ws {[ \t\r\n]*} |
| 375 | foreach {tag lbl} {"class" "private" "struct" "public"} { |
| 376 | gdb_test "ptype/r ${tag}_with_${lbl}_typedef" "type = $tag ${tag}_with_${lbl}_typedef \{${ws}int a;${ws}${tag}_with_${lbl}_typedef::INT b;${ws}typedef int INT;${ws}\}" |
| 377 | } |
| 378 | } |
| 379 | |
| 380 | # Test simple access to class members. |
| 381 | |
| 382 | proc test_non_inherited_member_access {} { |
| 383 | |
| 384 | # Print non-inherited members of g_A. |
| 385 | gdb_test "print g_A.a" ".* = 1" |
| 386 | gdb_test "print g_A.x" ".* = 2" |
| 387 | |
| 388 | # Print non-inherited members of g_B. |
| 389 | gdb_test "print g_B.b" ".* = 5" |
| 390 | gdb_test "print g_B.x" ".* = 6" |
| 391 | |
| 392 | # Print non-inherited members of g_C. |
| 393 | gdb_test "print g_C.c" ".* = 9" |
| 394 | gdb_test "print g_C.x" ".* = 10" |
| 395 | |
| 396 | # Print non-inherited members of g_D. |
| 397 | gdb_test "print g_D.d" ".* = 19" |
| 398 | gdb_test "print g_D.x" ".* = 20" |
| 399 | |
| 400 | # Print non-inherited members of g_E. |
| 401 | gdb_test "print g_E.e" ".* = 31" |
| 402 | gdb_test "print g_E.x" ".* = 32" |
| 403 | } |
| 404 | |
| 405 | # Test access to members of other classes. |
| 406 | # gdb should refuse to print them. |
| 407 | # (I feel old -- I remember when this was legal in C -- chastain). |
| 408 | |
| 409 | proc test_wrong_class_members {} { |
| 410 | gdb_test "print g_A.b" "There is no member( or method|) named b." |
| 411 | gdb_test "print g_B.c" "There is no member( or method|) named c." |
| 412 | gdb_test "print g_B.d" "There is no member( or method|) named d." |
| 413 | gdb_test "print g_C.b" "There is no member( or method|) named b." |
| 414 | gdb_test "print g_C.d" "There is no member( or method|) named d." |
| 415 | gdb_test "print g_D.e" "There is no member( or method|) named e." |
| 416 | } |
| 417 | |
| 418 | # Test access to names that are not members of any class. |
| 419 | |
| 420 | proc test_nonexistent_members {} { |
| 421 | gdb_test "print g_A.y" "There is no member( or method|) named y." |
| 422 | gdb_test "print g_B.z" "There is no member( or method|) named z." |
| 423 | gdb_test "print g_C.q" "There is no member( or method|) named q." |
| 424 | gdb_test "print g_D.p" "There is no member( or method|) named p." |
| 425 | } |
| 426 | |
| 427 | # Call a method that expects a base class parameter with base, inherited, |
| 428 | # and unrelated class arguments. |
| 429 | |
| 430 | proc test_method_param_class {} { |
| 431 | gdb_test "call class_param.Aptr_a (&g_A)" ".* = 1" |
| 432 | gdb_test "call class_param.Aptr_x (&g_A)" ".* = 2" |
| 433 | gdb_test "call class_param.Aptr_a (&g_B)" ".* = 3" |
| 434 | gdb_test "call class_param.Aptr_x (&g_B)" ".* = 4" |
| 435 | gdb_test "call class_param.Aref_a (g_A)" ".* = 1" |
| 436 | gdb_test "call class_param.Aref_x (g_A)" ".* = 2" |
| 437 | gdb_test "call class_param.Aref_a (g_B)" ".* = 3" |
| 438 | gdb_test "call class_param.Aref_x (g_B)" ".* = 4" |
| 439 | gdb_test "call class_param.Aval_a (g_A)" ".* = 1" |
| 440 | gdb_test "call class_param.Aval_x (g_A)" ".* = 2" |
| 441 | gdb_test "call class_param.Aval_a (g_B)" ".* = 3" |
| 442 | gdb_test "call class_param.Aval_x (g_B)" ".* = 4" |
| 443 | |
| 444 | gdb_test "call class_param.Aptr_a (&foo)" "Cannot resolve .*" "unrelated class *param" |
| 445 | gdb_test "call class_param.Aref_a (foo)" "Cannot resolve .*" "unrelated class ¶m" |
| 446 | gdb_test "call class_param.Aval_a (foo)" "Cannot resolve .*" "unrelated class param" |
| 447 | } |
| 448 | |
| 449 | # Examine a class with an enum field. |
| 450 | |
| 451 | proc test_enums {} { |
| 452 | global gdb_prompt |
| 453 | global nl |
| 454 | |
| 455 | # print the object |
| 456 | |
| 457 | # We match the enum values with and without qualifiers. As of |
| 458 | # 2008-08-21 we can output the qualifiers for DWARF-2. |
| 459 | |
| 460 | gdb_test "print obj_with_enum" \ |
| 461 | "\\$\[0-9\]+ = \{priv_enum = (ClassWithEnum::)?red, x = 0\}" \ |
| 462 | "print obj_with_enum (1)" |
| 463 | |
| 464 | # advance one line |
| 465 | |
| 466 | gdb_test "next" ".*" |
| 467 | |
| 468 | # print the object again |
| 469 | |
| 470 | gdb_test "print obj_with_enum" \ |
| 471 | "\\$\[0-9\]+ = \{priv_enum = (ClassWithEnum::)?green, x = 0\}" \ |
| 472 | "print obj_with_enum (2)" |
| 473 | |
| 474 | # print the enum member |
| 475 | |
| 476 | gdb_test "print obj_with_enum.priv_enum" "\\$\[0-9\]+ = (ClassWithEnum::)?green" |
| 477 | |
| 478 | # ptype on the enum member |
| 479 | |
| 480 | gdb_test_multiple "ptype obj_with_enum.priv_enum" "ptype obj_with_enum.priv_enum" { |
| 481 | -re "type = enum ClassWithEnum::PrivEnum (: unsigned (int|short|char) )?\{ ?(ClassWithEnum::)?red, (ClassWithEnum::)?green, (ClassWithEnum::)?blue, (ClassWithEnum::)?yellow = 42 ?\}$nl$gdb_prompt $" { |
| 482 | pass "ptype obj_with_enum.priv_enum" |
| 483 | } |
| 484 | -re "type = enum PrivEnum \{ ?(ClassWithEnum::)?red, (ClassWithEnum::)?green, (ClassWithEnum::)?blue, (ClassWithEnum::)?yellow = 42 ?\}$nl$gdb_prompt $" { |
| 485 | # gcc 2.95.3 -gdwarf-2 |
| 486 | # gcc 3.3.2 -gdwarf-2 |
| 487 | pass "ptype obj_with_enum.priv_enum" |
| 488 | } |
| 489 | -re "type = enum \{ ?red, green, blue, yellow = 42 ?\}$nl$gdb_prompt $" { |
| 490 | # This case case is a little dubious, but it's not clear what |
| 491 | # ought to be required of a ptype on a private enum... |
| 492 | # -sts 19990324 |
| 493 | # |
| 494 | # It bugs me that this happens with gcc 3. |
| 495 | # -- chastain 2003-12-30 |
| 496 | # |
| 497 | # gcc 2.95.3 -gstabs+ |
| 498 | # gcc 3.3.2 -gstabs+ |
| 499 | # gcc HEAD 2003-12-28 21:08:30 UTC -gstabs+ |
| 500 | pass "ptype obj_with_enum.priv_enum" |
| 501 | } |
| 502 | } |
| 503 | |
| 504 | # ptype on the object |
| 505 | |
| 506 | # NOTE: carlton/2003-02-28: One could certainly argue that plain |
| 507 | # "PrivEnum" |
| 508 | # is acceptable: PrivEnum is a member of ClassWithEnum, so |
| 509 | # there's no need to explicitly qualify its name with |
| 510 | # "ClassWithEnum::". The truth, though, is that GDB is simply |
| 511 | # forgetting that PrivEnum is a member of ClassWithEnum, so we do |
| 512 | # that output for a bad reason instead of a good reason. Under |
| 513 | # stabs, we probably can't get this right; under DWARF-2, we can. |
| 514 | |
| 515 | cp_test_ptype_class \ |
| 516 | "obj_with_enum" "" "class" "ClassWithEnum" \ |
| 517 | { |
| 518 | { field public "ClassWithEnum::PrivEnum priv_enum;" } |
| 519 | { field public "int x;" } |
| 520 | } \ |
| 521 | "" \ |
| 522 | { |
| 523 | { |
| 524 | "ClassWithEnum::PrivEnum priv_enum;" |
| 525 | "PrivEnum priv_enum;" |
| 526 | { setup_kfail "gdb/57" "*-*-*" } |
| 527 | } |
| 528 | } |
| 529 | |
| 530 | # I'll do this test two different ways, because of a parser bug. |
| 531 | # See PR gdb/1588. |
| 532 | |
| 533 | gdb_test_multiple "print (ClassWithEnum::PrivEnum) 42" "print (ClassWithEnum::PrivEnum) 42" { |
| 534 | -re "\\$\[0-9\]+ = (ClassWithEnum::)?yellow$nl$gdb_prompt $" { |
| 535 | pass "print (ClassWithEnum::PrivEnum) 42" |
| 536 | } |
| 537 | -re "A (parse|syntax) error in expression, near `42'.$nl$gdb_prompt $" { |
| 538 | # "parse error" is bison 1.35. |
| 539 | # "syntax error" is bison 1.875. |
| 540 | kfail "gdb/1588" "print (ClassWithEnum::PrivEnum) 42" |
| 541 | } |
| 542 | } |
| 543 | |
| 544 | gdb_test_multiple "print ('ClassWithEnum::PrivEnum') 42" "print ('ClassWithEnum::PrivEnum') 42" { |
| 545 | -re "\\$\[0-9\]+ = (ClassWithEnum::)?yellow$nl$gdb_prompt $" { |
| 546 | # gcc 3.3.2 -gstabs+ |
| 547 | # gcc HEAD 2003-12-28 21:08:30 UTC -gstabs+ |
| 548 | pass "print ('ClassWithEnum::PrivEnum') 42" |
| 549 | } |
| 550 | -re "No symbol \"ClassWithEnum::PrivEnum\" in current context.$nl$gdb_prompt $" { |
| 551 | # gcc 2.95.3 -gdwarf-2 |
| 552 | # gcc 3.3.2 -gdwarf-2 |
| 553 | # gcc HEAD 2003-12-28 21:08:30 UTC -gdwarf-2 |
| 554 | # gcc 2.95.3 -gstabs+ |
| 555 | kfail "gdb/57" "print ('ClassWithEnum::PrivEnum') 42" |
| 556 | } |
| 557 | } |
| 558 | } |
| 559 | |
| 560 | # Pointers to class members |
| 561 | |
| 562 | proc test_pointers_to_class_members {} { |
| 563 | gdb_test "print Bar::z" "Cannot reference non-static field \"z\"" |
| 564 | gdb_test "print &Foo::x" "\\$\[0-9\]+ = &Foo::x" |
| 565 | gdb_test "print (int)&Foo::x" "\\$\[0-9\]+ = 0" |
| 566 | gdb_test "print (int)&Bar::y == 2*sizeof(int)" "\\$\[0-9\]+ = true" |
| 567 | |
| 568 | gdb_test "ptype Bar::z" "type = int" |
| 569 | gdb_test "ptype &Bar::z" "type = int Bar::\\*" |
| 570 | |
| 571 | # TODO: this is a bogus test. It's looking at a variable that |
| 572 | # has not even been declared yet, so it's accessing random junk |
| 573 | # on the stack and comparing that it's NOT equal to a specific |
| 574 | # value. It's been like this since gdb 4.10 in 1993! |
| 575 | # -- chastain 2004-01-01 |
| 576 | gdb_test "print (int)pmi == sizeof(int)" ".* = false" |
| 577 | } |
| 578 | |
| 579 | # Test static members. |
| 580 | |
| 581 | proc test_static_members {} { |
| 582 | global hex |
| 583 | |
| 584 | gdb_test "print Foo::st" "\\$\[0-9\]+ = 100" |
| 585 | gdb_test_no_output "set foo.st = 200" "" |
| 586 | gdb_test "print bar.st" "\\$\[0-9\]+ = 200" |
| 587 | gdb_test "print &foo.st" "\\$\[0-9\]+ = \\(int ?\\*\\) $hex <Foo::st>" |
| 588 | gdb_test "print &Bar::st" "\\$\[0-9\]+ = \\(int ?\\*\\) $hex <Foo::st>" |
| 589 | gdb_test "print *\$" "\\$\[0-9\]+ = 200" |
| 590 | |
| 591 | gdb_test_no_output "set print static-members off" |
| 592 | gdb_test "print csi" \ |
| 593 | "{x = 10, y = 20}" \ |
| 594 | "print csi without static members" |
| 595 | gdb_test "print cnsi" \ |
| 596 | "{x = 30, y = 40}" \ |
| 597 | "print cnsi without static members" |
| 598 | |
| 599 | gdb_test_no_output "set print static-members on" |
| 600 | gdb_test "print csi" \ |
| 601 | "{x = 10, y = 20, static null = {x = 0, y = 0, static null = <same as static member of an already seen type>}}" \ |
| 602 | "print csi with static members" |
| 603 | gdb_test "print cnsi" \ |
| 604 | "{x = 30, y = 40, static null = {x = 0, y = 0, static null = <same as static member of an already seen type>, static yy = {z = 5, static xx = {x = 1, y = 2, static null = <same as static member of an already seen type>, static yy = <same as static member of an already seen type>}}}, static yy = <same as static member of an already seen type>}" \ |
| 605 | "print cnsi with static members" |
| 606 | |
| 607 | # Another case of infinite recursion. |
| 608 | gdb_test "print Outer::instance" \ |
| 609 | "{inner = {static instance = {static instance = <same as static member of an already seen type>}}, static instance = {inner = {static instance = {static instance = <same as static member of an already seen type>}}, static instance = <same as static member of an already seen type>}}" \ |
| 610 | "print recursive static member" |
| 611 | } |
| 612 | |
| 613 | proc do_tests {} { |
| 614 | global gdb_prompt |
| 615 | global nl |
| 616 | |
| 617 | |
| 618 | gdb_test_no_output "set language c++" "" |
| 619 | gdb_test_no_output "set width 0" "" |
| 620 | |
| 621 | if ![runto_main ] then { |
| 622 | perror "couldn't run to breakpoint" |
| 623 | return |
| 624 | } |
| 625 | |
| 626 | gdb_breakpoint inheritance2 |
| 627 | gdb_test "continue" ".*Breakpoint .* inheritance2.*" "" |
| 628 | |
| 629 | test_ptype_class_objects |
| 630 | test_non_inherited_member_access |
| 631 | test_wrong_class_members |
| 632 | test_nonexistent_members |
| 633 | test_method_param_class |
| 634 | |
| 635 | gdb_breakpoint enums2 |
| 636 | gdb_test "continue" ".*Breakpoint .* enums2.*" "continue to enums2(\\(\\)|)" |
| 637 | # Leave enums2. Make sure we reach the next line, in case there |
| 638 | # are any more instructions to finish the function call. |
| 639 | gdb_test_multiple "finish" "" { |
| 640 | -re "enums2 \\(\\);.*$gdb_prompt $" { |
| 641 | gdb_test "next" ".*" "" |
| 642 | } |
| 643 | -re "$gdb_prompt $" { } |
| 644 | } |
| 645 | test_enums |
| 646 | |
| 647 | gdb_test "finish" ".*" "" |
| 648 | test_pointers_to_class_members |
| 649 | test_static_members |
| 650 | |
| 651 | # Now some random tests that were just thrown in here. |
| 652 | |
| 653 | gdb_breakpoint marker_reg1 |
| 654 | gdb_test "continue" ".*Breakpoint .* marker_reg1.*" "" |
| 655 | gdb_test "finish" "Run till exit from.*" "finish from marker_reg1" |
| 656 | |
| 657 | # This class is so small that an instance of it can fit in a register. |
| 658 | # When gdb tries to call a method, it gets embarrassed about taking |
| 659 | # the address of a register. |
| 660 | # |
| 661 | # TODO: I think that message should be a PASS, not an XFAIL. |
| 662 | # gdb prints an informative message and declines to do something |
| 663 | # impossible. |
| 664 | # |
| 665 | # The method call actually succeeds if the compiler allocates very |
| 666 | # small classes in memory instead of registers. So this test does |
| 667 | # not tell us anything interesting if the call succeeds. |
| 668 | # |
| 669 | # -- chastain 2003-12-31 |
| 670 | gdb_test_multiple "print v.method ()" "calling method for small class" { |
| 671 | -re "\\$\[0-9\]+ = 82$nl$gdb_prompt $" { |
| 672 | # gcc 3.3.2 -gdwarf-2 |
| 673 | # gcc HEAD 2003-12-28 21:08:30 UTC -gdwarf-2 |
| 674 | # gcc 3.3.2 -gstabs+ |
| 675 | # gcc HEAD 2003-12-28 21:08:30 UTC -gstabs+ |
| 676 | pass "calling method for small class" |
| 677 | } |
| 678 | -re "Address requested for identifier \"v\" which is in register .*$nl$gdb_prompt $" { |
| 679 | # gcc 2.95.3 -gdwarf-2 |
| 680 | # gcc 2.95.3 -gstabs+ |
| 681 | setup_xfail "*-*-*" 2972 |
| 682 | fail "calling method for small class" |
| 683 | } |
| 684 | } |
| 685 | |
| 686 | gdb_test "print base1::Base1" "<.*Base1.*>" "print ctor of typedef class" |
| 687 | gdb_test "print base1::~Base1" "<.*~Base1(\\(\\))?>" \ |
| 688 | "print dtor of typedef class" |
| 689 | |
| 690 | gdb_test "list ByAnyOtherName::times" ".*int Foo::times.*" |
| 691 | } |
| 692 | |
| 693 | do_tests |