From: Anders Carlsson Date: Sat, 18 Jul 2009 20:50:59 +0000 (+0000) Subject: More layout builder work. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=93fab9d67ca62e3e291803e5a1309473d6e00344;p=clang More layout builder work. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76333 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h index fcf81f88bc..2350275d56 100644 --- a/include/clang/AST/RecordLayout.h +++ b/include/clang/AST/RecordLayout.h @@ -44,8 +44,10 @@ class ASTRecordLayout { } ASTRecordLayout(uint64_t Size, unsigned Alignment, + unsigned nextoffset, const uint64_t *fieldoffsets, unsigned fieldcount) - : Size(Size), FieldOffsets(0), Alignment(Alignment), FieldCount(fieldcount) { + : Size(Size), NextOffset(nextoffset), FieldOffsets(0), Alignment(Alignment), + FieldCount(fieldcount) { if (FieldCount > 0) { FieldOffsets = new uint64_t[FieldCount]; for (unsigned i = 0; i < FieldCount; ++i) diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index b72e588ca7..5230ba95d1 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -11,6 +11,7 @@ #include "clang/AST/Attr.h" #include "clang/AST/Decl.h" +#include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" #include "clang/AST/RecordLayout.h" #include "clang/Basic/TargetInfo.h" @@ -42,6 +43,36 @@ void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) { FinishLayout(); } +void ASTRecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D, + const ObjCImplementationDecl *Impl) { + if (ObjCInterfaceDecl *SD = D->getSuperClass()) { + const ASTRecordLayout &SL = Ctx.getASTObjCInterfaceLayout(SD); + + UpdateAlignment(SL.getAlignment()); + + // We start laying out ivars not at the end of the superclass + // structure, but at the next byte following the last field. + Size = llvm::RoundUpToAlignment(SL.NextOffset, 8); + NextOffset = Size; + } + + if (const PackedAttr *PA = D->getAttr()) + StructPacking = PA->getAlignment(); + + if (const AlignedAttr *AA = D->getAttr()) + UpdateAlignment(AA->getAlignment()); + + // Layout each ivar sequentially. + llvm::SmallVector Ivars; + Ctx.ShallowCollectObjCIvars(D, Ivars, Impl); + for (unsigned i = 0, e = Ivars.size(); i != e; ++i) + LayoutField(Ivars[i]); + + // Finally, round the size of the total struct up to the alignment of the + // struct itself. + FinishLayout(); +} + void ASTRecordLayoutBuilder::LayoutField(const FieldDecl *D) { unsigned FieldPacking = StructPacking; uint64_t FieldOffset = IsUnion ? 0 : Size; @@ -157,6 +188,21 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx, Builder.Layout(D); return new ASTRecordLayout(Builder.Size, Builder.Alignment, + Builder.NextOffset, + Builder.FieldOffsets.data(), + Builder.FieldOffsets.size()); +} + +const ASTRecordLayout * +ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx, + const ObjCInterfaceDecl *D, + const ObjCImplementationDecl *Impl) { + ASTRecordLayoutBuilder Builder(Ctx); + + Builder.Layout(D, Impl); + + return new ASTRecordLayout(Builder.Size, Builder.Alignment, + Builder.NextOffset, Builder.FieldOffsets.data(), Builder.FieldOffsets.size()); } diff --git a/lib/AST/RecordLayoutBuilder.h b/lib/AST/RecordLayoutBuilder.h index a51c626e14..473cb85659 100644 --- a/lib/AST/RecordLayoutBuilder.h +++ b/lib/AST/RecordLayoutBuilder.h @@ -16,6 +16,8 @@ namespace clang { class ASTContext; class ASTRecordLayout; class FieldDecl; + class ObjCImplementationDecl; + class ObjCInterfaceDecl; class RecordDecl; class ASTRecordLayoutBuilder { @@ -32,6 +34,9 @@ class ASTRecordLayoutBuilder { ASTRecordLayoutBuilder(ASTContext &Ctx); void Layout(const RecordDecl *D); + void Layout(const ObjCInterfaceDecl *D, + const ObjCImplementationDecl *Impl); + void LayoutField(const FieldDecl *D); void FinishLayout(); @@ -42,7 +47,9 @@ class ASTRecordLayoutBuilder { public: static const ASTRecordLayout *ComputeLayout(ASTContext &Ctx, const RecordDecl *RD); - + static const ASTRecordLayout *ComputeLayout(ASTContext &Ctx, + const ObjCInterfaceDecl *D, + const ObjCImplementationDecl *Impl); }; } // end namespace clang