diff options
author | Anders Carlsson <andersca@mac.com> | 2008-02-16 01:20:23 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2008-02-16 01:20:23 +0000 |
commit | 3ea23a45d97a38fdd893ad2738e3bb2dddaf10ff (patch) | |
tree | 874719e6e48b5d40b0eab5f2f37937b6423a784e /clang/AST/ASTContext.cpp | |
parent | 074965c5cbf5996b920bebb0b0f1ab46b77f50a0 (diff) | |
download | bcm5719-llvm-3ea23a45d97a38fdd893ad2738e3bb2dddaf10ff.tar.gz bcm5719-llvm-3ea23a45d97a38fdd893ad2738e3bb2dddaf10ff.zip |
Make sizeof and __alignof work correctly with packed structs.
llvm-svn: 47202
Diffstat (limited to 'clang/AST/ASTContext.cpp')
-rw-r--r-- | clang/AST/ASTContext.cpp | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/clang/AST/ASTContext.cpp b/clang/AST/ASTContext.cpp index 608858b55fd..7d7decb6ff0 100644 --- a/clang/AST/ASTContext.cpp +++ b/clang/AST/ASTContext.cpp @@ -319,10 +319,13 @@ const ASTRecordLayout &ASTContext::getASTRecordLayout(const RecordDecl *D, unsigned RecordAlign = 8; // Default alignment = 1 byte = 8 bits. if (D->getKind() != Decl::Union) { + bool StructIsPacked = D->getAttr<PackedAttr>(); + // Layout each field, for now, just sequentially, respecting alignment. In // the future, this will need to be tweakable by targets. for (unsigned i = 0, e = D->getNumMembers(); i != e; ++i) { const FieldDecl *FD = D->getMember(i); + bool FieldIsPacked = StructIsPacked || FD->getAttr<PackedAttr>(); uint64_t FieldSize; unsigned FieldAlign; if (FD->getType()->isIncompleteType()) { @@ -331,12 +334,12 @@ const ASTRecordLayout &ASTContext::getASTRecordLayout(const RecordDecl *D, // Flexible array members don't have any size, but they // have to be aligned appropriately for their element type. const ArrayType* ATy = FD->getType()->getAsArrayType(); - FieldAlign = getTypeAlign(ATy->getElementType(), L); + FieldAlign = FieldIsPacked ? 8 : getTypeAlign(ATy->getElementType(), L); FieldSize = 0; } else { std::pair<uint64_t, unsigned> FieldInfo = getTypeInfo(FD->getType(), L); FieldSize = FieldInfo.first; - FieldAlign = FieldInfo.second; + FieldAlign = FieldIsPacked ? 8 : FieldInfo.second; } // Round up the current record size to the field's alignment boundary. |