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

   Copyright 2011-2012 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/>.

   Contributed by Red Hat, originally written by Keith Seitz.  */

#include <stdlib.h>

typedef const char* const* my_type;
typedef int my_type_2;
typedef my_type my_other_type;
typedef my_type_2 my_other_type_2;
typedef unsigned long CORE_ADDR;
typedef enum {E_A, E_B, E_C} anon_enum;
typedef struct {int a; char b;} anon_struct;
typedef union {int a; char b;} anon_union;
typedef anon_enum aenum;
typedef anon_struct astruct;
typedef anon_union aunion;

typedef void (*fptr1) (my_other_type);
typedef void (*fptr2) (fptr1, my_other_type_2);
typedef void (*fptr3) (fptr2, my_other_type);
typedef void (*fptr4) (anon_enum a, anon_struct const& b, anon_union const*** c);

namespace A
{
  class foo
  {
  public:
    foo (void) { }
    foo (my_other_type a) { } // A::FOO::foo(my_other_type)
    foo (my_other_type_2 a) { } // A::FOO::foo(my_other_type_2)
    foo (my_other_type_2 a, const my_other_type b) { } // A::FOO::foo(my_other_type_2, const my_other_type)
    foo (fptr3) { } // A::FOO::foo(fptr3)
    foo (fptr1* a) { } // A::FOO::foo(fptr1*)
    foo (CORE_ADDR (*) [10]) { } // A::FOO::foo(CORE_ADDR (*) [10])
    foo (aenum a, astruct const& b, aunion const*** c) { } // A::FOO::foo(aenum, astruct const&, aunion const***)

    void test (my_other_type a) { } // A::FOO::test(my_other_type)
    void test (my_other_type_2 a) { } // A::FOO::test(my_other_type_2)
    void test (my_other_type_2 a, const my_other_type b) { } // A::FOO::test(my_other_type_2, const my_other_type)
    void test (fptr3 a) { } // A::FOO::test(fptr3)
    void test (fptr1* a) { } // A::FOO::test(fptr1*)
    void test (CORE_ADDR (*) [10]) { } // A::FOO::test(CORE_ADDR (*) [10])
    void test (aenum a, astruct const& b, aunion const*** c) { }; // A::FOO::test(aenum, astruct const&, aunion const***)
  };

  typedef foo FOO;
};

namespace B
{
  void
  test (my_other_type foo) { } // B::test(my_other_type)

  void
  test (aenum a, astruct const& b, aunion const*** c) { } // B::test(aenum, astruct const&, aunion const***)

  template <typename T1, typename T2>
  void test (T1 a, T2 b) { } // B::test (T1, T2)

  template <>
  void test (my_other_type foo, my_other_type_2) { } // B::test<my_other_type, my_other_type_2>(my_other_type, my_other_type_2)
};

namespace a
{
  namespace b
  {
    namespace c
    {
      namespace d
      {
	class bar { };
      }
    }

    typedef c::d::bar BAR;
  }
}

typedef a::b::BAR _BAR_;

template <typename T1, typename T2>
void test (T1 a, T2 b) {} // test (T1, T2)

template <>
void test (my_other_type foo, my_other_type_2) { } // test<my_other_type, my_other_type_2>(my_other_type, my_other_type_2)

void
test (my_other_type foo) { } // test(my_other_type)

void
test (_BAR_ &b) { } // test(_BAR_&)

void
test (aenum a, astruct const& b, aunion const*** c) { } // test(aenum, astruct const&, aunion const***)

int
main (void)
{
  A::FOO my_foo;
  fptr1 fptr;
  astruct as = { 0, 0 };
  aunion const au = { 0 };
  aunion const* aup = &au;
  aunion const** aupp = &aup;
  aunion const*** auppp = &aupp;

  my_foo.test (static_cast<my_other_type> (NULL));
  my_foo.test (0);
  my_foo.test (0, static_cast<my_type> (NULL));
  my_foo.test (static_cast<fptr3> (NULL));
  my_foo.test (&fptr);
  my_foo.test (static_cast<CORE_ADDR (*) [10]> (0));
  my_foo.test (E_A, as, auppp);

  B::test (static_cast<my_other_type> (NULL));
  B::test (static_cast<my_other_type> (NULL), 0);
  B::test (E_A, as, auppp);

  test (static_cast<my_other_type> (NULL));
  test<my_other_type, my_other_type_2> (static_cast<my_other_type> (NULL), 0);
  test (E_A, as, auppp);

  A::foo a (static_cast<my_other_type> (NULL));
  A::foo b (0);
  A::foo c (0, static_cast<my_other_type> (NULL));
  A::foo d (static_cast<fptr3> (NULL));
  A::foo e (&fptr);
  A::foo f (static_cast<CORE_ADDR (*) [10]> (0));
  A::foo g (E_A, as, auppp);

  fptr4 f4;

  return 0;
}
