1 // RUN: %clang_cc1 -fms-extensions -fexceptions -fcxx-exceptions -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>&1 | FileCheck %s
5 virtual void BaseFunc() {}
13 struct HasVtorDisp
: virtual Base
{
14 virtual ~HasVtorDisp() {}
15 virtual void Func() {}
18 int x
[sizeof(HasVtorDisp
)];
20 // HasVtorDisp: vtordisp because of pragma right before it.
22 // CHECK: *** Dumping AST Record Layout
23 // CHECK: *** Dumping AST Record Layout
24 // CHECK-NEXT: 0 | struct HasVtorDisp
25 // CHECK-NEXT: 0 | (HasVtorDisp vftable pointer)
26 // CHECK-NEXT: 8 | (HasVtorDisp vbtable pointer)
27 // CHECK-NEXT: 20 | (vtordisp for vbase Base)
28 // CHECK-NEXT: 24 | struct Base (virtual base)
29 // CHECK-NEXT: 24 | (Base vftable pointer)
30 // CHECK-NEXT: | [sizeof=32, align=8,
31 // CHECK-NEXT: | nvsize=16, nvalign=8]
36 struct NoVtorDisp1
: virtual Base
{
37 virtual ~NoVtorDisp1() {}
38 virtual void Func() {}
41 int x1
[sizeof(NoVtorDisp1
)];
43 // NoVtroDisp1: no vtordisp because of pragma disabling it.
45 // CHECK: *** Dumping AST Record Layout
46 // CHECK-NEXT: 0 | struct NoVtorDisp1
47 // CHECK-NEXT: 0 | (NoVtorDisp1 vftable pointer)
48 // CHECK-NEXT: 8 | (NoVtorDisp1 vbtable pointer)
49 // CHECK-NEXT: 16 | struct Base (virtual base)
50 // CHECK-NEXT: 16 | (Base vftable pointer)
51 // CHECK-NEXT: | [sizeof=24, align=8,
52 // CHECK-NEXT: | nvsize=16, nvalign=8]
56 // Local pragma #1 - must be disabled on exit from f1().
57 #pragma vtordisp(push, 2)
58 struct HasVtorDisp1
: virtual Base
{
59 virtual ~HasVtorDisp1() {}
60 virtual void Func() {}
63 int x2
[sizeof(HasVtorDisp1
)];
65 // HasVtorDisp1: vtordisp because of pragma right before it.
67 // CHECK: *** Dumping AST Record Layout
68 // CHECK-NEXT: 0 | struct HasVtorDisp1
69 // CHECK-NEXT: 0 | (HasVtorDisp1 vftable pointer)
70 // CHECK-NEXT: 8 | (HasVtorDisp1 vbtable pointer)
71 // CHECK-NEXT: 20 | (vtordisp for vbase Base)
72 // CHECK-NEXT: 24 | struct Base (virtual base)
73 // CHECK-NEXT: 24 | (Base vftable pointer)
74 // CHECK-NEXT: | [sizeof=32, align=8,
75 // CHECK-NEXT: | nvsize=16, nvalign=8]
77 struct InnerContainer
{
79 struct HasVtorDisp2
: virtual Base
{
80 virtual ~HasVtorDisp2() {}
81 virtual void Func() {}
84 int x3
[sizeof(HasVtorDisp2
)];
86 // HasVtorDisp2: vtordisp because of vtordisp(2) in f1().
88 // CHECK: *** Dumping AST Record Layout
89 // CHECK-NEXT: 0 | struct HasVtorDisp2
90 // CHECK-NEXT: 0 | (HasVtorDisp2 vftable pointer)
91 // CHECK-NEXT: 8 | (HasVtorDisp2 vbtable pointer)
92 // CHECK-NEXT: 20 | (vtordisp for vbase Base)
93 // CHECK-NEXT: 24 | struct Base (virtual base)
94 // CHECK-NEXT: 24 | (Base vftable pointer)
95 // CHECK-NEXT: | [sizeof=32, align=8,
96 // CHECK-NEXT: | nvsize=16, nvalign=8]
98 // Local pragma #2 - must be disabled on exit from g1().
99 #pragma vtordisp(push, 0)
100 struct NoVtorDisp2
: virtual Base
{
101 virtual ~NoVtorDisp2() {}
102 virtual void Func() {}
105 int x4
[sizeof(NoVtorDisp2
)];
107 // NoVtroDisp2: no vtordisp because of vtordisp(0) in g1().
109 // CHECK: *** Dumping AST Record Layout
110 // CHECK-NEXT: 0 | struct NoVtorDisp2
111 // CHECK-NEXT: 0 | (NoVtorDisp2 vftable pointer)
112 // CHECK-NEXT: 8 | (NoVtorDisp2 vbtable pointer)
113 // CHECK-NEXT: 16 | struct Base (virtual base)
114 // CHECK-NEXT: 16 | (Base vftable pointer)
115 // CHECK-NEXT: | [sizeof=24, align=8,
116 // CHECK-NEXT: | nvsize=16, nvalign=8]
120 struct HasVtorDisp3
: virtual Base
{
121 virtual ~HasVtorDisp3() {}
122 virtual void Func() {}
125 int x5
[sizeof(HasVtorDisp3
)];
127 // HasVtorDisp3: vtordisp because of vtordisp(2) in f1(),
128 // local vtordisp(0) in g1() is disabled.
130 // CHECK: *** Dumping AST Record Layout
131 // CHECK-NEXT: 0 | struct HasVtorDisp3
132 // CHECK-NEXT: 0 | (HasVtorDisp3 vftable pointer)
133 // CHECK-NEXT: 8 | (HasVtorDisp3 vbtable pointer)
134 // CHECK-NEXT: 20 | (vtordisp for vbase Base)
135 // CHECK-NEXT: 24 | struct Base (virtual base)
136 // CHECK-NEXT: 24 | (Base vftable pointer)
137 // CHECK-NEXT: | [sizeof=32, align=8,
138 // CHECK-NEXT: | nvsize=16, nvalign=8]
142 struct HasVtorDisp4
: virtual Base
{
143 virtual ~HasVtorDisp4() {}
144 virtual void Func() {}
147 int x6
[sizeof(HasVtorDisp4
)];
149 // HasVtorDisp4: vtordisp because of vtordisp(2) in f1(),
150 // local vtordisp(0) in g1() is disabled,
151 // g2() has no pragmas - stack is not affected.
153 // CHECK: *** Dumping AST Record Layout
154 // CHECK-NEXT: 0 | struct HasVtorDisp4
155 // CHECK-NEXT: 0 | (HasVtorDisp4 vftable pointer)
156 // CHECK-NEXT: 8 | (HasVtorDisp4 vbtable pointer)
157 // CHECK-NEXT: 20 | (vtordisp for vbase Base)
158 // CHECK-NEXT: 24 | struct Base (virtual base)
159 // CHECK-NEXT: 24 | (Base vftable pointer)
160 // CHECK-NEXT: | [sizeof=32, align=8,
161 // CHECK-NEXT: | nvsize=16, nvalign=8]
163 InnerContainer::g1();
164 InnerContainer::g2();
168 struct NoVtorDisp3
: virtual Base
{
169 virtual ~NoVtorDisp3() {}
170 virtual void Func() {}
173 int x7
[sizeof(NoVtorDisp3
)];
175 // NoVtroDisp3: no vtordisp because of global pragma (0),
176 // local vtordisp(2) is disabled on exit from f1().
178 // CHECK: *** Dumping AST Record Layout
179 // CHECK-NEXT: 0 | struct NoVtorDisp3
180 // CHECK-NEXT: 0 | (NoVtorDisp3 vftable pointer)
181 // CHECK-NEXT: 8 | (NoVtorDisp3 vbtable pointer)
182 // CHECK-NEXT: 16 | struct Base (virtual base)
183 // CHECK-NEXT: 16 | (Base vftable pointer)
184 // CHECK-NEXT: | [sizeof=24, align=8,
185 // CHECK-NEXT: | nvsize=16, nvalign=8]
191 struct HasVtorDisp5
: virtual Base
{
192 virtual ~HasVtorDisp5() {}
193 virtual void Func() {}
196 int x8
[sizeof(HasVtorDisp5
)];
198 // HasVtorDisp5: vtordisp because of pragma right before it.
200 // CHECK: *** Dumping AST Record Layout
201 // CHECK-NEXT: 0 | struct Container3::HasVtorDisp5
202 // CHECK-NEXT: 0 | (HasVtorDisp5 vftable pointer)
203 // CHECK-NEXT: 8 | (HasVtorDisp5 vbtable pointer)
204 // CHECK-NEXT: 20 | (vtordisp for vbase Base)
205 // CHECK-NEXT: 24 | struct Base (virtual base)
206 // CHECK-NEXT: 24 | (Base vftable pointer)
207 // CHECK-NEXT: | [sizeof=32, align=8,
208 // CHECK-NEXT: | nvsize=16, nvalign=8]