Commit | Line | Data |
---|---|---|
cec808ec KS |
1 | /* This testcase is part of GDB, the GNU debugger. |
2 | ||
28e7fd62 | 3 | Copyright 2008-2013 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> | |
52 | void flubber (void) // flubber | |
53 | { | |
54 | A a; | |
55 | B b; | |
56 | C c; | |
57 | D d; | |
58 | E e; | |
59 | ||
60 | ++a; | |
61 | ++b; | |
62 | ++c; | |
63 | ++d; | |
64 | ++e; | |
65 | } | |
66 | ||
67 | // Some contrived policies | |
68 | template <class T> | |
69 | struct operation_1 | |
70 | { | |
71 | static void function (void) { } // operation_1<T>::function | |
72 | }; | |
73 | ||
74 | template <class T> | |
75 | struct operation_2 | |
76 | { | |
77 | static void function (void) { } // operation_2<T>::function | |
78 | }; | |
79 | ||
80 | template <class T> | |
81 | struct operation_3 | |
82 | { | |
83 | static void function (void) { } // operation_3<T>::function | |
84 | }; | |
85 | ||
86 | template <class T> | |
87 | struct operation_4 | |
88 | { | |
89 | static void function (void) { } // operation_4<T>::function | |
90 | }; | |
91 | ||
92 | // A policy-based class w/ and w/o default policy | |
93 | template <class T, class Policy> | |
94 | class policy : public Policy | |
95 | { | |
96 | public: | |
97 | policy (T obj) : obj_ (obj) { } // policy<T, Policy>::policy | |
98 | ||
99 | private: | |
100 | T obj_; | |
101 | }; | |
102 | ||
103 | template <class T, class Policy = operation_1<T> > | |
104 | class policyd : public Policy | |
105 | { | |
106 | public: | |
107 | policyd (T obj) : obj_ (obj) { } // policyd<T, Policy>::policyd | |
108 | ~policyd (void) { } // policyd<T, Policy>::~policyd | |
109 | ||
110 | private: | |
111 | T obj_; | |
112 | }; | |
113 | ||
114 | typedef policy<int, operation_1<void*> > policy1; | |
115 | typedef policy<int, operation_2<void*> > policy2; | |
116 | typedef policy<int, operation_3<void*> > policy3; | |
117 | typedef policy<int, operation_4<void*> > policy4; | |
118 | ||
119 | typedef policyd<int> policyd1; | |
120 | typedef policyd<long> policyd2; | |
121 | typedef policyd<char> policyd3; | |
122 | typedef policyd<base> policyd4; | |
123 | typedef policyd<tclass<int> > policyd5; | |
124 | ||
125 | class fluff { }; | |
126 | static fluff *g_fluff = new fluff (); | |
127 | ||
128 | class base | |
129 | { | |
130 | protected: | |
131 | int foo_; | |
132 | ||
133 | public: | |
134 | base (void) : foo_ (42) { } // base::base(void) | |
135 | base (int foo) : foo_ (foo) { } // base::base(int) | |
136 | ~base (void) { } // base::~base | |
137 | ||
138 | // Some overloaded methods | |
139 | int overload (void) const { return 0; } // base::overload(void) const | |
140 | int overload (int i) const { return 1; } // base::overload(int) const | |
141 | int overload (short s) const { return 2; } // base::overload(short) const | |
142 | int overload (long l) const { return 3; } // base::overload(long) const | |
143 | int overload (char* a) const { return 4; } // base::overload(char*) const | |
144 | int overload (base& b) const { return 5; } // base::overload(base&) const | |
145 | ||
146 | // Operators | |
147 | int operator+ (base const& o) const // base::operator+ | |
148 | { return foo_ + o.foo_; } | |
149 | ||
150 | base operator++ (void) // base::operator++ | |
151 | { ++foo_; return *this; } | |
152 | ||
153 | base operator+=(base const& o) // base::operator+= | |
154 | { foo_ += o.foo_; return *this; } | |
155 | ||
156 | int operator- (base const& o) const // base::operator- | |
157 | { return foo_ - o.foo_; } | |
158 | ||
159 | base operator-- (void) // base::operator-- | |
160 | { --foo_; return *this; } | |
161 | ||
162 | base operator-= (base const& o) // base::operator-= | |
163 | { foo_ -= o.foo_; return *this; } | |
164 | ||
165 | int operator* (base const& o) const // base::operator* | |
166 | { return foo_ * o.foo_; } | |
167 | ||
168 | base operator*= (base const& o) // base::operator*= | |
169 | { foo_ *= o.foo_; return *this; } | |
170 | ||
171 | int operator/ (base const& o) const // base::operator/ | |
172 | { return foo_ / o.foo_; } | |
173 | ||
174 | base operator/= (base const& o) // base::operator/= | |
175 | { foo_ /= o.foo_; return *this; } | |
176 | ||
177 | int operator% (base const& o) const // base::operator% | |
178 | { return foo_ % o.foo_; } | |
179 | ||
180 | base operator%= (base const& o) // base::operator%= | |
181 | { foo_ %= o.foo_; return *this; } | |
182 | ||
183 | bool operator< (base const& o) const // base::operator< | |
184 | { return foo_ < o.foo_; } | |
185 | ||
186 | bool operator<= (base const& o) const // base::operator<= | |
187 | { return foo_ <= o.foo_; } | |
188 | ||
189 | bool operator> (base const& o) const // base::operator> | |
190 | { return foo_ > o.foo_; } | |
191 | ||
192 | bool operator>= (base const& o) const // base::operator>= | |
193 | { return foo_ >= o.foo_; } | |
194 | ||
195 | bool operator!= (base const& o) const // base::operator!= | |
196 | { return foo_ != o.foo_; } | |
197 | ||
198 | bool operator== (base const& o) const // base::operator== | |
199 | { return foo_ == o.foo_; } | |
200 | ||
201 | bool operator! (void) const // base::operator! | |
202 | { return !foo_; } | |
203 | ||
204 | bool operator&& (base const& o) const // base::operator&& | |
205 | { return foo_ && o.foo_; } | |
206 | ||
207 | bool operator|| (base const& o) const // base::operator|| | |
208 | { return foo_ || o.foo_; } | |
209 | ||
210 | int operator<< (int value) const // base::operator<< | |
211 | { return foo_ << value; } | |
212 | ||
213 | base operator<<= (int value) // base::operator<<= | |
214 | { foo_ <<= value; return *this; } | |
215 | ||
216 | int operator>> (int value) const // base::operator>> | |
217 | { return foo_ >> value; } | |
218 | ||
219 | base operator>>= (int value) // base::operator>>= | |
220 | { foo_ >>= value; return *this; } | |
221 | ||
222 | int operator~ (void) const // base::operator~ | |
223 | { return ~foo_; } | |
224 | ||
225 | int operator& (base const& o) const // base::operator& | |
226 | { return foo_ & o.foo_; } | |
227 | ||
228 | base operator&= (base const& o) // base::operator&= | |
229 | { foo_ &= o.foo_; return *this; } | |
230 | ||
231 | int operator| (base const& o) const // base::operator| | |
232 | { return foo_ | o.foo_; } | |
233 | ||
234 | base operator|= (base const& o) // base::operator|= | |
235 | { foo_ |= o.foo_; return *this; } | |
236 | ||
237 | int operator^ (base const& o) const // base::operator^ | |
238 | { return foo_ ^ o.foo_; } | |
239 | ||
240 | base operator^= (base const& o) // base::operator^= | |
241 | { foo_ ^= o.foo_; return *this; } | |
242 | ||
243 | base operator= (base const& o) // base::operator= | |
244 | { foo_ = o.foo_; return *this; } | |
245 | ||
246 | void operator() (void) const // base::operator() | |
247 | { return; } | |
248 | ||
249 | int operator[] (int idx) const // base::operator[] | |
250 | { return idx; } | |
251 | ||
252 | void* operator new (size_t size) throw () // base::operator new | |
253 | { return malloc (size); } | |
254 | ||
255 | void operator delete (void* ptr) // base::operator delete | |
256 | { free (ptr); } | |
257 | ||
258 | void* operator new[] (size_t size) throw () // base::operator new[] | |
259 | { return malloc (size); } | |
260 | ||
261 | void operator delete[] (void* ptr) // base::operator delete[] | |
262 | { free (ptr); } | |
263 | ||
264 | base const* operator-> (void) const // base::opeartor-> | |
265 | { return this; } | |
266 | ||
267 | int operator->* (base const& b) const // base::operator->* | |
268 | { return foo_ * b.foo_; } | |
269 | ||
270 | operator char* () const { return const_cast<char*> ("hello"); } // base::operator char* | |
271 | operator int () const { return 21; } // base::operator int | |
272 | operator fluff* () const { return new fluff (); } // base::operator fluff* | |
273 | operator fluff** () const { return &g_fluff; } // base::operator fluff** | |
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 | |
301 | void a_function (void) const // derived::a_function | |
302 | { | |
303 | this->base1::a_function (); | |
304 | this->base2::a_function (); | |
305 | } | |
306 | ||
307 | protected: | |
308 | int foo_; | |
309 | }; | |
310 | ||
50af5481 JK |
311 | class CV { public: |
312 | static const int i; | |
313 | typedef int t; | |
314 | void m(t); | |
315 | void m(t) const; | |
316 | void m(t) volatile; | |
317 | void m(t) const volatile; | |
318 | }; | |
319 | const int CV::i = 42; | |
320 | #ifdef __GNUC__ | |
321 | # define ATTRIBUTE_USED __attribute__((used)) | |
322 | #else | |
323 | # define ATTRIBUTE_USED | |
324 | #endif | |
325 | ATTRIBUTE_USED void CV::m(CV::t) {} | |
326 | ATTRIBUTE_USED void CV::m(CV::t) const {} | |
327 | ATTRIBUTE_USED void CV::m(CV::t) volatile {} | |
328 | ATTRIBUTE_USED void CV::m(CV::t) const volatile {} | |
329 | int CV_f (int x) | |
330 | { | |
331 | return x + 1; | |
332 | } | |
333 | ||
cec808ec | 334 | int |
640617ad DJ |
335 | test_function (int argc, char* argv[]) // test_function |
336 | { // test_function | |
cec808ec KS |
337 | derived d; |
338 | void (derived::*pfunc) (void) const = &derived::a_function; | |
339 | (d.*pfunc) (); | |
340 | ||
341 | base a (1), b (3), c (8); | |
342 | (void) a.overload (); | |
343 | (void) a.overload (static_cast<int> (0)); | |
344 | (void) a.overload (static_cast<short> (0)); | |
345 | (void) a.overload (static_cast<long> (0)); | |
346 | (void) a.overload (static_cast<char*> (0)); | |
347 | (void) a.overload (a); | |
348 | ||
349 | int r; | |
350 | r = b + c; | |
351 | ++a; | |
352 | a += b; | |
353 | r = b - c; | |
354 | --a; | |
355 | a -= b; | |
356 | r = b * c; | |
357 | a *= b; | |
358 | r = b / c; | |
359 | a /= b; | |
360 | r = b % c; | |
361 | a %= b; | |
362 | bool x = (b < c); | |
363 | x = (b <= c); | |
364 | x = (b > c); | |
365 | x = (b >= c); | |
366 | x = (b != c); | |
367 | x = (b == c); | |
368 | x = (!b); | |
369 | x = (b && c); | |
370 | x = (b || c); | |
371 | r = b << 2; | |
372 | a <<= 1; | |
373 | r = b >> 2; | |
374 | a >>= 1; | |
375 | r = ~b; | |
376 | r = b & c; | |
377 | a &= c; | |
378 | r = b | c; | |
379 | a |= c; | |
380 | r = b ^ c; | |
381 | a ^= c; | |
382 | a = c; | |
383 | a (); | |
384 | int i = a[3]; | |
385 | derived* f = new derived (); | |
386 | derived* g = new derived[3]; | |
387 | delete f; | |
388 | delete[] g; | |
389 | a->overload (); | |
390 | r = a->*b; | |
391 | ||
392 | tclass<char> char_tclass; | |
393 | tclass<int> int_tclass; | |
394 | tclass<short> short_tclass; | |
395 | tclass<long> long_tclass; | |
396 | tclass<base> base_tclass; | |
397 | char_tclass.do_something (); | |
398 | int_tclass.do_something (); | |
399 | short_tclass.do_something (); | |
400 | long_tclass.do_something (); | |
401 | base_tclass.do_something (); | |
402 | ||
403 | flubber<int, int, int, int, int> (); | |
404 | flubber<int, int, int, int, short> (); | |
405 | flubber<int, int, int, int, long> (); | |
406 | flubber<int, int, int, int, char> (); | |
407 | flubber<int, int, int, short, int> (); | |
408 | flubber<int, int, int, short, short> (); | |
409 | flubber<int, int, int, short, long> (); | |
410 | flubber<int, int, int, short, char> (); | |
411 | flubber<int, int, int, long, int> (); | |
412 | flubber<int, int, int, long, short> (); | |
413 | flubber<int, int, int, long, long> (); | |
414 | flubber<int, int, int, long, char> (); | |
415 | flubber<int, int, int, char, int> (); | |
416 | flubber<int, int, int, char, short> (); | |
417 | flubber<int, int, int, char, long> (); | |
418 | flubber<int, int, int, char, char> (); | |
419 | flubber<int, int, short, int, int> (); | |
420 | flubber<int, int, short, int, short> (); | |
421 | flubber<int, int, short, int, long> (); | |
422 | flubber<int, int, short, int, char> (); | |
423 | flubber<int, int, short, short, int> (); | |
424 | flubber<short, int, short, int, short> (); | |
425 | flubber<long, short, long, short, long> (); | |
426 | ||
427 | policy1 p1 (1); | |
428 | p1.function (); | |
429 | policy2 p2 (2); | |
430 | p2.function (); | |
431 | policy3 p3 (3); | |
432 | p3.function (); | |
433 | policy4 p4 (4); | |
434 | p4.function (); | |
435 | ||
436 | policyd1 pd1 (5); | |
437 | pd1.function (); | |
438 | policyd2 pd2 (6); | |
439 | pd2.function (); | |
440 | policyd3 pd3 (7); | |
441 | pd3.function (); | |
442 | policyd4 pd4 (d); | |
443 | pd4.function (); | |
444 | policyd5 pd5 (int_tclass); | |
445 | pd5.function (); | |
446 | ||
447 | base1 b1 (3); | |
448 | ||
449 | r = a; | |
450 | char* str = a; | |
451 | fluff* flp = a; | |
452 | fluff** flpp = 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 | } |