diff options
-rw-r--r-- | include/clang/AST/RecordLayout.h | 13 | ||||
-rw-r--r-- | lib/AST/ASTContext.cpp | 16 |
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>()) |