This commit was manufactured by cvs2svn to create branch 'gdb_7_0-branch'.
[external/binutils.git] / gdb / testsuite / gdb.cp / member-ptr.cc
1 /* This testcase is part of GDB, the GNU debugger.
2
3    Copyright 1998, 1999, 2004, 2006, 2007, 2008, 2009
4    Free Software Foundation, Inc.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18    */
19
20
21
22 extern "C" {
23 #include <stdio.h>
24 }
25
26
27 class A {
28 public:
29   A();
30   int foo (int x);
31   int bar (int y);
32   virtual int baz (int z);
33   char c;
34   int  j;
35   int  jj;
36   static int s;
37 };
38
39 class B {
40 public:
41   static int s;
42 };
43
44 int A::s = 10;
45 int B::s = 20;
46
47 A::A()
48 {
49   c = 'x';
50   j = 5;
51 }
52
53 int A::foo (int dummy)
54 {
55   j += 3;
56   return j + dummy;
57 }
58
59 int A::bar (int dummy)
60 {
61   int r;
62   j += 13;
63   r = this->foo(15);
64   return r + j + 2 * dummy;
65 }
66
67 int A::baz (int dummy)
68 {
69   int r;
70   j += 15;
71   r = this->foo(15);
72   return r + j + 12 * dummy;
73 }
74
75 int fum (int dummy)
76 {
77   return 2 + 13 * dummy;
78 }
79
80 typedef int (A::*PMF)(int);
81
82 typedef int A::*PMI;
83
84 /* This class is in front of the other base classes of Diamond, so
85    that we can detect if the offset for Left or the first Base is
86    added twice - otherwise it would be 2 * 0 == 0.  */
87 class Padding
88 {
89 public:
90   int spacer;
91   virtual int vspacer();
92 };
93
94 int Padding::vspacer()
95 {
96   return this->spacer;
97 }
98
99 class Base
100 {
101 public:
102   int x;
103   int get_x();
104   virtual int vget_base ();
105 };
106
107 int Base::get_x ()
108 {
109   return this->x;
110 }
111
112 int Base::vget_base ()
113 {
114   return this->x + 1000;
115 }
116
117 class Left : public Base {
118 public:
119   virtual int vget ();
120 };
121
122 int Left::vget ()
123 {
124   return this->x + 100;
125 }
126
127 class Right : public Base {
128 public:
129   virtual int vget ();
130 };
131
132 int Right::vget ()
133 {
134   return this->x + 200;
135 }
136
137 class Diamond : public Padding, public Left, public Right
138 {
139 public:
140   virtual int vget_base ();
141 };
142
143 int Diamond::vget_base ()
144 {
145   return this->Left::x + 2000;
146 }
147
148 int main ()
149 {
150   A a;
151   A * a_p;
152   PMF pmf;
153
154   PMF * pmf_p;
155   PMI pmi;
156
157   Diamond diamond;
158   int (Diamond::*left_pmf) ();
159   int (Diamond::*right_pmf) ();
160   int (Diamond::*left_vpmf) ();
161   int (Diamond::*left_base_vpmf) ();
162   int (Diamond::*right_vpmf) ();
163   int (Base::*base_vpmf) ();
164   int Diamond::*diamond_pmi;
165
166   PMI null_pmi;
167   PMF null_pmf;
168
169   a.j = 121;
170   a.jj = 1331;
171   
172   int k;
173
174   a_p = &a;
175
176   pmi = &A::j;
177   pmf = &A::bar;
178   pmf_p = &pmf;
179
180   diamond.Left::x = 77;
181   diamond.Right::x = 88;
182
183   /* Some valid pointer to members from a base class.  */
184   left_pmf = (int (Diamond::*) ()) (int (Left::*) ()) (&Base::get_x);
185   right_pmf = (int (Diamond::*) ()) (int (Right::*) ()) (&Base::get_x);
186   left_vpmf = &Left::vget;
187   left_base_vpmf = (int (Diamond::*) ()) (int (Left::*) ()) (&Base::vget_base);
188   right_vpmf = &Right::vget;
189
190   /* An unspecified, value preserving pointer to member cast.  */
191   base_vpmf = (int (Base::*) ()) (int (Left::*) ()) &Diamond::vget_base;
192
193   /* A pointer to data member from a base class.  */
194   diamond_pmi = (int Diamond::*) (int Left::*) &Base::x;
195
196   null_pmi = NULL;
197   null_pmf = NULL;
198
199   pmi = NULL; /* Breakpoint 1 here.  */
200
201   k = (a.*pmf)(3);
202
203   pmi = &A::jj;
204   pmf = &A::foo;
205   pmf_p = &pmf;
206
207   k = (a.*pmf)(4);
208
209   k = (a.**pmf_p)(5);
210
211   k = a.*pmi;
212   
213
214   k = a.bar(2);
215
216   k += fum (4);
217
218   B b;
219
220   k += b.s;
221   
222 }