xref: /aosp_15_r20/external/clang/test/Layout/ms-vtordisp-local.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // 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
2*67e74705SXin Li 
3*67e74705SXin Li struct Base {
~BaseBase4*67e74705SXin Li   virtual ~Base() {}
BaseFuncBase5*67e74705SXin Li   virtual void BaseFunc() {}
6*67e74705SXin Li };
7*67e74705SXin Li 
8*67e74705SXin Li #pragma vtordisp(0)
9*67e74705SXin Li 
10*67e74705SXin Li struct Container {
fContainer11*67e74705SXin Li   static void f() try {
12*67e74705SXin Li     #pragma vtordisp(2)
13*67e74705SXin Li     struct HasVtorDisp : virtual Base {
14*67e74705SXin Li       virtual ~HasVtorDisp() {}
15*67e74705SXin Li       virtual void Func() {}
16*67e74705SXin Li     };
17*67e74705SXin Li 
18*67e74705SXin Li     int x[sizeof(HasVtorDisp)];
19*67e74705SXin Li 
20*67e74705SXin Li     // HasVtorDisp: vtordisp because of pragma right before it.
21*67e74705SXin Li     //
22*67e74705SXin Li     // CHECK: *** Dumping AST Record Layout
23*67e74705SXin Li     // CHECK: *** Dumping AST Record Layout
24*67e74705SXin Li     // CHECK-NEXT:          0 | struct HasVtorDisp
25*67e74705SXin Li     // CHECK-NEXT:          0 |   (HasVtorDisp vftable pointer)
26*67e74705SXin Li     // CHECK-NEXT:          8 |   (HasVtorDisp vbtable pointer)
27*67e74705SXin Li     // CHECK-NEXT:         20 |   (vtordisp for vbase Base)
28*67e74705SXin Li     // CHECK-NEXT:         24 |   struct Base (virtual base)
29*67e74705SXin Li     // CHECK-NEXT:         24 |     (Base vftable pointer)
30*67e74705SXin Li     // CHECK-NEXT:            | [sizeof=32, align=8,
31*67e74705SXin Li     // CHECK-NEXT:            |  nvsize=16, nvalign=8]
32*67e74705SXin Li   } catch (...) {
33*67e74705SXin Li   }
34*67e74705SXin Li };
35*67e74705SXin Li 
36*67e74705SXin Li struct NoVtorDisp1 : virtual Base {
~NoVtorDisp1NoVtorDisp137*67e74705SXin Li   virtual ~NoVtorDisp1() {}
FuncNoVtorDisp138*67e74705SXin Li   virtual void Func() {}
39*67e74705SXin Li };
40*67e74705SXin Li 
41*67e74705SXin Li int x1[sizeof(NoVtorDisp1)];
42*67e74705SXin Li 
43*67e74705SXin Li // NoVtroDisp1: no vtordisp because of pragma disabling it.
44*67e74705SXin Li //
45*67e74705SXin Li // CHECK: *** Dumping AST Record Layout
46*67e74705SXin Li // CHECK-NEXT:          0 | struct NoVtorDisp1
47*67e74705SXin Li // CHECK-NEXT:          0 |   (NoVtorDisp1 vftable pointer)
48*67e74705SXin Li // CHECK-NEXT:          8 |   (NoVtorDisp1 vbtable pointer)
49*67e74705SXin Li // CHECK-NEXT:         16 |   struct Base (virtual base)
50*67e74705SXin Li // CHECK-NEXT:         16 |     (Base vftable pointer)
51*67e74705SXin Li // CHECK-NEXT:            | [sizeof=24, align=8,
52*67e74705SXin Li // CHECK-NEXT:            |  nvsize=16, nvalign=8]
53*67e74705SXin Li 
54*67e74705SXin Li struct Container2 {
f1Container255*67e74705SXin Li   static void f1() {
56*67e74705SXin Li     // Local pragma #1 - must be disabled on exit from f1().
57*67e74705SXin Li     #pragma vtordisp(push, 2)
58*67e74705SXin Li     struct HasVtorDisp1 : virtual Base {
59*67e74705SXin Li       virtual ~HasVtorDisp1() {}
60*67e74705SXin Li       virtual void Func() {}
61*67e74705SXin Li     };
62*67e74705SXin Li 
63*67e74705SXin Li     int x2[sizeof(HasVtorDisp1)];
64*67e74705SXin Li 
65*67e74705SXin Li     // HasVtorDisp1: vtordisp because of pragma right before it.
66*67e74705SXin Li     //
67*67e74705SXin Li     // CHECK: *** Dumping AST Record Layout
68*67e74705SXin Li     // CHECK-NEXT:          0 | struct HasVtorDisp1
69*67e74705SXin Li     // CHECK-NEXT:          0 |   (HasVtorDisp1 vftable pointer)
70*67e74705SXin Li     // CHECK-NEXT:          8 |   (HasVtorDisp1 vbtable pointer)
71*67e74705SXin Li     // CHECK-NEXT:         20 |   (vtordisp for vbase Base)
72*67e74705SXin Li     // CHECK-NEXT:         24 |   struct Base (virtual base)
73*67e74705SXin Li     // CHECK-NEXT:         24 |     (Base vftable pointer)
74*67e74705SXin Li     // CHECK-NEXT:            | [sizeof=32, align=8,
75*67e74705SXin Li     // CHECK-NEXT:            |  nvsize=16, nvalign=8]
76*67e74705SXin Li 
77*67e74705SXin Li     struct InnerContainer {
78*67e74705SXin Li       static void g1() {
79*67e74705SXin Li         struct HasVtorDisp2 : virtual Base {
80*67e74705SXin Li           virtual ~HasVtorDisp2() {}
81*67e74705SXin Li           virtual void Func() {}
82*67e74705SXin Li         };
83*67e74705SXin Li 
84*67e74705SXin Li         int x3[sizeof(HasVtorDisp2)];
85*67e74705SXin Li 
86*67e74705SXin Li         // HasVtorDisp2: vtordisp because of vtordisp(2) in f1().
87*67e74705SXin Li         //
88*67e74705SXin Li         // CHECK: *** Dumping AST Record Layout
89*67e74705SXin Li         // CHECK-NEXT:          0 | struct HasVtorDisp2
90*67e74705SXin Li         // CHECK-NEXT:          0 |   (HasVtorDisp2 vftable pointer)
91*67e74705SXin Li         // CHECK-NEXT:          8 |   (HasVtorDisp2 vbtable pointer)
92*67e74705SXin Li         // CHECK-NEXT:         20 |   (vtordisp for vbase Base)
93*67e74705SXin Li         // CHECK-NEXT:         24 |   struct Base (virtual base)
94*67e74705SXin Li         // CHECK-NEXT:         24 |     (Base vftable pointer)
95*67e74705SXin Li         // CHECK-NEXT:            | [sizeof=32, align=8,
96*67e74705SXin Li         // CHECK-NEXT:            |  nvsize=16, nvalign=8]
97*67e74705SXin Li 
98*67e74705SXin Li         // Local pragma #2 - must be disabled on exit from g1().
99*67e74705SXin Li         #pragma vtordisp(push, 0)
100*67e74705SXin Li         struct NoVtorDisp2 : virtual Base {
101*67e74705SXin Li           virtual ~NoVtorDisp2() {}
102*67e74705SXin Li           virtual void Func() {}
103*67e74705SXin Li         };
104*67e74705SXin Li 
105*67e74705SXin Li         int x4[sizeof(NoVtorDisp2)];
106*67e74705SXin Li 
107*67e74705SXin Li         // NoVtroDisp2: no vtordisp because of vtordisp(0) in g1().
108*67e74705SXin Li         //
109*67e74705SXin Li         // CHECK: *** Dumping AST Record Layout
110*67e74705SXin Li         // CHECK-NEXT:          0 | struct NoVtorDisp2
111*67e74705SXin Li         // CHECK-NEXT:          0 |   (NoVtorDisp2 vftable pointer)
112*67e74705SXin Li         // CHECK-NEXT:          8 |   (NoVtorDisp2 vbtable pointer)
113*67e74705SXin Li         // CHECK-NEXT:         16 |   struct Base (virtual base)
114*67e74705SXin Li         // CHECK-NEXT:         16 |     (Base vftable pointer)
115*67e74705SXin Li         // CHECK-NEXT:            | [sizeof=24, align=8,
116*67e74705SXin Li         // CHECK-NEXT:            |  nvsize=16, nvalign=8]
117*67e74705SXin Li       }
118*67e74705SXin Li 
119*67e74705SXin Li       static void g2() {
120*67e74705SXin Li         struct HasVtorDisp3 : virtual Base {
121*67e74705SXin Li           virtual ~HasVtorDisp3() {}
122*67e74705SXin Li           virtual void Func() {}
123*67e74705SXin Li         };
124*67e74705SXin Li 
125*67e74705SXin Li         int x5[sizeof(HasVtorDisp3)];
126*67e74705SXin Li 
127*67e74705SXin Li         // HasVtorDisp3: vtordisp because of vtordisp(2) in f1(),
128*67e74705SXin Li         //               local vtordisp(0) in g1() is disabled.
129*67e74705SXin Li         //
130*67e74705SXin Li         // CHECK: *** Dumping AST Record Layout
131*67e74705SXin Li         // CHECK-NEXT:          0 | struct HasVtorDisp3
132*67e74705SXin Li         // CHECK-NEXT:          0 |   (HasVtorDisp3 vftable pointer)
133*67e74705SXin Li         // CHECK-NEXT:          8 |   (HasVtorDisp3 vbtable pointer)
134*67e74705SXin Li         // CHECK-NEXT:         20 |   (vtordisp for vbase Base)
135*67e74705SXin Li         // CHECK-NEXT:         24 |   struct Base (virtual base)
136*67e74705SXin Li         // CHECK-NEXT:         24 |     (Base vftable pointer)
137*67e74705SXin Li         // CHECK-NEXT:            | [sizeof=32, align=8,
138*67e74705SXin Li         // CHECK-NEXT:            |  nvsize=16, nvalign=8]
139*67e74705SXin Li       }
140*67e74705SXin Li     };
141*67e74705SXin Li 
142*67e74705SXin Li     struct HasVtorDisp4 : virtual Base {
143*67e74705SXin Li       virtual ~HasVtorDisp4() {}
144*67e74705SXin Li       virtual void Func() {}
145*67e74705SXin Li     };
146*67e74705SXin Li 
147*67e74705SXin Li     int x6[sizeof(HasVtorDisp4)];
148*67e74705SXin Li 
149*67e74705SXin Li     // HasVtorDisp4: vtordisp because of vtordisp(2) in f1(),
150*67e74705SXin Li     //               local vtordisp(0) in g1() is disabled,
151*67e74705SXin Li     //               g2() has no pragmas - stack is not affected.
152*67e74705SXin Li     //
153*67e74705SXin Li     // CHECK: *** Dumping AST Record Layout
154*67e74705SXin Li     // CHECK-NEXT:          0 | struct HasVtorDisp4
155*67e74705SXin Li     // CHECK-NEXT:          0 |   (HasVtorDisp4 vftable pointer)
156*67e74705SXin Li     // CHECK-NEXT:          8 |   (HasVtorDisp4 vbtable pointer)
157*67e74705SXin Li     // CHECK-NEXT:         20 |   (vtordisp for vbase Base)
158*67e74705SXin Li     // CHECK-NEXT:         24 |   struct Base (virtual base)
159*67e74705SXin Li     // CHECK-NEXT:         24 |     (Base vftable pointer)
160*67e74705SXin Li     // CHECK-NEXT:            | [sizeof=32, align=8,
161*67e74705SXin Li     // CHECK-NEXT:            |  nvsize=16, nvalign=8]
162*67e74705SXin Li 
163*67e74705SXin Li     InnerContainer::g1();
164*67e74705SXin Li     InnerContainer::g2();
165*67e74705SXin Li   }
166*67e74705SXin Li 
f2Container2167*67e74705SXin Li   static void f2() {
168*67e74705SXin Li     struct NoVtorDisp3 : virtual Base {
169*67e74705SXin Li       virtual ~NoVtorDisp3() {}
170*67e74705SXin Li       virtual void Func() {}
171*67e74705SXin Li     };
172*67e74705SXin Li 
173*67e74705SXin Li     int x7[sizeof(NoVtorDisp3)];
174*67e74705SXin Li 
175*67e74705SXin Li     // NoVtroDisp3: no vtordisp because of global pragma (0),
176*67e74705SXin Li     //              local vtordisp(2) is disabled on exit from f1().
177*67e74705SXin Li     //
178*67e74705SXin Li     // CHECK: *** Dumping AST Record Layout
179*67e74705SXin Li     // CHECK-NEXT:          0 | struct NoVtorDisp3
180*67e74705SXin Li     // CHECK-NEXT:          0 |   (NoVtorDisp3 vftable pointer)
181*67e74705SXin Li     // CHECK-NEXT:          8 |   (NoVtorDisp3 vbtable pointer)
182*67e74705SXin Li     // CHECK-NEXT:         16 |   struct Base (virtual base)
183*67e74705SXin Li     // CHECK-NEXT:         16 |     (Base vftable pointer)
184*67e74705SXin Li     // CHECK-NEXT:            | [sizeof=24, align=8,
185*67e74705SXin Li     // CHECK-NEXT:            |  nvsize=16, nvalign=8]
186*67e74705SXin Li   }
187*67e74705SXin Li };
188*67e74705SXin Li 
189*67e74705SXin Li struct Container3 {
190*67e74705SXin Li   #pragma vtordisp(2)
191*67e74705SXin Li   struct HasVtorDisp5 : virtual Base {
~HasVtorDisp5Container3::HasVtorDisp5192*67e74705SXin Li     virtual ~HasVtorDisp5() {}
FuncContainer3::HasVtorDisp5193*67e74705SXin Li     virtual void Func() {}
194*67e74705SXin Li   };
195*67e74705SXin Li 
196*67e74705SXin Li   int x8[sizeof(HasVtorDisp5)];
197*67e74705SXin Li 
198*67e74705SXin Li   // HasVtorDisp5: vtordisp because of pragma right before it.
199*67e74705SXin Li   //
200*67e74705SXin Li   // CHECK: *** Dumping AST Record Layout
201*67e74705SXin Li   // CHECK-NEXT:          0 | struct Container3::HasVtorDisp5
202*67e74705SXin Li   // CHECK-NEXT:          0 |   (HasVtorDisp5 vftable pointer)
203*67e74705SXin Li   // CHECK-NEXT:          8 |   (HasVtorDisp5 vbtable pointer)
204*67e74705SXin Li   // CHECK-NEXT:         20 |   (vtordisp for vbase Base)
205*67e74705SXin Li   // CHECK-NEXT:         24 |   struct Base (virtual base)
206*67e74705SXin Li   // CHECK-NEXT:         24 |     (Base vftable pointer)
207*67e74705SXin Li   // CHECK-NEXT:            | [sizeof=32, align=8,
208*67e74705SXin Li   // CHECK-NEXT:            |  nvsize=16, nvalign=8]
209*67e74705SXin Li };
210*67e74705SXin Li 
main()211*67e74705SXin Li int main() {
212*67e74705SXin Li   Container::f();
213*67e74705SXin Li   Container2::f1();
214*67e74705SXin Li   Container2::f2();
215*67e74705SXin Li   Container3 cont3;
216*67e74705SXin Li   return 0;
217*67e74705SXin Li };
218