#if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
#include <stddef.h>
struct S0
{
virtual void s0 ();
};
struct S1 : virtual public S0
{
virtual void s1 ();
};
struct S2 : virtual public S1
{
virtual void s1 ();
virtual void s0 ();
};
struct S3
{
virtual void s3 ();
};
struct S4 : public S3, virtual public S2
{
virtual void s1 ();
};
void S0::s0 ()
{
}
void S1::s1 ()
{
}
void S2::s1 ()
{
}
void S2::s0 ()
{
}
void S3::s3 ()
{
}
void S4::s1 ()
{
}
extern "C" {
void _ZN2S32s3Ev ();
void _ZN2S42s1Ev ();
}
#if defined __ia64__
#define CMP_VPTR(A, B) (*(void **)(A) == *(void **)(B))
#ifdef _LP64
#define INC_VPTR(A) ((A) += 2)
#define INC_VDATA(A,N) ((A) += (N))
#else
#define INC_VPTR(A) ((A) += 4)
#define INC_VDATA(A,N) ((A) += 2*(N))
#endif
#else
#define CMP_VPTR(A, B) (*(A) == (ptrdiff_t)(B))
#define INC_VPTR(A) ((A) += 1)
#define INC_VDATA(A,N) ((A) += (N))
#endif
int main ()
{
S4 s4;
ptrdiff_t **vptr;
ptrdiff_t *vtbl;
vptr = (ptrdiff_t **) &s4;
vtbl = *vptr;
INC_VDATA (vtbl, -5);
if (*vtbl != ((char*) (S0*) &s4) - (char*) &s4)
return 1;
INC_VDATA (vtbl, 1);
if (*vtbl != ((char*) (S1*) &s4) - (char*) &s4)
return 2;
INC_VDATA (vtbl, 1);
if (*vtbl != ((char*) (S2*) &s4) - (char*) &s4)
return 3;
INC_VDATA (vtbl, 1);
if (*vtbl != 0)
return 4;
INC_VDATA (vtbl, 1);
INC_VDATA (vtbl, 1);
if (! CMP_VPTR (vtbl, &_ZN2S32s3Ev))
return 5;
INC_VPTR (vtbl);
if (! CMP_VPTR (vtbl, &_ZN2S42s1Ev))
return 6;
INC_VPTR (vtbl);
if (*vtbl != 0)
return 7;
INC_VDATA (vtbl, 1);
if (*vtbl != ((char*) &s4 - (char*) (S2*) &s4))
return 8;
INC_VDATA (vtbl, 1);
if (*vtbl != 0)
return 9;
INC_VDATA (vtbl, 1);
if (*vtbl != 0)
return 10;
INC_VDATA (vtbl, 1);
if (*vtbl != ((char*) &s4 - (char*) (S2*) &s4))
return 11;
INC_VDATA (vtbl, 1);
INC_VDATA (vtbl, 1);
INC_VPTR (vtbl);
INC_VPTR (vtbl);
}
#else
int main ()
{
}
#endif