diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-02-03 00:09:52 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-02-03 00:09:52 +0000 |
commit | 45012a7ef5abf1042c893f3f2fa5c23cb5485ea9 (patch) | |
tree | b46917390c26e701aeeafdcd05ccafc5d3fcbbe0 /lib/CodeGen/CGObjCMac.cpp | |
parent | 40a6be686e5d5bb4198f1affda574e8a4b3a7710 (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/CGObjCMac.cpp')
-rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 65 |
1 files changed, 55 insertions, 10 deletions
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 * |