1/* This testcase is part of GDB, the GNU debugger.
2
3   Copyright 1993-2020 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  =======================
21bool            v_bool;
22bool            v_bool_array[2];
23
24typedef struct fleep fleep;
25struct fleep { int a; } s;
26
27int number;
28int &number_ref = number;
29
30// ====================== simple class structures  =======================
31
32struct default_public_struct {
33 // defaults to public:
34  int a;
35  int b;
36};
37
38struct explicit_public_struct {
39 public:
40  int a;
41  int b;
42};
43
44struct protected_struct {
45 protected:
46  int a;
47  int b;
48};
49
50struct private_struct {
51 private:
52  int a;
53  int b;
54};
55
56struct mixed_protection_struct {
57 public:
58  int a;
59  int b;
60 private:
61  int c;
62  int d;
63 protected:
64  int e;
65  int f;
66 public:
67  int g;
68 private:
69  int h;
70 protected:
71  int i;
72};
73
74class public_class {
75 public:
76  int a;
77  int b;
78};
79
80class protected_class {
81 protected:
82  int a;
83  int b;
84};
85
86class default_private_class {
87 // defaults to private:
88  int a;
89  int b;
90};
91
92class explicit_private_class {
93 private:
94  int a;
95  int b;
96};
97
98class mixed_protection_class {
99 public:
100  int a;
101  int b;
102 private:
103  int c;
104  int d;
105 protected:
106  int e;
107  int f;
108 public:
109  int g;
110 private:
111  int h;
112 protected:
113  int i;
114};
115
116class const_vol_method_class {
117public:
118  int a;
119  int b;
120  int foo (int &) const;
121  int bar (int &) volatile;
122  int baz (int &) const volatile;
123};
124
125int const_vol_method_class::foo (int & ir) const
126{
127  return ir + 3;
128}
129int const_vol_method_class::bar (int & ir) volatile
130{
131  return ir + 4;
132}
133int const_vol_method_class::baz (int & ir) const volatile
134{
135  return ir + 5;
136}
137
138// ========================= simple inheritance ==========================
139
140class A {
141 public:
142  int a;
143  int x;
144};
145
146A g_A;
147
148class B : public A {
149 public:
150  int b;
151  int x;
152};
153
154B g_B;
155
156class C : public A {
157 public:
158  int c;
159  int x;
160};
161
162C g_C;
163
164class D : public B, public C {
165 public:
166  int d;
167  int x;
168};
169
170D g_D;
171
172class E : public D {
173 public:
174  int e;
175  int x;
176};
177
178E g_E;
179
180class class_with_anon_union
181{
182 public:
183  int one;
184  union
185  {
186    int a;
187    long b;
188  };
189};
190
191class_with_anon_union g_anon_union;
192
193void inheritance2 (void)
194{
195}
196
197void inheritance1 (void)
198{
199  int ival;
200  int *intp;
201
202  // {A::a, A::x}
203
204  g_A.A::a = 1;
205  g_A.A::x = 2;
206
207  // {{A::a,A::x},B::b,B::x}
208
209  g_B.A::a = 3;
210  g_B.A::x = 4;
211  g_B.B::b = 5;
212  g_B.B::x = 6;
213
214  // {{A::a,A::x},C::c,C::x}
215
216  g_C.A::a = 7;
217  g_C.A::x = 8;
218  g_C.C::c = 9;
219  g_C.C::x = 10;
220
221  // {{{A::a,A::x},B::b,B::x},{{A::a,A::x},C::c,C::x},D::d,D::x}
222
223  // The following initialization code is non-portable, but allows us
224  // to initialize all members of g_D until we can fill in the missing
225  // initialization code with legal C++ code.
226
227  for (intp = (int *) &g_D, ival = 11;
228       intp < ((int *) &g_D + sizeof (g_D) / sizeof (int));
229       intp++, ival++)
230    {
231      *intp = ival;
232    }
233
234  // Overlay the nonportable initialization with legal initialization.
235
236  // ????? = 11;  (g_D.A::a = 11; is ambiguous)
237  // ????? = 12;  (g_D.A::x = 12; is ambiguous)
238/* djb 6-3-2000
239
240	This should take care of it. Rather than try to initialize using an ambiguous
241	construct, use 2 unambiguous ones for each. Since the ambiguous a/x member is
242	coming from C, and B, initialize D's C::a, and B::a, and D's C::x and B::x.
243 */
244  g_D.C::a = 15;
245  g_D.C::x = 12;
246  g_D.B::a = 11;
247  g_D.B::x = 12;
248  g_D.B::b = 13;
249  g_D.B::x = 14;
250  // ????? = 15;
251  // ????? = 16;
252  g_D.C::c = 17;
253  g_D.C::x = 18;
254  g_D.D::d = 19;
255  g_D.D::x = 20;
256
257
258  // {{{{A::a,A::x},B::b,B::x},{{A::a,A::x},C::c,C::x},D::d,D::x}},E::e,E::x}
259
260  // The following initialization code is non-portable, but allows us
261  // to initialize all members of g_D until we can fill in the missing
262  // initialization code with legal C++ code.
263
264  for (intp = (int *) &g_E, ival = 21;
265       intp < ((int *) &g_E + sizeof (g_E) / sizeof (int));
266       intp++, ival++)
267  {
268    *intp = ival;
269  }
270
271  // Overlay the nonportable initialization with legal initialization.
272
273  // ????? = 21;  (g_E.A::a = 21; is ambiguous)
274  // ????? = 22;  (g_E.A::x = 22; is ambiguous)
275  g_E.B::b = 23;
276  g_E.B::x = 24;
277  // ????? = 25;
278  // ????? = 26;
279  g_E.C::c = 27;
280  g_E.C::x = 28;
281  g_E.D::d = 29;
282  g_E.D::x = 30;
283  g_E.E::e = 31;
284  g_E.E::x = 32;
285
286  g_anon_union.one = 1;
287  g_anon_union.a = 2;
288
289  inheritance2 ();
290}
291
292// ======================== static member functions =====================
293
294class Static {
295public:
296  static void ii(int, int);
297};
298void Static::ii (int, int) { }
299
300// ======================== virtual base classes=========================
301
302class vA {
303 public:
304  int va;
305  int vx;
306};
307
308vA g_vA;
309
310class vB : public virtual vA {
311 public:
312  int vb;
313  int vx;
314};
315
316vB g_vB;
317
318class vC : public virtual vA {
319 public:
320  int vc;
321  int vx;
322};
323
324vC g_vC;
325
326class vD : public virtual vB, public virtual vC {
327 public:
328  int vd;
329  int vx;
330};
331
332vD g_vD;
333
334class vE : public virtual vD {
335 public:
336  int ve;
337  int vx;
338};
339
340vE g_vE;
341
342void inheritance4 (void)
343{
344}
345
346void inheritance3 (void)
347{
348  int ival;
349  int *intp;
350
351  // {vA::va, vA::vx}
352
353  g_vA.vA::va = 1;
354  g_vA.vA::vx = 2;
355
356  // {{vA::va, vA::vx}, vB::vb, vB::vx}
357
358  g_vB.vA::va = 3;
359  g_vB.vA::vx = 4;
360  g_vB.vB::vb = 5;
361  g_vB.vB::vx = 6;
362
363  // {{vA::va, vA::vx}, vC::vc, vC::vx}
364
365  g_vC.vA::va = 7;
366  g_vC.vA::vx = 8;
367  g_vC.vC::vc = 9;
368  g_vC.vC::vx = 10;
369
370  // {{{{vA::va, vA::vx}, vB::vb, vB::vx}, vC::vc, vC::vx}, vD::vd,vD::vx}
371
372  g_vD.vA::va = 11;
373  g_vD.vA::vx = 12;
374  g_vD.vB::vb = 13;
375  g_vD.vB::vx = 14;
376  g_vD.vC::vc = 15;
377  g_vD.vC::vx = 16;
378  g_vD.vD::vd = 17;
379  g_vD.vD::vx = 18;
380
381
382  // {{{{{vA::va,vA::vx},vB::vb,vB::vx},vC::vc,vC::vx},vD::vd,vD::vx},vE::ve,vE::vx}
383
384  g_vD.vA::va = 19;
385  g_vD.vA::vx = 20;
386  g_vD.vB::vb = 21;
387  g_vD.vB::vx = 22;
388  g_vD.vC::vc = 23;
389  g_vD.vC::vx = 24;
390  g_vD.vD::vd = 25;
391  g_vD.vD::vx = 26;
392  g_vE.vE::ve = 27;
393  g_vE.vE::vx = 28;
394
395  inheritance4 ();
396}
397
398// ======================================================================
399
400class Base1 {
401 public:
402  int x;
403  Base1(int i) { x = i; }
404};
405
406class 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
418class Bar : public Base1, public Foo {
419 public:
420  int z;
421  Bar (int i, int j, int k) : Base1 (10*k), Foo (i, j) { z = k; }
422};
423
424int Foo::operator! () { return !x; }
425
426int Foo::times (int y) { return x * y; }
427
428int Foo::st = 100;
429
430Foo::operator int() { return x; }
431
432Foo foo(10, 11);
433Bar bar(20, 21, 22);
434
435class ClassWithEnum {
436public:
437  enum PrivEnum { red, green, blue, yellow = 42 };
438  PrivEnum priv_enum;
439  int x;
440};
441
442void enums2 (void)
443{
444}
445
446/* classes.exp relies on statement order in this function for testing
447   enumeration fields.  */
448
449void enums1 ()
450{
451  ClassWithEnum obj_with_enum;
452  obj_with_enum.priv_enum = ClassWithEnum::red;
453  obj_with_enum.x = 0;
454  enums2 ();
455  obj_with_enum.priv_enum = ClassWithEnum::green;
456}
457
458class ClassParam {
459public:
460  int Aptr_a (A *a) { return a->a; }
461  int Aptr_x (A *a) { return a->x; }
462  int Aref_a (A &a) { return a.a; }
463  int Aref_x (A &a) { return a.x; }
464  int Aval_a (A a) { return a.a; }
465  int Aval_x (A a) { return a.x; }
466};
467
468ClassParam class_param;
469
470class Contains_static_instance
471{
472 public:
473  int x;
474  int y;
475  Contains_static_instance (int i, int j) { x = i; y = j; }
476  static Contains_static_instance null;
477};
478
479Contains_static_instance Contains_static_instance::null(0,0);
480Contains_static_instance csi(10,20);
481
482class Contains_nested_static_instance
483{
484 public:
485  class Nested
486  {
487   public:
488    Nested(int i) : z(i) {}
489    int z;
490    static Contains_nested_static_instance xx;
491  };
492
493  Contains_nested_static_instance(int i, int j) : x(i), y(j) {}
494
495  int x;
496  int y;
497
498  static Contains_nested_static_instance null;
499  static Nested yy;
500};
501
502Contains_nested_static_instance Contains_nested_static_instance::null(0, 0);
503Contains_nested_static_instance::Nested Contains_nested_static_instance::yy(5);
504Contains_nested_static_instance
505  Contains_nested_static_instance::Nested::xx(1,2);
506Contains_nested_static_instance cnsi(30,40);
507
508typedef struct {
509  int one;
510  int two;
511} tagless_struct;
512tagless_struct v_tagless;
513
514void dummy()
515{
516  v_bool = true;
517  v_bool_array[0] = false;
518  v_bool_array[1] = v_bool;
519}
520
521void use_methods ()
522{
523  /* Refer to methods so that they don't get optimized away. */
524  int i;
525  i = class_param.Aptr_a (&g_A);
526  i = class_param.Aptr_x (&g_A);
527  i = class_param.Aref_a (g_A);
528  i = class_param.Aref_x (g_A);
529  i = class_param.Aval_a (g_A);
530  i = class_param.Aval_x (g_A);
531}
532
533
534int
535main()
536{
537  dummy();
538  inheritance1 ();
539  inheritance3 ();
540  enums1 ();
541
542  /* FIXME: pmi gets optimized out.  Need to do some more computation with
543     it or something.  (No one notices, because the test is xfail'd anyway,
544     but that probably won't always be true...).  */
545  int Foo::* pmi = &Foo::y;
546
547  /* Make sure the AIX linker doesn't remove the variable.  */
548  v_tagless.one = 5;
549
550  use_methods ();
551
552  return foo.*pmi;
553}
554
555/* Create an instance for some classes, otherwise they get optimized away.  */
556
557default_public_struct default_public_s;
558explicit_public_struct explicit_public_s;
559protected_struct protected_s;
560private_struct private_s;
561mixed_protection_struct mixed_protection_s;
562public_class public_c;
563protected_class protected_c;
564default_private_class default_private_c;
565explicit_private_class explicit_private_c;
566mixed_protection_class mixed_protection_c;
567