1/* This testcase is part of GDB, the GNU debugger.
2
3   Copyright 1998, 1999, 2004, 2006, 2007 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
19
20
21extern "C" {
22#include <stdio.h>
23}
24
25
26class A {
27public:
28  A();
29  int foo (int x);
30  int bar (int y);
31  virtual int baz (int z);
32  char c;
33  int  j;
34  int  jj;
35  static int s;
36};
37
38class B {
39public:
40  static int s;
41};
42
43int A::s = 10;
44int B::s = 20;
45
46A::A()
47{
48  c = 'x';
49  j = 5;
50}
51
52int A::foo (int dummy)
53{
54  j += 3;
55  return j + dummy;
56}
57
58int A::bar (int dummy)
59{
60  int r;
61  j += 13;
62  r = this->foo(15);
63  return r + j + 2 * dummy;
64}
65
66int A::baz (int dummy)
67{
68  int r;
69  j += 15;
70  r = this->foo(15);
71  return r + j + 12 * dummy;
72}
73
74int fum (int dummy)
75{
76  return 2 + 13 * dummy;
77}
78
79typedef int (A::*PMF)(int);
80
81typedef int A::*PMI;
82
83/* This class is in front of the other base classes of Diamond, so
84   that we can detect if the offset for Left or the first Base is
85   added twice - otherwise it would be 2 * 0 == 0.  */
86class Padding
87{
88public:
89  int spacer;
90  virtual int vspacer();
91};
92
93int Padding::vspacer()
94{
95  return this->spacer;
96}
97
98class Base
99{
100public:
101  int x;
102  int get_x();
103  virtual int vget_base ();
104};
105
106int Base::get_x ()
107{
108  return this->x;
109}
110
111int Base::vget_base ()
112{
113  return this->x + 1000;
114}
115
116class Left : public Base {
117public:
118  virtual int vget ();
119};
120
121int Left::vget ()
122{
123  return this->x + 100;
124}
125
126class Right : public Base {
127public:
128  virtual int vget ();
129};
130
131int Right::vget ()
132{
133  return this->x + 200;
134}
135
136class Diamond : public Padding, public Left, public Right
137{
138public:
139  virtual int vget_base ();
140};
141
142int Diamond::vget_base ()
143{
144  return this->Left::x + 2000;
145}
146
147int main ()
148{
149  A a;
150  A * a_p;
151  PMF pmf;
152
153  PMF * pmf_p;
154  PMI pmi;
155
156  Diamond diamond;
157  int (Diamond::*left_pmf) ();
158  int (Diamond::*right_pmf) ();
159  int (Diamond::*left_vpmf) ();
160  int (Diamond::*left_base_vpmf) ();
161  int (Diamond::*right_vpmf) ();
162  int (Base::*base_vpmf) ();
163  int Diamond::*diamond_pmi;
164
165  PMI null_pmi;
166  PMF null_pmf;
167
168  a.j = 121;
169  a.jj = 1331;
170
171  int k;
172
173  a_p = &a;
174
175  pmi = &A::j;
176  pmf = &A::bar;
177  pmf_p = &pmf;
178
179  diamond.Left::x = 77;
180  diamond.Right::x = 88;
181
182  /* Some valid pointer to members from a base class.  */
183  left_pmf = (int (Diamond::*) ()) (int (Left::*) ()) (&Base::get_x);
184  right_pmf = (int (Diamond::*) ()) (int (Right::*) ()) (&Base::get_x);
185  left_vpmf = &Left::vget;
186  left_base_vpmf = (int (Diamond::*) ()) (int (Left::*) ()) (&Base::vget_base);
187  right_vpmf = &Right::vget;
188
189  /* An unspecified, value preserving pointer to member cast.  */
190  base_vpmf = (int (Base::*) ()) (int (Left::*) ()) &Diamond::vget_base;
191
192  /* A pointer to data member from a base class.  */
193  diamond_pmi = (int Diamond::*) (int Left::*) &Base::x;
194
195  null_pmi = NULL;
196  null_pmf = NULL;
197
198  pmi = NULL; /* Breakpoint 1 here.  */
199
200  k = (a.*pmf)(3);
201
202  pmi = &A::jj;
203  pmf = &A::foo;
204  pmf_p = &pmf;
205
206  k = (a.*pmf)(4);
207
208  k = (a.**pmf_p)(5);
209
210  k = a.*pmi;
211
212
213  k = a.bar(2);
214
215  k += fum (4);
216
217  B b;
218
219  k += b.s;
220
221}
222