From 84ad77a8f83121713ea69d8002d1fd19565f87ab Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Wed, 22 Apr 2009 09:39:34 +0000 Subject: [PATCH] Add CGObjCRuntime::GetConcreteClassStruct to encapsulate access to the underlying llvm::StructType for an interface. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69796 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGObjCGNU.cpp | 11 ++--------- lib/CodeGen/CGObjCMac.cpp | 39 +++++++++++++------------------------ lib/CodeGen/CGObjCRuntime.h | 12 +++++++++--- 3 files changed, 24 insertions(+), 38 deletions(-) diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index 9c3449f500..2cf73b6483 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -735,12 +735,7 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) { // Get the size of instances. For runtimes that support late-bound instances // this should probably be something different (size just of instance // varaibles in this class, not superclasses?). - const llvm::Type *ObjTy; - - if (ClassDecl->isForwardDecl()) - ObjTy = llvm::StructType::get(NULL, NULL); - else - ObjTy = CGM.getTypes().ConvertType(Context.getObjCInterfaceType(ClassDecl)); + const llvm::Type *ObjTy = GetConcreteClassStruct(CGM, ClassDecl); int instanceSize = CGM.getTargetData().getTypePaddedSize(ObjTy); // Collect information about instance variables. @@ -1085,9 +1080,7 @@ llvm::Value *CGObjCGNU::EmitIvarOffset(CodeGen::CodeGenFunction &CGF, const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar) { uint64_t Offset = ComputeIvarBaseOffset(CGF.CGM, Interface, Ivar); - return llvm::ConstantInt::get( - CGM.getTypes().ConvertType(CGM.getContext().LongTy), - Offset); + return llvm::ConstantInt::get(LongTy, Offset); } CodeGen::CGObjCRuntime *CodeGen::CreateGNUObjCRuntime(CodeGen::CodeGenModule &CGM){ diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index dc66fa46b1..7b7c2fbd05 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -33,15 +33,22 @@ using namespace CodeGen; // don't belong in CGObjCRuntime either so we will live with it for // 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(CGM.getTypes().ConvertType(T)); +} + uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, const ObjCInterfaceDecl *OID, const ObjCIvarDecl *Ivar) { assert(!OID->isForwardDecl() && "Invalid interface decl!"); QualType T = CGM.getContext().getObjCInterfaceType(OID); - const llvm::StructType *InterfaceTy = - cast(CGM.getTypes().ConvertType(T)); + const llvm::StructType *STy = GetConcreteClassStruct(CGM, OID); const llvm::StructLayout *Layout = - CGM.getTargetData().getStructLayout(InterfaceTy); + CGM.getTargetData().getStructLayout(STy); const FieldDecl *Field = OID->lookupFieldDeclForIvar(CGM.getContext(), Ivar); if (!Field->isBitField()) @@ -768,11 +775,6 @@ protected: /// name. The return value has type char *. 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 /// implementation for the __strong or __weak case. /// @@ -1820,12 +1822,7 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) { EmitProtocolList("\01L_OBJC_CLASS_PROTOCOLS_" + ID->getNameAsString(), Interface->protocol_begin(), Interface->protocol_end()); - const llvm::Type *InterfaceTy; - if (Interface->isForwardDecl()) - InterfaceTy = llvm::StructType::get(NULL, NULL); - else - InterfaceTy = - CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(Interface)); + const llvm::Type *InterfaceTy = GetConcreteClassStruct(CGM, Interface); unsigned Flags = eClassFlags_Factory; unsigned Size = CGM.getTargetData().getTypePaddedSize(InterfaceTy); @@ -2857,17 +2854,6 @@ llvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) { 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(CGM.getTypes().ConvertType(T)); - return CGM.getTargetData().getStructLayout(InterfaceTy); -} - /// GetIvarLayoutName - Returns a unique constant for the given /// ivar layout bitmap. llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident, @@ -3133,7 +3119,8 @@ llvm::Constant *CGObjCCommonMac::BuildIvarLayout( SkipIvars.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, Index, SkIndex, hasUnion); if (Index == -1) diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h index 28ee0f4e9f..c275a4d720 100644 --- a/lib/CodeGen/CGObjCRuntime.h +++ b/lib/CodeGen/CGObjCRuntime.h @@ -28,6 +28,7 @@ namespace llvm { class Function; class Module; class StructLayout; + class StructType; class Type; class Value; } @@ -65,9 +66,14 @@ protected: // eventually be folded into other places (the structure layout // code). - // 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! + /// Return the (fixed) LLVM struct type for the interface. This is + /// only very meaningful for runtimes which use a non-fragile ABI. + 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, const ObjCInterfaceDecl *OID, const ObjCIvarDecl *Ivar); -- 2.40.0