1 /* This testcase is part of GDB, the GNU debugger.
2 
3    Copyright 2008-2021 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
27 class base;
28 class derived;
29 
30 // A simple template with specializations
31 template <typename T>
32 class tclass
33 {
34 public:
do_something()35   void do_something () { } // tclass<T>::do_something
36 };
37 
38 template <>
do_something()39 void tclass<char>::do_something () { } // tclass<char>::do_something
40 
41 template <>
do_something()42 void tclass<int>::do_something () { } // tclass<int>::do_something
43 
44 template<>
do_something()45 void tclass<long>::do_something () { } // tclass<long>::do_something
46 
47 template<>
do_something()48 void tclass<short>::do_something () { } // tclass<short>::do_something
49 
50 // A simple template with multiple template parameters
51 template <class A, class B, class C, class D, class E>
flubber(void)52 void 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
67 template <class T>
68 struct operation_1
69 {
functionoperation_170   static void function (void) { } // operation_1<T>::function
71 };
72 
73 template <class T>
74 struct operation_2
75 {
functionoperation_276   static void function (void) { } // operation_2<T>::function
77 };
78 
79 template <class T>
80 struct operation_3
81 {
functionoperation_382   static void function (void) { } // operation_3<T>::function
83 };
84 
85 template <class T>
86 struct operation_4
87 {
functionoperation_488   static void function (void) { } // operation_4<T>::function
89 };
90 
91 // A policy-based class w/ and w/o default policy
92 template <class T, class Policy>
93 class policy : public Policy
94 {
95 public:
policy(T obj)96   policy (T obj) : obj_ (obj) { } // policy<T, Policy>::policy
97 
98 private:
99   T obj_;
100 };
101 
102 template <class T, class Policy = operation_1<T> >
103 class policyd : public Policy
104 {
105 public:
policyd(T obj)106   policyd (T obj) : obj_ (obj) { } // policyd<T, Policy>::policyd
~policyd(void)107   ~policyd (void) { } // policyd<T, Policy>::~policyd
108 
109 private:
110   T obj_;
111 };
112 
113 typedef policy<int, operation_1<void*> > policy1;
114 typedef policy<int, operation_2<void*> > policy2;
115 typedef policy<int, operation_3<void*> > policy3;
116 typedef policy<int, operation_4<void*> > policy4;
117 
118 typedef policyd<int> policyd1;
119 typedef policyd<long> policyd2;
120 typedef policyd<char> policyd3;
121 typedef policyd<base> policyd4;
122 typedef policyd<tclass<int> > policyd5;
123 
124 class fluff { };
125 static fluff *g_fluff = new fluff ();
126 
127 class base
128 {
129 protected:
130   int foo_;
131 
132 public:
base(void)133   base (void) : foo_ (42) { } // base::base(void)
base(int foo)134   base (int foo) : foo_ (foo) { } // base::base(int)
~base(void)135   ~base (void) { } // base::~base
136 
137   // Some overloaded methods
overload(void) const138   int overload (void) const { return 0; } // base::overload(void) const
overload(int i) const139   int overload (int i) const { return 1; } // base::overload(int) const
overload(short s) const140   int overload (short s) const { return 2; } // base::overload(short) const
overload(long l) const141   int overload (long l) const { return 3; } // base::overload(long) const
overload(char * a) const142   int overload (char* a) const { return 4; } // base::overload(char*) const
overload(base & b) const143   int overload (base& b) const { return 5; } // base::overload(base&) const
144 
145   // Operators
operator +(base const & o) const146   int operator+ (base const& o) const { // base::operator+
147     return foo_ + o.foo_;  }
148 
operator ++(void)149   base operator++ (void) { // base::operator++
150     ++foo_; return *this; }
151 
operator +=(base const & o)152   base operator+=(base const& o) { // base::operator+=
153     foo_ += o.foo_; return *this; }
154 
operator -(base const & o) const155   int operator- (base const& o) const { // base::operator-
156     return foo_ - o.foo_; }
157 
operator --(void)158   base operator-- (void) { // base::operator--
159     --foo_; return *this; }
160 
operator -=(base const & o)161   base operator-= (base const& o) { // base::operator-=
162     foo_ -= o.foo_; return *this; }
163 
operator *(base const & o) const164   int operator* (base const& o) const { // base::operator*
165     return foo_ * o.foo_; }
166 
operator *=(base const & o)167   base operator*= (base const& o) { // base::operator*=
168     foo_ *= o.foo_; return *this; }
169 
operator /(base const & o) const170   int operator/ (base const& o) const { // base::operator/
171     return foo_ / o.foo_; }
172 
operator /=(base const & o)173   base operator/= (base const& o) { // base::operator/=
174     foo_ /= o.foo_; return *this; }
175 
operator %(base const & o) const176   int operator% (base const& o) const { // base::operator%
177     return foo_ % o.foo_; }
178 
operator %=(base const & o)179   base operator%= (base const& o) { // base::operator%=
180     foo_ %= o.foo_; return *this; }
181 
operator <(base const & o) const182   bool operator< (base const& o) const { // base::operator<
183     return foo_ < o.foo_; }
184 
operator <=(base const & o) const185   bool operator<= (base const& o) const { // base::operator<=
186     return foo_ <= o.foo_; }
187 
operator >(base const & o) const188   bool operator> (base const& o) const { // base::operator>
189     return foo_ > o.foo_; }
190 
operator >=(base const & o) const191   bool operator>= (base const& o) const { // base::operator>=
192     return foo_ >= o.foo_; }
193 
operator !=(base const & o) const194   bool operator!= (base const& o) const { // base::operator!=
195     return foo_ != o.foo_; }
196 
operator ==(base const & o) const197   bool operator== (base const& o) const { // base::operator==
198     return foo_ == o.foo_; }
199 
operator !(void) const200   bool operator! (void) const { // base::operator!
201     return !foo_; }
202 
operator &&(base const & o) const203   bool operator&& (base const& o) const { // base::operator&&
204     return foo_ && o.foo_; }
205 
operator ||(base const & o) const206   bool operator|| (base const& o) const { // base::operator||
207     return foo_ || o.foo_; }
208 
operator <<(int value) const209   int operator<< (int value) const { // base::operator<<
210     return foo_  << value; }
211 
operator <<=(int value)212   base operator<<= (int value) { // base::operator<<=
213     foo_ <<= value; return *this; }
214 
operator >>(int value) const215   int operator>> (int value) const { // base::operator>>
216     return foo_  >> value; }
217 
operator >>=(int value)218   base operator>>= (int value) { // base::operator>>=
219     foo_ >>= value; return *this; }
220 
operator ~(void) const221   int operator~ (void) const { // base::operator~
222     return ~foo_; }
223 
operator &(base const & o) const224   int operator& (base const& o) const { // base::operator&
225     return foo_ & o.foo_; }
226 
operator &=(base const & o)227   base operator&= (base const& o) { // base::operator&=
228     foo_ &= o.foo_; return *this; }
229 
operator |(base const & o) const230   int operator| (base const& o) const { // base::operator|
231     return foo_ | o.foo_; }
232 
operator |=(base const & o)233   base operator|= (base const& o) { // base::operator|=
234     foo_ |= o.foo_; return *this; }
235 
operator ^(base const & o) const236   int operator^ (base const& o) const { // base::operator^
237     return foo_ ^ o.foo_; }
238 
operator ^=(base const & o)239   base operator^= (base const& o) { // base::operator^=
240     foo_ ^= o.foo_; return *this; }
241 
operator =(base const & o)242   base operator= (base const& o) { // base::operator=
243     foo_ = o.foo_; return *this; }
244 
operator ()(void) const245   void operator() (void) const { // base::operator()
246     return; }
247 
operator [](int idx) const248   int operator[] (int idx) const { // base::operator[]
249     return idx; }
250 
operator new(size_t size)251   void* operator new (size_t size) throw () { // base::operator new
252     return malloc (size); }
253 
operator delete(void * ptr)254   void operator delete (void* ptr) { // base::operator delete
255     free (ptr); }
256 
operator new[](size_t size)257   void* operator new[] (size_t size) throw () { // base::operator new[]
258     return malloc (size); }
259 
operator delete[](void * ptr)260   void operator delete[] (void* ptr) { // base::operator delete[]
261     free (ptr); }
262 
operator ->(void) const263   base const* operator-> (void) const { // base::opeartor->
264     return this; }
265 
operator ->*(base const & b) const266   int operator->* (base const& b) const { // base::operator->*
267     return foo_ * b.foo_; }
268 
operator char*() const269   operator char* () const { return const_cast<char*> ("hello"); } // base::operator char*
operator int() const270   operator int () const { return 21; } // base::operator int
operator fluff*() const271   operator fluff* () const { return new fluff (); } // base::operator fluff*
operator fluff**() const272   operator fluff** () const { return &g_fluff; } // base::operator fluff**
operator fluff const*const*() const273   operator fluff const* const* () const { return &g_fluff; } // base::operator fluff const* const*
274 };
275 
276 class base1 : public virtual base
277 {
278 public:
base1(void)279   base1 (void) : foo_ (21) { } // base1::base1(void)
base1(int a)280   base1 (int a) : foo_(a) { } // base1::base1(int)
a_function(void) const281   void a_function (void) const { } // base1::a_function
282 
283 protected:
284   int foo_;
285 };
286 
287 class base2 : public virtual base
288 {
289 public:
base2()290   base2 () : foo_ (3) { } // base2::base2
291 
292 protected:
a_function(void) const293   void a_function (void) const { } // base2::a_function
294   int foo_;
295 };
296 
297 class derived : public base1, public base2
298 {
299   public:
derived(void)300   derived(void) : foo_ (4) { } // derived::derived
a_function(void) const301   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 
310 class 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 };
318 const int CV::i = 42;
319 #ifdef __GNUC__
320 # define ATTRIBUTE_USED __attribute__((used))
321 #else
322 # define ATTRIBUTE_USED
323 #endif
m(CV::t)324 ATTRIBUTE_USED void CV::m(CV::t) {}
m(CV::t) const325 ATTRIBUTE_USED void CV::m(CV::t) const {}
m(CV::t)326 ATTRIBUTE_USED void CV::m(CV::t) volatile {}
m(CV::t) const327 ATTRIBUTE_USED void CV::m(CV::t) const volatile {}
CV_f(int x)328 int CV_f (int x)
329 {
330   return x + 1;
331 }
332 
333 int
test_function(int argc,char * argv[])334 test_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 
459 int
main(int argc,char * argv[])460 main (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