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
This commit is contained in:
Daniel Dunbar 2010-04-02 21:14:02 +00:00
Родитель 27a961a6ad
Коммит e83be12280
1 изменённых файлов: 25 добавлений и 43 удалений

Просмотреть файл

@ -42,41 +42,11 @@ using namespace CodeGen;
// don't belong in CGObjCRuntime either so we will live with it for // don't belong in CGObjCRuntime either so we will live with it for
// now. // 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<ObjCIvarDecl*, 16> 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, static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM,
const ObjCInterfaceDecl *OID, const ObjCInterfaceDecl *OID,
const ObjCImplementationDecl *ID, const ObjCImplementationDecl *ID,
const ObjCIvarDecl *Ivar) { const ObjCIvarDecl *Ivar) {
unsigned Index; const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
const ObjCInterfaceDecl *Container =
FindIvarInterface(CGM.getContext(), OID, Ivar, Index);
assert(Container && "Unable to find ivar container");
// Check that the Obj-C decl contexts match what we expect. // Check that the Obj-C decl contexts match what we expect.
const ObjCContainerDecl *DC = cast<ObjCContainerDecl>(Ivar->getDeclContext()); const ObjCContainerDecl *DC = cast<ObjCContainerDecl>(Ivar->getDeclContext());
@ -98,6 +68,22 @@ static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM,
RL = &CGM.getContext().getASTObjCImplementationLayout(ID); RL = &CGM.getContext().getASTObjCImplementationLayout(ID);
else else
RL = &CGM.getContext().getASTObjCInterfaceLayout(Container); 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<ObjCIvarDecl*, 16> 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); return RL->getFieldOffset(Index);
} }
@ -4740,14 +4726,10 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitMethodList(llvm::Twine Name,
/// ObjCIvarOffsetVariable - Returns the ivar offset variable for /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
/// the given ivar. /// the given ivar.
llvm::GlobalVariable * CGObjCNonFragileABIMac::ObjCIvarOffsetVariable( llvm::GlobalVariable *
const ObjCInterfaceDecl *ID, CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
const ObjCIvarDecl *Ivar) { const ObjCIvarDecl *Ivar) {
// FIXME: We shouldn't need to do this lookup. const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
unsigned Index;
const ObjCInterfaceDecl *Container =
FindIvarInterface(CGM.getContext(), ID, Ivar, Index);
assert(Container && "Unable to find ivar container!");
std::string Name = "OBJC_IVAR_$_" + Container->getNameAsString() + std::string Name = "OBJC_IVAR_$_" + Container->getNameAsString() +
'.' + Ivar->getNameAsString(); '.' + Ivar->getNameAsString();
llvm::GlobalVariable *IvarOffsetGV = llvm::GlobalVariable *IvarOffsetGV =
@ -4762,10 +4744,10 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(
return IvarOffsetGV; return IvarOffsetGV;
} }
llvm::Constant * CGObjCNonFragileABIMac::EmitIvarOffsetVar( llvm::Constant *
const ObjCInterfaceDecl *ID, CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
const ObjCIvarDecl *Ivar, const ObjCIvarDecl *Ivar,
unsigned long int Offset) { unsigned long int Offset) {
llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar); llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
IvarOffsetGV->setInitializer(llvm::ConstantInt::get(ObjCTypes.LongTy, IvarOffsetGV->setInitializer(llvm::ConstantInt::get(ObjCTypes.LongTy,
Offset)); Offset));