/* This testcase is part of GDB, the GNU debugger.

   Copyright 1998-2013 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */



extern "C" {
#include <stdio.h>
}


class A {
public:
  A();
  int foo (int x);
  int bar (int y);
  virtual int baz (int z);
  char c;
  int  j;
  int  jj;
  static int s;
};

class B {
public:
  static int s;
};

int A::s = 10;
int B::s = 20;

A::A()
{
  c = 'x';
  j = 5;
}

int A::foo (int dummy)
{
  j += 3;
  return j + dummy;
}

int A::bar (int dummy)
{
  int r;
  j += 13;
  r = this->foo(15);
  return r + j + 2 * dummy;
}

int A::baz (int dummy)
{
  int r;
  j += 15;
  r = this->foo(15);
  return r + j + 12 * dummy;
}

int fum (int dummy)
{
  return 2 + 13 * dummy;
}

typedef int (A::*PMF)(int);

typedef int A::*PMI;

/* This class is in front of the other base classes of Diamond, so
   that we can detect if the offset for Left or the first Base is
   added twice - otherwise it would be 2 * 0 == 0.  */
class Padding
{
public:
  int spacer;
  virtual int vspacer();
};

int Padding::vspacer()
{
  return this->spacer;
}

class Base
{
public:
  int x;
  int get_x();
  virtual int vget_base ();
};

int Base::get_x ()
{
  return this->x;
}

int Base::vget_base ()
{
  return this->x + 1000;
}

class Left : public Base {
public:
  virtual int vget ();
};

int Left::vget ()
{
  return this->x + 100;
}

class Right : public Base {
public:
  virtual int vget ();
};

int Right::vget ()
{
  return this->x + 200;
}

class Diamond : public Padding, public Left, public Right
{
public:
  virtual int vget_base ();
  int (*func_ptr) (int);
};

int Diamond::vget_base ()
{
  return this->Left::x + 2000;
}

int
func (int x)
{
  return 19 + x;
}

int main ()
{
  A a;
  A * a_p;
  PMF pmf;

  PMF * pmf_p;
  PMI pmi;

  Diamond diamond;
  int (Diamond::*left_pmf) ();
  int (Diamond::*right_pmf) ();
  int (Diamond::*left_vpmf) ();
  int (Diamond::*left_base_vpmf) ();
  int (Diamond::*right_vpmf) ();
  int (Base::*base_vpmf) ();
  int Diamond::*diamond_pmi;
  int (* Diamond::*diamond_pfunc_ptr) (int);

  PMI null_pmi;
  PMF null_pmf;

  a.j = 121;
  a.jj = 1331;
  
  int k;

  a_p = &a;

  pmi = &A::j;
  pmf = &A::bar;
  pmf_p = &pmf;

  diamond.Left::x = 77;
  diamond.Right::x = 88;
  diamond.func_ptr = func;

  /* Some valid pointer to members from a base class.  */
  left_pmf = (int (Diamond::*) ()) (int (Left::*) ()) (&Base::get_x);
  right_pmf = (int (Diamond::*) ()) (int (Right::*) ()) (&Base::get_x);
  left_vpmf = &Left::vget;
  left_base_vpmf = (int (Diamond::*) ()) (int (Left::*) ()) (&Base::vget_base);
  right_vpmf = &Right::vget;

  /* An unspecified, value preserving pointer to member cast.  */
  base_vpmf = (int (Base::*) ()) (int (Left::*) ()) &Diamond::vget_base;

  /* A pointer to data member from a base class.  */
  diamond_pmi = (int Diamond::*) (int Left::*) &Base::x;

  /* A pointer to data member, where the member is itself a pointer to
     a function.  */
  diamond_pfunc_ptr = (int (* Diamond::*) (int)) &Diamond::func_ptr;

  null_pmi = NULL;
  null_pmf = NULL;

  pmi = NULL; /* Breakpoint 1 here.  */

  (diamond.*diamond_pfunc_ptr) (20);

  k = (a.*pmf)(3);

  pmi = &A::jj;
  pmf = &A::foo;
  pmf_p = &pmf;

  k = (a.*pmf)(4);

  k = (a.**pmf_p)(5);

  k = a.*pmi;
  

  k = a.bar(2);

  k += fum (4);

  B b;

  k += b.s;
  
}
