aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-07-18 20:50:59 +0000
committerAnders Carlsson <andersca@mac.com>2009-07-18 20:50:59 +0000
commit93fab9d67ca62e3e291803e5a1309473d6e00344 (patch)
treefbf6c97e223f859ace439364c3d8a2cbde8aff6d
parentbda4c1015e27ac82d31afb4519dd53586e61a51a (diff)
More layout builder work.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76333 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/RecordLayout.h4
-rw-r--r--lib/AST/RecordLayoutBuilder.cpp46
-rw-r--r--lib/AST/RecordLayoutBuilder.h9
3 files changed, 57 insertions, 2 deletions
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<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;
@@ -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