218 lines · cpp
1// RUN: %clang_cc1 -fms-extensions -fexceptions -fcxx-exceptions -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>&1 | FileCheck %s2 3struct Base {4 virtual ~Base() {}5 virtual void BaseFunc() {}6};7 8#pragma vtordisp(0)9 10struct Container {11 static void f() try {12 #pragma vtordisp(2)13 struct HasVtorDisp : virtual Base {14 virtual ~HasVtorDisp() {}15 virtual void Func() {}16 };17 18 int x[sizeof(HasVtorDisp)];19 20 // HasVtorDisp: vtordisp because of pragma right before it.21 //22 // CHECK: *** Dumping AST Record Layout23 // CHECK: *** Dumping AST Record Layout24 // CHECK-NEXT: 0 | struct HasVtorDisp25 // 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 (...) {33 }34};35 36struct NoVtorDisp1 : virtual Base {37 virtual ~NoVtorDisp1() {}38 virtual void Func() {}39};40 41int x1[sizeof(NoVtorDisp1)];42 43// NoVtroDisp1: no vtordisp because of pragma disabling it.44//45// CHECK: *** Dumping AST Record Layout46// CHECK-NEXT: 0 | struct NoVtorDisp147// 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]53 54struct 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() {}61 };62 63 int x2[sizeof(HasVtorDisp1)];64 65 // HasVtorDisp1: vtordisp because of pragma right before it.66 //67 // CHECK: *** Dumping AST Record Layout68 // CHECK-NEXT: 0 | struct HasVtorDisp169 // 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]76 77 struct InnerContainer {78 static void g1() {79 struct HasVtorDisp2 : virtual Base {80 virtual ~HasVtorDisp2() {}81 virtual void Func() {}82 };83 84 int x3[sizeof(HasVtorDisp2)];85 86 // HasVtorDisp2: vtordisp because of vtordisp(2) in f1().87 //88 // CHECK: *** Dumping AST Record Layout89 // CHECK-NEXT: 0 | struct HasVtorDisp290 // 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]97 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() {}103 };104 105 int x4[sizeof(NoVtorDisp2)];106 107 // NoVtroDisp2: no vtordisp because of vtordisp(0) in g1().108 //109 // CHECK: *** Dumping AST Record Layout110 // CHECK-NEXT: 0 | struct NoVtorDisp2111 // 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]117 }118 119 static void g2() {120 struct HasVtorDisp3 : virtual Base {121 virtual ~HasVtorDisp3() {}122 virtual void Func() {}123 };124 125 int x5[sizeof(HasVtorDisp3)];126 127 // HasVtorDisp3: vtordisp because of vtordisp(2) in f1(),128 // local vtordisp(0) in g1() is disabled.129 //130 // CHECK: *** Dumping AST Record Layout131 // CHECK-NEXT: 0 | struct HasVtorDisp3132 // 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]139 }140 };141 142 struct HasVtorDisp4 : virtual Base {143 virtual ~HasVtorDisp4() {}144 virtual void Func() {}145 };146 147 int x6[sizeof(HasVtorDisp4)];148 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.152 //153 // CHECK: *** Dumping AST Record Layout154 // CHECK-NEXT: 0 | struct HasVtorDisp4155 // 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]162 163 InnerContainer::g1();164 InnerContainer::g2();165 }166 167 static void f2() {168 struct NoVtorDisp3 : virtual Base {169 virtual ~NoVtorDisp3() {}170 virtual void Func() {}171 };172 173 int x7[sizeof(NoVtorDisp3)];174 175 // NoVtroDisp3: no vtordisp because of global pragma (0),176 // local vtordisp(2) is disabled on exit from f1().177 //178 // CHECK: *** Dumping AST Record Layout179 // CHECK-NEXT: 0 | struct NoVtorDisp3180 // 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]186 }187};188 189struct Container3 {190 #pragma vtordisp(2)191 struct HasVtorDisp5 : virtual Base {192 virtual ~HasVtorDisp5() {}193 virtual void Func() {}194 };195 196 int x8[sizeof(HasVtorDisp5)];197 198 // HasVtorDisp5: vtordisp because of pragma right before it.199 //200 // CHECK: *** Dumping AST Record Layout201 // CHECK-NEXT: 0 | struct Container3::HasVtorDisp5202 // 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]209};210 211int main() {212 Container::f();213 Container2::f1();214 Container2::f2();215 Container3 cont3;216 return 0;217};218