From: Daniel Dunbar Date: Fri, 2 Apr 2010 21:14:02 +0000 (+0000) Subject: IRgen/Obj-C: Eliminate FindIvarInterface, now that ivar's are in the right DeclContex... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e83be1228028f44de76cbad9d908e2dc9e261171;p=clang IRgen/Obj-C: Eliminate FindIvarInterface, now that ivar's are in the right DeclContexts (-2 FIXMEs). We still have an annoying linear scan + hidden dependency on how Obj-C layout is done. - This is also an algorithmic improvement in IRgen for Obj-C, although it probably doesn't matter in practice. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@100228 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index d799162fa4..0838a57241 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -42,41 +42,11 @@ using namespace CodeGen; // don't belong in CGObjCRuntime either so we will live with it for // now. -/// FindIvarInterface - Find the interface containing the ivar. -/// -/// 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) { - // 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; - llvm::SmallVector Ivars; - Context.ShallowCollectObjCIvars(OID, Ivars); - for (unsigned k = 0, e = Ivars.size(); k != e; ++k) { - if (OIVD == Ivars[k]) - return OID; - ++Index; - } - - // Otherwise check in the super class. - if (const ObjCInterfaceDecl *Super = OID->getSuperClass()) - return FindIvarInterface(Context, Super, OIVD, Index); - - return 0; -} - static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM, const ObjCInterfaceDecl *OID, const ObjCImplementationDecl *ID, const ObjCIvarDecl *Ivar) { - unsigned Index; - const ObjCInterfaceDecl *Container = - FindIvarInterface(CGM.getContext(), OID, Ivar, Index); - assert(Container && "Unable to find ivar container"); + const ObjCInterfaceDecl *Container = Ivar->getContainingInterface(); // Check that the Obj-C decl contexts match what we expect. const ObjCContainerDecl *DC = cast(Ivar->getDeclContext()); @@ -98,6 +68,22 @@ static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM, RL = &CGM.getContext().getASTObjCImplementationLayout(ID); else RL = &CGM.getContext().getASTObjCInterfaceLayout(Container); + + // Compute field index. + // + // 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. + unsigned Index = 0; + llvm::SmallVector Ivars; + CGM.getContext().ShallowCollectObjCIvars(Container, Ivars); + for (unsigned k = 0, e = Ivars.size(); k != e; ++k) { + if (Ivar == Ivars[k]) + break; + ++Index; + } + assert(Index != Ivars.size() && "Ivar is not inside container!"); + return RL->getFieldOffset(Index); } @@ -4740,14 +4726,10 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitMethodList(llvm::Twine Name, /// ObjCIvarOffsetVariable - Returns the ivar offset variable for /// the given ivar. -llvm::GlobalVariable * CGObjCNonFragileABIMac::ObjCIvarOffsetVariable( - const ObjCInterfaceDecl *ID, - const ObjCIvarDecl *Ivar) { - // FIXME: We shouldn't need to do this lookup. - unsigned Index; - const ObjCInterfaceDecl *Container = - FindIvarInterface(CGM.getContext(), ID, Ivar, Index); - assert(Container && "Unable to find ivar container!"); +llvm::GlobalVariable * +CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID, + const ObjCIvarDecl *Ivar) { + const ObjCInterfaceDecl *Container = Ivar->getContainingInterface(); std::string Name = "OBJC_IVAR_$_" + Container->getNameAsString() + '.' + Ivar->getNameAsString(); llvm::GlobalVariable *IvarOffsetGV = @@ -4762,10 +4744,10 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::ObjCIvarOffsetVariable( return IvarOffsetGV; } -llvm::Constant * CGObjCNonFragileABIMac::EmitIvarOffsetVar( - const ObjCInterfaceDecl *ID, - const ObjCIvarDecl *Ivar, - unsigned long int Offset) { +llvm::Constant * +CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID, + const ObjCIvarDecl *Ivar, + unsigned long int Offset) { llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar); IvarOffsetGV->setInitializer(llvm::ConstantInt::get(ObjCTypes.LongTy, Offset));