Add CGObjCRuntime::GetConcreteClassStruct to encapsulate access to the

underlying llvm::StructType for an interface.

llvm-svn: 69796
This commit is contained in:
Daniel Dunbar 2009-04-22 09:39:34 +00:00
parent 66cb01313b
commit 7b4dfc8b78
3 changed files with 24 additions and 38 deletions

View File

@ -735,12 +735,7 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
// Get the size of instances. For runtimes that support late-bound instances // Get the size of instances. For runtimes that support late-bound instances
// this should probably be something different (size just of instance // this should probably be something different (size just of instance
// varaibles in this class, not superclasses?). // varaibles in this class, not superclasses?).
const llvm::Type *ObjTy; const llvm::Type *ObjTy = GetConcreteClassStruct(CGM, ClassDecl);
if (ClassDecl->isForwardDecl())
ObjTy = llvm::StructType::get(NULL, NULL);
else
ObjTy = CGM.getTypes().ConvertType(Context.getObjCInterfaceType(ClassDecl));
int instanceSize = CGM.getTargetData().getTypePaddedSize(ObjTy); int instanceSize = CGM.getTargetData().getTypePaddedSize(ObjTy);
// Collect information about instance variables. // Collect information about instance variables.
@ -1085,9 +1080,7 @@ llvm::Value *CGObjCGNU::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
const ObjCInterfaceDecl *Interface, const ObjCInterfaceDecl *Interface,
const ObjCIvarDecl *Ivar) { const ObjCIvarDecl *Ivar) {
uint64_t Offset = ComputeIvarBaseOffset(CGF.CGM, Interface, Ivar); uint64_t Offset = ComputeIvarBaseOffset(CGF.CGM, Interface, Ivar);
return llvm::ConstantInt::get( return llvm::ConstantInt::get(LongTy, Offset);
CGM.getTypes().ConvertType(CGM.getContext().LongTy),
Offset);
} }
CodeGen::CGObjCRuntime *CodeGen::CreateGNUObjCRuntime(CodeGen::CodeGenModule &CGM){ CodeGen::CGObjCRuntime *CodeGen::CreateGNUObjCRuntime(CodeGen::CodeGenModule &CGM){

View File

@ -33,15 +33,22 @@ using namespace CodeGen;
// don't belong in CGObjCRuntime either so we will live with it for // don't belong in CGObjCRuntime either so we will live with it for
// now. // now.
const llvm::StructType *
CGObjCRuntime::GetConcreteClassStruct(CodeGen::CodeGenModule &CGM,
const ObjCInterfaceDecl *OID) {
assert(!OID->isForwardDecl() && "Invalid interface decl!");
QualType T = CGM.getContext().getObjCInterfaceType(OID);
return cast<llvm::StructType>(CGM.getTypes().ConvertType(T));
}
uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
const ObjCInterfaceDecl *OID, const ObjCInterfaceDecl *OID,
const ObjCIvarDecl *Ivar) { const ObjCIvarDecl *Ivar) {
assert(!OID->isForwardDecl() && "Invalid interface decl!"); assert(!OID->isForwardDecl() && "Invalid interface decl!");
QualType T = CGM.getContext().getObjCInterfaceType(OID); QualType T = CGM.getContext().getObjCInterfaceType(OID);
const llvm::StructType *InterfaceTy = const llvm::StructType *STy = GetConcreteClassStruct(CGM, OID);
cast<llvm::StructType>(CGM.getTypes().ConvertType(T));
const llvm::StructLayout *Layout = const llvm::StructLayout *Layout =
CGM.getTargetData().getStructLayout(InterfaceTy); CGM.getTargetData().getStructLayout(STy);
const FieldDecl *Field = const FieldDecl *Field =
OID->lookupFieldDeclForIvar(CGM.getContext(), Ivar); OID->lookupFieldDeclForIvar(CGM.getContext(), Ivar);
if (!Field->isBitField()) if (!Field->isBitField())
@ -768,11 +775,6 @@ protected:
/// name. The return value has type char *. /// name. The return value has type char *.
llvm::Constant *GetClassName(IdentifierInfo *Ident); llvm::Constant *GetClassName(IdentifierInfo *Ident);
/// GetInterfaceDeclStructLayout - Get layout for ivars of given
/// interface declaration.
const llvm::StructLayout *GetInterfaceDeclStructLayout(
const ObjCInterfaceDecl *ID) const;
/// BuildIvarLayout - Builds ivar layout bitmap for the class /// BuildIvarLayout - Builds ivar layout bitmap for the class
/// implementation for the __strong or __weak case. /// implementation for the __strong or __weak case.
/// ///
@ -1820,12 +1822,7 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
EmitProtocolList("\01L_OBJC_CLASS_PROTOCOLS_" + ID->getNameAsString(), EmitProtocolList("\01L_OBJC_CLASS_PROTOCOLS_" + ID->getNameAsString(),
Interface->protocol_begin(), Interface->protocol_begin(),
Interface->protocol_end()); Interface->protocol_end());
const llvm::Type *InterfaceTy; const llvm::Type *InterfaceTy = GetConcreteClassStruct(CGM, Interface);
if (Interface->isForwardDecl())
InterfaceTy = llvm::StructType::get(NULL, NULL);
else
InterfaceTy =
CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(Interface));
unsigned Flags = eClassFlags_Factory; unsigned Flags = eClassFlags_Factory;
unsigned Size = CGM.getTargetData().getTypePaddedSize(InterfaceTy); unsigned Size = CGM.getTargetData().getTypePaddedSize(InterfaceTy);
@ -2857,17 +2854,6 @@ llvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) {
return getConstantGEP(Entry, 0, 0); return getConstantGEP(Entry, 0, 0);
} }
/// GetInterfaceDeclStructLayout - Get layout for ivars of given
/// interface declaration.
const llvm::StructLayout *CGObjCCommonMac::GetInterfaceDeclStructLayout(
const ObjCInterfaceDecl *OID) const {
assert(!OID->isForwardDecl() && "Invalid interface decl!");
QualType T = CGM.getContext().getObjCInterfaceType(OID);
const llvm::StructType *InterfaceTy =
cast<llvm::StructType>(CGM.getTypes().ConvertType(T));
return CGM.getTargetData().getStructLayout(InterfaceTy);
}
/// GetIvarLayoutName - Returns a unique constant for the given /// GetIvarLayoutName - Returns a unique constant for the given
/// ivar layout bitmap. /// ivar layout bitmap.
llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident, llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
@ -3133,7 +3119,8 @@ llvm::Constant *CGObjCCommonMac::BuildIvarLayout(
SkipIvars.clear(); SkipIvars.clear();
IvarsInfo.clear(); IvarsInfo.clear();
const llvm::StructLayout *Layout = GetInterfaceDeclStructLayout(OI); const llvm::StructLayout *Layout =
CGM.getTargetData().getStructLayout(GetConcreteClassStruct(CGM, OI));
BuildAggrIvarLayout(OI, Layout, 0, RecFields, 0, ForStrongLayout, BuildAggrIvarLayout(OI, Layout, 0, RecFields, 0, ForStrongLayout,
Index, SkIndex, hasUnion); Index, SkIndex, hasUnion);
if (Index == -1) if (Index == -1)

View File

@ -28,6 +28,7 @@ namespace llvm {
class Function; class Function;
class Module; class Module;
class StructLayout; class StructLayout;
class StructType;
class Type; class Type;
class Value; class Value;
} }
@ -65,9 +66,14 @@ protected:
// eventually be folded into other places (the structure layout // eventually be folded into other places (the structure layout
// code). // code).
// Compute an offset to the given ivar, suitable for passing to /// Return the (fixed) LLVM struct type for the interface. This is
// EmitValueForIvarAtOffset. Note that the correct handling of /// only very meaningful for runtimes which use a non-fragile ABI.
// bit-fields is carefully coordinated by these two, use caution! const llvm::StructType * GetConcreteClassStruct(CodeGen::CodeGenModule &CGM,
const ObjCInterfaceDecl *OID);
/// Compute an offset to the given ivar, suitable for passing to
/// EmitValueForIvarAtOffset. Note that the correct handling of
/// bit-fields is carefully coordinated by these two, use caution!
uint64_t ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, uint64_t ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
const ObjCInterfaceDecl *OID, const ObjCInterfaceDecl *OID,
const ObjCIvarDecl *Ivar); const ObjCIvarDecl *Ivar);