class A
{
public:
  A() : member_ (0) {};
  int member_;
};
class B : public A {};

typedef A TA1;
typedef A TA2;
typedef TA2 TA3;

enum my_enum {MY_A, MY_B, MY_C, MY_D};

/* Without this variable older 'enum my_enum' incl. its 'MY_A' would be omitted
   by older versions of GCC (~4.1) failing the testcase using it below.  */
enum my_enum my_enum_var;

int foo0_1 (TA1)  { return 1; }
int foo0_2 (TA3)  { return 2; }
int foo0_3 (A***) { return 3; }

int foo1_1 (char *) {return 11;}
int foo1_2 (char[]) {return 12;}
int foo1_3 (int*)   {return 13;}
int foo1_4 (A*)     {return 14;}
int foo1_5 (void*)  {return 15;}
int foo1_6 (void**) {return 16;}
int foo1_7 (bool)   {return 17;}
int foo1_8 (long)   {return 18;}

int foo2_1 (char**  )  {return 21;}
int foo2_2 (char[][1]) {return 22;}
int foo2_3 (char *[])  {return 23;}
int foo2_4 (int  *[])  {return 24;}

int foo3_1 (int a, const char **b) { return 31; }
int foo3_2 (int a, int b) { return 32; }
int foo3_2 (int a, const char **b) { return 320; }

int foo1_type_check (char *a) { return 1000; }
int foo2_type_check (char *a, char *b) { return 1001; }
int foo3_type_check (char *a, char *b, char *c) { return 1002; }

int main()
{

  TA2 ta;      // typedef to..
  foo0_1 (ta); // ..another typedef
  foo0_2 (ta); // ..typedef of a typedef

  B*** bppp;    // Pointer-to-pointer-to-pointer-to-derived..
//foo0_3(bppp); // Pointer-to-pointer-to-pointer base.
  foo0_3((A***)bppp); // to ensure that the function is emitted.

  char *a;             // pointer to..
  B *bp;
  foo1_1 (a);          // ..pointer
  foo1_2 (a);          // ..array
  foo1_3 ((int*)a);    // ..pointer of wrong type
  foo1_3 ((int*)bp);   // ..pointer of wrong type
  foo1_4 (bp);         // ..ancestor pointer
  foo1_5 (bp);         // ..void pointer
  foo1_6 ((void**)bp); // ..void pointer pointer
  foo1_7 (bp);         // ..boolean
  foo1_8 ((long)bp);   // ..long int

  char **b;          // pointer pointer to..
  char ba[1][1];
  foo1_5 (b);        // ..void pointer
  foo2_1 (b);        // ..pointer pointer
  foo2_2 (ba);       // ..array of arrays
  foo2_3 (b);        // ..array of pointers
  foo2_4 ((int**)b); // ..array of wrong pointers

  // X to boolean conversions allowed by the standard
  int integer = 0;
  long long_int = 1;
  float fp = 1.0;
  double dp = 1.0;
  foo1_7 (integer);		// integer to boolean
  foo1_7 (long_int);		// long to boolean
  foo1_7 (*a);			// char to boolean
  foo1_7 (MY_A);		// unscoped enum to boolean
  /* converts.exp tests the next statement directly.  It is not compiled
     here for verification because older versions of GCC (~4.1) fail to
     compile it:

     warning: the address of 'int foo1_7(bool)' will always evaluate as true
     
  foo1_7 (&foo1_7);		// pointer to boolean
  */
     
  foo1_7 (&A::member_);		// pointer to member to boolean
  foo1_7 (a);			// pointer to boolean
  foo1_7 (fp);			// float to boolean
  foo1_7 (dp);			// double  to boolean

  foo3_1 (0, 0);
  foo3_2 (0, static_cast<char const**> (0));
  foo3_2 (0, 0);

  foo1_type_check (a);
  foo2_type_check (a, a);
  foo3_type_check (a, a, a);

  return 0;          // end of main
}
