From: Devang Patel Date: Fri, 6 Jun 2008 02:14:01 +0000 (+0000) Subject: During interface layout, don't forget super class. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6a5a34c0e5587263df719c62030761cf59d27fe4;p=clang During interface layout, don't forget super class. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52035 91177308-0d34-0410-b5e6-96231b3b80d8 --- 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(); if (const AlignedAttr *AA = D->getAttr())