[cfe-commits] r51966 - in /cfe/trunk: include/clang/AST/RecordLayout.h lib/AST/ASTContext.cpp
Devang Patel
dpatel at apple.com
Wed Jun 4 14:22:18 PDT 2008
Author: dpatel
Date: Wed Jun 4 16:22:16 2008
New Revision: 51966
URL: http://llvm.org/viewvc/llvm-project?rev=51966&view=rev
Log:
Refactoring.
Move field layout code in a ASTRecordLayout member fn.
Modified:
cfe/trunk/include/clang/AST/RecordLayout.h
cfe/trunk/lib/AST/ASTContext.cpp
Modified: cfe/trunk/include/clang/AST/RecordLayout.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecordLayout.h?rev=51966&r1=51965&r2=51966&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecordLayout.h (original)
+++ cfe/trunk/include/clang/AST/RecordLayout.h Wed Jun 4 16:22:16 2008
@@ -29,15 +29,29 @@
uint64_t *FieldOffsets;
friend class ASTContext;
- ASTRecordLayout() {}
+ ASTRecordLayout() : Size(0), Alignment(8) {}
~ASTRecordLayout() {
delete [] FieldOffsets;
}
+
+ /// Initialize record layout. N is the number of fields in this record.
+ void InitializeLayout(unsigned N) {
+ FieldOffsets = new uint64_t[N];
+ }
- void SetLayout(uint64_t size, unsigned alignment, uint64_t *fieldOffsets) {
- Size = size; Alignment = alignment;
- FieldOffsets = fieldOffsets;
+ /// Finalize record layout. Adjust record size based on the alignment.
+ void FinalizeLayout() {
+ // Finally, round the size of the record up to the alignment of the
+ // record itself.
+ Size = (Size + (Alignment-1)) & ~(Alignment-1);
}
+
+ void SetAlignment(unsigned A) { Alignment = A; }
+
+ /// LayoutField - Field layout.
+ void LayoutField(const FieldDecl *FD, unsigned FieldNo,
+ bool IsUnion, bool StructIsPacked,
+ ASTContext &Context);
ASTRecordLayout(const ASTRecordLayout&); // DO NOT IMPLEMENT
void operator=(const ASTRecordLayout&); // DO NOT IMPLEMENT
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=51966&r1=51965&r2=51966&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Jun 4 16:22:16 2008
@@ -311,6 +311,81 @@
return std::make_pair(Width, Align);
}
+/// LayoutField - Field layout.
+void ASTRecordLayout::LayoutField(const FieldDecl *FD, unsigned FieldNo,
+ bool IsUnion, bool StructIsPacked,
+ ASTContext &Context) {
+ bool FieldIsPacked = StructIsPacked || FD->getAttr<PackedAttr>();
+ uint64_t FieldOffset = IsUnion ? 0 : Size;
+ uint64_t FieldSize;
+ unsigned FieldAlign;
+
+ if (const Expr *BitWidthExpr = FD->getBitWidth()) {
+ // TODO: Need to check this algorithm on other targets!
+ // (tested on Linux-X86)
+ llvm::APSInt I(32);
+ bool BitWidthIsICE =
+ BitWidthExpr->isIntegerConstantExpr(I, Context);
+ assert (BitWidthIsICE && "Invalid BitField size expression");
+ FieldSize = I.getZExtValue();
+
+ std::pair<uint64_t, unsigned> FieldInfo =
+ Context.getTypeInfo(FD->getType());
+ uint64_t TypeSize = FieldInfo.first;
+
+ FieldAlign = FieldInfo.second;
+ if (FieldIsPacked)
+ FieldAlign = 1;
+ if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
+ FieldAlign = std::max(FieldAlign, AA->getAlignment());
+
+ // Check if we need to add padding to give the field the correct
+ // alignment.
+ if (FieldSize == 0 || (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize)
+ FieldOffset = (FieldOffset + (FieldAlign-1)) & ~(FieldAlign-1);
+
+ // Padding members don't affect overall alignment
+ if (!FD->getIdentifier())
+ FieldAlign = 1;
+ } else {
+ if (FD->getType()->isIncompleteType()) {
+ // This must be a flexible array member; we can't directly
+ // query getTypeInfo about these, so we figure it out here.
+ // Flexible array members don't have any size, but they
+ // have to be aligned appropriately for their element type.
+ FieldSize = 0;
+ const ArrayType* ATy = FD->getType()->getAsArrayType();
+ FieldAlign = Context.getTypeAlign(ATy->getElementType());
+ } else {
+ std::pair<uint64_t, unsigned> FieldInfo =
+ Context.getTypeInfo(FD->getType());
+ FieldSize = FieldInfo.first;
+ FieldAlign = FieldInfo.second;
+ }
+
+ if (FieldIsPacked)
+ FieldAlign = 8;
+ if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
+ FieldAlign = std::max(FieldAlign, AA->getAlignment());
+
+ // Round up the current record size to the field's alignment boundary.
+ FieldOffset = (FieldOffset + (FieldAlign-1)) & ~(FieldAlign-1);
+ }
+
+ // Place this field at the current location.
+ FieldOffsets[FieldNo] = FieldOffset;
+
+ // Reserve space for this field.
+ if (IsUnion) {
+ Size = std::max(Size, FieldSize);
+ } else {
+ Size = FieldOffset + FieldSize;
+ }
+
+ // Remember max struct/class alignment.
+ Alignment = std::max(Alignment, FieldAlign);
+}
+
/// getASTRecordLayout - Get or compute information about the layout of the
/// specified record (struct/union/class), which indicates its size and field
/// position information.
@@ -326,93 +401,24 @@
ASTRecordLayout *NewEntry = new ASTRecordLayout();
Entry = NewEntry;
- uint64_t *FieldOffsets = new uint64_t[D->getNumMembers()];
- uint64_t RecordSize = 0;
- unsigned RecordAlign = 8; // Default alignment = 1 byte = 8 bits.
+ NewEntry->InitializeLayout(D->getNumMembers());
bool StructIsPacked = D->getAttr<PackedAttr>();
bool IsUnion = (D->getKind() == Decl::Union);
if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
- RecordAlign = std::max(RecordAlign, AA->getAlignment());
+ NewEntry->SetAlignment(std::max(NewEntry->getAlignment(),
+ AA->getAlignment()));
// 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 FieldOffset = IsUnion ? 0 : RecordSize;
- uint64_t FieldSize;
- unsigned FieldAlign;
-
- if (const Expr *BitWidthExpr = FD->getBitWidth()) {
- // TODO: Need to check this algorithm on other targets!
- // (tested on Linux-X86)
- llvm::APSInt I(32);
- bool BitWidthIsICE =
- BitWidthExpr->isIntegerConstantExpr(I, *this);
- assert (BitWidthIsICE && "Invalid BitField size expression");
- FieldSize = I.getZExtValue();
-
- std::pair<uint64_t, unsigned> FieldInfo = getTypeInfo(FD->getType());
- uint64_t TypeSize = FieldInfo.first;
-
- FieldAlign = FieldInfo.second;
- if (FieldIsPacked)
- FieldAlign = 1;
- if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
- FieldAlign = std::max(FieldAlign, AA->getAlignment());
-
- // Check if we need to add padding to give the field the correct
- // alignment.
- if (FieldSize == 0 || (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize)
- FieldOffset = (FieldOffset + (FieldAlign-1)) & ~(FieldAlign-1);
-
- // Padding members don't affect overall alignment
- if (!FD->getIdentifier())
- FieldAlign = 1;
- } else {
- if (FD->getType()->isIncompleteType()) {
- // This must be a flexible array member; we can't directly
- // query getTypeInfo about these, so we figure it out here.
- // Flexible array members don't have any size, but they
- // have to be aligned appropriately for their element type.
- FieldSize = 0;
- const ArrayType* ATy = FD->getType()->getAsArrayType();
- FieldAlign = getTypeAlign(ATy->getElementType());
- } else {
- std::pair<uint64_t, unsigned> FieldInfo = getTypeInfo(FD->getType());
- FieldSize = FieldInfo.first;
- FieldAlign = FieldInfo.second;
- }
-
- if (FieldIsPacked)
- FieldAlign = 8;
- if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
- FieldAlign = std::max(FieldAlign, AA->getAlignment());
-
- // Round up the current record size to the field's alignment boundary.
- FieldOffset = (FieldOffset + (FieldAlign-1)) & ~(FieldAlign-1);
- }
-
- // Place this field at the current location.
- FieldOffsets[i] = FieldOffset;
-
- // Reserve space for this field.
- if (IsUnion) {
- RecordSize = std::max(RecordSize, FieldSize);
- } else {
- RecordSize = FieldOffset + FieldSize;
- }
-
- // Remember max struct/class alignment.
- RecordAlign = std::max(RecordAlign, FieldAlign);
+ NewEntry->LayoutField(FD, i, IsUnion, StructIsPacked, *this);
}
// Finally, round the size of the total struct up to the alignment of the
// struct itself.
- RecordSize = (RecordSize + (RecordAlign-1)) & ~(RecordAlign-1);
-
- NewEntry->SetLayout(RecordSize, RecordAlign, FieldOffsets);
+ NewEntry->FinalizeLayout();
return *NewEntry;
}
More information about the cfe-commits
mailing list