aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGObjCMac.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-02-10 20:21:06 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-02-10 20:21:06 +0000
commited157d3952637afe0ec38bf850b4d025b9a701ac (patch)
tree8ce793a18690a679da8e46ff320c2b6b73e015e0 /lib/CodeGen/CGObjCMac.cpp
parent071e4da10b07ca5278a7ce9dcabd853e0d57e5a4 (diff)
Generate ir for ivar offset. This will pass
type-nsobject-attribute.m in the dejagnu test suite in the nonfragile abi mode. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64233 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGObjCMac.cpp')
-rw-r--r--lib/CodeGen/CGObjCMac.cpp65
1 files changed, 42 insertions, 23 deletions
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 43da911fc6..0e26379f62 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -633,7 +633,7 @@ private:
/// IvarListnfABIPtrTy.
llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID);
- llvm::Constant *EmitIvarOffsetVar(const ObjCImplementationDecl *ID,
+ llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
const ObjCIvarDecl *Ivar,
unsigned long int offset);
@@ -673,6 +673,12 @@ private:
llvm::Value *EmitMetaClassRef(CGBuilderTy &Builder,
const ObjCInterfaceDecl *ID);
+ /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
+ /// the given ivar.
+ ///
+ llvm::GlobalVariable * ObjCIvarOffsetVariable(std::string &Name,
+ const NamedDecl *IDName,
+ const ObjCIvarDecl *Ivar);
public:
CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
@@ -746,7 +752,6 @@ public:
virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
ObjCInterfaceDecl *Interface,
const ObjCIvarDecl *Ivar);
- virtual bool LateBoundIVars() const { return true; }
};
} // end anonymous namespace
@@ -3907,11 +3912,34 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitMethodList(
ObjCTypes.MethodListnfABIPtrTy);
}
+/// ObjCIvarOffsetVariable - Returns the ivar offset variable for
+/// the given ivar.
+///
+llvm::GlobalVariable * CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(
+ std::string &Name,
+ const NamedDecl *IDName,
+ const ObjCIvarDecl *Ivar) {
+ Name += "\01_OBJC_IVAR_$_" + IDName->getNameAsString() + '.'
+ + Ivar->getNameAsString();
+ llvm::GlobalVariable *IvarOffsetGV =
+ CGM.getModule().getGlobalVariable(Name);
+ if (!IvarOffsetGV)
+ IvarOffsetGV =
+ new llvm::GlobalVariable(ObjCTypes.LongTy,
+ false,
+ llvm::GlobalValue::ExternalLinkage,
+ 0,
+ Name,
+ &CGM.getModule());
+ return IvarOffsetGV;
+}
+
llvm::Constant * CGObjCNonFragileABIMac::EmitIvarOffsetVar(
- const ObjCImplementationDecl *ID,
+ const ObjCInterfaceDecl *ID,
const ObjCIvarDecl *Ivar,
unsigned long int Offset) {
+ assert(ID && "EmitIvarOffsetVar - null interface decl.");
std::string ExternalName("\01_OBJC_IVAR_$_" + ID->getNameAsString() + '.'
+ Ivar->getNameAsString());
llvm::Constant *Init = llvm::ConstantInt::get(ObjCTypes.LongTy, Offset);
@@ -3943,9 +3971,8 @@ llvm::Constant * CGObjCNonFragileABIMac::EmitIvarOffsetVar(
if (!globalVisibility)
IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
else
- if (const ObjCInterfaceDecl *OID = ID->getClassInterface())
- if (IsClassHidden(OID))
- IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
+ if (IsClassHidden(ID))
+ IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
IvarOffsetGV->setSection("__DATA, __objc_const");
UsedGlobals.push_back(IvarOffsetGV);
@@ -3994,7 +4021,7 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
unsigned long offset = Layout->getElementOffset(CGM.getTypes().
getLLVMFieldNo(Field));
const ObjCIvarDecl *ivarDecl = *I++;
- Ivar[0] = EmitIvarOffsetVar(ID, ivarDecl, offset);
+ Ivar[0] = EmitIvarOffsetVar(ID->getClassInterface(), ivarDecl, offset);
if (Field->getIdentifier())
Ivar[1] = GetMethodVarName(Field->getIdentifier());
else
@@ -4268,21 +4295,9 @@ LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
assert(ObjectTy->isObjCInterfaceType() &&
"CGObjCNonFragileABIMac::EmitObjCValueForIvar");
NamedDecl *ID = ObjectTy->getAsObjCInterfaceType()->getDecl();
- // NOTE. This name must match one in EmitIvarOffsetVar.
- // FIXME. Consolidate into one naming routine.
- std::string ExternalName("\01_OBJC_IVAR_$_" + ID->getNameAsString() + '.'
- + Ivar->getNameAsString());
-
- llvm::GlobalVariable *IvarOffsetGV =
- CGM.getModule().getGlobalVariable(ExternalName);
- if (!IvarOffsetGV)
- IvarOffsetGV =
- new llvm::GlobalVariable(ObjCTypes.LongTy,
- false,
- llvm::GlobalValue::ExternalLinkage,
- 0,
- ExternalName,
- &CGM.getModule());
+ std::string ExternalName;
+ llvm::GlobalVariable *IvarOffsetGV =
+ ObjCIvarOffsetVariable(ExternalName, ID, Ivar);
// (char *) BaseValue
llvm::Value *V = CGF.Builder.CreateBitCast(BaseValue,
@@ -4310,7 +4325,11 @@ llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset(
CodeGen::CodeGenFunction &CGF,
ObjCInterfaceDecl *Interface,
const ObjCIvarDecl *Ivar) {
- return 0;
+ std::string ExternalName;
+ llvm::GlobalVariable *IvarOffsetGV =
+ ObjCIvarOffsetVariable(ExternalName, Interface, Ivar);
+
+ return CGF.Builder.CreateLoad(IvarOffsetGV, false, "ivar");
}
CodeGen::RValue CGObjCNonFragileABIMac::EmitMessageSend(