r206000 - [MS-ABI] Fix to vbptr injection site calculation.

Warren Hunt whunt at google.com
Thu Apr 10 16:23:34 PDT 2014


Author: whunt
Date: Thu Apr 10 18:23:34 2014
New Revision: 206000

URL: http://llvm.org/viewvc/llvm-project?rev=206000&view=rev
Log:
[MS-ABI] Fix to vbptr injection site calculation.
The vbptr is injected after the last non-virtual base lexographically 
rather than the last non-virtual base in layout order.  Test case 
included.  Also, some line ending fixes.


Modified:
    cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
    cfe/trunk/test/Layout/ms-x86-alias-avoidance-padding.cpp
    cfe/trunk/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp

Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=206000&r1=205999&r2=206000&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Thu Apr 10 18:23:34 2014
@@ -2211,8 +2211,6 @@ public:
   bool HasOwnVFPtr : 1;
   /// \brief True if the class has a vbtable pointer.
   bool HasVBPtr : 1;
-  /// \brief Lets us know if we're in 64-bit mode
-  bool Is64BitMode : 1;
   /// \brief True if the last sub-object within the type is zero sized or the
   /// object itself is zero sized.  This *does not* count members that are not
   /// records.  Only used for MS-ABI.
@@ -2310,13 +2308,13 @@ void MicrosoftRecordLayoutBuilder::cxxLa
 
 void MicrosoftRecordLayoutBuilder::initializeLayout(const RecordDecl *RD) {
   IsUnion = RD->isUnion();
-  Is64BitMode = Context.getTargetInfo().getPointerWidth(0) == 64;
   Size = CharUnits::Zero();
   Alignment = CharUnits::One();
   // In 64-bit mode we always perform an alignment step after laying out vbases.
   // In 32-bit mode we do not.  The check to see if we need to perform alignment
   // checks the RequiredAlignment field and performs alignment if it isn't 0.
-  RequiredAlignment = Is64BitMode ? CharUnits::One() : CharUnits::Zero();
+  RequiredAlignment = Context.getTargetInfo().getPointerWidth(0) == 64 ?
+                      CharUnits::One() : CharUnits::Zero();
   // Compute the maximum field alignment.
   MaxFieldAlignment = CharUnits::Zero();
   // Honor the default struct packing maximum alignment flag.
@@ -2402,8 +2400,10 @@ MicrosoftRecordLayoutBuilder::layoutNonV
     const CXXRecordDecl *BaseDecl = I.getType()->getAsCXXRecordDecl();
     const ASTRecordLayout &BaseLayout = Context.getASTRecordLayout(BaseDecl);
     // Only lay out bases without extendable VFPtrs on the second pass.
-    if (BaseLayout.hasExtendableVFPtr())
+    if (BaseLayout.hasExtendableVFPtr()) {
+      VBPtrOffset = Bases[BaseDecl] + BaseLayout.getNonVirtualSize();
       continue;
+    }
     // If this is the first layout, check to see if it leads with a zero sized
     // object.  If it does, so do we.
     if (CheckLeadingLayout) {
@@ -2412,6 +2412,7 @@ MicrosoftRecordLayoutBuilder::layoutNonV
     }
     // Lay out the base.
     layoutNonVirtualBase(BaseDecl, BaseLayout, PreviousBaseLayout);
+    VBPtrOffset = Bases[BaseDecl] + BaseLayout.getNonVirtualSize();
   }
   // Set our VBPtroffset if we know it at this point.
   if (!HasVBPtr)
@@ -2437,7 +2438,6 @@ void MicrosoftRecordLayoutBuilder::layou
   Bases.insert(std::make_pair(BaseDecl, BaseOffset));
   Size = BaseOffset + BaseLayout.getNonVirtualSize();
   PreviousBaseLayout = &BaseLayout;
