ivar meta-data generation for nonfragile-abi.

Still more work to do in this area.

llvm-svn: 63126
This commit is contained in:
Fariborz Jahanian 2009-01-27 19:38:51 +00:00
parent 2ad3ff0bd6
commit 7415caa3d4
2 changed files with 89 additions and 2 deletions

View File

@ -927,9 +927,11 @@ public:
/// ObjCImplementationDecl - Represents a class definition - this is where
/// method definitions are specified. For example:
///
/// @code
/// @implementation MyClass
/// - (void)myMethod { /* do something */ }
/// @end
/// @endcode
///
/// Typically, instance variables are specified in the class interface,
/// *not* in the implementation. Nevertheless (for legacy reasons), we

View File

@ -562,7 +562,13 @@ private:
/// implementation. The return value has type MethodListnfABITy.
llvm::Constant *EmitMethodList(const std::string &Name,
const char *Section,
const ConstantVector &Methods);
const ConstantVector &Methods);
/// 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
/// interface ivars will be emitted. The return value has type
/// IvarListnfABIPtrTy.
llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID);
public:
CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
@ -3157,7 +3163,10 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
Values[ 5] = EmitMethodList(MethodListName,
".section __DATA,__data,regular,no_dead_strip", Methods);
Values[ 6] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
if (flags & CLS_META)
Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
else
Values[ 7] = EmitIvarList(ID);
Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy,
@ -3505,6 +3514,82 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitMethodList(
return llvm::ConstantExpr::getBitCast(GV,
ObjCTypes.MethodListnfABIPtrTy);
}
/// 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
/// interface ivars will be emitted. The return value has type
/// IvarListnfABIPtrTy.
/// struct _ivar_t {
/// unsigned long int *offset; // pointer to ivar offset location
/// char *name;
/// char *type;
/// uint32_t alignment;
/// uint32_t size;
/// }
/// struct _ivar_list_t {
/// uint32 entsize; // sizeof(struct _ivar_t)
/// uint32 count;
/// struct _iver_t list[count];
/// }
///
llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
const ObjCImplementationDecl *ID) {
std::vector<llvm::Constant*> Ivars, Ivar(5);
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) {
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));
if (Field->getIdentifier())
Ivar[1] = GetMethodVarName(Field->getIdentifier());
else
Ivar[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
std::string TypeStr;
CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
Ivar[2] = GetMethodVarType(TypeStr);
const llvm::Type *FieldTy =
CGM.getTypes().ConvertTypeForMem(Field->getType());
unsigned Size = CGM.getTargetData().getTypePaddedSize(FieldTy);
unsigned Align = CGM.getContext().getPreferredTypeAlign(
Field->getType().getTypePtr()) >> 3;
Align = llvm::Log2_32(Align);
Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align);
Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar));
}
// Return null for empty list.
if (Ivars.empty())
return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
std::vector<llvm::Constant*> Values(3);
unsigned Size = CGM.getTargetData().getTypePaddedSize(ObjCTypes.IvarnfABITy);
Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarnfABITy,
Ivars.size());
Values[2] = llvm::ConstantArray::get(AT, Ivars);
llvm::Constant *Init = llvm::ConstantStruct::get(Values);
const char *Prefix = "\01l_OBJC_$_INSTANCE_VARIABLES_";
llvm::GlobalVariable *GV =
new llvm::GlobalVariable(Init->getType(), false,
llvm::GlobalValue::InternalLinkage,
Init,
Prefix + OID->getNameAsString(),
&CGM.getModule());
GV->setSection(".section __DATA,__data,regular,no_dead_strip");
UsedGlobals.push_back(GV);
return llvm::ConstantExpr::getBitCast(GV,
ObjCTypes.IvarListnfABIPtrTy);
}
/* *** */
CodeGen::CGObjCRuntime *