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

#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cassert>

/* A simple structure with a single integer field. Should be returned in
   a register.  */
struct SimpleBase
{
  SimpleBase (int32_t x) : x (x) {}

  int32_t x;
};

/* A simple structure derived from the simple base. Should be returned in
   a register.  */
struct SimpleDerived : public SimpleBase
{
  SimpleDerived (int32_t x) : SimpleBase (x) {}
};

/* A structure derived from the simple base with a non-trivial destructor.
   Should be returned on the stack.  */
struct NonTrivialDestructorDerived : public SimpleBase
{
  NonTrivialDestructorDerived (int32_t x) : SimpleBase (x) {}
  ~NonTrivialDestructorDerived() { x = 1; }
};

/* A structure with unaligned fields. Should be returned on the stack.  */
struct UnalignedFields
{
  UnalignedFields (int32_t x, double y) : x (x), y (y) {}

  int32_t x;
  double y;
} __attribute__((packed));

/* A structure with unaligned fields in its base class. Should be
   returned on the stack.  */
struct UnalignedFieldsInBase : public UnalignedFields
{
  UnalignedFieldsInBase (int32_t x, double y, int32_t x2)
  : UnalignedFields (x, y), x2 (x2) {}

  int32_t x2;
};

struct Bitfields
{
  Bitfields(unsigned int x, unsigned int y)
    : fld(x), fld2(y)
  {}

  unsigned fld : 7;
  unsigned fld2 : 7;
};

class Foo
{
public:
  SimpleBase
  return_simple_base (int32_t x)
  {
    assert (this->tag == EXPECTED_TAG);
    return SimpleBase (x);
  }

  SimpleDerived
  return_simple_derived (int32_t x)
  {
    assert (this->tag == EXPECTED_TAG);
    return SimpleDerived (x);
  }

  NonTrivialDestructorDerived
  return_non_trivial_destructor (int32_t x)
  {
    assert (this->tag == EXPECTED_TAG);
    return NonTrivialDestructorDerived (x);
  }

  UnalignedFields
  return_unaligned (int32_t x, double y)
  {
    assert (this->tag == EXPECTED_TAG);
    return UnalignedFields (x, y);
  }

  UnalignedFieldsInBase
  return_unaligned_in_base (int32_t x, double y, int32_t x2)
  {
    assert (this->tag == EXPECTED_TAG);
    return UnalignedFieldsInBase (x, y, x2);
  }

  Bitfields
  return_bitfields (unsigned int x, unsigned int y)
  {
    assert (this->tag == EXPECTED_TAG);
    return Bitfields(x, y);
  }

private:
  /* Use a tag to detect if the "this" value is correct.  */
  static const int EXPECTED_TAG = 0xF00F00F0;
  int tag = EXPECTED_TAG;
};

int
main (int argc, char *argv[])
{
  Foo foo;
  foo.return_simple_base(1);
  foo.return_simple_derived(2);
  foo.return_non_trivial_destructor(3);
  foo.return_unaligned(4, 5);
  foo.return_unaligned_in_base(6, 7, 8);
  foo.return_bitfields(23, 74);
  return 0;  // break-here
}
