struct Foo {
typedef int Foo::*FooInt;
int f;
};
#ifdef VMB
enum {
kSingleDataAlign = 1 * sizeof(int),
kSingleFunctionAlign = 1 * sizeof(void *),
kMultipleDataAlign = 1 * sizeof(int),
kMultipleFunctionAlign = 8,
#ifdef _M_X64
kVirtualDataAlign = 4,
#else
kVirtualDataAlign = 8,
#endif
kVirtualFunctionAlign = 8,
kUnspecifiedDataAlign = 8,
kUnspecifiedFunctionAlign = 8,
kSingleDataSize = 1 * sizeof(int),
kSingleFunctionSize = 1 * sizeof(void *),
kMultipleDataSize = 1 * sizeof(int),
kMultipleFunctionSize = 2 * sizeof(void *),
kVirtualDataSize = 2 * sizeof(int),
kVirtualFunctionSize = 2 * sizeof(int) + 1 * sizeof(void *),
kUnspecifiedDataSize = 3 * sizeof(int),
kUnspecifiedFunctionSize = 2 * sizeof(int) + 2 * sizeof(void *),
};
#elif VMV
enum {
#ifdef _M_X64
kVirtualDataAlign = 4,
#else
kVirtualDataAlign = 8,
#endif
kMultipleDataAlign = kVirtualDataAlign,
kSingleDataAlign = kVirtualDataAlign,
kUnspecifiedFunctionAlign = 8,
kVirtualFunctionAlign = kUnspecifiedFunctionAlign,
kMultipleFunctionAlign = kUnspecifiedFunctionAlign,
kSingleFunctionAlign = kUnspecifiedFunctionAlign,
kUnspecifiedDataSize = 3 * sizeof(int),
kVirtualDataSize = kUnspecifiedDataSize,
kMultipleDataSize = kUnspecifiedDataSize,
kSingleDataSize = kUnspecifiedDataSize,
kUnspecifiedFunctionSize = 2 * sizeof(int) + 2 * sizeof(void *),
kVirtualFunctionSize = kUnspecifiedFunctionSize,
kMultipleFunctionSize = kUnspecifiedFunctionSize,
kSingleFunctionSize = kUnspecifiedFunctionSize,
};
#else
#error "test doesn't yet support this mode!"
#endif
#ifdef VMB
class __single_inheritance IncSingle;
class __multiple_inheritance IncMultiple;
class __virtual_inheritance IncVirtual;
#else
class IncSingle;
class IncMultiple;
class IncVirtual;
#endif
static_assert(sizeof(int IncSingle::*) == kSingleDataSize, "");
static_assert(sizeof(int IncMultiple::*) == kMultipleDataSize, "");
static_assert(sizeof(int IncVirtual::*) == kVirtualDataSize, "");
static_assert(sizeof(void (IncSingle::*)()) == kSingleFunctionSize, "");
static_assert(sizeof(void (IncMultiple::*)()) == kMultipleFunctionSize, "");
static_assert(sizeof(void (IncVirtual::*)()) == kVirtualFunctionSize, "");
static_assert(__alignof(int IncSingle::*) == __alignof(void *), "");
static_assert(__alignof(int IncMultiple::*) == __alignof(void *), "");
static_assert(__alignof(int IncVirtual::*) == __alignof(void *), "");
static_assert(__alignof(void (IncSingle::*)()) == __alignof(void *), "");
static_assert(__alignof(void (IncMultiple::*)()) == __alignof(void *), "");
static_assert(__alignof(void (IncVirtual::*)()) == __alignof(void *), "");
class IncUnspecified;
static_assert(sizeof(int IncUnspecified::*) == kUnspecifiedDataSize, "");
static_assert(sizeof(void (IncUnspecified::*)()) == kUnspecifiedFunctionSize, "");
struct B1 { };
struct B2 { };
struct Single { };
struct Multiple : B1, B2 { };
struct Virtual : virtual B1 { };
static_assert(sizeof(int Single::*) == kSingleDataSize, "");
static_assert(sizeof(int Multiple::*) == kMultipleDataSize, "");
static_assert(sizeof(int Virtual::*) == kVirtualDataSize, "");
static_assert(sizeof(void (Single::*)()) == kSingleFunctionSize, "");
static_assert(sizeof(void (Multiple::*)()) == kMultipleFunctionSize, "");
static_assert(sizeof(void (Virtual::*)()) == kVirtualFunctionSize, "");
template <typename T> class X;
#ifdef VMB
template <> class __single_inheritance X<IncSingle>;
template <> class __multiple_inheritance X<IncMultiple>;
template <> class __virtual_inheritance X<IncVirtual>;
#else
template <> class X<IncSingle>;
template <> class X<IncMultiple>;
template <> class X<IncVirtual>;
#endif
static_assert(sizeof(int X<IncSingle>::*) == kSingleDataSize, "");
static_assert(sizeof(int X<IncMultiple>::*) == kMultipleDataSize, "");
static_assert(sizeof(int X<IncVirtual>::*) == kVirtualDataSize, "");
static_assert(sizeof(int X<IncUnspecified>::*) == kUnspecifiedDataSize, "");
static_assert(sizeof(void (X<IncSingle>::*)()) == kSingleFunctionSize, "");
static_assert(sizeof(void (X<IncMultiple>::*)()) == kMultipleFunctionSize, "");
static_assert(sizeof(void (X<IncVirtual>::*)()) == kVirtualFunctionSize, "");
static_assert(sizeof(void (X<IncUnspecified>::*)()) == kUnspecifiedFunctionSize, "");
template <typename T>
struct Y : T { };
static_assert(sizeof(int Y<Single>::*) == kSingleDataSize, "");
static_assert(sizeof(int Y<Multiple>::*) == kMultipleDataSize, "");
static_assert(sizeof(int Y<Virtual>::*) == kVirtualDataSize, "");
static_assert(sizeof(void (Y<Single>::*)()) == kSingleFunctionSize, "");
static_assert(sizeof(void (Y<Multiple>::*)()) == kMultipleFunctionSize, "");
static_assert(sizeof(void (Y<Virtual>::*)()) == kVirtualFunctionSize, "");
struct A { int x; void bar(); };
struct B : A { virtual void foo(); };
static_assert(sizeof(int B::*) == kSingleDataSize, "");
static_assert(sizeof(void (B::*)()) == kMultipleFunctionSize, "");
struct AA { int x; virtual void foo(); };
struct BB : AA { void bar(); };
struct CC : BB { virtual void baz(); };
static_assert(sizeof(void (CC::*)()) == kSingleFunctionSize, "");
struct ForwardDecl1;
struct ForwardDecl2;
struct ForwardDecl1;
struct ForwardDecl2;
typedef int ForwardDecl1::*MemPtr1;
typedef int ForwardDecl2::*MemPtr2;
MemPtr1 variable_forces_sizing;
struct ForwardDecl1 : B {
virtual void foo();
};
struct ForwardDecl2 : B {
virtual void foo();
};
static_assert(sizeof(variable_forces_sizing) == kUnspecifiedDataSize, "");
static_assert(sizeof(MemPtr1) == kUnspecifiedDataSize, "");
static_assert(sizeof(MemPtr2) == kSingleDataSize, "");
struct MemPtrInBody {
typedef int MemPtrInBody::*MemPtr;
int a;
operator MemPtr() const {
return a ? &MemPtrInBody::a : 0;
}
};
static_assert(sizeof(MemPtrInBody::MemPtr) == kSingleDataSize, "");
template<typename T>
struct SingleTemplate;
template<typename T>
struct SingleTemplate<void (T::*)(void)> {
static_assert(sizeof(int T::*) == kSingleDataSize, "");
static_assert(sizeof(void (T::*)()) == kSingleFunctionSize, "");
};
template<typename T>
struct UnspecTemplate;
template<typename T>
struct UnspecTemplate<void (T::*)(void)> {
static_assert(sizeof(int T::*) == kUnspecifiedDataSize, "");
static_assert(sizeof(void (T::*)()) == kUnspecifiedFunctionSize, "");
};
struct NewUnspecified;
SingleTemplate<void (IncSingle::*)()> tmpl_single;
UnspecTemplate<void (NewUnspecified::*)()> tmpl_unspec;
struct NewUnspecified { };
static_assert(sizeof(void (NewUnspecified::*)()) == kUnspecifiedFunctionSize, "");
template <typename T>
struct MemPtrInTemplate {
int T::*data_ptr;
void (T::*func_ptr)();
};
#ifdef VMB
int Virtual::*CastTest = reinterpret_cast<int Virtual::*>(&AA::x);
#endif
namespace ErrorTest {
template <typename T, typename U> struct __single_inheritance A;
template <typename T> struct __multiple_inheritance A<T, T>;
template <> struct __single_inheritance A<int, float>;
struct B {}; struct __multiple_inheritance B;
struct __multiple_inheritance C {};
struct __virtual_inheritance D;
struct D : virtual B {};
}
#ifdef VMB
namespace PR20017 {
template <typename T>
struct A {
int T::*f();
};
struct B;
auto a = &A<B>::f;
struct B {};
void q() {
A<B> b;
(b.*a)();
}
}
#pragma pointers_to_members(full_generality, multiple_inheritance)
struct TrulySingleInheritance;
static_assert(sizeof(int TrulySingleInheritance::*) == kMultipleDataSize, "");
#pragma pointers_to_members(best_case)
struct TrulySingleInheritance {};
#pragma pointers_to_members(full_generality, virtual_inheritance)
struct SingleInheritanceAsVirtualAfterPragma {};
static_assert(sizeof(int SingleInheritanceAsVirtualAfterPragma::*) == 12, "");
#pragma pointers_to_members(best_case)
struct SingleInheritanceAsVirtualBeforePragma {};
#pragma pointers_to_members(virtual_inheritance)
static_assert(sizeof(int SingleInheritanceAsVirtualBeforePragma::*) == 12, "");
#pragma pointers_to_members(single)
#endif
namespace merging {
struct __single_inheritance S;
struct __single_inheritance S;
struct __single_inheritance M; struct __multiple_inheritance M; }