Commit | Line | Data |
---|---|---|
cec808ec KS |
1 | /* This testcase is part of GDB, the GNU debugger. |
2 | ||
b811d2c2 | 3 | Copyright 2008-2020 Free Software Foundation, Inc. |
cec808ec KS |
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: | |
35 | void do_something () { } // tclass<T>::do_something | |
36 | }; | |
37 | ||
38 | template <> | |
39 | void tclass<char>::do_something () { } // tclass<char>::do_something | |
40 | ||
41 | template <> | |
42 | void tclass<int>::do_something () { } // tclass<int>::do_something | |
43 | ||
44 | template<> | |
45 | void tclass<long>::do_something () { } // tclass<long>::do_something | |
46 | ||
47 | template<> | |
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> | |
25d4e99d | 52 | void flubber (void) { // flubber |
cec808ec KS |
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 | { | |
70 | static void function (void) { } // operation_1<T>::function | |
71 | }; | |
72 | ||
73 | template <class T> | |
74 | struct operation_2 | |
75 | { | |
76 | static void function (void) { } // operation_2<T>::function | |
77 | }; | |
78 | ||
79 | template <class T> | |
80 | struct operation_3 | |
81 | { | |
82 | static void function (void) { } // operation_3<T>::function | |
83 | }; | |
84 | ||
85 | template <class T> | |
86 | struct 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 | |
92 | template <class T, class Policy> | |
93 | class policy : public Policy | |
94 | { | |
95 | public: | |
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: | |
106 | policyd (T obj) : obj_ (obj) { } // policyd<T, Policy>::policyd | |
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: | |
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 | |
25d4e99d DB |
146 | int operator+ (base const& o) const { // base::operator+ |
147 | return foo_ + o.foo_; } | |
cec808ec | 148 | |
25d4e99d DB |
149 | base operator++ (void) { // base::operator++ |
150 | ++foo_; return *this; } | |
cec808ec | 151 | |
25d4e99d DB |
152 | base operator+=(base const& o) { // base::operator+= |
153 | foo_ += o.foo_; return *this; } | |
cec808ec | 154 | |
25d4e99d DB |
155 | int operator- (base const& o) const { // base::operator- |
156 | return foo_ - o.foo_; } | |
cec808ec | 157 | |
25d4e99d DB |
158 | base operator-- (void) { // base::operator-- |
159 | --foo_; return *this; } | |
cec808ec | 160 | |
25d4e99d DB |
161 | base operator-= (base const& o) { // base::operator-= |
162 | foo_ -= o.foo_; return *this; } | |
cec808ec | 163 | |
25d4e99d DB |
164 | int operator* (base const& o) const { // base::operator* |
165 | return foo_ * o.foo_; } | |
cec808ec | 166 | |
25d4e99d DB |
167 | base operator*= (base const& o) { // base::operator*= |
168 | foo_ *= o.foo_; return *this; } | |
cec808ec | 169 | |
25d4e99d DB |
170 | int operator/ (base const& o) const { // base::operator/ |
171 | return foo_ / o.foo_; } | |
cec808ec | 172 | |
25d4e99d DB |
173 | base operator/= (base const& o) { // base::operator/= |
174 | foo_ /= o.foo_; return *this; } | |
cec808ec | 175 | |
25d4e99d DB |
176 | int operator% (base const& o) const { // base::operator% |
177 | return foo_ % o.foo_; } | |
cec808ec | 178 | |
25d4e99d DB |
179 | base operator%= (base const& o) { // base::operator%= |
180 | foo_ %= o.foo_; return *this; } | |
cec808ec | 181 | |
25d4e99d DB |
182 | bool operator< (base const& o) const { // base::operator< |
183 | return foo_ < o.foo_; } | |
cec808ec | 184 | |
25d4e99d DB |
185 | bool operator<= (base const& o) const { // base::operator<= |
186 | return foo_ <= o.foo_; } | |
cec808ec | 187 | |
25d4e99d DB |
188 | bool operator> (base const& o) const { // base::operator> |
189 | return foo_ > o.foo_; } | |
cec808ec | 190 | |
25d4e99d DB |
191 | bool operator>= (base const& o) const { // base::operator>= |
192 | return foo_ >= o.foo_; } | |
cec808ec | 193 | |
25d4e99d DB |
194 | bool operator!= (base const& o) const { // base::operator!= |
195 | return foo_ != o.foo_; } | |
cec808ec | 196 | |
25d4e99d DB |
197 | bool operator== (base const& o) const { // base::operator== |
198 | return foo_ == o.foo_; } | |
cec808ec | 199 | |
25d4e99d DB |
200 | bool operator! (void) const { // base::operator! |
201 | return !foo_; } | |
cec808ec | 202 | |
25d4e99d DB |
203 | bool operator&& (base const& o) const { // base::operator&& |
204 | return foo_ && o.foo_; } | |
cec808ec | 205 | |
25d4e99d DB |
206 | bool operator|| (base const& o) const { // base::operator|| |
207 | return foo_ || o.foo_; } | |
cec808ec | 208 | |
25d4e99d DB |
209 | int operator<< (int value) const { // base::operator<< |
210 | return foo_ << value; } | |
cec808ec | 211 | |
25d4e99d DB |
212 | base operator<<= (int value) { // base::operator<<= |
213 | foo_ <<= value; return *this; } | |
cec808ec | 214 | |
25d4e99d DB |
215 | int operator>> (int value) const { // base::operator>> |
216 | return foo_ >> value; } | |
cec808ec | 217 | |
25d4e99d DB |
218 | base operator>>= (int value) { // base::operator>>= |
219 | foo_ >>= value; return *this; } | |
cec808ec | 220 | |
25d4e99d DB |
221 | int operator~ (void) const { // base::operator~ |
222 | return ~foo_; } | |
cec808ec | 223 | |
25d4e99d DB |
224 | int operator& (base const& o) const { // base::operator& |
225 | return foo_ & o.foo_; } | |
cec808ec | 226 | |
25d4e99d DB |
227 | base operator&= (base const& o) { // base::operator&= |
228 | foo_ &= o.foo_; return *this; } | |
cec808ec | 229 | |
25d4e99d DB |
230 | int operator| (base const& o) const { // base::operator| |
231 | return foo_ | o.foo_; } | |
cec808ec | 232 | |
25d4e99d DB |
233 | base operator|= (base const& o) { // base::operator|= |
234 | foo_ |= o.foo_; return *this; } | |
cec808ec | 235 | |
25d4e99d DB |
236 | int operator^ (base const& o) const { // base::operator^ |
237 | return foo_ ^ o.foo_; } | |
cec808ec | 238 | |
25d4e99d DB |
239 | base operator^= (base const& o) { // base::operator^= |
240 | foo_ ^= o.foo_; return *this; } | |
cec808ec | 241 | |
25d4e99d DB |
242 | base operator= (base const& o) { // base::operator= |
243 | foo_ = o.foo_; return *this; } | |
cec808ec | 244 | |
25d4e99d DB |
245 | void operator() (void) const { // base::operator() |
246 | return; } | |
cec808ec | 247 | |
25d4e99d DB |
248 | int operator[] (int idx) const { // base::operator[] |
249 | return idx; } | |
cec808ec | 250 | |
25d4e99d DB |
251 | void* operator new (size_t size) throw () { // base::operator new |
252 | return malloc (size); } | |
cec808ec | 253 | |
25d4e99d DB |
254 | void operator delete (void* ptr) { // base::operator delete |
255 | free (ptr); } | |
cec808ec | 256 | |
25d4e99d DB |
257 | void* operator new[] (size_t size) throw () { // base::operator new[] |
258 | return malloc (size); } | |
cec808ec | 259 | |
25d4e99d DB |
260 | void operator delete[] (void* ptr) { // base::operator delete[] |
261 | free (ptr); } | |
cec808ec | 262 | |
25d4e99d DB |
263 | base const* operator-> (void) const { // base::opeartor-> |
264 | return this; } | |
cec808ec | 265 | |
25d4e99d DB |
266 | int operator->* (base const& b) const { // base::operator->* |
267 | return foo_ * b.foo_; } | |
cec808ec KS |
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** | |
c8ba13ad | 273 | operator fluff const* const* () const { return &g_fluff; } // base::operator fluff const* const* |
cec808ec KS |
274 | }; |
275 | ||
276 | class base1 : public virtual base | |
277 | { | |
278 | public: | |
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 | ||
283 | protected: | |
284 | int foo_; | |
285 | }; | |
286 | ||
287 | class base2 : public virtual base | |
288 | { | |
289 | public: | |
290 | base2 () : foo_ (3) { } // base2::base2 | |
291 | ||
292 | protected: | |
293 | void a_function (void) const { } // base2::a_function | |
294 | int foo_; | |
295 | }; | |
296 | ||
297 | class derived : public base1, public base2 | |
298 | { | |
299 | public: | |
300 | derived(void) : foo_ (4) { } // derived::derived | |
25d4e99d | 301 | void a_function (void) const { // derived::a_function |
cec808ec KS |
302 | this->base1::a_function (); |
303 | this->base2::a_function (); | |
304 | } | |
305 | ||
306 | protected: | |
307 | int foo_; | |
308 | }; | |
309 | ||
50af5481 JK |
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 | |
324 | ATTRIBUTE_USED void CV::m(CV::t) {} | |
325 | ATTRIBUTE_USED void CV::m(CV::t) const {} | |
326 | ATTRIBUTE_USED void CV::m(CV::t) volatile {} | |
327 | ATTRIBUTE_USED void CV::m(CV::t) const volatile {} | |
328 | int CV_f (int x) | |
329 | { | |
330 | return x + 1; | |
331 | } | |
332 | ||
cec808ec | 333 | int |
640617ad DJ |
334 | test_function (int argc, char* argv[]) // test_function |
335 | { // test_function | |
cec808ec KS |
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; | |
c8ba13ad | 452 | fluff const* const* flcpcp = a; |
640617ad | 453 | |
50af5481 JK |
454 | CV_f(CV::i); |
455 | ||
640617ad | 456 | return 0; |
cec808ec KS |
457 | } |
458 | ||
640617ad DJ |
459 | int |
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 | } |