[PATCH] Microsoft 64-bit Record Layout

Reid Kleckner rnk at google.com
Wed Oct 23 13:56:58 PDT 2013


  w00t!  Lots of deleted code and added tests.  :)  Probably worth another round of review.


================
Comment at: lib/AST/RecordLayoutBuilder.cpp:2009-2010
@@ -2347,3 +2008,4 @@
 static bool isMsLayout(const RecordDecl* D) {
   // FIXME: Use MS record layout for x64 code and remove MS C++ support from the
   // Itanium record layout code.
+  return D->getASTContext().getTargetInfo().getCXXABI().isMicrosoft();
----------------
This is now fixed.

================
Comment at: lib/AST/RecordLayoutBuilder.cpp:2274
@@ -2603,2 +2273,3 @@
   VirtualAlignment = CharUnits::One();
+  AlignAfterVBases = PointerSize.getQuantity() != 4;
 
----------------
Check the architecture on the triple rather than the pointer size.  You could cache that in an IsX64 builder member for readability.

================
Comment at: lib/AST/RecordLayoutBuilder.cpp:2336
@@ -2663,2 +2335,3 @@
   updateAlignment(PointerAlignment);
-  Size += Alignment;
+  if (PointerSize.getQuantity() != 4)
+    Size = Size.RoundUpToAlignment(PointerAlignment) + PointerSize;
----------------
Ditto

================
Comment at: lib/AST/RecordLayoutBuilder.cpp:2345
@@ -2669,2 +2344,3 @@
   LazyEmptyBase = 0;
+  LastBaseWasEmpty = 0;
 
----------------
s/0/false/

================
Comment at: lib/AST/RecordLayoutBuilder.cpp:2418
@@ +2417,3 @@
+    // second to last base was also zero sized.
+    int64_t X = (SizeX + PtrSizeX + PtrAlignX - 1) / PtrAlignX * PtrAlignX;
+    if (BasesAndFieldsAlignment <= PointerAlignment) {
----------------
X seems like a bad name.  I missed that in the other review.

================
Comment at: lib/AST/RecordLayoutBuilder.cpp:2408-2418
@@ -2729,17 +2407,13 @@
     VBPtrOffset = Size.RoundUpToAlignment(PointerAlignment);
-
-    if (Alignment == PointerAlignment && Size % PointerAlignment) {
-      CharUnits x = Size + Alignment + Alignment;
-      Size = VBPtrOffset + Alignment;
-      // Handle strange padding rules.  I have no explanation for why the
-      // virtual base is padded in such an odd way.  My guess is that they
-      // always Add 2 * Alignment and incorrectly round down to the appropriate
-      // alignment.  It's important to get this case correct because it impacts
-      // the layout of the first member of the struct.
-      
-      RecordDecl::field_iterator FieldBegin = RD->field_begin();
-      if (FieldBegin != RD->field_end())
-        Size += CharUnits::fromQuantity(
-            x % getAdjustedFieldInfo(*FieldBegin).second);
-    } else
-      Size += Alignment;
+    int64_t AlignX = BasesAndFieldsAlignment.getQuantity();
+    int64_t SizeX = Size.getQuantity();
+    int64_t PtrAlignX = PointerAlignment.getQuantity();
+    int64_t PtrSizeX = PointerSize.getQuantity();
+    // Handle strange padding rules for the lazily placed base.  I have no
+    // explanation for why the last virtual base is padded in such an odd way.
+    // Two things to note about this padding are that the rules are different
+    // if the alignment of the bases+fields is <= to the alignemnt of a pointer
+    // and that the rule in 64-bit mode behaves differently depending on if the
+    // second to last base was also zero sized.
+    int64_t X = (SizeX + PtrSizeX + PtrAlignX - 1) / PtrAlignX * PtrAlignX;
+    if (BasesAndFieldsAlignment <= PointerAlignment) {
----------------
I think this can all be something like:

  CharUnits LazyBaseOffset = (Size + PointerSize).RoundUpToAlignment(PtrAlign);

And then you can nuke the int64_t *X vars.

================
Comment at: lib/AST/RecordLayoutBuilder.cpp:2422
@@ +2421,3 @@
+    } else {
+      if (PtrSizeX == 4)
+        Size += BasesAndFieldsAlignment;
----------------
Should be IsX64 or something checking the triple.

================
Comment at: lib/AST/RecordLayoutBuilder.cpp:2572
@@ -2891,1 +2571,3 @@
+    // is less than 4 bytes, at which it is placed at 4 byte offset in the
+    // chunck.  We have no idea why.
     if (RD && Context.getASTRecordLayout(RD).getNonVirtualSize().isZero())
----------------
s/chunck/chunk/

================
Comment at: lib/AST/RecordLayoutBuilder.cpp:2591
@@ -2908,2 +2590,3 @@
 
+  // vtordisps are always 4 bytes (even in 64-bit mode)
   if (HasVtordisp)
----------------
Yep, this is true throughout the ABI.  It seems objects cannot be larger than 2**32.


http://llvm-reviews.chandlerc.com/D2003



More information about the cfe-commits mailing list