123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457 |
- // RUN: %clang_cc1 -fno-rtti -fms-extensions -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>&1 \
- // RUN: | FileCheck %s
- // RUN: %clang_cc1 -fno-rtti -fms-extensions -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
- // RUN: | FileCheck %s -check-prefix CHECK-X64
- extern "C" int printf(const char *fmt, ...);
- struct B0 {
- int a;
- B0() : a(0xf00000B0) {}
- virtual void f() { printf("B0"); }
- };
- struct __declspec(align(16)) B1 {
- int a;
- B1() : a(0xf00000B1) {}
- virtual void f() { printf("B1"); }
- };
- struct __declspec(align(16)) Align16 {};
- struct __declspec(align(32)) Align32 {};
- struct VAlign16 : virtual Align16 {};
- struct VAlign32 : virtual Align32 {};
- struct A : virtual B0, virtual B1 {
- int a;
- A() : a(0xf000000A) {}
- virtual void f() { printf("A"); }
- virtual void g() { printf("A"); }
- };
- // CHECK: *** Dumping AST Record Layout
- // CHECK: *** Dumping AST Record Layout
- // CHECK: *** Dumping AST Record Layout
- // CHECK-NEXT: 0 | struct A
- // CHECK-NEXT: 0 | (A vftable pointer)
- // CHECK-NEXT: 4 | (A vbtable pointer)
- // CHECK-NEXT: 8 | int a
- // CHECK-NEXT: 16 | (vtordisp for vbase B0)
- // CHECK-NEXT: 20 | struct B0 (virtual base)
- // CHECK-NEXT: 20 | (B0 vftable pointer)
- // CHECK-NEXT: 24 | int a
- // CHECK-NEXT: 44 | (vtordisp for vbase B1)
- // CHECK-NEXT: 48 | struct B1 (virtual base)
- // CHECK-NEXT: 48 | (B1 vftable pointer)
- // CHECK-NEXT: 52 | int a
- // CHECK-NEXT: | [sizeof=64, align=16
- // CHECK-NEXT: | nvsize=12, nvalign=16]
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64-NEXT: 0 | struct A
- // CHECK-X64-NEXT: 0 | (A vftable pointer)
- // CHECK-X64-NEXT: 8 | (A vbtable pointer)
- // CHECK-X64-NEXT: 16 | int a
- // CHECK-X64-NEXT: 36 | (vtordisp for vbase B0)
- // CHECK-X64-NEXT: 40 | struct B0 (virtual base)
- // CHECK-X64-NEXT: 40 | (B0 vftable pointer)
- // CHECK-X64-NEXT: 48 | int a
- // CHECK-X64-NEXT: 76 | (vtordisp for vbase B1)
- // CHECK-X64-NEXT: 80 | struct B1 (virtual base)
- // CHECK-X64-NEXT: 80 | (B1 vftable pointer)
- // CHECK-X64-NEXT: 88 | int a
- // CHECK-X64-NEXT: | [sizeof=96, align=16
- // CHECK-X64-NEXT: | nvsize=24, nvalign=16]
- struct C : virtual B0, virtual B1, VAlign32 {
- int a;
- C() : a(0xf000000C) {}
- virtual void f() { printf("C"); }
- virtual void g() { printf("C"); }
- };
- // CHECK: *** Dumping AST Record Layout
- // CHECK: *** Dumping AST Record Layout
- // CHECK: *** Dumping AST Record Layout
- // CHECK-NEXT: 0 | struct C
- // CHECK-NEXT: 0 | (C vftable pointer)
- // CHECK-NEXT: 32 | struct VAlign32 (base)
- // CHECK-NEXT: 32 | (VAlign32 vbtable pointer)
- // CHECK-NEXT: 36 | int a
- // CHECK-NEXT: 64 | (vtordisp for vbase B0)
- // CHECK-NEXT: 68 | struct B0 (virtual base)
- // CHECK-NEXT: 68 | (B0 vftable pointer)
- // CHECK-NEXT: 72 | int a
- // CHECK-NEXT: 108 | (vtordisp for vbase B1)
- // CHECK-NEXT: 112 | struct B1 (virtual base)
- // CHECK-NEXT: 112 | (B1 vftable pointer)
- // CHECK-NEXT: 116 | int a
- // CHECK-NEXT: 128 | struct Align32 (virtual base) (empty)
- // CHECK-NEXT: | [sizeof=128, align=32
- // CHECK-NEXT: | nvsize=64, nvalign=32]
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64-NEXT: 0 | struct C
- // CHECK-X64-NEXT: 0 | (C vftable pointer)
- // CHECK-X64-NEXT: 32 | struct VAlign32 (base)
- // CHECK-X64-NEXT: 32 | (VAlign32 vbtable pointer)
- // CHECK-X64-NEXT: 40 | int a
- // CHECK-X64-NEXT: 68 | (vtordisp for vbase B0)
- // CHECK-X64-NEXT: 72 | struct B0 (virtual base)
- // CHECK-X64-NEXT: 72 | (B0 vftable pointer)
- // CHECK-X64-NEXT: 80 | int a
- // CHECK-X64-NEXT: 108 | (vtordisp for vbase B1)
- // CHECK-X64-NEXT: 112 | struct B1 (virtual base)
- // CHECK-X64-NEXT: 112 | (B1 vftable pointer)
- // CHECK-X64-NEXT: 120 | int a
- // CHECK-X64-NEXT: 128 | struct Align32 (virtual base) (empty)
- // CHECK-X64-NEXT: | [sizeof=128, align=32
- // CHECK-X64-NEXT: | nvsize=64, nvalign=32]
- struct __declspec(align(32)) D : virtual B0, virtual B1 {
- int a;
- D() : a(0xf000000D) {}
- virtual void f() { printf("D"); }
- virtual void g() { printf("D"); }
- };
- // CHECK: *** Dumping AST Record Layout
- // CHECK-NEXT: 0 | struct D
- // CHECK-NEXT: 0 | (D vftable pointer)
- // CHECK-NEXT: 4 | (D vbtable pointer)
- // CHECK-NEXT: 8 | int a
- // CHECK-NEXT: 32 | (vtordisp for vbase B0)
- // CHECK-NEXT: 36 | struct B0 (virtual base)
- // CHECK-NEXT: 36 | (B0 vftable pointer)
- // CHECK-NEXT: 40 | int a
- // CHECK-NEXT: 76 | (vtordisp for vbase B1)
- // CHECK-NEXT: 80 | struct B1 (virtual base)
- // CHECK-NEXT: 80 | (B1 vftable pointer)
- // CHECK-NEXT: 84 | int a
- // CHECK-NEXT: | [sizeof=96, align=32
- // CHECK-NEXT: | nvsize=12, nvalign=32]
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64-NEXT: 0 | struct D
- // CHECK-X64-NEXT: 0 | (D vftable pointer)
- // CHECK-X64-NEXT: 8 | (D vbtable pointer)
- // CHECK-X64-NEXT: 16 | int a
- // CHECK-X64-NEXT: 36 | (vtordisp for vbase B0)
- // CHECK-X64-NEXT: 40 | struct B0 (virtual base)
- // CHECK-X64-NEXT: 40 | (B0 vftable pointer)
- // CHECK-X64-NEXT: 48 | int a
- // CHECK-X64-NEXT: 76 | (vtordisp for vbase B1)
- // CHECK-X64-NEXT: 80 | struct B1 (virtual base)
- // CHECK-X64-NEXT: 80 | (B1 vftable pointer)
- // CHECK-X64-NEXT: 88 | int a
- // CHECK-X64-NEXT: | [sizeof=96, align=32
- // CHECK-X64-NEXT: | nvsize=24, nvalign=32]
- struct AT {
- virtual ~AT(){}
- };
- struct CT : virtual AT {
- virtual ~CT();
- };
- CT::~CT(){}
- // CHECK: *** Dumping AST Record Layout
- // CHECK: *** Dumping AST Record Layout
- // CHECK-NEXT: 0 | struct CT
- // CHECK-NEXT: 0 | (CT vbtable pointer)
- // CHECK-NEXT: 4 | struct AT (virtual base)
- // CHECK-NEXT: 4 | (AT vftable pointer)
- // CHECK-NEXT: | [sizeof=8, align=4
- // CHECK-NEXT: | nvsize=4, nvalign=4]
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64-NEXT: 0 | struct CT
- // CHECK-X64-NEXT: 0 | (CT vbtable pointer)
- // CHECK-X64-NEXT: 8 | struct AT (virtual base)
- // CHECK-X64-NEXT: 8 | (AT vftable pointer)
- // CHECK-X64-NEXT: | [sizeof=16, align=8
- // CHECK-X64-NEXT: | nvsize=8, nvalign=8]
- struct XA {
- XA() { printf("XA"); }
- long long ll;
- };
- struct XB : XA {
- XB() { printf("XB"); }
- virtual void foo() {}
- int b;
- };
- struct XC : virtual XB {
- XC() { printf("XC"); }
- virtual void foo() {}
- };
- // CHECK: *** Dumping AST Record Layout
- // CHECK: *** Dumping AST Record Layout
- // CHECK: *** Dumping AST Record Layout
- // CHECK-NEXT: 0 | struct XC
- // CHECK-NEXT: 0 | (XC vbtable pointer)
- // CHECK-NEXT: 4 | (vtordisp for vbase XB)
- // CHECK-NEXT: 8 | struct XB (virtual base)
- // CHECK-NEXT: 8 | (XB vftable pointer)
- // CHECK-NEXT: 16 | struct XA (base)
- // CHECK-NEXT: 16 | long long ll
- // CHECK-NEXT: 24 | int b
- // CHECK-NEXT: | [sizeof=32, align=8
- // CHECK-NEXT: | nvsize=4, nvalign=8]
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64-NEXT: 0 | struct XC
- // CHECK-X64-NEXT: 0 | (XC vbtable pointer)
- // CHECK-X64-NEXT: 12 | (vtordisp for vbase XB)
- // CHECK-X64-NEXT: 16 | struct XB (virtual base)
- // CHECK-X64-NEXT: 16 | (XB vftable pointer)
- // CHECK-X64-NEXT: 24 | struct XA (base)
- // CHECK-X64-NEXT: 24 | long long ll
- // CHECK-X64-NEXT: 32 | int b
- // CHECK-X64-NEXT: | [sizeof=40, align=8
- // CHECK-X64-NEXT: | nvsize=8, nvalign=8]
- namespace pragma_test1 {
- // No overrides means no vtordisps by default.
- struct A { virtual ~A(); virtual void foo(); int a; };
- struct B : virtual A { virtual ~B(); virtual void bar(); int b; };
- struct C : virtual B { int c; };
- // CHECK: *** Dumping AST Record Layout
- // CHECK: *** Dumping AST Record Layout
- // CHECK: *** Dumping AST Record Layout
- // CHECK-NEXT: 0 | struct pragma_test1::C
- // CHECK-NEXT: 0 | (C vbtable pointer)
- // CHECK-NEXT: 4 | int c
- // CHECK-NEXT: 8 | struct pragma_test1::A (virtual base)
- // CHECK-NEXT: 8 | (A vftable pointer)
- // CHECK-NEXT: 12 | int a
- // CHECK-NEXT: 16 | struct pragma_test1::B (virtual base)
- // CHECK-NEXT: 16 | (B vftable pointer)
- // CHECK-NEXT: 20 | (B vbtable pointer)
- // CHECK-NEXT: 24 | int b
- // CHECK-NEXT: | [sizeof=28, align=4
- // CHECK-NEXT: | nvsize=8, nvalign=4]
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64: *** Dumping AST Record Layout
- }
- namespace pragma_test2 {
- struct A { virtual ~A(); virtual void foo(); int a; };
- #pragma vtordisp(push,2)
- struct B : virtual A { virtual ~B(); virtual void bar(); int b; };
- struct C : virtual B { int c; };
- #pragma vtordisp(pop)
- // CHECK: *** Dumping AST Record Layout
- // CHECK: *** Dumping AST Record Layout
- // CHECK: *** Dumping AST Record Layout
- // CHECK-NEXT: 0 | struct pragma_test2::C
- // CHECK-NEXT: 0 | (C vbtable pointer)
- // CHECK-NEXT: 4 | int c
- // CHECK-NEXT: 8 | (vtordisp for vbase A)
- // CHECK-NEXT: 12 | struct pragma_test2::A (virtual base)
- // CHECK-NEXT: 12 | (A vftable pointer)
- // CHECK-NEXT: 16 | int a
- // By adding a virtual method and vftable to B, now we need a vtordisp.
- // CHECK-NEXT: 20 | (vtordisp for vbase B)
- // CHECK-NEXT: 24 | struct pragma_test2::B (virtual base)
- // CHECK-NEXT: 24 | (B vftable pointer)
- // CHECK-NEXT: 28 | (B vbtable pointer)
- // CHECK-NEXT: 32 | int b
- // CHECK-NEXT: | [sizeof=36, align=4
- // CHECK-NEXT: | nvsize=8, nvalign=4]
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64: *** Dumping AST Record Layout
- }
- namespace pragma_test3 {
- struct A { virtual ~A(); virtual void foo(); int a; };
- #pragma vtordisp(push,2)
- struct B : virtual A { virtual ~B(); virtual void foo(); int b; };
- struct C : virtual B { int c; };
- #pragma vtordisp(pop)
- // CHECK: *** Dumping AST Record Layout
- // CHECK: *** Dumping AST Record Layout
- // CHECK: *** Dumping AST Record Layout
- // CHECK-NEXT: 0 | struct pragma_test3::C
- // CHECK-NEXT: 0 | (C vbtable pointer)
- // CHECK-NEXT: 4 | int c
- // CHECK-NEXT: 8 | (vtordisp for vbase A)
- // CHECK-NEXT: 12 | struct pragma_test3::A (virtual base)
- // CHECK-NEXT: 12 | (A vftable pointer)
- // CHECK-NEXT: 16 | int a
- // No vtordisp before B! It doesn't have its own vftable.
- // CHECK-NEXT: 20 | struct pragma_test3::B (virtual base)
- // CHECK-NEXT: 20 | (B vbtable pointer)
- // CHECK-NEXT: 24 | int b
- // CHECK-NEXT: | [sizeof=28, align=4
- // CHECK-NEXT: | nvsize=8, nvalign=4]
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64: *** Dumping AST Record Layout
- }
- namespace pragma_test4 {
- struct A {
- A();
- virtual void foo();
- int a;
- };
- // Make sure the pragma applies to class template decls before they've been
- // instantiated.
- #pragma vtordisp(push,2)
- template <typename T>
- struct B : virtual A {
- B();
- virtual ~B();
- virtual void bar();
- T b;
- };
- #pragma vtordisp(pop)
- struct C : virtual B<int> { int c; };
- // CHECK: *** Dumping AST Record Layout
- // CHECK: *** Dumping AST Record Layout
- // CHECK: *** Dumping AST Record Layout
- // CHECK-NEXT: 0 | struct pragma_test4::C
- // CHECK-NEXT: 0 | (C vbtable pointer)
- // CHECK-NEXT: 4 | int c
- // Pragma applies to B, which has vbase A.
- // CHECK-NEXT: 8 | (vtordisp for vbase A)
- // CHECK-NEXT: 12 | struct pragma_test4::A (virtual base)
- // CHECK-NEXT: 12 | (A vftable pointer)
- // CHECK-NEXT: 16 | int a
- // Pragma does not apply to C, and B doesn't usually need a vtordisp in C.
- // CHECK-NEXT: 20 | struct pragma_test4::B<int> (virtual base)
- // CHECK-NEXT: 20 | (B vftable pointer)
- // CHECK-NEXT: 24 | (B vbtable pointer)
- // CHECK-NEXT: 28 | int b
- // CHECK-NEXT: | [sizeof=32, align=4
- // CHECK-NEXT: | nvsize=8, nvalign=4]
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64: *** Dumping AST Record Layout
- }
- struct GA {
- virtual void fun() {}
- };
- struct GB: public GA {};
- struct GC: public virtual GA {
- virtual void fun() {}
- GC() {}
- };
- struct GD: public virtual GC, public virtual GB {};
- // CHECK: *** Dumping AST Record Layout
- // CHECK: *** Dumping AST Record Layout
- // CHECK: *** Dumping AST Record Layout
- // CHECK: *** Dumping AST Record Layout
- // CHECK-NEXT: 0 | struct GD
- // CHECK-NEXT: 0 | (GD vbtable pointer)
- // CHECK-NEXT: 4 | (vtordisp for vbase GA)
- // CHECK-NEXT: 8 | struct GA (virtual base)
- // CHECK-NEXT: 8 | (GA vftable pointer)
- // CHECK-NEXT: 12 | struct GC (virtual base)
- // CHECK-NEXT: 12 | (GC vbtable pointer)
- // CHECK-NEXT: 16 | struct GB (virtual base)
- // CHECK-NEXT: 16 | struct GA (primary base)
- // CHECK-NEXT: 16 | (GA vftable pointer)
- // CHECK-NEXT: | [sizeof=20, align=4
- // CHECK-NEXT: | nvsize=4, nvalign=4]
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64-NEXT: 0 | struct GD
- // CHECK-X64-NEXT: 0 | (GD vbtable pointer)
- // CHECK-X64-NEXT: 12 | (vtordisp for vbase GA)
- // CHECK-X64-NEXT: 16 | struct GA (virtual base)
- // CHECK-X64-NEXT: 16 | (GA vftable pointer)
- // CHECK-X64-NEXT: 24 | struct GC (virtual base)
- // CHECK-X64-NEXT: 24 | (GC vbtable pointer)
- // CHECK-X64-NEXT: 32 | struct GB (virtual base)
- // CHECK-X64-NEXT: 32 | struct GA (primary base)
- // CHECK-X64-NEXT: 32 | (GA vftable pointer)
- // CHECK-X64-NEXT: | [sizeof=40, align=8
- // CHECK-X64-NEXT: | nvsize=8, nvalign=8]
- struct HA {
- virtual void fun() {}
- };
- #pragma vtordisp(push, 2)
- struct HB : virtual HA {};
- #pragma vtordisp(pop)
- #pragma vtordisp(push, 0)
- struct HC : virtual HB {};
- #pragma vtordisp(pop)
- // CHECK: *** Dumping AST Record Layout
- // CHECK: *** Dumping AST Record Layout
- // CHECK: *** Dumping AST Record Layout
- // CHECK-NEXT: 0 | struct HC
- // CHECK-NEXT: 0 | (HC vbtable pointer)
- // CHECK-NEXT: 4 | (vtordisp for vbase HA)
- // CHECK-NEXT: 8 | struct HA (virtual base)
- // CHECK-NEXT: 8 | (HA vftable pointer)
- // CHECK-NEXT: 12 | struct HB (virtual base)
- // CHECK-NEXT: 12 | (HB vbtable pointer)
- // CHECK-NEXT: | [sizeof=16, align=4
- // CHECK-NEXT: | nvsize=4, nvalign=4]
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64-NEXT: 0 | struct HC
- // CHECK-X64-NEXT: 0 | (HC vbtable pointer)
- // CHECK-X64-NEXT: 12 | (vtordisp for vbase HA)
- // CHECK-X64-NEXT: 16 | struct HA (virtual base)
- // CHECK-X64-NEXT: 16 | (HA vftable pointer)
- // CHECK-X64-NEXT: 24 | struct HB (virtual base)
- // CHECK-X64-NEXT: 24 | (HB vbtable pointer)
- // CHECK-X64-NEXT: | [sizeof=32, align=8
- // CHECK-X64-NEXT: | nvsize=8, nvalign=8]
- struct IA {
- virtual void f();
- };
- struct __declspec(dllexport) IB : virtual IA {
- virtual void f() = 0;
- IB() {}
- };
- // CHECK: *** Dumping AST Record Layout
- // CHECK: *** Dumping AST Record Layout
- // CHECK-NEXT: 0 | struct IB
- // CHECK-NEXT: 0 | (IB vbtable pointer)
- // CHECK-NEXT: 4 | struct IA (virtual base)
- // CHECK-NEXT: 4 | (IA vftable pointer)
- // CHECK-NEXT: | [sizeof=8, align=4
- // CHECK-NEXT: | nvsize=4, nvalign=4]
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64: *** Dumping AST Record Layout
- // CHECK-X64-NEXT: 0 | struct IB
- // CHECK-X64-NEXT: 0 | (IB vbtable pointer)
- // CHECK-X64-NEXT: 8 | struct IA (virtual base)
- // CHECK-X64-NEXT: 8 | (IA vftable pointer)
- // CHECK-X64-NEXT: | [sizeof=16, align=8
- // CHECK-X64-NEXT: | nvsize=8, nvalign=8]
- int a[
- sizeof(A)+
- sizeof(C)+
- sizeof(D)+
- sizeof(CT)+
- sizeof(XC)+
- sizeof(pragma_test1::C)+
- sizeof(pragma_test2::C)+
- sizeof(pragma_test3::C)+
- sizeof(pragma_test4::C)+
- sizeof(GD)+
- sizeof(HC)+
- sizeof(IB)+
- 0];
|