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

   Copyright 2019-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/>.  */

class ByVal {
public:
  ByVal (void);

  int x;
};

ByVal::ByVal (void)
{
  x = 2;
}

class ByRef {
public:
  ByRef (void);

  ByRef (const ByRef &rhs);

  int x;
};

ByRef::ByRef (void)
{
  x = 2;
}

ByRef::ByRef (const ByRef &rhs)
{
  x = 3; /* ByRef-cctor */
}

class ArrayContainerByVal {
public:
  ByVal items[2];
};

int
cbvArrayContainerByVal (ArrayContainerByVal arg)
{
  arg.items[0].x += 4;  // intentionally modify
  return arg.items[0].x;
}

class ArrayContainerByRef {
public:
  ByRef items[2];
};

int
cbvArrayContainerByRef (ArrayContainerByRef arg)
{
  arg.items[0].x += 4;  // intentionally modify
  return arg.items[0].x;
}

class DynamicBase {
public:
  DynamicBase (void);

  virtual int get (void);

  int x;
};

DynamicBase::DynamicBase (void)
{
  x = 2;
}

int
DynamicBase::get (void)
{
  return 42;
}

class Dynamic : public DynamicBase {
public:
  virtual int get (void);
};

int
Dynamic::get (void)
{
  return 9999;
}

int
cbvDynamic (DynamicBase arg)
{
  arg.x += 4;  // intentionally modify
  return arg.x + arg.get ();
}

class Inlined {
public:
  Inlined (void);

  __attribute__((always_inline))
  Inlined (const Inlined &rhs)
  {
    x = 3;
  }

  int x;
};

Inlined::Inlined (void)
{
  x = 2;
}

int
cbvInlined (Inlined arg)
{
  arg.x += 4;  // intentionally modify
  return arg.x;
}

class DtorDel {
public:
  DtorDel (void);

  ~DtorDel (void) = delete;

  int x;
};

DtorDel::DtorDel (void)
{
  x = 2;
}

int
cbvDtorDel (DtorDel arg)
{
  // Calling this method should be rejected
  return arg.x;
}

class FourCCtor {
public:
  FourCCtor (void);

  FourCCtor (FourCCtor &rhs);
  FourCCtor (const FourCCtor &rhs);
  FourCCtor (volatile FourCCtor &rhs);
  FourCCtor (const volatile FourCCtor &rhs);

  int x;
};

FourCCtor::FourCCtor (void)
{
  x = 2;
}

FourCCtor::FourCCtor (FourCCtor &rhs)
{
  x = 3;
}

FourCCtor::FourCCtor (const FourCCtor &rhs)
{
  x = 4;
}

FourCCtor::FourCCtor (volatile FourCCtor &rhs)
{
  x = 5;
}

FourCCtor::FourCCtor (const volatile FourCCtor &rhs)
{
  x = 6;
}

int
cbvFourCCtor (FourCCtor arg)
{
  arg.x += 10;  // intentionally modify
  return arg.x;
}

class TwoMCtor {
public:
  TwoMCtor (void);

  /* Even though one move ctor is defaulted, the other
     is explicit.  */
  TwoMCtor (const TwoMCtor &&rhs);
  TwoMCtor (TwoMCtor &&rhs) = default;

  int x;
};

TwoMCtor::TwoMCtor (void)
{
  x = 2;
}

TwoMCtor::TwoMCtor (const TwoMCtor &&rhs)
{
  x = 3;
}

int
cbvTwoMCtor (TwoMCtor arg)
{
  arg.x += 10;  // intentionally modify
  return arg.x;
}

class TwoMCtorAndCCtor {
public:
  TwoMCtorAndCCtor (void);

  TwoMCtorAndCCtor (const TwoMCtorAndCCtor &rhs) = default;

  /* Even though one move ctor is defaulted, the other
     is explicit.  This makes the type pass-by-ref.  */
  TwoMCtorAndCCtor (const TwoMCtorAndCCtor &&rhs);
  TwoMCtorAndCCtor (TwoMCtorAndCCtor &&rhs) = default;

  int x;
};

TwoMCtorAndCCtor::TwoMCtorAndCCtor (void)
{
  x = 2;
}

TwoMCtorAndCCtor::TwoMCtorAndCCtor (const TwoMCtorAndCCtor &&rhs)
{
  x = 4;
}

int
cbvTwoMCtorAndCCtor (TwoMCtorAndCCtor arg)
{
  arg.x += 10;  // intentionally modify
  return arg.x;
}

ArrayContainerByVal arrayContainerByVal;
ArrayContainerByRef arrayContainerByRef;
Dynamic dynamic;
Inlined inlined;
// Cannot stack-allocate DtorDel
DtorDel *dtorDel;
FourCCtor fourCctor_c0v0;
const FourCCtor fourCctor_c1v0;
volatile FourCCtor fourCctor_c0v1;
const volatile FourCCtor fourCctor_c1v1;
TwoMCtor twoMctor;
TwoMCtorAndCCtor twoMctorAndCctor;

int
main (void)
{
  int v;
  dtorDel = new DtorDel;
  /* Explicitly call the cbv function to make sure the compiler
     will not omit any code in the binary.  */
  v = cbvArrayContainerByVal (arrayContainerByVal);
  v = cbvArrayContainerByRef (arrayContainerByRef);
  v = cbvDynamic (dynamic);
  v = cbvInlined (inlined);
  v = cbvFourCCtor (fourCctor_c0v0);
  v = cbvFourCCtor (fourCctor_c1v0);
  v = cbvFourCCtor (fourCctor_c0v1);
  v = cbvFourCCtor (fourCctor_c1v1);
  /* v = cbvTwoMCtor (twoMctor); */ // This is illegal, cctor is deleted
  v = cbvTwoMCtorAndCCtor (twoMctorAndCctor);

  /* stop here */

  return 0;
}