-  VBPtrOffset = Size;
 }
 
 void MicrosoftRecordLayoutBuilder::layoutFields(const RecordDecl *RD) {
@@ -2542,8 +2542,8 @@ void MicrosoftRecordLayoutBuilder::injec
     *i += Context.toBits(Offset);
   for (BaseOffsetsMapTy::iterator i = Bases.begin(), e = Bases.end();
        i != e; ++i)
-       if (i->second >= InjectionSite)
-         i->second += Offset;
+    if (i->second >= InjectionSite)
+      i->second += Offset;
 }
 
 void MicrosoftRecordLayoutBuilder::injectVFPtr(const CXXRecordDecl *RD) {

Modified: cfe/trunk/test/Layout/ms-x86-alias-avoidance-padding.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Layout/ms-x86-alias-avoidance-padding.cpp?rev=206000&r1=205999&r2=206000&view=diff
==============================================================================
--- cfe/trunk/test/Layout/ms-x86-alias-avoidance-padding.cpp (original)
+++ cfe/trunk/test/Layout/ms-x86-alias-avoidance-padding.cpp Thu Apr 10 18:23:34 2014
@@ -327,19 +327,19 @@ struct RZ0 : RX0, RY {};
 // CHECK-NEXT:    2 |   struct RY (base) (empty)
 // CHECK-NEXT:      | [sizeof=2, align=1
 // CHECK-NEXT:      |  nvsize=2, nvalign=1]
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64-NEXT:    0 | struct RZ0
-// CHECK-X64-NEXT:    0 |   struct RX0 (base)
-// CHECK-X64-NEXT:    0 |     struct RB (base)
-// CHECK-X64-NEXT:    0 |       char c
-// CHECK-X64-NEXT:    1 |     struct RA (base) (empty)
-// CHECK-X64-NEXT:    2 |   struct RY (base) (empty)
-// CHECK-X64-NEXT:      | [sizeof=2, align=1
-// CHECK-X64-NEXT:      |  nvsize=2, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct RZ0
+// CHECK-X64-NEXT:    0 |   struct RX0 (base)
+// CHECK-X64-NEXT:    0 |     struct RB (base)
+// CHECK-X64-NEXT:    0 |       char c
+// CHECK-X64-NEXT:    1 |     struct RA (base) (empty)
+// CHECK-X64-NEXT:    2 |   struct RY (base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=2, align=1
+// CHECK-X64-NEXT:      |  nvsize=2, nvalign=1]
 
 struct RZ1 : RX1, RY {};
 // CHECK: *** Dumping AST Record Layout
@@ -352,16 +352,16 @@ struct RZ1 : RX1, RY {};
 // CHECK-NEXT:    1 |   struct RY (base) (empty)
 // CHECK-NEXT:      | [sizeof=1, align=1
 // CHECK-NEXT:      |  nvsize=1, nvalign=1]
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64-NEXT:    0 | struct RZ1
-// CHECK-X64-NEXT:    0 |   struct RX1 (base)
-// CHECK-X64-NEXT:    0 |     struct RA (base) (empty)
-// CHECK-X64-NEXT:    0 |     struct RB (base)
-// CHECK-X64-NEXT:    0 |       char c
-// CHECK-X64-NEXT:    1 |   struct RY (base) (empty)
-// CHECK-X64-NEXT:      | [sizeof=1, align=1
-// CHECK-X64-NEXT:      |  nvsize=1, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct RZ1
+// CHECK-X64-NEXT:    0 |   struct RX1 (base)
+// CHECK-X64-NEXT:    0 |     struct RA (base) (empty)
+// CHECK-X64-NEXT:    0 |     struct RB (base)
+// CHECK-X64-NEXT:    0 |       char c
+// CHECK-X64-NEXT:    1 |   struct RY (base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=1, align=1
+// CHECK-X64-NEXT:      |  nvsize=1, nvalign=1]
 
 struct RZ2 : RX2, RY {};
 // CHECK: *** Dumping AST Record Layout
@@ -373,15 +373,15 @@ struct RZ2 : RX2, RY {};
 // CHECK-NEXT:    2 |   struct RY (base) (empty)
 // CHECK-NEXT:      | [sizeof=2, align=1
 // CHECK-NEXT:      |  nvsize=2, nvalign=1]
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64-NEXT:    0 | struct RZ2
-// CHECK-X64-NEXT:    0 |   struct RX2 (base)
-// CHECK-X64-NEXT:    0 |     struct RA (base) (empty)
-// CHECK-X64-NEXT:    0 |     char a
-// CHECK-X64-NEXT:    2 |   struct RY (base) (empty)
-// CHECK-X64-NEXT:      | [sizeof=2, align=1
-// CHECK-X64-NEXT:      |  nvsize=2, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct RZ2
+// CHECK-X64-NEXT:    0 |   struct RX2 (base)
+// CHECK-X64-NEXT:    0 |     struct RA (base) (empty)
+// CHECK-X64-NEXT:    0 |     char a
+// CHECK-X64-NEXT:    2 |   struct RY (base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=2, align=1
+// CHECK-X64-NEXT:      |  nvsize=2, nvalign=1]
 
 struct RZ3 : RX3, RY {};
 // CHECK: *** Dumping AST Record Layout
@@ -396,18 +396,18 @@ struct RZ3 : RX3, RY {};
 // CHECK-NEXT:    1 |   struct RY (base) (empty)
 // CHECK-NEXT:      | [sizeof=1, align=1
 // CHECK-NEXT:      |  nvsize=1, nvalign=1]
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64-NEXT:    0 | struct RZ3
-// CHECK-X64-NEXT:    0 |   struct RX3 (base)
-// CHECK-X64-NEXT:    0 |     struct RA (base) (empty)
-// CHECK-X64-NEXT:    0 |     struct RB a
-// CHECK-X64-NEXT:    0 |       char c
-// CHECK-X64-NEXT:      |     [sizeof=1, align=1
-// CHECK-X64-NEXT:      |      nvsize=1, nvalign=1]
-// CHECK-X64-NEXT:    1 |   struct RY (base) (empty)
-// CHECK-X64-NEXT:      | [sizeof=1, align=1
-// CHECK-X64-NEXT:      |  nvsize=1, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct RZ3
+// CHECK-X64-NEXT:    0 |   struct RX3 (base)
+// CHECK-X64-NEXT:    0 |     struct RA (base) (empty)
+// CHECK-X64-NEXT:    0 |     struct RB a
+// CHECK-X64-NEXT:    0 |       char c
+// CHECK-X64-NEXT:      |     [sizeof=1, align=1
+// CHECK-X64-NEXT:      |      nvsize=1, nvalign=1]
+// CHECK-X64-NEXT:    1 |   struct RY (base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=1, align=1
+// CHECK-X64-NEXT:      |  nvsize=1, nvalign=1]
 
 struct RZ4 : RX4, RY {};
 // CHECK: *** Dumping AST Record Layout
@@ -421,17 +421,17 @@ struct RZ4 : RX4, RY {};
 // CHECK-NEXT:    3 |   struct RY (base) (empty)
 // CHECK-NEXT:      | [sizeof=3, align=1
 // CHECK-NEXT:      |  nvsize=3, nvalign=1]
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64-NEXT:    0 | struct RZ4
-// CHECK-X64-NEXT:    0 |   struct RX4 (base)
-// CHECK-X64-NEXT:    0 |     struct RA a (empty)
-// CHECK-X64-NEXT:      |     [sizeof=1, align=1
-// CHECK-X64-NEXT:      |      nvsize=0, nvalign=1]
-// CHECK-X64-NEXT:    1 |     char b
-// CHECK-X64-NEXT:    3 |   struct RY (base) (empty)
-// CHECK-X64-NEXT:      | [sizeof=3, align=1
-// CHECK-X64-NEXT:      |  nvsize=3, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct RZ4
+// CHECK-X64-NEXT:    0 |   struct RX4 (base)
+// CHECK-X64-NEXT:    0 |     struct RA a (empty)
+// CHECK-X64-NEXT:      |     [sizeof=1, align=1
+// CHECK-X64-NEXT:      |      nvsize=0, nvalign=1]
+// CHECK-X64-NEXT:    1 |     char b
+// CHECK-X64-NEXT:    3 |   struct RY (base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=3, align=1
+// CHECK-X64-NEXT:      |  nvsize=3, nvalign=1]
 
 struct RZ5 : RX5, RY {};
 // CHECK: *** Dumping AST Record Layout
@@ -448,20 +448,20 @@ struct RZ5 : RX5, RY {};
 // CHECK-NEXT:    2 |   struct RY (base) (empty)
 // CHECK-NEXT:      | [sizeof=2, align=1
 // CHECK-NEXT:      |  nvsize=2, nvalign=1]
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64-NEXT:    0 | struct RZ5
-// CHECK-X64-NEXT:    0 |   struct RX5 (base)
-// CHECK-X64-NEXT:    0 |     struct RA a (empty)
-// CHECK-X64-NEXT:      |     [sizeof=1, align=1
-// CHECK-X64-NEXT:      |      nvsize=0, nvalign=1]
-// CHECK-X64-NEXT:    1 |     struct RB b
-// CHECK-X64-NEXT:    1 |       char c
-// CHECK-X64-NEXT:      |     [sizeof=1, align=1
-// CHECK-X64-NEXT:      |      nvsize=1, nvalign=1]
-// CHECK-X64-NEXT:    2 |   struct RY (base) (empty)
-// CHECK-X64-NEXT:      | [sizeof=2, align=1
-// CHECK-X64-NEXT:      |  nvsize=2, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct RZ5
+// CHECK-X64-NEXT:    0 |   struct RX5 (base)
+// CHECK-X64-NEXT:    0 |     struct RA a (empty)
+// CHECK-X64-NEXT:      |     [sizeof=1, align=1
+// CHECK-X64-NEXT:      |      nvsize=0, nvalign=1]
+// CHECK-X64-NEXT:    1 |     struct RB b
+// CHECK-X64-NEXT:    1 |       char c
+// CHECK-X64-NEXT:      |     [sizeof=1, align=1
+// CHECK-X64-NEXT:      |      nvsize=1, nvalign=1]
+// CHECK-X64-NEXT:    2 |   struct RY (base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=2, align=1
+// CHECK-X64-NEXT:      |  nvsize=2, nvalign=1]
 
 struct RZ6 : RX6, RY {};
 // CHECK: *** Dumping AST Record Layout
@@ -478,20 +478,20 @@ struct RZ6 : RX6, RY {};
 // CHECK-NEXT:   12 |   struct RV (virtual base) (empty)
 // CHECK-NEXT:      | [sizeof=12, align=4
 // CHECK-NEXT:      |  nvsize=12, nvalign=4]
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64-NEXT:    0 | struct RZ6
-// CHECK-X64-NEXT:    0 |   struct RX6 (base)
-// CHECK-X64-NEXT:    0 |     (RX6 vbtable pointer)
-// CHECK-X64-NEXT:    8 |     struct RB a
-// CHECK-X64-NEXT:    8 |       char c
-// CHECK-X64-NEXT:      |     [sizeof=1, align=1
-// CHECK-X64-NEXT:      |      nvsize=1, nvalign=1]
-// CHECK-X64-NEXT:   17 |   struct RY (base) (empty)
-// CHECK-X64-NEXT:   24 |   struct RV (virtual base) (empty)
-// CHECK-X64-NEXT:      | [sizeof=24, align=8
-// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct RZ6
+// CHECK-X64-NEXT:    0 |   struct RX6 (base)
+// CHECK-X64-NEXT:    0 |     (RX6 vbtable pointer)
+// CHECK-X64-NEXT:    8 |     struct RB a
+// CHECK-X64-NEXT:    8 |       char c
+// CHECK-X64-NEXT:      |     [sizeof=1, align=1
+// CHECK-X64-NEXT:      |      nvsize=1, nvalign=1]
+// CHECK-X64-NEXT:   17 |   struct RY (base) (empty)
+// CHECK-X64-NEXT:   24 |   struct RV (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 struct RZ7 : RX7, RY {};
 // CHECK: *** Dumping AST Record Layout
@@ -508,20 +508,20 @@ struct RZ7 : RX7, RY {};
 // CHECK-NEXT:    8 |     char c
 // CHECK-NEXT:      | [sizeof=9, align=4
 // CHECK-NEXT:      |  nvsize=8, nvalign=4]
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64-NEXT:    0 | struct RZ7
-// CHECK-X64-NEXT:    0 |   struct RX7 (base)
-// CHECK-X64-NEXT:    0 |     (RX7 vbtable pointer)
-// CHECK-X64-NEXT:    8 |     struct RA a (empty)
-// CHECK-X64-NEXT:      |     [sizeof=1, align=1
-// CHECK-X64-NEXT:      |      nvsize=0, nvalign=1]
-// CHECK-X64-NEXT:   16 |   struct RY (base) (empty)
-// CHECK-X64-NEXT:   16 |   struct RW (virtual base)
-// CHECK-X64-NEXT:   16 |     char c
-// CHECK-X64-NEXT:      | [sizeof=24, align=8
-// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct RZ7
+// CHECK-X64-NEXT:    0 |   struct RX7 (base)
+// CHECK-X64-NEXT:    0 |     (RX7 vbtable pointer)
+// CHECK-X64-NEXT:    8 |     struct RA a (empty)
+// CHECK-X64-NEXT:      |     [sizeof=1, align=1
+// CHECK-X64-NEXT:      |      nvsize=0, nvalign=1]
+// CHECK-X64-NEXT:   16 |   struct RY (base) (empty)
+// CHECK-X64-NEXT:   16 |   struct RW (virtual base)
+// CHECK-X64-NEXT:   16 |     char c
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
 
 struct RZ8 : RX8, RY {};
 // CHECK: *** Dumping AST Record Layout
@@ -535,17 +535,17 @@ struct RZ8 : RX8, RY {};
 // CHECK-NEXT:    4 |     char c
 // CHECK-NEXT:      | [sizeof=5, align=4
 // CHECK-NEXT:      |  nvsize=4, nvalign=4]
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64-NEXT:    0 | struct RZ8
-// CHECK-X64-NEXT:    0 |   struct RX8 (base)
-// CHECK-X64-NEXT:    8 |     struct RA (base) (empty)
-// CHECK-X64-NEXT:    0 |     (RX8 vbtable pointer)
-// CHECK-X64-NEXT:    8 |   struct RY (base) (empty)
-// CHECK-X64-NEXT:    8 |   struct RW (virtual base)
-// CHECK-X64-NEXT:    8 |     char c
-// CHECK-X64-NEXT:      | [sizeof=16, align=8
-// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct RZ8
+// CHECK-X64-NEXT:    0 |   struct RX8 (base)
+// CHECK-X64-NEXT:    8 |     struct RA (base) (empty)
+// CHECK-X64-NEXT:    0 |     (RX8 vbtable pointer)
+// CHECK-X64-NEXT:    8 |   struct RY (base) (empty)
+// CHECK-X64-NEXT:    8 |   struct RW (virtual base)
+// CHECK-X64-NEXT:    8 |     char c
+// CHECK-X64-NEXT:      | [sizeof=16, align=8
+// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
 
 
 

Modified: cfe/trunk/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp?rev=206000&r1=205999&r2=206000&view=diff
==============================================================================
--- cfe/trunk/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp (original)
+++ cfe/trunk/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp Thu Apr 10 18:23:34 2014
@@ -766,6 +766,45 @@ struct C2 : public C1, public C0 {};
 // CHECK-X64-NEXT:      | [sizeof=8, align=4
 // CHECK-X64-NEXT:      |  nvsize=8, nvalign=4]
 
+struct JA { char a; };
+struct JB {
+  char a;
+  virtual void f() {}
+};
+struct JC { char a; };
+struct JD : JA, JB, virtual JC {};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct JD
+// CHECK-NEXT:    0 |   struct JB (primary base)
+// CHECK-NEXT:    0 |     (JB vftable pointer)
+// CHECK-NEXT:    4 |     char a
+// CHECK-NEXT:   12 |   struct JA (base)
+// CHECK-NEXT:   12 |     char a
+// CHECK-NEXT:    8 |   (JD vbtable pointer)
+// CHECK-NEXT:   16 |   struct JC (virtual base)
+// CHECK-NEXT:   16 |     char a
+// CHECK-NEXT:      | [sizeof=17, align=4
+// CHECK-NEXT:      |  nvsize=16, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct JD
+// CHECK-X64-NEXT:    0 |   struct JB (primary base)
+// CHECK-X64-NEXT:    0 |     (JB vftable pointer)
+// CHECK-X64-NEXT:    8 |     char a
+// CHECK-X64-NEXT:   24 |   struct JA (base)
+// CHECK-X64-NEXT:   24 |     char a
+// CHECK-X64-NEXT:   16 |   (JD vbtable pointer)
+// CHECK-X64-NEXT:   32 |   struct JC (virtual base)
+// CHECK-X64-NEXT:   32 |     char a
+// CHECK-X64-NEXT:      | [sizeof=40, align=8
+// CHECK-X64-NEXT:      |  nvsize=32, nvalign=8]
+
 int a[
 sizeof(AA)+
 sizeof(AB)+
@@ -793,4 +832,6 @@ sizeof(AX)+
 sizeof(BX)+
 sizeof(CX)+
 sizeof(DX)+
-sizeof(C2)];
+sizeof(C2)+
+sizeof(JD)+
+0];





More information about the cfe-commits mailing list