]> granicus.if.org Git - clang/commitdiff
[ms-abi] Update Alignment for VtorDisps
authorWarren Hunt <whunt@google.com>
Thu, 19 Dec 2013 00:43:59 +0000 (00:43 +0000)
committerWarren Hunt <whunt@google.com>
Thu, 19 Dec 2013 00:43:59 +0000 (00:43 +0000)
The alignment impact of the virtual bases apperas to be applied in
order, rather than up front.  This patch adds the new behavior and
provides a test case.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@197639 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/RecordLayoutBuilder.cpp
test/Layout/ms-x86-vtordisp.cpp

index d81fb00466f47c3f1685f3387fbef349d18664f8..74010ce7aa0f6fe83859ca02e0281fd81a9d1e5b 100644 (file)
@@ -2525,14 +2525,6 @@ void MicrosoftRecordLayoutBuilder::layoutVirtualBases(const CXXRecordDecl *RD) {
   if (!HasVBPtr)
     return;
 
-  // Update the alignment 
-  for (CXXRecordDecl::base_class_const_iterator i = RD->vbases_begin(),
-                                                e = RD->vbases_end();
-       i != e; ++i) {
-    const CXXRecordDecl *BaseDecl = i->getType()->getAsCXXRecordDecl();
-    const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl);
-    updateAlignment(getBaseAlignment(Layout));
-  }
   PreviousBaseLayout = 0;
 
   llvm::SmallPtrSet<const CXXRecordDecl *, 2> HasVtordisp =
@@ -2569,6 +2561,8 @@ void MicrosoftRecordLayoutBuilder::layoutVirtualBase(const CXXRecordDecl *RD,
 
   // Insert the base here.
   Size = Size.RoundUpToAlignment(getBaseAlignment(Layout));
+  // Update the alignment 
+  updateAlignment(getBaseAlignment(Layout));
   VBases.insert(
       std::make_pair(RD, ASTRecordLayout::VBaseInfo(Size, HasVtordisp)));
   Size += Layout.getNonVirtualSize();
index b16f09ed704c6cadac030caa6d168c90471300e3..6a37eb1d1fce3dacb6d37b2bd3addd9c15f46460 100644 (file)
@@ -163,8 +163,46 @@ CT::~CT(){}
 // CHECK-X64:      | [sizeof=16, align=8
 // CHECK-X64:      |  nvsize=8, nvalign=8]
 
+struct XA {
+       XA() { printf("XA"); }
+       long long ll;
+};
+struct XB : XA {
+       XB() { printf("XB"); }
+       virtual void foo() {}
+       int b;
+};
+struct XC : virtual XB {
+       XC() { printf("XC"); }
+       virtual void foo() {}
+};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK:    0 | struct XC
+// CHECK:    0 |   (XC vbtable pointer)
+// CHECK:    4 |   (vtordisp for vbase XB)
+// CHECK:    8 |   struct XB (virtual base)
+// CHECK:    8 |     (XB vftable pointer)
+// CHECK:   16 |     struct XA (base)
+// CHECK:   16 |       long long ll
+// CHECK:   24 |     int b
+// CHECK:      | [sizeof=32, align=8
+// CHECK:      |  nvsize=4, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64:    0 | struct XC
+// CHECK-X64:    0 |   (XC vbtable pointer)
+// CHECK-X64:   12 |   (vtordisp for vbase XB)
+// CHECK-X64:   16 |   struct XB (virtual base)
+// CHECK-X64:   16 |     (XB vftable pointer)
+// CHECK-X64:   24 |     struct XA (base)
+// CHECK-X64:   24 |       long long ll
+// CHECK-X64:   32 |     int b
+// CHECK-X64:      | [sizeof=40, align=8
+// CHECK-X64:      |  nvsize=8, nvalign=8]
+
 int a[
 sizeof(A)+
 sizeof(C)+
 sizeof(D)+
-sizeof(CT)];
+sizeof(CT)+
+sizeof(XC)];