aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-02-03 00:09:52 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-02-03 00:09:52 +0000
commit45012a7ef5abf1042c893f3f2fa5c23cb5485ea9 (patch)
treeb46917390c26e701aeeafdcd05ccafc5d3fcbbe0 /lib/CodeGen
parent40a6be686e5d5bb4198f1affda574e8a4b3a7710 (diff)
objc2's ir-gen for nonfragile ivar access.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63578 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/CGExpr.cpp13
-rw-r--r--lib/CodeGen/CGObjC.cpp11
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp2
-rw-r--r--lib/CodeGen/CGObjCMac.cpp65
-rw-r--r--lib/CodeGen/CGObjCRuntime.h1
-rw-r--r--lib/CodeGen/CodeGenFunction.h7
6 files changed, 83 insertions, 16 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 2c16c1940b..4f8bd46b52 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -1020,7 +1020,8 @@ llvm::Value *CodeGenFunction::EmitIvarOffset(ObjCInterfaceDecl *Interface,
Offset);
}
-LValue CodeGenFunction::EmitLValueForIvar(llvm::Value *BaseValue,
+LValue CodeGenFunction::EmitLValueForIvar(QualType ObjectTy,
+ llvm::Value *BaseValue,
const ObjCIvarDecl *Ivar,
const FieldDecl *Field,
unsigned CVRQualifiers) {
@@ -1035,6 +1036,7 @@ LValue CodeGenFunction::EmitLValueForIvar(llvm::Value *BaseValue,
CVRQualifiers, Index);
}
llvm::Value *V = CGM.getObjCRuntime().EmitObjCValueForIvar(*this,
+ ObjectTy,
BaseValue, Ivar, Field, CVRQualifiers);
LValue LV = LValue::MakeAddr(V, Ivar->getType().getCVRQualifiers()|CVRQualifiers);
SetVarDeclObjCAttribute(getContext(), Ivar, Ivar->getType(), LV);
@@ -1047,19 +1049,22 @@ LValue CodeGenFunction::EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E) {
llvm::Value *BaseValue = 0;
const Expr *BaseExpr = E->getBase();
unsigned CVRQualifiers = 0;
+ QualType ObjectTy;
if (E->isArrow()) {
BaseValue = EmitScalarExpr(BaseExpr);
const PointerType *PTy =
cast<PointerType>(getContext().getCanonicalType(BaseExpr->getType()));
- CVRQualifiers = PTy->getPointeeType().getCVRQualifiers();
+ ObjectTy = PTy->getPointeeType();
+ CVRQualifiers = ObjectTy.getCVRQualifiers();
} else {
LValue BaseLV = EmitLValue(BaseExpr);
// FIXME: this isn't right for bitfields.
BaseValue = BaseLV.getAddress();
- CVRQualifiers = BaseExpr->getType().getCVRQualifiers();
+ ObjectTy = BaseExpr->getType();
+ CVRQualifiers = ObjectTy.getCVRQualifiers();
}
- return EmitLValueForIvar(BaseValue, E->getDecl(),
+ return EmitLValueForIvar(ObjectTy, BaseValue, E->getDecl(),
getContext().getFieldDecl(E), CVRQualifiers);
}
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index 9dc45efc68..3ebee12f0d 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -194,7 +194,8 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
} else {
FieldDecl *Field =
IMP->getClassInterface()->lookupFieldDeclForIvar(getContext(), Ivar);
- LValue LV = EmitLValueForIvar(LoadObjCSelf(), Ivar, Field, 0);
+ LValue LV = EmitLValueForIvar(TypeOfSelfObject(),
+ LoadObjCSelf(), Ivar, Field, 0);
if (hasAggregateLLVMType(Ivar->getType())) {
EmitAggregateCopy(ReturnValue, LV.getAddress(), Ivar->getType());
}
@@ -294,6 +295,14 @@ llvm::Value *CodeGenFunction::LoadObjCSelf() {
return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self");
}
+QualType CodeGenFunction::TypeOfSelfObject() {
+ const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
+ ImplicitParamDecl *selfDecl = OMD->getSelfDecl();
+ const PointerType *PTy =
+ cast<PointerType>(getContext().getCanonicalType(selfDecl->getType()));
+ return PTy->getPointeeType();
+}
+
RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp) {
// FIXME: Split it into two separate routines.
if (const ObjCPropertyRefExpr *E = dyn_cast<ObjCPropertyRefExpr>(Exp)) {
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index 1ce28bf91d..d3b57b0e9a 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -141,6 +141,7 @@ public:
virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
llvm::Value *src, llvm::Value *dest);
virtual llvm::Value *EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
+ QualType ObjectTy,
llvm::Value *BaseValue,
const ObjCIvarDecl *Ivar,
const FieldDecl *Field,
@@ -1037,6 +1038,7 @@ void CGObjCGNU::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
}
llvm::Value *CGObjCGNU::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
+ QualType ObjectTy,
llvm::Value *BaseValue,
const ObjCIvarDecl *Ivar,
const FieldDecl *Field,
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index a577bd03cb..2b1d9fff0b 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -551,6 +551,7 @@ private:
llvm::Value *src, llvm::Value *dest);
virtual llvm::Value *EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
+ QualType ObjectTy,
llvm::Value *BaseValue,
const ObjCIvarDecl *Ivar,
const FieldDecl *Field,
@@ -676,12 +677,11 @@ public:
llvm::Value *src, llvm::Value *dest)
{ return; }
virtual llvm::Value *EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
+ QualType ObjectTy,
llvm::Value *BaseValue,
const ObjCIvarDecl *Ivar,
const FieldDecl *Field,
- unsigned CVRQualifiers)
- { return 0; }
-
+ unsigned CVRQualifiers);
};
} // end anonymous namespace
@@ -2114,6 +2114,7 @@ void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
/// EmitObjCValueForIvar - Code Gen for ivar reference.
///
llvm::Value *CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
+ QualType ObjectTy,
llvm::Value *BaseValue,
const ObjCIvarDecl *Ivar,
const FieldDecl *Field,
@@ -3755,15 +3756,16 @@ llvm::Constant * CGObjCNonFragileABIMac::EmitIvarOffsetVar(
std::string ExternalName("\01_OBJC_IVAR_$_" + ID->getNameAsString() + '.'
+ Ivar->getNameAsString());
- llvm::Constant *Init = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset);
+ llvm::Constant *Init = llvm::ConstantInt::get(ObjCTypes.LongTy, Offset);
llvm::GlobalVariable *IvarOffsetGV =
CGM.getModule().getGlobalVariable(ExternalName);
if (IvarOffsetGV) {
// ivar offset symbol already built due to user code referencing it.
IvarOffsetGV->setAlignment(
- CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.Int8PtrTy));
+ CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.LongTy));
IvarOffsetGV->setInitializer(Init);
+ IvarOffsetGV->setSection("__DATA, __objc_const");
UsedGlobals.push_back(IvarOffsetGV);
return IvarOffsetGV;
}
@@ -3776,7 +3778,7 @@ llvm::Constant * CGObjCNonFragileABIMac::EmitIvarOffsetVar(
ExternalName,
&CGM.getModule());
IvarOffsetGV->setAlignment(
- CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.Int8PtrTy));
+ CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.LongTy));
// @private and @package have hidden visibility.
bool globalVisibility = (Ivar->getAccessControl() == ObjCIvarDecl::Public ||
Ivar->getAccessControl() == ObjCIvarDecl::Protected);
@@ -3789,10 +3791,7 @@ llvm::Constant * CGObjCNonFragileABIMac::EmitIvarOffsetVar(
IvarOffsetGV->setSection("__DATA, __objc_const");
UsedGlobals.push_back(IvarOffsetGV);
-
- return llvm::ConstantExpr::getBitCast(
- IvarOffsetGV,
- llvm::PointerType::getUnqual(ObjCTypes.LongTy));
+ return IvarOffsetGV;
}
/// EmitIvarList - Emit the ivar list for the given
@@ -4094,6 +4093,52 @@ CGObjCNonFragileABIMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc);
}
+
+/// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference.
+/// This code gen. amounts to generating code for:
+/// @code
+/// (type *)((char *)base + _OBJC_IVAR_$_.ivar;
+/// @encode
+///
+llvm::Value *CGObjCNonFragileABIMac::EmitObjCValueForIvar(
+ CodeGen::CodeGenFunction &CGF,
+ QualType ObjectTy,
+ llvm::Value *BaseValue,
+ const ObjCIvarDecl *Ivar,
+ const FieldDecl *Field,
+ unsigned CVRQualifiers) {
+ 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());
+ // (char *) BaseValue
+ llvm::Value *V = CGF.Builder.CreateBitCast(BaseValue,
+ ObjCTypes.Int8PtrTy);
+ llvm::Value *Offset = CGF.Builder.CreateLoad(IvarOffsetGV);
+ // (char*)BaseValue + Offset_symbol
+ V = CGF.Builder.CreateGEP(V, Offset, "add.ptr");
+ // (type *)((char*)BaseValue + Offset_symbol)
+ const llvm::Type *IvarTy =
+ CGM.getTypes().ConvertType(Ivar->getType());
+ llvm::Type *ptrIvarTy = llvm::PointerType::getUnqual(IvarTy);
+ V = CGF.Builder.CreateBitCast(V, ptrIvarTy);
+ return V;
+}
+
/* *** */
CodeGen::CGObjCRuntime *
diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h
index ded1db2c0b..ade77af156 100644
--- a/lib/CodeGen/CGObjCRuntime.h
+++ b/lib/CodeGen/CGObjCRuntime.h
@@ -158,6 +158,7 @@ public:
llvm::Value *src, llvm::Value *dest) = 0;
virtual llvm::Value *EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
+ QualType ObjectTy,
llvm::Value *BaseValue,
const ObjCIvarDecl *Ivar,
const FieldDecl *Field,
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 9033a65be2..75353a7d98 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -233,6 +233,10 @@ public:
/// LoadObjCSelf - Load the value of self. This function is only
/// valid while generating code for an Objective-C method.
llvm::Value *LoadObjCSelf();
+
+ /// TypeOfSelfObject
+ /// Return type of object that this self represents.
+ QualType TypeOfSelfObject();
/// isObjCPointerType - Return true if the specificed AST type will map onto
/// some Objective-C pointer type.
@@ -521,7 +525,8 @@ public:
const ObjCIvarDecl *Ivar);
LValue EmitLValueForField(llvm::Value* Base, FieldDecl* Field,
bool isUnion, unsigned CVRQualifiers);
- LValue EmitLValueForIvar(llvm::Value* Base, const ObjCIvarDecl *Ivar,
+ LValue EmitLValueForIvar(QualType ObjectTy,
+ llvm::Value* Base, const ObjCIvarDecl *Ivar,
const FieldDecl *Field,
unsigned CVRQualifiers);