[cfe-commits] r76846 - in /cfe/trunk/lib/CodeGen: CGRecordLayoutBuilder.cpp CGRecordLayoutBuilder.h
Anders Carlsson
andersca at mac.com
Wed Jul 22 20:44:19 PDT 2009
Author: andersca
Date: Wed Jul 22 22:43:54 2009
New Revision: 76846
URL: http://llvm.org/viewvc/llvm-project?rev=76846&view=rev
Log:
Implement union layout support.
Modified:
cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp
cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.h
Modified: cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp?rev=76846&r1=76845&r2=76846&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp Wed Jul 22 22:43:54 2009
@@ -27,6 +27,11 @@
using namespace CodeGen;
void CGRecordLayoutBuilder::Layout(const RecordDecl *D) {
+ if (D->isUnion()) {
+ LayoutUnion(D);
+ return;
+ }
+
if (const PackedAttr* PA = D->getAttr<PackedAttr>())
StructPacking = PA->getAlignment();
@@ -141,11 +146,49 @@
return true;
}
+void CGRecordLayoutBuilder::LayoutUnion(const RecordDecl *D) {
+ assert(D->isUnion() && "Can't call LayoutUnion on a non-union record!");
+
+ const ASTRecordLayout &Layout = Types.getContext().getASTRecordLayout(D);
+
+ const llvm::Type *Ty = 0;
+ uint64_t Size = 0;
+ unsigned Align = 0;
+
+ unsigned FieldNo = 0;
+ for (RecordDecl::field_iterator Field = D->field_begin(),
+ FieldEnd = D->field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
+ assert(Layout.getFieldOffset(FieldNo) == 0 &&
+ "Union field offset did not start at the beginning of record!");
+
+ const llvm::Type *FieldTy =
+ Types.ConvertTypeForMemRecursive(Field->getType());
+ unsigned FieldAlign = Types.getTargetData().getTypeAllocSize(FieldTy);
+ uint64_t FieldSize = Types.getTargetData().getABITypeAlignment(FieldTy);
+
+ if (FieldAlign < Align)
+ continue;
+
+ if (FieldAlign > Align || FieldSize > Size) {
+ Ty = FieldTy;
+ Align = FieldAlign;
+ Size = FieldSize;
+ }
+ }
+
+ // Now add our field.
+ if (Ty)
+ AppendField(0, Size, Ty);
+
+ // Append tail padding.
+ if (Layout.getSize() / 8 > Size)
+ AppendPadding(Layout.getSize() / 8, Align);
+}
+
bool CGRecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
assert(!D->isUnion() && "Can't call LayoutFields on a union!");
- const ASTRecordLayout &Layout =
- Types.getContext().getASTRecordLayout(D);
+ const ASTRecordLayout &Layout = Types.getContext().getASTRecordLayout(D);
unsigned FieldNo = 0;
for (RecordDecl::field_iterator Field = D->field_begin(),
@@ -241,9 +284,6 @@
const RecordDecl *D) {
CGRecordLayoutBuilder Builder(Types);
- if (D->isUnion())
- return 0;
-
Builder.Layout(D);
// FIXME: Once this works well enough, enable it.
Modified: cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.h?rev=76846&r1=76845&r2=76846&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.h (original)
+++ cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.h Wed Jul 22 22:43:54 2009
@@ -83,6 +83,9 @@
/// Layout - Will layout a RecordDecl.
void Layout(const RecordDecl *D);
+ /// LayoutUnion - Will layout a union RecordDecl.
+ void LayoutUnion(const RecordDecl *D);
+
/// LayoutField - try to layout all fields in the record decl.
/// Returns false if the operation failed because the struct is not packed.
bool LayoutFields(const RecordDecl *D);
More information about the cfe-commits
mailing list