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