summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-08-04 16:29:15 +0000
committerAnders Carlsson <andersca@mac.com>2009-08-04 16:29:15 +0000
commit19702bb05492116e00206b9b54666cb55bc6b3cf (patch)
tree606fc4b6d26250689b731729e204ad7a0d344980
parentf222054df72840c1d3472e30461570c86b639110 (diff)
downloadbcm5719-llvm-19702bb05492116e00206b9b54666cb55bc6b3cf.tar.gz
bcm5719-llvm-19702bb05492116e00206b9b54666cb55bc6b3cf.zip
Simplify alignment handling in the record builder.
llvm-svn: 78069
-rw-r--r--clang/lib/CodeGen/CGRecordLayoutBuilder.cpp30
1 files changed, 18 insertions, 12 deletions
diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
index bd3cabd5bfb..5f07a5f0833 100644
--- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/clang/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()));
OpenPOWER on IntegriCloud