[cfe-commits] r76338 - in /cfe/trunk: include/clang/AST/RecordLayout.h lib/AST/ASTContext.cpp lib/AST/RecordLayoutBuilder.h
Anders Carlsson
andersca at mac.com
Sat Jul 18 14:19:52 PDT 2009
Author: andersca
Date: Sat Jul 18 16:19:52 2009
New Revision: 76338
URL: http://llvm.org/viewvc/llvm-project?rev=76338&view=rev
Log:
Migrate over to the record layout builder.
Modified:
cfe/trunk/include/clang/AST/RecordLayout.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/RecordLayoutBuilder.h
Modified: cfe/trunk/include/clang/AST/RecordLayout.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecordLayout.h?rev=76338&r1=76337&r2=76338&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecordLayout.h (original)
+++ cfe/trunk/include/clang/AST/RecordLayout.h Sat Jul 18 16:19:52 2009
@@ -37,12 +37,6 @@
friend class ASTContext;
friend class ASTRecordLayoutBuilder;
- ASTRecordLayout(uint64_t S = 0, unsigned A = 8)
- : Size(S), NextOffset(S), Alignment(A), FieldCount(0) {}
- ~ASTRecordLayout() {
- delete [] FieldOffsets;
- }
-
ASTRecordLayout(uint64_t Size, unsigned Alignment,
unsigned nextoffset,
const uint64_t *fieldoffsets, unsigned fieldcount)
@@ -54,37 +48,10 @@
FieldOffsets[i] = fieldoffsets[i];
}
}
-
- /// Initialize record layout. N is the number of fields in this record.
- void InitializeLayout(unsigned N) {
- FieldCount = N;
- FieldOffsets = new uint64_t[N];
- }
-
- /// Finalize record layout. Adjust record size based on the alignment.
- void FinalizeLayout(bool ForceNonEmpty = false) {
- // In C++, records cannot be of size 0.
- if (ForceNonEmpty && Size == 0)
- Size = 8;
- // Finally, round the size of the record up to the alignment of the
- // record itself.
- Size = (Size + (Alignment-1)) & ~(Alignment-1);
- }
-
- void SetFieldOffset(unsigned FieldNo, uint64_t Offset) {
- assert (FieldNo < FieldCount && "Invalid Field No");
- FieldOffsets[FieldNo] = Offset;
+ ~ASTRecordLayout() {
+ delete [] FieldOffsets;
}
- void SetAlignment(unsigned A) { Alignment = A; }
-
- /// LayoutField - Field layout. StructPacking is the specified
- /// packing alignment (maximum alignment) in bits to use for the
- /// structure, or 0 if no packing alignment is specified.
- void LayoutField(const FieldDecl *FD, unsigned FieldNo,
- bool IsUnion, unsigned StructPacking,
- ASTContext &Context);
-
ASTRecordLayout(const ASTRecordLayout&); // DO NOT IMPLEMENT
void operator=(const ASTRecordLayout&); // DO NOT IMPLEMENT
public:
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=76338&r1=76337&r2=76338&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Sat Jul 18 16:19:52 2009
@@ -24,6 +24,8 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "RecordLayoutBuilder.h"
+
using namespace clang;
enum FloatingRank {
@@ -726,102 +728,6 @@
return ABIAlign;
}
-
-/// LayoutField - Field layout.
-void ASTRecordLayout::LayoutField(const FieldDecl *FD, unsigned FieldNo,
- bool IsUnion, unsigned StructPacking,
- ASTContext &Context) {
- unsigned FieldPacking = StructPacking;
- uint64_t FieldOffset = IsUnion ? 0 : Size;
- uint64_t FieldSize;
- unsigned FieldAlign;
-
- // FIXME: Should this override struct packing? Probably we want to
- // take the minimum?
- if (const PackedAttr *PA = FD->getAttr<PackedAttr>())
- FieldPacking = PA->getAlignment();
-
- if (const Expr *BitWidthExpr = FD->getBitWidth()) {
- // TODO: Need to check this algorithm on other targets!
- // (tested on Linux-X86)
- FieldSize = BitWidthExpr->EvaluateAsInt(Context).getZExtValue();
-
- std::pair<uint64_t, unsigned> FieldInfo =
- Context.getTypeInfo(FD->getType());
- uint64_t TypeSize = FieldInfo.first;
-
- // Determine the alignment of this bitfield. The packing
- // attributes define a maximum and the alignment attribute defines
- // a minimum.
- // FIXME: What is the right behavior when the specified alignment
- // is smaller than the specified packing?
- FieldAlign = FieldInfo.second;
- if (FieldPacking)
- FieldAlign = std::min(FieldAlign, FieldPacking);
- 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()->isIncompleteArrayType()) {
- // This is 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 = Context.getAsArrayType(FD->getType());
- FieldAlign = Context.getTypeAlign(ATy->getElementType());
- } else if (const ReferenceType *RT = FD->getType()->getAsReferenceType()) {
- unsigned AS = RT->getPointeeType().getAddressSpace();
- FieldSize = Context.Target.getPointerWidth(AS);
- FieldAlign = Context.Target.getPointerAlign(AS);
- } else {
- std::pair<uint64_t, unsigned> FieldInfo =
- Context.getTypeInfo(FD->getType());
- FieldSize = FieldInfo.first;
- FieldAlign = FieldInfo.second;
- }
-
- // Determine the alignment of this bitfield. The packing
- // attributes define a maximum and the alignment attribute defines
- // a minimum. Additionally, the packing alignment must be at least
- // a byte for non-bitfields.
- //
- // FIXME: What is the right behavior when the specified alignment
- // is smaller than the specified packing?
- if (FieldPacking)
- FieldAlign = std::min(FieldAlign, std::max(8U, FieldPacking));
- 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 the next available offset.
- NextOffset = Size;
-
- // Remember max struct/class alignment.
- Alignment = std::max(Alignment, FieldAlign);
-}
-
static void CollectLocalObjCIvars(ASTContext *Ctx,
const ObjCInterfaceDecl *OI,
llvm::SmallVectorImpl<FieldDecl*> &Fields) {
@@ -934,9 +840,9 @@
if (const ASTRecordLayout *Entry = ObjCLayouts[Key])
return *Entry;
- unsigned FieldCount = D->ivar_size();
// Add in synthesized ivar count if laying out an implementation.
if (Impl) {
+ unsigned FieldCount = D->ivar_size();
unsigned SynthCount = CountSynthesizedIvars(D);
FieldCount += SynthCount;
// If there aren't any sythesized ivars then reuse the interface
@@ -947,40 +853,10 @@
return getObjCLayout(D, 0);
}
- ASTRecordLayout *NewEntry = NULL;
- if (ObjCInterfaceDecl *SD = D->getSuperClass()) {
- const ASTRecordLayout &SL = getASTObjCInterfaceLayout(SD);
- unsigned Alignment = SL.getAlignment();
-
- // We start laying out ivars not at the end of the superclass
- // structure, but at the next byte following the last field.
- uint64_t Size = llvm::RoundUpToAlignment(SL.NextOffset, 8);
-
- ObjCLayouts[Key] = NewEntry = new ASTRecordLayout(Size, Alignment);
- NewEntry->InitializeLayout(FieldCount);
- } else {
- ObjCLayouts[Key] = NewEntry = new ASTRecordLayout();
- NewEntry->InitializeLayout(FieldCount);
- }
-
- unsigned StructPacking = 0;
- if (const PackedAttr *PA = D->getAttr<PackedAttr>())
- StructPacking = PA->getAlignment();
-
- if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
- NewEntry->SetAlignment(std::max(NewEntry->getAlignment(),
- AA->getAlignment()));
-
- // Layout each ivar sequentially.
- unsigned i = 0;
- llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
- ShallowCollectObjCIvars(D, Ivars, Impl);
- for (unsigned k = 0, e = Ivars.size(); k != e; ++k)
- NewEntry->LayoutField(Ivars[k], i++, false, StructPacking, *this);
-
- // Finally, round the size of the total struct up to the alignment of the
- // struct itself.
- NewEntry->FinalizeLayout();
+ const ASTRecordLayout *NewEntry =
+ ASTRecordLayoutBuilder::ComputeLayout(*this, D, Impl);
+ ObjCLayouts[Key] = NewEntry;
+
return *NewEntry;
}
@@ -1005,34 +881,10 @@
const ASTRecordLayout *&Entry = ASTRecordLayouts[D];
if (Entry) return *Entry;
- // Allocate and assign into ASTRecordLayouts here. The "Entry" reference can
- // be invalidated (dangle) if the ASTRecordLayouts hashtable is inserted into.
- ASTRecordLayout *NewEntry = new ASTRecordLayout();
+ const ASTRecordLayout *NewEntry =
+ ASTRecordLayoutBuilder::ComputeLayout(*this, D);
Entry = NewEntry;
-
- // FIXME: Avoid linear walk through the fields, if possible.
- NewEntry->InitializeLayout(std::distance(D->field_begin(), D->field_end()));
- bool IsUnion = D->isUnion();
-
- unsigned StructPacking = 0;
- if (const PackedAttr *PA = D->getAttr<PackedAttr>())
- StructPacking = PA->getAlignment();
-
- if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
- 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.
- unsigned FieldIdx = 0;
- for (RecordDecl::field_iterator Field = D->field_begin(),
- FieldEnd = D->field_end();
- Field != FieldEnd; (void)++Field, ++FieldIdx)
- NewEntry->LayoutField(*Field, FieldIdx, IsUnion, StructPacking, *this);
-
- // Finally, round the size of the total struct up to the alignment of the
- // struct itself.
- NewEntry->FinalizeLayout(getLangOptions().CPlusPlus);
+
return *NewEntry;
}
Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.h?rev=76338&r1=76337&r2=76338&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.h (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.h Sat Jul 18 16:19:52 2009
@@ -38,6 +38,9 @@
const ObjCImplementationDecl *Impl);
void LayoutField(const FieldDecl *D);
+
+ /// FinishLayout - Finalize record layout. Adjust record size based on the
+ /// alignment.
void FinishLayout();
void UpdateAlignment(unsigned NewAlignment);
More information about the cfe-commits
mailing list