aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-05-03 12:57:56 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-05-03 12:57:56 +0000
commit9f89f2bc111339ee7fa0df3c2f18e39493b460c4 (patch)
treec14f1eabccf0ac502e77fc4c0479e0a9efe08cb4 /lib/CodeGen
parentd8fd6ff0ea47ba63f836d0f4e6a1bee49863f64a (diff)
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
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/CGObjCMac.cpp30
-rw-r--r--lib/CodeGen/CGObjCRuntime.h6
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<ObjCIvarDecl*, 16> 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,