}
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)
#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"
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<PackedAttr>())
+ StructPacking = PA->getAlignment();
+
+ if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
+ UpdateAlignment(AA->getAlignment());
+
+ // Layout each ivar sequentially.
+ llvm::SmallVector<ObjCIvarDecl*, 16> 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;
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());
}
class ASTContext;
class ASTRecordLayout;
class FieldDecl;
+ class ObjCImplementationDecl;
+ class ObjCInterfaceDecl;
class RecordDecl;
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();
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