зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
27a961a6ad
Коммит
e83be12280
|
@ -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));
|
||||||
|
|
Загрузка…
Ссылка в новой задаче