Commit | Line | Data |
---|---|---|
cec808ec KS |
1 | /* This testcase is part of GDB, the GNU debugger. |
2 | ||
618f726f | 3 | Copyright 2008-2016 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** | |
273 | }; | |
274 | ||
275 | class base1 : public virtual base | |
276 | { | |
277 | public: | |
278 | base1 (void) : foo_ (21) { } // base1::base1(void) | |
279 | base1 (int a) : foo_(a) { } // base1::base1(int) | |
280 | void a_function (void) const { } // base1::a_function | |
281 | ||
282 | protected: | |
283 | int foo_; | |
284 | }; | |
285 | ||
286 | class base2 : public virtual base | |
287 | { | |
288 | public: | |
289 | base2 () : foo_ (3) { } // base2::base2 | |
290 | ||
291 | protected: | |
292 | void a_function (void) const { } // base2::a_function | |
293 | int foo_; | |
294 | }; | |
295 | ||
296 | class derived : public base1, public base2 | |
297 | { | |
298 | public: | |
299 | derived(void) : foo_ (4) { } // derived::derived | |
25d4e99d | 300 | void a_function (void) const { // derived::a_function |
cec808ec KS |
301 | this->base1::a_function (); |
302 | this->base2::a_function (); | |
303 | } | |
304 | ||
305 | protected: | |
306 | int foo_; | |
307 | }; | |
308 | ||
50af5481 JK |
309 | class CV { public: |
310 | static const int i; | |
311 | typedef int t; | |
312 | void m(t); | |
313 | void m(t) const; | |
314 | void m(t) volatile; | |
315 | void m(t) const volatile; | |
316 | }; | |
317 | const int CV::i = 42; | |
318 | #ifdef __GNUC__ | |
319 | # define ATTRIBUTE_USED __attribute__((used)) | |
320 | #else | |
321 | # define ATTRIBUTE_USED | |
322 | #endif | |
323 | ATTRIBUTE_USED void CV::m(CV::t) {} | |
324 | ATTRIBUTE_USED void CV::m(CV::t) const {} | |
325 | ATTRIBUTE_USED void CV::m(CV::t) volatile {} | |
326 | ATTRIBUTE_USED void CV::m(CV::t) const volatile {} | |
327 | int CV_f (int x) | |
328 | { | |
329 | return x + 1; | |
330 | } | |
331 | ||
cec808ec | 332 | int |
640617ad DJ |
333 | test_function (int argc, char* argv[]) // test_function |
334 | { // test_function | |
cec808ec KS |
335 | derived d; |
336 | void (derived::*pfunc) (void) const = &derived::a_function; | |
337 | (d.*pfunc) (); | |
338 | ||
339 | base a (1), b (3), c (8); | |
340 | (void) a.overload (); | |
341 | (void) a.overload (static_cast<int> (0)); | |
342 | (void) a.overload (static_cast<short> (0)); | |
343 | (void) a.overload (static_cast<long> (0)); | |
344 | (void) a.overload (static_cast<char*> (0)); | |
345 | (void) a.overload (a); | |
346 | ||
347 | int r; | |
348 | r = b + c; | |
349 | ++a; | |
350 | a += b; | |
351 | r = b - c; | |
352 | --a; | |
353 | a -= b; | |
354 | r = b * c; | |
355 | a *= b; | |
356 | r = b / c; | |
357 | a /= b; | |
358 | r = b % c; | |
359 | a %= b; | |
360 | bool x = (b < c); | |
361 | x = (b <= c); | |
362 | x = (b > c); | |
363 | x = (b >= c); | |
364 | x = (b != c); | |
365 | x = (b == c); | |
366 | x = (!b); | |
367 | x = (b && c); | |
368 | x = (b || c); | |
369 | r = b << 2; | |
370 | a <<= 1; | |
371 | r = b >> 2; | |
372 | a >>= 1; | |
373 | r = ~b; | |
374 | r = b & c; | |
375 | a &= c; | |
376 | r = b | c; | |
377 | a |= c; | |
378 | r = b ^ c; | |
379 | a ^= c; | |
380 | a = c; | |
381 | a (); | |
382 | int i = a[3]; | |
383 | derived* f = new derived (); | |
384 | derived* g = new derived[3]; | |
385 | delete f; | |
386 | delete[] g; | |
387 | a->overload (); | |
388 | r = a->*b; | |
389 | ||
390 | tclass<char> char_tclass; | |
391 | tclass<int> int_tclass; | |
392 | tclass<short> short_tclass; | |
393 | tclass<long> long_tclass; | |
394 | tclass<base> base_tclass; | |
395 | char_tclass.do_something (); | |
396 | int_tclass.do_something (); | |
397 | short_tclass.do_something (); | |
398 | long_tclass.do_something (); | |
399 | base_tclass.do_something (); | |
400 | ||
401 | flubber<int, int, int, int, int> (); | |
402 | flubber<int, int, int, int, short> (); | |
403 | flubber<int, int, int, int, long> (); | |
404 | flubber<int, int, int, int, char> (); | |
405 | flubber<int, int, int, short, int> (); | |
406 | flubber<int, int, int, short, short> (); | |
407 | flubber<int, int, int, short, long> (); | |
408 | flubber<int, int, int, short, char> (); | |
409 | flubber<int, int, int, long, int> (); | |
410 | flubber<int, int, int, long, short> (); | |
411 | flubber<int, int, int, long, long> (); | |
412 | flubber<int, int, int, long, char> (); | |
413 | flubber<int, int, int, char, int> (); | |
414 | flubber<int, int, int, char, short> (); | |
415 | flubber<int, int, int, char, long> (); | |
416 | flubber<int, int, int, char, char> (); | |
417 | flubber<int, int, short, int, int> (); | |
418 | flubber<int, int, short, int, short> (); | |
419 | flubber<int, int, short, int, long> (); | |
420 | flubber<int, int, short, int, char> (); | |
421 | flubber<int, int, short, short, int> (); | |
422 | flubber<short, int, short, int, short> (); | |
423 | flubber<long, short, long, short, long> (); | |
424 | ||
425 | policy1 p1 (1); | |
426 | p1.function (); | |
427 | policy2 p2 (2); | |
428 | p2.function (); | |
429 | policy3 p3 (3); | |
430 | p3.function (); | |
431 | policy4 p4 (4); | |
432 | p4.function (); | |
433 | ||
434 | policyd1 pd1 (5); | |
435 | pd1.function (); | |
436 | policyd2 pd2 (6); | |
437 | pd2.function (); | |
438 | policyd3 pd3 (7); | |
439 | pd3.function (); | |
440 | policyd4 pd4 (d); | |
441 | pd4.function (); | |
442 | policyd5 pd5 (int_tclass); | |
443 | pd5.function (); | |
444 | ||
445 | base1 b1 (3); | |
446 | ||
447 | r = a; | |
448 | char* str = a; | |
449 | fluff* flp = a; | |
450 | fluff** flpp = a; | |
640617ad | 451 | |
50af5481 JK |
452 | CV_f(CV::i); |
453 | ||
640617ad | 454 | return 0; |
cec808ec KS |
455 | } |
456 | ||
640617ad DJ |
457 | int |
458 | main (int argc, char* argv[]) | |
459 | { | |
460 | int i; | |
461 | ||
462 | /* Call the test function repeatedly, enough times for all our tests | |
463 | without running forever if something goes wrong. */ | |
464 | for (i = 0; i < 1000; i++) | |
465 | test_function (argc, argv); | |
466 | ||
467 | return 0; | |
468 | } |