[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / Layout / ms-vtordisp-local.cpp
blob048f4e58297bb87a723bc38d62bcb2f48ea817b3
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
3 struct Base {
4 virtual ~Base() {}
5 virtual void BaseFunc() {}
6 };
8 #pragma vtordisp(0)
10 struct Container {
11 static void f() try {
12 #pragma vtordisp(2)
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]
32 } catch (...) {
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]
54 struct Container2 {
55 static void f1() {
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 {
78 static void g1() {
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]
119 static void g2() {
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();
167 static void f2() {
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]
189 struct Container3 {
190 #pragma vtordisp(2)
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]
211 int main() {
212 Container::f();
213 Container2::f1();
214 Container2::f2();
215 Container3 cont3;
216 return 0;