From 9f89f2bc111339ee7fa0df3c2f18e39493b460c4 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Sun, 3 May 2009 12:57:56 +0000 Subject: [PATCH] Add a ComputeIvarBaseOffset overload taking an implementation decl. Only this routine will be suitable for computing the offset of a synthesized ivar. - No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70696 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGObjCMac.cpp | 30 ++++++++++++++++++++---------- lib/CodeGen/CGObjCRuntime.h | 6 ++++++ 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 830b19f57e..1ab4bf1056 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -72,6 +72,7 @@ static const FieldDecl *LookupFieldDeclForIvar(ASTContext &Context, static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM, const ObjCInterfaceDecl *OID, + const ObjCImplementationDecl *ID, const ObjCIvarDecl *Ivar) { assert(!OID->isForwardDecl() && "Invalid interface decl!"); const ObjCInterfaceDecl *Container; @@ -98,7 +99,13 @@ static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM, uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, const ObjCInterfaceDecl *OID, const ObjCIvarDecl *Ivar) { - return LookupFieldBitOffset(CGM, OID, Ivar) / 8; + return LookupFieldBitOffset(CGM, OID, 0, Ivar) / 8; +} + +uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, + const ObjCImplementationDecl *OID, + const ObjCIvarDecl *Ivar) { + return LookupFieldBitOffset(CGM, OID->getClassInterface(), OID, Ivar) / 8; } LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF, @@ -107,10 +114,6 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF, const ObjCIvarDecl *Ivar, unsigned CVRQualifiers, llvm::Value *Offset) { - // We need to compute the bit offset for the bit-field, the offset - // is to the byte. - uint64_t BitOffset = LookupFieldBitOffset(CGF.CGM, OID, Ivar) % 8; - // Compute (type*) ( (char *) BaseValue + Offset) llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); QualType IvarTy = Ivar->getType(); @@ -120,6 +123,13 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF, V = CGF.Builder.CreateBitCast(V, llvm::PointerType::getUnqual(LTy)); if (Ivar->isBitField()) { + // We need to compute the bit offset for the bit-field, the offset + // is to the byte. Note, there is a subtle invariant here: we can + // only call this routine on non-sythesized ivars but we may be + // called for synthesized ivars. However, a synthesized ivar can + // never be a bit-field so this is safe. + uint64_t BitOffset = LookupFieldBitOffset(CGF.CGM, OID, 0, Ivar) % 8; + uint64_t BitFieldSize = Ivar->getBitWidth()->EvaluateAsInt(CGF.getContext()).getZExtValue(); return LValue::MakeBitfield(V, BitOffset, BitFieldSize, @@ -1184,7 +1194,7 @@ private: return "OBJC_CLASS_$_"; } - void GetClassSizeInfo(const ObjCInterfaceDecl *OID, + void GetClassSizeInfo(const ObjCImplementationDecl *OID, uint32_t &InstanceStart, uint32_t &InstanceSize); @@ -4258,14 +4268,14 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData( return GV; } -void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCInterfaceDecl *OID, +void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID, uint32_t &InstanceStart, uint32_t &InstanceSize) { // Find first and last (non-padding) ivars in this interface. // FIXME: Use iterator. llvm::SmallVector OIvars; - GetNamedIvarList(OID, OIvars); + GetNamedIvarList(OID->getClassInterface(), OIvars); if (OIvars.empty()) { InstanceStart = InstanceSize = 0; @@ -4368,7 +4378,7 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { ID->getClassInterface()->getSuperClass()->getNameAsString(); SuperClassGV = GetClassGlobal(ObjCClassName + RootClassName); } - GetClassSizeInfo(ID->getClassInterface(), InstanceStart, InstanceSize); + GetClassSizeInfo(ID, InstanceStart, InstanceSize); CLASS_RO_GV = BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, @@ -4664,7 +4674,7 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList( for (unsigned i = 0, e = OIvars.size(); i != e; ++i) { ObjCIvarDecl *IVD = OIvars[i]; Ivar[0] = EmitIvarOffsetVar(ID->getClassInterface(), IVD, - ComputeIvarBaseOffset(CGM, OID, IVD)); + ComputeIvarBaseOffset(CGM, ID, IVD)); Ivar[1] = GetMethodVarName(IVD->getIdentifier()); Ivar[2] = GetMethodVarType(IVD); const llvm::Type *FieldTy = diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h index fe514111b5..ada449559d 100644 --- a/lib/CodeGen/CGObjCRuntime.h +++ b/lib/CodeGen/CGObjCRuntime.h @@ -70,9 +70,15 @@ protected: /// 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! + /// + /// The latter overload is suitable for computing the offset of a + /// sythesized ivar. uint64_t ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, const ObjCInterfaceDecl *OID, const ObjCIvarDecl *Ivar); + uint64_t ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, + const ObjCImplementationDecl *OID, + const ObjCIvarDecl *Ivar); LValue EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF, const ObjCInterfaceDecl *OID, -- 2.40.0