]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/testsuite/gdb.cp/classes.cc
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / gdb / testsuite / gdb.cp / classes.cc
1 /* This testcase is part of GDB, the GNU debugger.
2
3 Copyright 1993-2024 Free Software Foundation, Inc.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18 // Test various -*- C++ -*- things.
19
20 // ====================== basic C++ types =======================
21 bool v_bool;
22 bool v_bool_array[2];
23
24 typedef struct fleep fleep;
25 struct fleep { int a; } s;
26
27 // ====================== simple class structures =======================
28
29 struct default_public_struct {
30 // defaults to public:
31 int a;
32 int b;
33 };
34
35 struct explicit_public_struct {
36 public:
37 int a;
38 int b;
39 };
40
41 struct protected_struct {
42 protected:
43 int a;
44 int b;
45 };
46
47 struct private_struct {
48 private:
49 int a;
50 int b;
51 };
52
53 struct mixed_protection_struct {
54 public:
55 int a;
56 int b;
57 private:
58 int c;
59 int d;
60 protected:
61 int e;
62 int f;
63 public:
64 int g;
65 private:
66 int h;
67 protected:
68 int i;
69 };
70
71 class public_class {
72 public:
73 int a;
74 int b;
75 };
76
77 class protected_class {
78 protected:
79 int a;
80 int b;
81 };
82
83 class default_private_class {
84 // defaults to private:
85 int a;
86 int b;
87 };
88
89 class explicit_private_class {
90 private:
91 int a;
92 int b;
93 };
94
95 class mixed_protection_class {
96 public:
97 int a;
98 int b;
99 private:
100 int c;
101 int d;
102 protected:
103 int e;
104 int f;
105 public:
106 int g;
107 private:
108 int h;
109 protected:
110 int i;
111 };
112
113 class const_vol_method_class {
114 public:
115 int a;
116 int b;
117 int foo (int &) const;
118 int bar (int &) volatile;
119 int baz (int &) const volatile;
120 };
121
122 int const_vol_method_class::foo (int & ir) const
123 {
124 return ir + 3;
125 }
126 int const_vol_method_class::bar (int & ir) volatile
127 {
128 return ir + 4;
129 }
130 int const_vol_method_class::baz (int & ir) const volatile
131 {
132 return ir + 5;
133 }
134
135 // ========================= simple inheritance ==========================
136
137 class A {
138 public:
139 int a;
140 int x;
141 };
142
143 A g_A;
144
145 class B : public A {
146 public:
147 int b;
148 int x;
149 };
150
151 B g_B;
152
153 class C : public A {
154 public:
155 int c;
156 int x;
157 };
158
159 C g_C;
160
161 class D : public B, public C {
162 public:
163 int d;
164 int x;
165 };
166
167 D g_D;
168
169 class E : public D {
170 public:
171 int e;
172 int x;
173 };
174
175 E g_E;
176
177 class class_with_anon_union
178 {
179 public:
180 int one;
181 union
182 {
183 int a;
184 long b;
185 };
186 };
187
188 class_with_anon_union g_anon_union;
189
190 void inheritance2 (void)
191 {
192 }
193
194 void inheritance1 (void)
195 {
196 int ival;
197 int *intp;
198
199 // {A::a, A::x}
200
201 g_A.A::a = 1;
202 g_A.A::x = 2;
203
204 // {{A::a,A::x},B::b,B::x}
205
206 g_B.A::a = 3;
207 g_B.A::x = 4;
208 g_B.B::b = 5;
209 g_B.B::x = 6;
210
211 // {{A::a,A::x},C::c,C::x}
212
213 g_C.A::a = 7;
214 g_C.A::x = 8;
215 g_C.C::c = 9;
216 g_C.C::x = 10;
217
218 // {{{A::a,A::x},B::b,B::x},{{A::a,A::x},C::c,C::x},D::d,D::x}
219
220 // The following initialization code is non-portable, but allows us
221 // to initialize all members of g_D until we can fill in the missing
222 // initialization code with legal C++ code.
223
224 for (intp = (int *) &g_D, ival = 11;
225 intp < ((int *) &g_D + sizeof (g_D) / sizeof (int));
226 intp++, ival++)
227 {
228 *intp = ival;
229 }
230
231 // Overlay the nonportable initialization with legal initialization.
232
233 // ????? = 11; (g_D.A::a = 11; is ambiguous)
234 // ????? = 12; (g_D.A::x = 12; is ambiguous)
235 /* djb 6-3-2000
236
237 This should take care of it. Rather than try to initialize using an ambiguous
238 construct, use 2 unambiguous ones for each. Since the ambiguous a/x member is
239 coming from C, and B, initialize D's C::a, and B::a, and D's C::x and B::x.
240 */
241 g_D.C::a = 15;
242 g_D.C::x = 12;
243 g_D.B::a = 11;
244 g_D.B::x = 12;
245 g_D.B::b = 13;
246 g_D.B::x = 14;
247 // ????? = 15;
248 // ????? = 16;
249 g_D.C::c = 17;
250 g_D.C::x = 18;
251 g_D.D::d = 19;
252 g_D.D::x = 20;
253
254
255 // {{{{A::a,A::x},B::b,B::x},{{A::a,A::x},C::c,C::x},D::d,D::x}},E::e,E::x}
256
257 // The following initialization code is non-portable, but allows us
258 // to initialize all members of g_D until we can fill in the missing
259 // initialization code with legal C++ code.
260
261 for (intp = (int *) &g_E, ival = 21;
262 intp < ((int *) &g_E + sizeof (g_E) / sizeof (int));
263 intp++, ival++)
264 {
265 *intp = ival;
266 }
267
268 // Overlay the nonportable initialization with legal initialization.
269
270 // ????? = 21; (g_E.A::a = 21; is ambiguous)
271 // ????? = 22; (g_E.A::x = 22; is ambiguous)
272 g_E.B::b = 23;
273 g_E.B::x = 24;
274 // ????? = 25;
275 // ????? = 26;
276 g_E.C::c = 27;
277 g_E.C::x = 28;
278 g_E.D::d = 29;
279 g_E.D::x = 30;
280 g_E.E::e = 31;
281 g_E.E::x = 32;
282
283 g_anon_union.one = 1;
284 g_anon_union.a = 2;
285
286 inheritance2 ();
287 }
288
289 // ======================== static member functions =====================
290
291 class Static {
292 public:
293 static void ii(int, int);
294 };
295 void Static::ii (int, int) { }
296
297 // ======================== virtual base classes=========================
298
299 class vA {
300 public:
301 int va;
302 int vx;
303 };
304
305 vA g_vA;
306
307 class vB : public virtual vA {
308 public:
309 int vb;
310 int vx;
311 };
312
313 vB g_vB;
314
315 class vC : public virtual vA {
316 public:
317 int vc;
318 int vx;
319 };
320
321 vC g_vC;
322
323 class vD : public virtual vB, public virtual vC {
324 public:
325 int vd;
326 int vx;
327 };
328
329 vD g_vD;
330
331 class vE : public virtual vD {
332 public:
333 int ve;
334 int vx;
335 };
336
337 vE g_vE;
338
339 void inheritance4 (void)
340 {
341 }
342
343 void inheritance3 (void)
344 {
345 int ival;
346 int *intp;
347
348 // {vA::va, vA::vx}
349
350 g_vA.vA::va = 1;
351 g_vA.vA::vx = 2;
352
353 // {{vA::va, vA::vx}, vB::vb, vB::vx}
354
355 g_vB.vA::va = 3;
356 g_vB.vA::vx = 4;
357 g_vB.vB::vb = 5;
358 g_vB.vB::vx = 6;
359
360 // {{vA::va, vA::vx}, vC::vc, vC::vx}
361
362 g_vC.vA::va = 7;
363 g_vC.vA::vx = 8;
364 g_vC.vC::vc = 9;
365 g_vC.vC::vx = 10;
366
367 // {{{{vA::va, vA::vx}, vB::vb, vB::vx}, vC::vc, vC::vx}, vD::vd,vD::vx}
368
369 g_vD.vA::va = 11;
370 g_vD.vA::vx = 12;
371 g_vD.vB::vb = 13;
372 g_vD.vB::vx = 14;
373 g_vD.vC::vc = 15;
374 g_vD.vC::vx = 16;
375 g_vD.vD::vd = 17;
376 g_vD.vD::vx = 18;
377
378
379 // {{{{{vA::va,vA::vx},vB::vb,vB::vx},vC::vc,vC::vx},vD::vd,vD::vx},vE::ve,vE::vx}
380
381 g_vD.vA::va = 19;
382 g_vD.vA::vx = 20;
383 g_vD.vB::vb = 21;
384 g_vD.vB::vx = 22;
385 g_vD.vC::vc = 23;
386 g_vD.vC::vx = 24;
387 g_vD.vD::vd = 25;
388 g_vD.vD::vx = 26;
389 g_vE.vE::ve = 27;
390 g_vE.vE::vx = 28;
391
392 inheritance4 ();
393 }
394
395 // ======================================================================
396
397 class Base1 {
398 public:
399 int x;
400 Base1(int i) { x = i; }
401 ~Base1 () { }
402 };
403
404 typedef Base1 base1;
405
406 class Foo
407 {
408 public:
409 int x;
410 int y;
411 static int st;
412 Foo (int i, int j) { x = i; y = j; }
413 int operator! ();
414 operator int ();
415 int times (int y);
416 };
417
418 typedef Foo ByAnyOtherName;
419
420 class Bar : public Base1, public Foo {
421 public:
422 int z;
423 Bar (int i, int j, int k) : Base1 (10*k), Foo (i, j) { z = k; }
424 };
425
426 int Foo::operator! () { return !x; }
427
428 int Foo::times (int y) { return x * y; }
429
430 int Foo::st = 100;
431
432 Foo::operator int() { return x; }
433
434 ByAnyOtherName foo(10, 11);
435 Bar bar(20, 21, 22);
436
437 /* Use a typedef for the baseclass to exercise gnu-v3-abi.c:gnuv3_dynamic_class
438 recursion. It's important that the class itself have no name to make sure
439 the typedef makes it through to the recursive call. */
440 typedef class {
441 public:
442 int x;
443 virtual int get_x () { return x; }
444 } DynamicBase2;
445
446 class DynamicBar : public DynamicBase2
447 {
448 public:
449 DynamicBar (int i, int j) { x = i; y = j; }
450 int y;
451 };
452
453 DynamicBar dynbar (23, 24);
454
455 class ClassWithEnum {
456 public:
457 enum PrivEnum { red, green, blue, yellow = 42 };
458 PrivEnum priv_enum;
459 int x;
460 };
461
462 void enums2 (void)
463 {
464 }
465
466 /* classes.exp relies on statement order in this function for testing
467 enumeration fields. */
468
469 void enums1 ()
470 {
471 ClassWithEnum obj_with_enum;
472 obj_with_enum.priv_enum = ClassWithEnum::red;
473 obj_with_enum.x = 0;
474 enums2 ();
475 obj_with_enum.priv_enum = ClassWithEnum::green;
476 obj_with_enum.x = 1;
477 }
478
479 class ClassParam {
480 public:
481 int Aptr_a (A *a) { return a->a; }
482 int Aptr_x (A *a) { return a->x; }
483 int Aref_a (A &a) { return a.a; }
484 int Aref_x (A &a) { return a.x; }
485 int Aval_a (A a) { return a.a; }
486 int Aval_x (A a) { return a.x; }
487 };
488
489 ClassParam class_param;
490
491 class Contains_static_instance
492 {
493 public:
494 int x;
495 int y;
496 Contains_static_instance (int i, int j) { x = i; y = j; }
497 static Contains_static_instance null;
498 };
499
500 Contains_static_instance Contains_static_instance::null(0,0);
501 Contains_static_instance csi(10,20);
502
503 class Contains_nested_static_instance
504 {
505 public:
506 class Nested
507 {
508 public:
509 Nested(int i) : z(i) {}
510 int z;
511 static Contains_nested_static_instance xx;
512 };
513
514 Contains_nested_static_instance(int i, int j) : x(i), y(j) {}
515
516 int x;
517 int y;
518
519 static Contains_nested_static_instance null;
520 static Nested yy;
521 };
522
523 Contains_nested_static_instance Contains_nested_static_instance::null(0, 0);
524 Contains_nested_static_instance::Nested Contains_nested_static_instance::yy(5);
525 Contains_nested_static_instance
526 Contains_nested_static_instance::Nested::xx(1,2);
527 Contains_nested_static_instance cnsi(30,40);
528
529 typedef struct {
530 int one;
531 int two;
532 } tagless_struct;
533 tagless_struct v_tagless;
534
535 class class_with_typedefs
536 {
537 public:
538 typedef int public_int;
539 protected:
540 typedef int protected_int;
541 private:
542 typedef int private_int;
543
544 public:
545 class_with_typedefs ()
546 : public_int_ (1), protected_int_ (2), private_int_ (3) {}
547 public_int add_public (public_int a) { return a + public_int_; }
548 public_int add_all (int a)
549 { return add_public (a) + add_protected (a) + add_private (a); }
550
551 protected:
552 protected_int add_protected (protected_int a) { return a + protected_int_; }
553
554 private:
555 private_int add_private (private_int a) { return a + private_int_; }
556
557 protected:
558 public_int public_int_;
559 protected_int protected_int_;
560 private_int private_int_;
561 };
562
563 class class_with_public_typedef
564 {
565 int a;
566 public:
567 typedef int INT;
568 INT b;
569 };
570
571 class class_with_protected_typedef
572 {
573 int a;
574 protected:
575 typedef int INT;
576 INT b;
577 };
578
579 class class_with_private_typedef
580 {
581 int a;
582 private:
583 typedef int INT;
584 INT b;
585 };
586
587 struct struct_with_public_typedef
588 {
589 int a;
590 public:
591 typedef int INT;
592 INT b;
593 };
594
595 struct struct_with_protected_typedef
596 {
597 int a;
598 protected:
599 typedef int INT;
600 INT b;
601 };
602
603 struct struct_with_private_typedef
604 {
605 int a;
606 private:
607 typedef int INT;
608 INT b;
609 };
610
611 void dummy()
612 {
613 v_bool = true;
614 v_bool_array[0] = false;
615 v_bool_array[1] = v_bool;
616 }
617
618 void use_methods ()
619 {
620 /* Refer to methods so that they don't get optimized away. */
621 int i;
622 i = class_param.Aptr_a (&g_A);
623 i = class_param.Aptr_x (&g_A);
624 i = class_param.Aref_a (g_A);
625 i = class_param.Aref_x (g_A);
626 i = class_param.Aval_a (g_A);
627 i = class_param.Aval_x (g_A);
628
629 base1 b (3);
630 }
631
632 struct Inner
633 {
634 static Inner instance;
635 };
636
637 struct Outer
638 {
639 Inner inner;
640 static Outer instance;
641 };
642
643 Inner Inner::instance;
644 Outer Outer::instance;
645
646 int
647 main()
648 {
649 int Foo::* pmi = &Foo::y;
650
651 dummy();
652 inheritance1 ();
653 inheritance3 ();
654 enums1 ();
655
656 /* Make sure the AIX linker doesn't remove the variable. */
657 v_tagless.one = 5;
658
659 use_methods ();
660
661 return foo.*pmi;
662 }
663
664 /* Create an instance for some classes, otherwise they get optimized away. */
665
666 default_public_struct default_public_s;
667 explicit_public_struct explicit_public_s;
668 protected_struct protected_s;
669 private_struct private_s;
670 mixed_protection_struct mixed_protection_s;
671 public_class public_c;
672 protected_class protected_c;
673 default_private_class default_private_c;
674 explicit_private_class explicit_private_c;
675 mixed_protection_class mixed_protection_c;
676 class_with_typedefs class_with_typedefs_c;
677 class_with_public_typedef class_with_public_typedef_c;
678 class_with_protected_typedef class_with_protected_typedef_c;
679 class_with_private_typedef class_with_private_typedef_c;
680 struct_with_public_typedef struct_with_public_typedef_s;
681 struct_with_protected_typedef struct_with_protected_typedef_s;
682 struct_with_private_typedef struct_with_private_typedef_s;