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

   Copyright 1998-2021 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;
  
  return 0;
}
