ms-x86-vtordisp.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. // RUN: %clang_cc1 -fno-rtti -fms-extensions -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>&1 \
  2. // RUN: | FileCheck %s
  3. // RUN: %clang_cc1 -fno-rtti -fms-extensions -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
  4. // RUN: | FileCheck %s -check-prefix CHECK-X64
  5. extern "C" int printf(const char *fmt, ...);
  6. struct B0 {
  7. int a;
  8. B0() : a(0xf00000B0) {}
  9. virtual void f() { printf("B0"); }
  10. };
  11. struct __declspec(align(16)) B1 {
  12. int a;
  13. B1() : a(0xf00000B1) {}
  14. virtual void f() { printf("B1"); }
  15. };
  16. struct __declspec(align(16)) Align16 {};
  17. struct __declspec(align(32)) Align32 {};
  18. struct VAlign16 : virtual Align16 {};
  19. struct VAlign32 : virtual Align32 {};
  20. struct A : virtual B0, virtual B1 {
  21. int a;
  22. A() : a(0xf000000A) {}
  23. virtual void f() { printf("A"); }
  24. virtual void g() { printf("A"); }
  25. };
  26. // CHECK: *** Dumping AST Record Layout
  27. // CHECK: *** Dumping AST Record Layout
  28. // CHECK: *** Dumping AST Record Layout
  29. // CHECK-NEXT: 0 | struct A
  30. // CHECK-NEXT: 0 | (A vftable pointer)
  31. // CHECK-NEXT: 4 | (A vbtable pointer)
  32. // CHECK-NEXT: 8 | int a
  33. // CHECK-NEXT: 16 | (vtordisp for vbase B0)
  34. // CHECK-NEXT: 20 | struct B0 (virtual base)
  35. // CHECK-NEXT: 20 | (B0 vftable pointer)
  36. // CHECK-NEXT: 24 | int a
  37. // CHECK-NEXT: 44 | (vtordisp for vbase B1)
  38. // CHECK-NEXT: 48 | struct B1 (virtual base)
  39. // CHECK-NEXT: 48 | (B1 vftable pointer)
  40. // CHECK-NEXT: 52 | int a
  41. // CHECK-NEXT: | [sizeof=64, align=16
  42. // CHECK-NEXT: | nvsize=12, nvalign=16]
  43. // CHECK-X64: *** Dumping AST Record Layout
  44. // CHECK-X64: *** Dumping AST Record Layout
  45. // CHECK-X64: *** Dumping AST Record Layout
  46. // CHECK-X64-NEXT: 0 | struct A
  47. // CHECK-X64-NEXT: 0 | (A vftable pointer)
  48. // CHECK-X64-NEXT: 8 | (A vbtable pointer)
  49. // CHECK-X64-NEXT: 16 | int a
  50. // CHECK-X64-NEXT: 36 | (vtordisp for vbase B0)
  51. // CHECK-X64-NEXT: 40 | struct B0 (virtual base)
  52. // CHECK-X64-NEXT: 40 | (B0 vftable pointer)
  53. // CHECK-X64-NEXT: 48 | int a
  54. // CHECK-X64-NEXT: 76 | (vtordisp for vbase B1)
  55. // CHECK-X64-NEXT: 80 | struct B1 (virtual base)
  56. // CHECK-X64-NEXT: 80 | (B1 vftable pointer)
  57. // CHECK-X64-NEXT: 88 | int a
  58. // CHECK-X64-NEXT: | [sizeof=96, align=16
  59. // CHECK-X64-NEXT: | nvsize=24, nvalign=16]
  60. struct C : virtual B0, virtual B1, VAlign32 {
  61. int a;
  62. C() : a(0xf000000C) {}
  63. virtual void f() { printf("C"); }
  64. virtual void g() { printf("C"); }
  65. };
  66. // CHECK: *** Dumping AST Record Layout
  67. // CHECK: *** Dumping AST Record Layout
  68. // CHECK: *** Dumping AST Record Layout
  69. // CHECK-NEXT: 0 | struct C
  70. // CHECK-NEXT: 0 | (C vftable pointer)
  71. // CHECK-NEXT: 32 | struct VAlign32 (base)
  72. // CHECK-NEXT: 32 | (VAlign32 vbtable pointer)
  73. // CHECK-NEXT: 36 | int a
  74. // CHECK-NEXT: 64 | (vtordisp for vbase B0)
  75. // CHECK-NEXT: 68 | struct B0 (virtual base)
  76. // CHECK-NEXT: 68 | (B0 vftable pointer)
  77. // CHECK-NEXT: 72 | int a
  78. // CHECK-NEXT: 108 | (vtordisp for vbase B1)
  79. // CHECK-NEXT: 112 | struct B1 (virtual base)
  80. // CHECK-NEXT: 112 | (B1 vftable pointer)
  81. // CHECK-NEXT: 116 | int a
  82. // CHECK-NEXT: 128 | struct Align32 (virtual base) (empty)
  83. // CHECK-NEXT: | [sizeof=128, align=32
  84. // CHECK-NEXT: | nvsize=64, nvalign=32]
  85. // CHECK-X64: *** Dumping AST Record Layout
  86. // CHECK-X64: *** Dumping AST Record Layout
  87. // CHECK-X64: *** Dumping AST Record Layout
  88. // CHECK-X64-NEXT: 0 | struct C
  89. // CHECK-X64-NEXT: 0 | (C vftable pointer)
  90. // CHECK-X64-NEXT: 32 | struct VAlign32 (base)
  91. // CHECK-X64-NEXT: 32 | (VAlign32 vbtable pointer)
  92. // CHECK-X64-NEXT: 40 | int a
  93. // CHECK-X64-NEXT: 68 | (vtordisp for vbase B0)
  94. // CHECK-X64-NEXT: 72 | struct B0 (virtual base)
  95. // CHECK-X64-NEXT: 72 | (B0 vftable pointer)
  96. // CHECK-X64-NEXT: 80 | int a
  97. // CHECK-X64-NEXT: 108 | (vtordisp for vbase B1)
  98. // CHECK-X64-NEXT: 112 | struct B1 (virtual base)
  99. // CHECK-X64-NEXT: 112 | (B1 vftable pointer)
  100. // CHECK-X64-NEXT: 120 | int a
  101. // CHECK-X64-NEXT: 128 | struct Align32 (virtual base) (empty)
  102. // CHECK-X64-NEXT: | [sizeof=128, align=32
  103. // CHECK-X64-NEXT: | nvsize=64, nvalign=32]
  104. struct __declspec(align(32)) D : virtual B0, virtual B1 {
  105. int a;
  106. D() : a(0xf000000D) {}
  107. virtual void f() { printf("D"); }
  108. virtual void g() { printf("D"); }
  109. };
  110. // CHECK: *** Dumping AST Record Layout
  111. // CHECK-NEXT: 0 | struct D
  112. // CHECK-NEXT: 0 | (D vftable pointer)
  113. // CHECK-NEXT: 4 | (D vbtable pointer)
  114. // CHECK-NEXT: 8 | int a
  115. // CHECK-NEXT: 32 | (vtordisp for vbase B0)
  116. // CHECK-NEXT: 36 | struct B0 (virtual base)
  117. // CHECK-NEXT: 36 | (B0 vftable pointer)
  118. // CHECK-NEXT: 40 | int a
  119. // CHECK-NEXT: 76 | (vtordisp for vbase B1)
  120. // CHECK-NEXT: 80 | struct B1 (virtual base)
  121. // CHECK-NEXT: 80 | (B1 vftable pointer)
  122. // CHECK-NEXT: 84 | int a
  123. // CHECK-NEXT: | [sizeof=96, align=32
  124. // CHECK-NEXT: | nvsize=12, nvalign=32]
  125. // CHECK-X64: *** Dumping AST Record Layout
  126. // CHECK-X64-NEXT: 0 | struct D
  127. // CHECK-X64-NEXT: 0 | (D vftable pointer)
  128. // CHECK-X64-NEXT: 8 | (D vbtable pointer)
  129. // CHECK-X64-NEXT: 16 | int a
  130. // CHECK-X64-NEXT: 36 | (vtordisp for vbase B0)
  131. // CHECK-X64-NEXT: 40 | struct B0 (virtual base)
  132. // CHECK-X64-NEXT: 40 | (B0 vftable pointer)
  133. // CHECK-X64-NEXT: 48 | int a
  134. // CHECK-X64-NEXT: 76 | (vtordisp for vbase B1)
  135. // CHECK-X64-NEXT: 80 | struct B1 (virtual base)
  136. // CHECK-X64-NEXT: 80 | (B1 vftable pointer)
  137. // CHECK-X64-NEXT: 88 | int a
  138. // CHECK-X64-NEXT: | [sizeof=96, align=32
  139. // CHECK-X64-NEXT: | nvsize=24, nvalign=32]
  140. struct AT {
  141. virtual ~AT(){}
  142. };
  143. struct CT : virtual AT {
  144. virtual ~CT();
  145. };
  146. CT::~CT(){}
  147. // CHECK: *** Dumping AST Record Layout
  148. // CHECK: *** Dumping AST Record Layout
  149. // CHECK-NEXT: 0 | struct CT
  150. // CHECK-NEXT: 0 | (CT vbtable pointer)
  151. // CHECK-NEXT: 4 | struct AT (virtual base)
  152. // CHECK-NEXT: 4 | (AT vftable pointer)
  153. // CHECK-NEXT: | [sizeof=8, align=4
  154. // CHECK-NEXT: | nvsize=4, nvalign=4]
  155. // CHECK-X64: *** Dumping AST Record Layout
  156. // CHECK-X64: *** Dumping AST Record Layout
  157. // CHECK-X64-NEXT: 0 | struct CT
  158. // CHECK-X64-NEXT: 0 | (CT vbtable pointer)
  159. // CHECK-X64-NEXT: 8 | struct AT (virtual base)
  160. // CHECK-X64-NEXT: 8 | (AT vftable pointer)
  161. // CHECK-X64-NEXT: | [sizeof=16, align=8
  162. // CHECK-X64-NEXT: | nvsize=8, nvalign=8]
  163. struct XA {
  164. XA() { printf("XA"); }
  165. long long ll;
  166. };
  167. struct XB : XA {
  168. XB() { printf("XB"); }
  169. virtual void foo() {}
  170. int b;
  171. };
  172. struct XC : virtual XB {
  173. XC() { printf("XC"); }
  174. virtual void foo() {}
  175. };
  176. // CHECK: *** Dumping AST Record Layout
  177. // CHECK: *** Dumping AST Record Layout
  178. // CHECK: *** Dumping AST Record Layout
  179. // CHECK-NEXT: 0 | struct XC
  180. // CHECK-NEXT: 0 | (XC vbtable pointer)
  181. // CHECK-NEXT: 4 | (vtordisp for vbase XB)
  182. // CHECK-NEXT: 8 | struct XB (virtual base)
  183. // CHECK-NEXT: 8 | (XB vftable pointer)
  184. // CHECK-NEXT: 16 | struct XA (base)
  185. // CHECK-NEXT: 16 | long long ll
  186. // CHECK-NEXT: 24 | int b
  187. // CHECK-NEXT: | [sizeof=32, align=8
  188. // CHECK-NEXT: | nvsize=4, nvalign=8]
  189. // CHECK-X64: *** Dumping AST Record Layout
  190. // CHECK-X64: *** Dumping AST Record Layout
  191. // CHECK-X64: *** Dumping AST Record Layout
  192. // CHECK-X64-NEXT: 0 | struct XC
  193. // CHECK-X64-NEXT: 0 | (XC vbtable pointer)
  194. // CHECK-X64-NEXT: 12 | (vtordisp for vbase XB)
  195. // CHECK-X64-NEXT: 16 | struct XB (virtual base)
  196. // CHECK-X64-NEXT: 16 | (XB vftable pointer)
  197. // CHECK-X64-NEXT: 24 | struct XA (base)
  198. // CHECK-X64-NEXT: 24 | long long ll
  199. // CHECK-X64-NEXT: 32 | int b
  200. // CHECK-X64-NEXT: | [sizeof=40, align=8
  201. // CHECK-X64-NEXT: | nvsize=8, nvalign=8]
  202. namespace pragma_test1 {
  203. // No overrides means no vtordisps by default.
  204. struct A { virtual ~A(); virtual void foo(); int a; };
  205. struct B : virtual A { virtual ~B(); virtual void bar(); int b; };
  206. struct C : virtual B { int c; };
  207. // CHECK: *** Dumping AST Record Layout
  208. // CHECK: *** Dumping AST Record Layout
  209. // CHECK: *** Dumping AST Record Layout
  210. // CHECK-NEXT: 0 | struct pragma_test1::C
  211. // CHECK-NEXT: 0 | (C vbtable pointer)
  212. // CHECK-NEXT: 4 | int c
  213. // CHECK-NEXT: 8 | struct pragma_test1::A (virtual base)
  214. // CHECK-NEXT: 8 | (A vftable pointer)
  215. // CHECK-NEXT: 12 | int a
  216. // CHECK-NEXT: 16 | struct pragma_test1::B (virtual base)
  217. // CHECK-NEXT: 16 | (B vftable pointer)
  218. // CHECK-NEXT: 20 | (B vbtable pointer)
  219. // CHECK-NEXT: 24 | int b
  220. // CHECK-NEXT: | [sizeof=28, align=4
  221. // CHECK-NEXT: | nvsize=8, nvalign=4]
  222. // CHECK-X64: *** Dumping AST Record Layout
  223. // CHECK-X64: *** Dumping AST Record Layout
  224. // CHECK-X64: *** Dumping AST Record Layout
  225. }
  226. namespace pragma_test2 {
  227. struct A { virtual ~A(); virtual void foo(); int a; };
  228. #pragma vtordisp(push,2)
  229. struct B : virtual A { virtual ~B(); virtual void bar(); int b; };
  230. struct C : virtual B { int c; };
  231. #pragma vtordisp(pop)
  232. // CHECK: *** Dumping AST Record Layout
  233. // CHECK: *** Dumping AST Record Layout
  234. // CHECK: *** Dumping AST Record Layout
  235. // CHECK-NEXT: 0 | struct pragma_test2::C
  236. // CHECK-NEXT: 0 | (C vbtable pointer)
  237. // CHECK-NEXT: 4 | int c
  238. // CHECK-NEXT: 8 | (vtordisp for vbase A)
  239. // CHECK-NEXT: 12 | struct pragma_test2::A (virtual base)
  240. // CHECK-NEXT: 12 | (A vftable pointer)
  241. // CHECK-NEXT: 16 | int a
  242. // By adding a virtual method and vftable to B, now we need a vtordisp.
  243. // CHECK-NEXT: 20 | (vtordisp for vbase B)
  244. // CHECK-NEXT: 24 | struct pragma_test2::B (virtual base)
  245. // CHECK-NEXT: 24 | (B vftable pointer)
  246. // CHECK-NEXT: 28 | (B vbtable pointer)
  247. // CHECK-NEXT: 32 | int b
  248. // CHECK-NEXT: | [sizeof=36, align=4
  249. // CHECK-NEXT: | nvsize=8, nvalign=4]
  250. // CHECK-X64: *** Dumping AST Record Layout
  251. // CHECK-X64: *** Dumping AST Record Layout
  252. // CHECK-X64: *** Dumping AST Record Layout
  253. }
  254. namespace pragma_test3 {
  255. struct A { virtual ~A(); virtual void foo(); int a; };
  256. #pragma vtordisp(push,2)
  257. struct B : virtual A { virtual ~B(); virtual void foo(); int b; };
  258. struct C : virtual B { int c; };
  259. #pragma vtordisp(pop)
  260. // CHECK: *** Dumping AST Record Layout
  261. // CHECK: *** Dumping AST Record Layout
  262. // CHECK: *** Dumping AST Record Layout
  263. // CHECK-NEXT: 0 | struct pragma_test3::C
  264. // CHECK-NEXT: 0 | (C vbtable pointer)
  265. // CHECK-NEXT: 4 | int c
  266. // CHECK-NEXT: 8 | (vtordisp for vbase A)
  267. // CHECK-NEXT: 12 | struct pragma_test3::A (virtual base)
  268. // CHECK-NEXT: 12 | (A vftable pointer)
  269. // CHECK-NEXT: 16 | int a
  270. // No vtordisp before B! It doesn't have its own vftable.
  271. // CHECK-NEXT: 20 | struct pragma_test3::B (virtual base)
  272. // CHECK-NEXT: 20 | (B vbtable pointer)
  273. // CHECK-NEXT: 24 | int b
  274. // CHECK-NEXT: | [sizeof=28, align=4
  275. // CHECK-NEXT: | nvsize=8, nvalign=4]
  276. // CHECK-X64: *** Dumping AST Record Layout
  277. // CHECK-X64: *** Dumping AST Record Layout
  278. // CHECK-X64: *** Dumping AST Record Layout
  279. }
  280. namespace pragma_test4 {
  281. struct A {
  282. A();
  283. virtual void foo();
  284. int a;
  285. };
  286. // Make sure the pragma applies to class template decls before they've been
  287. // instantiated.
  288. #pragma vtordisp(push,2)
  289. template <typename T>
  290. struct B : virtual A {
  291. B();
  292. virtual ~B();
  293. virtual void bar();
  294. T b;
  295. };
  296. #pragma vtordisp(pop)
  297. struct C : virtual B<int> { int c; };
  298. // CHECK: *** Dumping AST Record Layout
  299. // CHECK: *** Dumping AST Record Layout
  300. // CHECK: *** Dumping AST Record Layout
  301. // CHECK-NEXT: 0 | struct pragma_test4::C
  302. // CHECK-NEXT: 0 | (C vbtable pointer)
  303. // CHECK-NEXT: 4 | int c
  304. // Pragma applies to B, which has vbase A.
  305. // CHECK-NEXT: 8 | (vtordisp for vbase A)
  306. // CHECK-NEXT: 12 | struct pragma_test4::A (virtual base)
  307. // CHECK-NEXT: 12 | (A vftable pointer)
  308. // CHECK-NEXT: 16 | int a
  309. // Pragma does not apply to C, and B doesn't usually need a vtordisp in C.
  310. // CHECK-NEXT: 20 | struct pragma_test4::B<int> (virtual base)
  311. // CHECK-NEXT: 20 | (B vftable pointer)
  312. // CHECK-NEXT: 24 | (B vbtable pointer)
  313. // CHECK-NEXT: 28 | int b
  314. // CHECK-NEXT: | [sizeof=32, align=4
  315. // CHECK-NEXT: | nvsize=8, nvalign=4]
  316. // CHECK-X64: *** Dumping AST Record Layout
  317. // CHECK-X64: *** Dumping AST Record Layout
  318. // CHECK-X64: *** Dumping AST Record Layout
  319. }
  320. struct GA {
  321. virtual void fun() {}
  322. };
  323. struct GB: public GA {};
  324. struct GC: public virtual GA {
  325. virtual void fun() {}
  326. GC() {}
  327. };
  328. struct GD: public virtual GC, public virtual GB {};
  329. // CHECK: *** Dumping AST Record Layout
  330. // CHECK: *** Dumping AST Record Layout
  331. // CHECK: *** Dumping AST Record Layout
  332. // CHECK: *** Dumping AST Record Layout
  333. // CHECK-NEXT: 0 | struct GD
  334. // CHECK-NEXT: 0 | (GD vbtable pointer)
  335. // CHECK-NEXT: 4 | (vtordisp for vbase GA)
  336. // CHECK-NEXT: 8 | struct GA (virtual base)
  337. // CHECK-NEXT: 8 | (GA vftable pointer)
  338. // CHECK-NEXT: 12 | struct GC (virtual base)
  339. // CHECK-NEXT: 12 | (GC vbtable pointer)
  340. // CHECK-NEXT: 16 | struct GB (virtual base)
  341. // CHECK-NEXT: 16 | struct GA (primary base)
  342. // CHECK-NEXT: 16 | (GA vftable pointer)
  343. // CHECK-NEXT: | [sizeof=20, align=4
  344. // CHECK-NEXT: | nvsize=4, nvalign=4]
  345. // CHECK-X64: *** Dumping AST Record Layout
  346. // CHECK-X64: *** Dumping AST Record Layout
  347. // CHECK-X64: *** Dumping AST Record Layout
  348. // CHECK-X64: *** Dumping AST Record Layout
  349. // CHECK-X64-NEXT: 0 | struct GD
  350. // CHECK-X64-NEXT: 0 | (GD vbtable pointer)
  351. // CHECK-X64-NEXT: 12 | (vtordisp for vbase GA)
  352. // CHECK-X64-NEXT: 16 | struct GA (virtual base)
  353. // CHECK-X64-NEXT: 16 | (GA vftable pointer)
  354. // CHECK-X64-NEXT: 24 | struct GC (virtual base)
  355. // CHECK-X64-NEXT: 24 | (GC vbtable pointer)
  356. // CHECK-X64-NEXT: 32 | struct GB (virtual base)
  357. // CHECK-X64-NEXT: 32 | struct GA (primary base)
  358. // CHECK-X64-NEXT: 32 | (GA vftable pointer)
  359. // CHECK-X64-NEXT: | [sizeof=40, align=8
  360. // CHECK-X64-NEXT: | nvsize=8, nvalign=8]
  361. struct HA {
  362. virtual void fun() {}
  363. };
  364. #pragma vtordisp(push, 2)
  365. struct HB : virtual HA {};
  366. #pragma vtordisp(pop)
  367. #pragma vtordisp(push, 0)
  368. struct HC : virtual HB {};
  369. #pragma vtordisp(pop)
  370. // CHECK: *** Dumping AST Record Layout
  371. // CHECK: *** Dumping AST Record Layout
  372. // CHECK: *** Dumping AST Record Layout
  373. // CHECK-NEXT: 0 | struct HC
  374. // CHECK-NEXT: 0 | (HC vbtable pointer)
  375. // CHECK-NEXT: 4 | (vtordisp for vbase HA)
  376. // CHECK-NEXT: 8 | struct HA (virtual base)
  377. // CHECK-NEXT: 8 | (HA vftable pointer)
  378. // CHECK-NEXT: 12 | struct HB (virtual base)
  379. // CHECK-NEXT: 12 | (HB vbtable pointer)
  380. // CHECK-NEXT: | [sizeof=16, align=4
  381. // CHECK-NEXT: | nvsize=4, nvalign=4]
  382. // CHECK-X64: *** Dumping AST Record Layout
  383. // CHECK-X64: *** Dumping AST Record Layout
  384. // CHECK-X64: *** Dumping AST Record Layout
  385. // CHECK-X64-NEXT: 0 | struct HC
  386. // CHECK-X64-NEXT: 0 | (HC vbtable pointer)
  387. // CHECK-X64-NEXT: 12 | (vtordisp for vbase HA)
  388. // CHECK-X64-NEXT: 16 | struct HA (virtual base)
  389. // CHECK-X64-NEXT: 16 | (HA vftable pointer)
  390. // CHECK-X64-NEXT: 24 | struct HB (virtual base)
  391. // CHECK-X64-NEXT: 24 | (HB vbtable pointer)
  392. // CHECK-X64-NEXT: | [sizeof=32, align=8
  393. // CHECK-X64-NEXT: | nvsize=8, nvalign=8]
  394. struct IA {
  395. virtual void f();
  396. };
  397. struct __declspec(dllexport) IB : virtual IA {
  398. virtual void f() = 0;
  399. IB() {}
  400. };
  401. // CHECK: *** Dumping AST Record Layout
  402. // CHECK: *** Dumping AST Record Layout
  403. // CHECK-NEXT: 0 | struct IB
  404. // CHECK-NEXT: 0 | (IB vbtable pointer)
  405. // CHECK-NEXT: 4 | struct IA (virtual base)
  406. // CHECK-NEXT: 4 | (IA vftable pointer)
  407. // CHECK-NEXT: | [sizeof=8, align=4
  408. // CHECK-NEXT: | nvsize=4, nvalign=4]
  409. // CHECK-X64: *** Dumping AST Record Layout
  410. // CHECK-X64: *** Dumping AST Record Layout
  411. // CHECK-X64-NEXT: 0 | struct IB
  412. // CHECK-X64-NEXT: 0 | (IB vbtable pointer)
  413. // CHECK-X64-NEXT: 8 | struct IA (virtual base)
  414. // CHECK-X64-NEXT: 8 | (IA vftable pointer)
  415. // CHECK-X64-NEXT: | [sizeof=16, align=8
  416. // CHECK-X64-NEXT: | nvsize=8, nvalign=8]
  417. int a[
  418. sizeof(A)+
  419. sizeof(C)+
  420. sizeof(D)+
  421. sizeof(CT)+
  422. sizeof(XC)+
  423. sizeof(pragma_test1::C)+
  424. sizeof(pragma_test2::C)+
  425. sizeof(pragma_test3::C)+
  426. sizeof(pragma_test4::C)+
  427. sizeof(GD)+
  428. sizeof(HC)+
  429. sizeof(IB)+
  430. 0];