aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/RecordLayout.h13
-rw-r--r--lib/AST/ASTContext.cpp16
2 files changed, 25 insertions, 4 deletions
diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h
index 82880abfcf..1b72017cd3 100644
--- a/include/clang/AST/RecordLayout.h
+++ b/include/clang/AST/RecordLayout.h
@@ -30,16 +30,19 @@ namespace clang {
class ASTRecordLayout {
uint64_t Size; // Size of record in bits.
unsigned Alignment; // Alignment of record in bits.
+ unsigned FieldCount; // Number of fields
uint64_t *FieldOffsets;
friend class ASTContext;
-
- ASTRecordLayout() : Size(0), Alignment(8) {}
+
+ ASTRecordLayout(uint64_t S = 0, unsigned A = 8)
+ : Size(S), Alignment(A), FieldCount(0) {}
~ASTRecordLayout() {
delete [] FieldOffsets;
}
/// Initialize record layout. N is the number of fields in this record.
void InitializeLayout(unsigned N) {
+ FieldCount = N;
FieldOffsets = new uint64_t[N];
}
@@ -50,6 +53,11 @@ class ASTRecordLayout {
Size = (Size + (Alignment-1)) & ~(Alignment-1);
}
+ void SetFieldOffset(unsigned FieldNo, uint64_t Offset) {
+ assert (FieldNo < FieldCount && "Invalid Field No");
+ FieldOffsets[FieldNo] = Offset;
+ }
+
void SetAlignment(unsigned A) { Alignment = A; }
/// LayoutField - Field layout.
@@ -65,6 +73,7 @@ public:
uint64_t getSize() const { return Size; }
uint64_t getFieldOffset(unsigned FieldNo) const {
+ assert (FieldNo < FieldCount && "Invalid Field No");
return FieldOffsets[FieldNo];
}
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 4a1fb39bb6..d8e2c06fc0 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -405,10 +405,22 @@ ASTContext::getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) {
// Allocate and assign into ASTRecordLayouts here. The "Entry" reference can
// be invalidated (dangle) if the ASTRecordLayouts hashtable is inserted into.
- ASTRecordLayout *NewEntry = new ASTRecordLayout();
+ ASTRecordLayout *NewEntry = NULL;
+ unsigned FieldCount = D->ivar_size();
+ if (ObjCInterfaceDecl *SD = D->getSuperClass()) {
+ FieldCount++;
+ const ASTRecordLayout &SL = getASTObjCInterfaceLayout(SD);
+ unsigned Alignment = SL.getAlignment();
+ uint64_t Size = SL.getSize();
+ NewEntry = new ASTRecordLayout(Size, Alignment);
+ NewEntry->InitializeLayout(FieldCount);
+ NewEntry->SetFieldOffset(0, 0); // Super class is at the beginning of the layout.
+ } else {
+ NewEntry = new ASTRecordLayout();
+ NewEntry->InitializeLayout(FieldCount);
+ }
Entry = NewEntry;
- NewEntry->InitializeLayout(D->ivar_size());
bool IsPacked = D->getAttr<PackedAttr>();
if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())