]> granicus.if.org Git - clang/commitdiff
Simplify alignment handling in the record builder.
authorAnders Carlsson <andersca@mac.com>
Tue, 4 Aug 2009 16:29:15 +0000 (16:29 +0000)
committerAnders Carlsson <andersca@mac.com>
Tue, 4 Aug 2009 16:29:15 +0000 (16:29 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78069 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGRecordLayoutBuilder.cpp

index bd3cabd5bfb31797b1eb37928c92b02efa56d082..5f07a5f0833463984391b220f6d25c0b0ab1e8e4 100644 (file)
@@ -117,22 +117,28 @@ bool CGRecordLayoutBuilder::LayoutField(const FieldDecl *D,
     return true;
   }
   
+  assert(FieldOffset % 8 == 0 && "FieldOffset is not on a byte boundary!");
+  uint64_t FieldOffsetInBytes = FieldOffset / 8;
+  
   const llvm::Type *Ty = Types.ConvertTypeForMemRecursive(D->getType());
+  unsigned TypeAlignment = getTypeAlignment(Ty);
 
-  // Check if the field is aligned.
-  if (const AlignedAttr *PA = D->getAttr<AlignedAttr>()) {
-    unsigned FieldAlign = PA->getAlignment();
-   
-    if (!Packed && getTypeAlignment(Ty) > FieldAlign)
-      return false;
+  // Round up the field offset to the alignment of the field type.
+  uint64_t AlignedNextFieldOffsetInBytes = 
+    llvm::RoundUpToAlignment(NextFieldOffsetInBytes, TypeAlignment);
+
+  if (FieldOffsetInBytes < AlignedNextFieldOffsetInBytes) {
+    assert(!Packed && "Could not place field even with packed struct!");
+    return false;
   }
-   
-  assert(FieldOffset % 8 == 0 && "FieldOffset is not on a byte boundary!");
   
-  uint64_t FieldOffsetInBytes = FieldOffset / 8;
-  
-  // Append padding if necessary.
-  AppendPadding(FieldOffsetInBytes, Ty);
+  if (AlignedNextFieldOffsetInBytes < FieldOffsetInBytes) {
+    // Even with alignment, the field offset is not at the right place,
+    // insert padding.
+    uint64_t PaddingInBytes = FieldOffsetInBytes - NextFieldOffsetInBytes;
+    
+    AppendBytes(PaddingInBytes);
+  }
   
   // Now append the field.
   LLVMFields.push_back(LLVMFieldInfo(D, FieldTypes.size()));