#if defined __MN10300__ || defined __SH5__ || defined __arm__ || defined __thumb__ || defined __mips__
#define ADJUST_PTRFN(func, virt) ((void (*)())(func))
#define ADJUST_DELTA(delta, virt) (((delta) << 1) + !!(virt))
#else
#define ADJUST_PTRFN(func, virt) ((void (*)())((ptrdiff_t)(func) + !!(virt)))
#define ADJUST_DELTA(delta, virt) (delta)
#endif
#if defined __ia64__
#define CMP_PTRFN(A, B) (*(void **)(A) == *(void **)(B))
#define VPTE_SIZE (16)
#else
#define CMP_PTRFN(A, B) ((A) == (B))
#define VPTE_SIZE sizeof(void *)
#endif
#if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
#include <cstddef>
struct S
{
int i;
int j;
};
struct T : public S
{
void f () {}
virtual void g () {}
virtual void h () {}
};
extern "C" void _ZN1T1fEv ();
extern "C" void _ZN1T1gEv ();
extern "C" void _ZN1T1hEv ();
struct ptrmemfunc
{
void (*ptr) ();
ptrdiff_t adj;
};
typedef int S::*sdp;
typedef void (S::*sp)();
typedef void (T::*tp)();
int
main ()
{
S s;
T t;
sp x;
tp y;
ptrmemfunc *xp = (ptrmemfunc *) &x;
ptrmemfunc *yp = (ptrmemfunc *) &y;
ptrdiff_t delta = ((char *) &t) - ((char*) (S*) (&t));
if (sizeof (sp) != sizeof (ptrmemfunc))
return 1;
if (__alignof__ (sp) != __alignof__ (ptrmemfunc))
return 2;
x = 0;
if (xp->ptr != 0)
return 3;
y = x;
if (yp->ptr != 0)
return 4;
y = &T::f;
if (! CMP_PTRFN (yp->ptr, ADJUST_PTRFN (&_ZN1T1fEv, 0)))
return 5;
if (yp->adj != ADJUST_DELTA (0, 0))
return 6;
x = (sp) y;
if (! CMP_PTRFN (xp->ptr, ADJUST_PTRFN (&_ZN1T1fEv, 0)))
return 7;
if (xp->adj != ADJUST_DELTA (delta, 0))
return 8;
y = &T::h;
if (yp->ptr != ADJUST_PTRFN (VPTE_SIZE, 1))
return 9;
if (yp->adj != ADJUST_DELTA (0, 1))
return 10;
x = (sp) y;
if (xp->ptr != ADJUST_PTRFN (VPTE_SIZE, 1))
return 11;
if (xp->adj != ADJUST_DELTA (delta, 1))
return 12;
if (sizeof (sdp) != sizeof (ptrdiff_t))
return 13;
if (__alignof__ (sdp) != __alignof__ (ptrdiff_t))
return 14;
sdp z = &S::j;
if ((char *) &s.j - (char *) &s != *((ptrdiff_t *) &z))
return 15;
z = 0;
if (*((ptrdiff_t *) &z) != -1)
return 16;
}
#else
int main ()
{
}
#endif