From 453addbaea98f9678e2f9858057722a028f1ae3c Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Sun, 3 May 2009 11:16:44 +0000 Subject: [PATCH] Implement the interface/implementation layout distinction. - These routines should now be independent of the Sema state. - This is nearly zero functionality change, the distinction only matters in the non-fragile ABI, and the consumers that care about this distinction should be using getASTObjCImplementationLayout. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70692 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/ASTContext.cpp | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 3342ca5bc9..65c9cddd9d 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -745,16 +745,29 @@ const ASTRecordLayout & ASTContext::getObjCLayout(const ObjCInterfaceDecl *D, const ObjCImplementationDecl *Impl) { // Look up this layout, if already laid out, return what we have. - const ASTRecordLayout *&Entry = ObjCLayouts[D]; + const ASTRecordLayout *&Entry = + ObjCLayouts[Impl ? (ObjCContainerDecl*) Impl : (ObjCContainerDecl*) D]; if (Entry) return *Entry; + unsigned FieldCount = D->ivar_size(); + // Add in synthesized ivar count if laying out an implementation. + if (Impl) { + for (ObjCInterfaceDecl::prop_iterator I = D->prop_begin(*this), + E = D->prop_end(*this); I != E; ++I) + if ((*I)->getPropertyIvarDecl()) + ++FieldCount; + + // If there aren't any sythesized ivar's then reuse the interface + // entry. Note we can't cache this because we simply free all + // entries later; however we shouldn't look up implementations + // frequently. + if (FieldCount == D->ivar_size()) + return getObjCLayout(D, 0); + } + // Allocate and assign into ASTRecordLayouts here. The "Entry" reference can // be invalidated (dangle) if the ASTRecordLayouts hashtable is inserted into. ASTRecordLayout *NewEntry = NULL; - // FIXME. Add actual count of synthesized ivars, instead of count - // of properties which is the upper bound, but is safe. - unsigned FieldCount = - D->ivar_size() + std::distance(D->prop_begin(*this), D->prop_end(*this)); if (ObjCInterfaceDecl *SD = D->getSuperClass()) { FieldCount++; const ASTRecordLayout &SL = getASTObjCInterfaceLayout(SD); @@ -785,11 +798,13 @@ ASTContext::getObjCLayout(const ObjCInterfaceDecl *D, const ObjCIvarDecl* Ivar = (*IVI); NewEntry->LayoutField(Ivar, i++, false, StructPacking, *this); } - // Also synthesized ivars - for (ObjCInterfaceDecl::prop_iterator I = D->prop_begin(*this), - E = D->prop_end(*this); I != E; ++I) { - if (ObjCIvarDecl *Ivar = (*I)->getPropertyIvarDecl()) - NewEntry->LayoutField(Ivar, i++, false, StructPacking, *this); + // And synthesized ivars, if this is an implementation. + if (Impl) { + for (ObjCInterfaceDecl::prop_iterator I = D->prop_begin(*this), + E = D->prop_end(*this); I != E; ++I) { + if (ObjCIvarDecl *Ivar = (*I)->getPropertyIvarDecl()) + NewEntry->LayoutField(Ivar, i++, false, StructPacking, *this); + } } // Finally, round the size of the total struct up to the alignment of the -- 2.40.0