diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-01-28 01:05:23 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-01-28 01:05:23 +0000 |
commit | 1bf0afbb08a23412d1607505c092a537f305d8c7 (patch) | |
tree | 01611fe8373c924ad5848a404e97d6337509a9ec /lib/CodeGen/CGObjCMac.cpp | |
parent | 75368893339d89f6523c312b0a0eb23d438b6dff (diff) |
Generation of ivar-offset symbols in objc2's non-fragile abi.
Changed section names for meta-data (to match current gcc).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63163 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGObjCMac.cpp')
-rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 72 |
1 files changed, 59 insertions, 13 deletions
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index eb26a95807..ad8bba4aaf 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -570,6 +570,10 @@ private: /// IvarListnfABIPtrTy. llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID); + llvm::Constant *EmitIvarOffsetVar(const ObjCImplementationDecl *ID, + const FieldDecl *Field, + unsigned long int offset); + public: CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm); // FIXME. All stubs for now! @@ -3161,7 +3165,7 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer( } // FIXME. Section may always be .data Values[ 5] = EmitMethodList(MethodListName, - ".section __DATA,__data,regular,no_dead_strip", Methods); + "__DATA, __objc_const", Methods); Values[ 6] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); if (flags & CLS_META) Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy); @@ -3179,7 +3183,7 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer( std::string("\01l_OBJC_METACLASS_RO_$_")+ClassName : std::string("\01l_OBJC_CLASS_RO_$_")+ClassName, &CGM.getModule()); - CLASS_RO_GV->setSection(".section __DATA,__data,regular,no_dead_strip"); + CLASS_RO_GV->setSection("__DATA, __objc_const"); UsedGlobals.push_back(CLASS_RO_GV); return CLASS_RO_GV; @@ -3220,7 +3224,7 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData( Init, ClassName, &CGM.getModule()); - GV->setSection(".section __DATA,__data,regular,no_dead_strip"); + GV->setSection("__DATA, __objc_const"); UsedGlobals.push_back(GV); // FIXME! why? GV->setAlignment(32); @@ -3424,7 +3428,7 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) } Values[2] = EmitMethodList(MethodListName, - ".section __DATA,__data,regular,no_dead_strip", + "__DATA, __objc_const", Methods); MethodListName = Prefix; @@ -3438,7 +3442,7 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) } Values[3] = EmitMethodList(MethodListName, - ".section __DATA,__data,regular,no_dead_strip", + "__DATA, __objc_const", Methods); Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); @@ -3453,7 +3457,7 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) Init, ExtCatName, &CGM.getModule()); - GCATV->setSection(".section __DATA,__data,regular,no_dead_strip"); + GCATV->setSection("__DATA, __objc_const"); UsedGlobals.push_back(GCATV); DefinedCategories.push_back(GCATV); } @@ -3515,6 +3519,38 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitMethodList( ObjCTypes.MethodListnfABIPtrTy); } +llvm::Constant * CGObjCNonFragileABIMac::EmitIvarOffsetVar( + const ObjCImplementationDecl *ID, + const FieldDecl *Field, + unsigned long int Offset) { + + std::string ExternalName("\01_OBJC_IVAR_$_" + ID->getNameAsString() + '.' + + Field->getNameAsString()); + llvm::Constant *Init = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset); + + llvm::GlobalVariable *IvarOffsetGV = + CGM.getModule().getGlobalVariable(ExternalName); + if (IvarOffsetGV) { + // ivar offset symbol already built due to user code referencing it. + IvarOffsetGV->setInitializer(Init); + return IvarOffsetGV; + } + + IvarOffsetGV = + new llvm::GlobalVariable(Init->getType(), + false, + llvm::GlobalValue::ExternalLinkage, + Init, + ExternalName, + &CGM.getModule()); + IvarOffsetGV->setSection("__DATA, __objc_const"); + UsedGlobals.push_back(IvarOffsetGV); + + return llvm::ConstantExpr::getBitCast( + IvarOffsetGV, + llvm::PointerType::getUnqual(ObjCTypes.LongTy)); +} + /// EmitIvarList - Emit the ivar list for the given /// implementation. If ForClass is true the list of class ivars /// (i.e. metaclass ivars) is emitted, otherwise the list of @@ -3541,13 +3577,23 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList( const ObjCInterfaceDecl *OID = ID->getClassInterface(); assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface"); - for(ObjCInterfaceDecl::ivar_iterator i = OID->ivar_begin(), - e = OID->ivar_end(); i != e; ++i) { + // FIXME. Consolidate this with similar code in GenerateClass. + const llvm::Type *InterfaceTy = + CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType( + const_cast<ObjCInterfaceDecl*>(OID))); + + const llvm::StructLayout *Layout = + CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceTy)); + int countSuperClassIvars = countInheritedIvars(OID->getSuperClass()); + const RecordDecl *RD = CGM.getContext().addRecordToClass(OID); + RecordDecl::field_iterator i = RD->field_begin(); + while (countSuperClassIvars-- > 0) + ++i; + for (RecordDecl::field_iterator e = RD->field_end(); i != e; ++i) { FieldDecl *Field = *i; - // FIXME. Put the offset symbol address after code gen. - // for non-fragile ivar access is in. - Ivar[0] = llvm::Constant::getNullValue( - llvm::PointerType::getUnqual(ObjCTypes.LongTy)); + unsigned long offset = Layout->getElementOffset(CGM.getTypes(). + getLLVMFieldNo(Field)); + Ivar[0] = EmitIvarOffsetVar(ID, Field, offset); if (Field->getIdentifier()) Ivar[1] = GetMethodVarName(Field->getIdentifier()); else @@ -3589,7 +3635,7 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList( Prefix + OID->getNameAsString(), &CGM.getModule()); - GV->setSection(".section __DATA,__data,regular,no_dead_strip"); + GV->setSection("__DATA, __objc_const"); UsedGlobals.push_back(GV); return llvm::ConstantExpr::getBitCast(GV, |