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 d799162..0838a57 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -42,41 +42,11 @@
// 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<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,
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<ObjCContainerDecl>(Ivar->getDeclContext());
@@ -98,6 +68,22 @@
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<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);
}
@@ -4740,14 +4726,10 @@
/// 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 @@
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));