aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGObjCMac.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-01-28 01:05:23 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-01-28 01:05:23 +0000
commit1bf0afbb08a23412d1607505c092a537f305d8c7 (patch)
tree01611fe8373c924ad5848a404e97d6337509a9ec /lib/CodeGen/CGObjCMac.cpp
parent75368893339d89f6523c312b0a0eb23d438b6dff (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.cpp72
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,