diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-05-03 13:15:50 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-05-03 13:15:50 +0000 |
commit | 532d4daa038d972240138e2fd6e1122517340833 (patch) | |
tree | 63397aa3bf02b6edff3bad8947ded0f82ec611e5 /lib/CodeGen/CGObjCMac.cpp | |
parent | 9f89f2bc111339ee7fa0df3c2f18e39493b460c4 (diff) |
Use ASTRecordLayout for computing ivar offsets instead of shadow
struct.
- We still need to do more lookup than necessary because ivars don't
live in a reasonable DeclContext.
- The only remaining client of the interface shadow struct is the
ivar layout bitmap.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70756 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGObjCMac.cpp')
-rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 84 |
1 files changed, 43 insertions, 41 deletions
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 1ab4bf1056..a2ef680e2b 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -43,57 +43,59 @@ GetConcreteClassStruct(CodeGen::CodeGenModule &CGM, return cast<llvm::StructType>(CGM.getTypes().ConvertTagDeclType(RD)); } - -/// LookupFieldDeclForIvar - looks up a field decl in the laid out -/// storage which matches this 'ivar'. +/// FindIvarInterface - Find the interface containing the ivar. /// -static const FieldDecl *LookupFieldDeclForIvar(ASTContext &Context, - const ObjCInterfaceDecl *OID, - const ObjCIvarDecl *OIVD, - const ObjCInterfaceDecl *&Found) { - assert(!OID->isForwardDecl() && "Invalid interface decl!"); - const RecordDecl *RecordForDecl = Context.addRecordToClass(OID); - assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class"); - DeclContext::lookup_const_result Lookup = - RecordForDecl->lookup(Context, OIVD->getDeclName()); +/// FIXME: We shouldn't need to do this, the containing context should +/// be fixed. +static const ObjCInterfaceDecl *FindIvarInterface(ASTContext &Context, + const ObjCInterfaceDecl *OID, + const ObjCIvarDecl *OIVD, + unsigned &Index) { + const ObjCInterfaceDecl *Super = OID->getSuperClass(); - if (Lookup.first != Lookup.second) { - Found = OID; - return cast<FieldDecl>(*Lookup.first); + // FIXME: The index here is closely tied to how + // ASTContext::getObjCLayout is implemented. This should be fixed to + // get the information from the layout directly. + Index = 0; + for (ObjCInterfaceDecl::ivar_iterator IVI = OID->ivar_begin(), + IVE = OID->ivar_end(); IVI != IVE; ++IVI, ++Index) + if (OIVD == *IVI) + return OID; + + // Also look in synthesized ivars. + for (ObjCInterfaceDecl::prop_iterator I = OID->prop_begin(Context), + E = OID->prop_end(Context); I != E; ++I) { + if (ObjCIvarDecl *Ivar = (*I)->getPropertyIvarDecl()) { + if (OIVD == Ivar) + return OID; + ++Index; + } } - // If lookup failed, try the superclass. - // - // FIXME: This is slow, we shouldn't need to do this. - const ObjCInterfaceDecl *Super = OID->getSuperClass(); - assert(Super && "field decl not found!"); - return LookupFieldDeclForIvar(Context, Super, OIVD, Found); + // Otherwise check in the super class. + if (Super) + return FindIvarInterface(Context, Super, OIVD, Index); + + return 0; } static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM, const ObjCInterfaceDecl *OID, const ObjCImplementationDecl *ID, const ObjCIvarDecl *Ivar) { - assert(!OID->isForwardDecl() && "Invalid interface decl!"); - const ObjCInterfaceDecl *Container; - const FieldDecl *Field = - LookupFieldDeclForIvar(CGM.getContext(), OID, Ivar, Container); - const llvm::StructType *STy = - GetConcreteClassStruct(CGM, Container); - const llvm::StructLayout *Layout = - CGM.getTargetData().getStructLayout(STy); - if (!Field->isBitField()) - return Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Field)) * 8; - - // FIXME. Must be a better way of getting a bitfield base offset. - CodeGenTypes::BitFieldInfo BFI = CGM.getTypes().getBitFieldInfo(Field); - // FIXME: The "field no" for bitfields is something completely - // different; it is the offset in multiples of the base type size! - uint64_t Offset = CGM.getTypes().getLLVMFieldNo(Field); - const llvm::Type *Ty = - CGM.getTypes().ConvertTypeForMemRecursive(Field->getType()); - Offset *= CGM.getTypes().getTargetData().getTypePaddedSizeInBits(Ty); - return Offset + BFI.Begin; + unsigned Index; + const ObjCInterfaceDecl *Container = + FindIvarInterface(CGM.getContext(), OID, Ivar, Index); + assert(Container && "Unable to find ivar container"); + + // If we know have an implementation (and the ivar is in it) then + // look up in the implementation layout. + const ASTRecordLayout *RL; + if (ID && ID->getClassInterface() == Container) + RL = &CGM.getContext().getASTObjCImplementationLayout(ID); + else + RL = &CGM.getContext().getASTObjCInterfaceLayout(Container); + return RL->getFieldOffset(Index); } uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, |