1/* This testcase is part of GDB, the GNU debugger.
2
3   Copyright 2008-2023 Free Software Foundation, Inc.
4
5   Contributed by Red Hat, originally written by Keith Seitz.
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 3 of the License, or
10   (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20   Please email any bugs, comments, and/or additions to this file to:
21   bug-gdb@gnu.org  */
22
23#include <stdlib.h>
24#include <iostream>
25
26// Forward decls
27class base;
28class derived;
29
30// A simple template with specializations
31template <typename T>
32class tclass
33{
34public:
35  void do_something () { } // tclass<T>::do_something
36};
37
38template <>
39void tclass<char>::do_something () { } // tclass<char>::do_something
40
41template <>
42void tclass<int>::do_something () { } // tclass<int>::do_something
43
44template<>
45void tclass<long>::do_something () { } // tclass<long>::do_something
46
47template<>
48void tclass<short>::do_something () { } // tclass<short>::do_something
49
50// A simple template with multiple template parameters
51template <class A, class B, class C, class D, class E>
52void flubber (void) { // flubber
53  A a;
54  B b;
55  C c;
56  D d;
57  E e;
58
59  ++a;
60  ++b;
61  ++c;
62  ++d;
63  ++e;
64}
65
66// Some contrived policies
67template <class T>
68struct operation_1
69{
70  static void function (void) { } // operation_1<T>::function
71};
72
73template <class T>
74struct operation_2
75{
76  static void function (void) { } // operation_2<T>::function
77};
78
79template <class T>
80struct operation_3
81{
82  static void function (void) { } // operation_3<T>::function
83};
84
85template <class T>
86struct operation_4
87{
88  static void function (void) { } // operation_4<T>::function
89};
90
91// A policy-based class w/ and w/o default policy
92template <class T, class Policy>
93class policy : public Policy
94{
95public:
96  policy (T obj) : obj_ (obj) { } // policy<T, Policy>::policy
97
98private:
99  T obj_;
100};
101
102template <class T, class Policy = operation_1<T> >
103class policyd : public Policy
104{
105public:
106  policyd (T obj) : obj_ (obj) { } // policyd<T, Policy>::policyd
107  ~policyd (void) { } // policyd<T, Policy>::~policyd
108
109private:
110  T obj_;
111};
112
113typedef policy<int, operation_1<void*> > policy1;
114typedef policy<int, operation_2<void*> > policy2;
115typedef policy<int, operation_3<void*> > policy3;
116typedef policy<int, operation_4<void*> > policy4;
117
118typedef policyd<int> policyd1;
119typedef policyd<long> policyd2;
120typedef policyd<char> policyd3;
121typedef policyd<base> policyd4;
122typedef policyd<tclass<int> > policyd5;
123
124class fluff { };
125static fluff *g_fluff = new fluff ();
126
127class base
128{
129protected:
130  int foo_;
131
132public:
133  base (void) : foo_ (42) { } // base::base(void)
134  base (int foo) : foo_ (foo) { } // base::base(int)
135  ~base (void) { } // base::~base
136
137  // Some overloaded methods
138  int overload (void) const { return 0; } // base::overload(void) const
139  int overload (int i) const { return 1; } // base::overload(int) const
140  int overload (short s) const { return 2; } // base::overload(short) const
141  int overload (long l) const { return 3; } // base::overload(long) const
142  int overload (char* a) const { return 4; } // base::overload(char*) const
143  int overload (base& b) const { return 5; } // base::overload(base&) const
144
145  // Operators
146  int operator+ (base const& o) const { // base::operator+
147    return foo_ + o.foo_;  }
148
149  base operator++ (void) { // base::operator++
150    ++foo_; return *this; }
151
152  base operator+=(base const& o) { // base::operator+=
153    foo_ += o.foo_; return *this; }
154
155  int operator- (base const& o) const { // base::operator-
156    return foo_ - o.foo_; }
157
158  base operator-- (void) { // base::operator--
159    --foo_; return *this; }
160
161  base operator-= (base const& o) { // base::operator-=
162    foo_ -= o.foo_; return *this; }
163
164  int operator* (base const& o) const { // base::operator*
165    return foo_ * o.foo_; }
166
167  base operator*= (base const& o) { // base::operator*=
168    foo_ *= o.foo_; return *this; }
169
170  int operator/ (base const& o) const { // base::operator/
171    return foo_ / o.foo_; }
172
173  base operator/= (base const& o) { // base::operator/=
174    foo_ /= o.foo_; return *this; }
175
176  int operator% (base const& o) const { // base::operator%
177    return foo_ % o.foo_; }
178
179  base operator%= (base const& o) { // base::operator%=
180    foo_ %= o.foo_; return *this; }
181
182  bool operator< (base const& o) const { // base::operator<
183    return foo_ < o.foo_; }
184
185  bool operator<= (base const& o) const { // base::operator<=
186    return foo_ <= o.foo_; }
187
188  bool operator> (base const& o) const { // base::operator>
189    return foo_ > o.foo_; }
190
191  bool operator>= (base const& o) const { // base::operator>=
192    return foo_ >= o.foo_; }
193
194  bool operator!= (base const& o) const { // base::operator!=
195    return foo_ != o.foo_; }
196
197  bool operator== (base const& o) const { // base::operator==
198    return foo_ == o.foo_; }
199
200  bool operator! (void) const { // base::operator!
201    return !foo_; }
202
203  bool operator&& (base const& o) const { // base::operator&&
204    return foo_ && o.foo_; }
205
206  bool operator|| (base const& o) const { // base::operator||
207    return foo_ || o.foo_; }
208
209  int operator<< (int value) const { // base::operator<<
210    return foo_  << value; }
211
212  base operator<<= (int value) { // base::operator<<=
213    foo_ <<= value; return *this; }
214
215  int operator>> (int value) const { // base::operator>>
216    return foo_  >> value; }
217
218  base operator>>= (int value) { // base::operator>>=
219    foo_ >>= value; return *this; }
220
221  int operator~ (void) const { // base::operator~
222    return ~foo_; }
223
224  int operator& (base const& o) const { // base::operator&
225    return foo_ & o.foo_; }
226
227  base operator&= (base const& o) { // base::operator&=
228    foo_ &= o.foo_; return *this; }
229
230  int operator| (base const& o) const { // base::operator|
231    return foo_ | o.foo_; }
232
233  base operator|= (base const& o) { // base::operator|=
234    foo_ |= o.foo_; return *this; }
235
236  int operator^ (base const& o) const { // base::operator^
237    return foo_ ^ o.foo_; }
238
239  base operator^= (base const& o) { // base::operator^=
240    foo_ ^= o.foo_; return *this; }
241
242  base operator= (base const& o) { // base::operator=
243    foo_ = o.foo_; return *this; }
244
245  void operator() (void) const { // base::operator()
246    return; }
247
248  int operator[] (int idx) const { // base::operator[]
249    return idx; }
250
251  void* operator new (size_t size) throw () { // base::operator new
252    return malloc (size); }
253
254  void operator delete (void* ptr) { // base::operator delete
255    free (ptr); }
256
257  void* operator new[] (size_t size) throw () { // base::operator new[]
258    return malloc (size); }
259
260  void operator delete[] (void* ptr) { // base::operator delete[]
261    free (ptr); }
262
263  base const* operator-> (void) const { // base::opeartor->
264    return this; }
265
266  int operator->* (base const& b) const { // base::operator->*
267    return foo_ * b.foo_; }
268
269  operator char* () const { return const_cast<char*> ("hello"); } // base::operator char*
270  operator int () const { return 21; } // base::operator int
271  operator fluff* () const { return new fluff (); } // base::operator fluff*
272  operator fluff** () const { return &g_fluff; } // base::operator fluff**
273  operator fluff const* const* () const { return &g_fluff; } // base::operator fluff const* const*
274};
275
276class base1 : public virtual base
277{
278public:
279  base1 (void) : foo_ (21) { } // base1::base1(void)
280  base1 (int a) : foo_(a) { } // base1::base1(int)
281  void a_function (void) const { } // base1::a_function
282
283protected:
284  int foo_;
285};
286
287class base2 : public virtual base
288{
289public:
290  base2 () : foo_ (3) { } // base2::base2
291
292protected:
293  void a_function (void) const { } // base2::a_function
294  int foo_;
295};
296
297class derived : public base1, public base2
298{
299  public:
300  derived(void) : foo_ (4) { } // derived::derived
301  void a_function (void) const { // derived::a_function
302    this->base1::a_function ();
303    this->base2::a_function ();
304  }
305
306  protected:
307  int foo_;
308};
309
310class CV { public:
311  static const int i;
312  typedef int t;
313  void m(t);
314  void m(t) const;
315  void m(t) volatile;
316  void m(t) const volatile;
317};
318const int CV::i = 42;
319#ifdef __GNUC__
320# define ATTRIBUTE_USED __attribute__((used))
321#else
322# define ATTRIBUTE_USED
323#endif
324ATTRIBUTE_USED void CV::m(CV::t) {}
325ATTRIBUTE_USED void CV::m(CV::t) const {}
326ATTRIBUTE_USED void CV::m(CV::t) volatile {}
327ATTRIBUTE_USED void CV::m(CV::t) const volatile {}
328int CV_f (int x)
329{
330  return x + 1;
331}
332
333int
334test_function (int argc, char* argv[]) // test_function
335{ // test_function
336  derived d;
337  void (derived::*pfunc) (void) const = &derived::a_function;
338  (d.*pfunc) ();
339
340  base a (1), b (3), c (8);
341  (void) a.overload ();
342  (void) a.overload (static_cast<int> (0));
343  (void) a.overload (static_cast<short> (0));
344  (void) a.overload (static_cast<long> (0));
345  (void) a.overload (static_cast<char*> (0));
346  (void) a.overload (a);
347
348  int r;
349  r = b + c;
350  ++a;
351  a += b;
352  r = b - c;
353  --a;
354  a -= b;
355  r = b * c;
356  a *= b;
357  r = b / c;
358  a /= b;
359  r = b % c;
360  a %= b;
361  bool x = (b < c);
362  x = (b <= c);
363  x = (b > c);
364  x = (b >= c);
365  x = (b != c);
366  x = (b == c);
367  x = (!b);
368  x = (b && c);
369  x = (b || c);
370  r = b << 2;
371  a <<= 1;
372  r = b >> 2;
373  a >>= 1;
374  r = ~b;
375  r = b & c;
376  a &= c;
377  r = b | c;
378  a |= c;
379  r = b ^ c;
380  a ^= c;
381  a = c;
382  a ();
383  int i = a[3];
384  derived* f = new derived ();
385  derived* g = new derived[3];
386  delete f;
387  delete[] g;
388  a->overload ();
389  r = a->*b;
390
391  tclass<char> char_tclass;
392  tclass<int> int_tclass;
393  tclass<short> short_tclass;
394  tclass<long> long_tclass;
395  tclass<base> base_tclass;
396  char_tclass.do_something ();
397  int_tclass.do_something ();
398  short_tclass.do_something ();
399  long_tclass.do_something ();
400  base_tclass.do_something ();
401
402  flubber<int, int, int, int, int> ();
403  flubber<int, int, int, int, short> ();
404  flubber<int, int, int, int, long> ();
405  flubber<int, int, int, int, char> ();
406  flubber<int, int, int, short, int> ();
407  flubber<int, int, int, short, short> ();
408  flubber<int, int, int, short, long> ();
409  flubber<int, int, int, short, char> ();
410  flubber<int, int, int, long, int> ();
411  flubber<int, int, int, long, short> ();
412  flubber<int, int, int, long, long> ();
413  flubber<int, int, int, long, char> ();
414  flubber<int, int, int, char, int> ();
415  flubber<int, int, int, char, short> ();
416  flubber<int, int, int, char, long> ();
417  flubber<int, int, int, char, char> ();
418  flubber<int, int, short, int, int> ();
419  flubber<int, int, short, int, short> ();
420  flubber<int, int, short, int, long> ();
421  flubber<int, int, short, int, char> ();
422  flubber<int, int, short, short, int> ();
423  flubber<short, int, short, int, short> ();
424  flubber<long, short, long, short, long> ();
425
426  policy1 p1 (1);
427  p1.function ();
428  policy2 p2 (2);
429  p2.function ();
430  policy3 p3 (3);
431  p3.function ();
432  policy4 p4 (4);
433  p4.function ();
434
435  policyd1 pd1 (5);
436  pd1.function ();
437  policyd2 pd2 (6);
438  pd2.function ();
439  policyd3 pd3 (7);
440  pd3.function ();
441  policyd4 pd4 (d);
442  pd4.function ();
443  policyd5 pd5 (int_tclass);
444  pd5.function ();
445
446  base1 b1 (3);
447
448  r = a;
449  char* str = a;
450  fluff* flp = a;
451  fluff** flpp = a;
452  fluff const* const* flcpcp = a;
453
454  CV_f(CV::i);
455
456  return 0;
457}
458
459int
460main (int argc, char* argv[])
461{
462  int i;
463
464  /* Call the test function repeatedly, enough times for all our tests
465     without running forever if something goes wrong.  */
466  for (i = 0; i < 1000; i++)
467    test_function (argc, argv);
468
469  return 0;
470}
471