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