diff options
author | Anders Carlsson <andersca@mac.com> | 2009-08-04 16:29:15 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-08-04 16:29:15 +0000 |
commit | de9f2c937a4892d155cfe695657ce4cc3556836f (patch) | |
tree | 1ddc79771190427bebddaea9aacb98c9e6cc7d3f /lib/CodeGen | |
parent | 00d02abf2492ebf54fd5088f647af38db461b842 (diff) |
Simplify alignment handling in the record builder.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78069 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGRecordLayoutBuilder.cpp | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp index bd3cabd5bf..5f07a5f083 100644 --- a/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -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())); |