summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2012-11-06 22:15:52 +0000
committerEli Friedman <eli.friedman@gmail.com>2012-11-06 22:15:52 +0000
commite5b4666d9b86ea30b90b599691e75d380f84ddd6 (patch)
tree6870f7d11a491a85a3d30aa68609b432a3f285c6
parent03c60765c7607cbfb4e1e8593028824dab13ad54 (diff)
downloadclang-e5b4666d9b86ea30b90b599691e75d380f84ddd6.tar.gz
clang-e5b4666d9b86ea30b90b599691e75d380f84ddd6.tar.bz2
clang-e5b4666d9b86ea30b90b599691e75d380f84ddd6.tar.xz
Back out 167431+167437+167487; I didn't realize how incomplete our test
coverage of this code is. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@167495 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp9
-rw-r--r--lib/CodeGen/CGObjCMac.cpp235
-rw-r--r--lib/CodeGen/CGObjCRuntime.cpp20
-rw-r--r--lib/CodeGen/CGObjCRuntime.h12
4 files changed, 141 insertions, 135 deletions
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index c181034d51..99abf0545b 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -2083,7 +2083,7 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
Context.getObjCEncodingForType(IVD->getType(), TypeStr);
IvarTypes.push_back(MakeConstantString(TypeStr));
// Get the offset
- uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD).getQuantity();
+ uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
uint64_t Offset = BaseOffset;
if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
Offset = BaseOffset - superInstanceSize;
@@ -2655,7 +2655,7 @@ llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
// description.
if (!CGM.getContext().getObjCImplementation(
const_cast<ObjCInterfaceDecl *>(ID)))
- Offset = ComputeIvarBaseOffset(CGM, ID, Ivar).getQuantity();
+ Offset = ComputeIvarBaseOffset(CGM, ID, Ivar);
llvm::ConstantInt *OffsetGuess = llvm::ConstantInt::get(Int32Ty, Offset,
/*isSigned*/true);
@@ -2728,9 +2728,8 @@ llvm::Value *CGObjCGNU::EmitIvarOffset(CodeGenFunction &CGF,
Offset = CGF.Builder.CreateZExtOrBitCast(Offset, PtrDiffTy);
return Offset;
}
- CharUnits Offset = ComputeIvarBaseOffset(CGF.CGM, Interface, Ivar);
- return llvm::ConstantInt::get(PtrDiffTy, Offset.getQuantity(),
- /*isSigned*/true);
+ uint64_t Offset = ComputeIvarBaseOffset(CGF.CGM, Interface, Ivar);
+ return llvm::ConstantInt::get(PtrDiffTy, Offset, /*isSigned*/true);
}
CGObjCRuntime *
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 6c0b82bb26..7c9d215a27 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -736,10 +736,9 @@ public:
// FIXME - accessibility
class GC_IVAR {
public:
- CharUnits ivar_bytepos;
- CharUnits ivar_size;
- GC_IVAR(CharUnits bytepos = CharUnits::Zero(),
- CharUnits size = CharUnits::Zero())
+ unsigned ivar_bytepos;
+ unsigned ivar_size;
+ GC_IVAR(unsigned bytepos = 0, unsigned size = 0)
: ivar_bytepos(bytepos), ivar_size(size) {}
// Allow sorting based on byte pos.
@@ -811,11 +810,10 @@ public:
class RUN_SKIP {
public:
enum BLOCK_LAYOUT_OPCODE opcode;
- CharUnits block_var_bytepos;
- CharUnits block_var_size;
+ unsigned block_var_bytepos;
+ unsigned block_var_size;
RUN_SKIP(enum BLOCK_LAYOUT_OPCODE Opcode = BLOCK_LAYOUT_OPERATOR,
- CharUnits BytePos = CharUnits::Zero(),
- CharUnits Size = CharUnits::Zero())
+ unsigned BytePos = 0, unsigned Size = 0)
: opcode(Opcode), block_var_bytepos(BytePos), block_var_size(Size) {}
// Allow sorting based on byte pos.
@@ -935,29 +933,29 @@ protected:
llvm::Constant *BuildIvarLayoutBitmap(std::string &BitMap);
void BuildAggrIvarRecordLayout(const RecordType *RT,
- CharUnits BytePos, bool ForStrongLayout,
+ unsigned int BytePos, bool ForStrongLayout,
bool &HasUnion);
void BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
const llvm::StructLayout *Layout,
const RecordDecl *RD,
ArrayRef<const FieldDecl*> RecFields,
- CharUnits BytePos, bool ForStrongLayout,
+ unsigned int BytePos, bool ForStrongLayout,
bool &HasUnion);
Qualifiers::ObjCLifetime getBlockCaptureLifetime(QualType QT);
void UpdateRunSkipBlockVars(bool IsByref,
Qualifiers::ObjCLifetime LifeTime,
- CharUnits FieldOffset,
- CharUnits FieldSize);
+ unsigned FieldOffset,
+ unsigned FieldSize);
void BuildRCBlockVarRecordLayout(const RecordType *RT,
- CharUnits BytePos, bool &HasUnion);
+ unsigned int BytePos, bool &HasUnion);
void BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
const RecordDecl *RD,
ArrayRef<const FieldDecl*> RecFields,
- CharUnits BytePos, bool &HasUnion);
+ unsigned int BytePos, bool &HasUnion);
uint64_t InlineLayoutInstruction(SmallVectorImpl<unsigned char> &Layout);
@@ -1326,7 +1324,7 @@ private:
llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
const ObjCIvarDecl *Ivar,
- CharUnits offset);
+ unsigned long int offset);
/// GetOrEmitProtocol - Get the protocol object for the given
/// declaration, emitting it if necessary. The return value has type
@@ -1890,13 +1888,12 @@ llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
bool hasUnion = false;
SkipIvars.clear();
IvarsInfo.clear();
- CharUnits WordSize =
- CGM.getContext().toCharUnitsFromBits(
- CGM.getContext().getTargetInfo().getPointerWidth(0));
+ unsigned WordSizeInBits = CGM.getContext().getTargetInfo().getPointerWidth(0);
+ unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth();
// __isa is the first field in block descriptor and must assume by runtime's
// convention that it is GC'able.
- IvarsInfo.push_back(GC_IVAR(CharUnits::Zero(), WordSize));
+ IvarsInfo.push_back(GC_IVAR(0, 1));
const BlockDecl *blockDecl = blockInfo.getBlockDecl();
@@ -1918,12 +1915,11 @@ llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
// Ignore constant captures.
if (capture.isConstant()) continue;
- CharUnits fieldOffset =
- CharUnits::fromQuantity(layout->getElementOffset(capture.getIndex()));
+ uint64_t fieldOffset = layout->getElementOffset(capture.getIndex());
// __block variables are passed by their descriptor address.
if (ci->isByRef()) {
- IvarsInfo.push_back(GC_IVAR(fieldOffset, WordSize));
+ IvarsInfo.push_back(GC_IVAR(fieldOffset, /*size in words*/ 1));
continue;
}
@@ -1934,12 +1930,14 @@ llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
}
Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), type);
- CharUnits fieldSize = CGM.getContext().getTypeSizeInChars(type);
+ unsigned fieldSize = CGM.getContext().getTypeSize(type);
if (GCAttr == Qualifiers::Strong)
- IvarsInfo.push_back(GC_IVAR(fieldOffset, fieldSize));
+ IvarsInfo.push_back(GC_IVAR(fieldOffset,
+ fieldSize / WordSizeInBits));
else if (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak)
- SkipIvars.push_back(GC_IVAR(fieldOffset, fieldSize));
+ SkipIvars.push_back(GC_IVAR(fieldOffset,
+ fieldSize / ByteSizeInBits));
}
if (IvarsInfo.empty())
@@ -1982,37 +1980,40 @@ Qualifiers::ObjCLifetime CGObjCCommonMac::getBlockCaptureLifetime(QualType FQT)
void CGObjCCommonMac::UpdateRunSkipBlockVars(bool IsByref,
Qualifiers::ObjCLifetime LifeTime,
- CharUnits FieldOffset,
- CharUnits FieldSize) {
+ unsigned FieldOffset,
+ unsigned FieldSize) {
+ unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth();
+ unsigned FieldSizeInBytes = FieldSize/ByteSizeInBits;
+
// __block variables are passed by their descriptor address.
if (IsByref)
RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset,
- FieldSize));
+ FieldSizeInBytes));
else if (LifeTime == Qualifiers::OCL_Strong)
RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset,
- FieldSize));
+ FieldSizeInBytes));
else if (LifeTime == Qualifiers::OCL_Weak)
RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset,
- FieldSize));
+ FieldSizeInBytes));
else if (LifeTime == Qualifiers::OCL_ExplicitNone)
RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset,
- FieldSize));
+ FieldSizeInBytes));
else
RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES,
FieldOffset,
- FieldSize));
+ FieldSizeInBytes));
}
void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
const RecordDecl *RD,
ArrayRef<const FieldDecl*> RecFields,
- CharUnits BytePos, bool &HasUnion) {
+ unsigned int BytePos, bool &HasUnion) {
bool IsUnion = (RD && RD->isUnion());
- CharUnits MaxUnionSize = CharUnits::Zero();
+ uint64_t MaxUnionSize = 0;
const FieldDecl *MaxField = 0;
const FieldDecl *LastFieldBitfieldOrUnnamed = 0;
- CharUnits MaxFieldOffset = CharUnits::Zero();
- CharUnits LastBitfieldOrUnnamedOffset = CharUnits::Zero();
+ uint64_t MaxFieldOffset = 0;
+ uint64_t LastBitfieldOrUnnamedOffset = 0;
if (RecFields.empty())
return;
@@ -2020,11 +2021,11 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
const FieldDecl *Field = RecFields[i];
+ uint64_t FieldOffset;
// Note that 'i' here is actually the field index inside RD of Field,
// although this dependency is hidden.
const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
- CharUnits FieldOffset =
- CGM.getContext().toCharUnitsFromBits(RL.getFieldOffset(i));
+ FieldOffset = (RL.getFieldOffset(i) / ByteSizeInBits);
// Skip over unnamed or bitfields
if (!Field->getIdentifier() || Field->isBitField()) {
@@ -2069,7 +2070,7 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
// one element is already done.
uint64_t ElIx = 1;
for (int FirstIndex = RunSkipBlockVars.size() - 1 ;ElIx < ElCount; ElIx++) {
- CharUnits Size = CGM.getContext().getTypeSizeInChars(RT);
+ uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits;
for (int i = OldIndex+1; i <= FirstIndex; ++i)
RunSkipBlockVars.push_back(
RUN_SKIP(RunSkipBlockVars[i].opcode,
@@ -2079,9 +2080,9 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
continue;
}
}
- CharUnits FieldSize = CGM.getContext().getTypeSizeInChars(Field->getType());
+ unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType());
if (IsUnion) {
- CharUnits UnionIvarSize = FieldSize;
+ uint64_t UnionIvarSize = FieldSize;
if (UnionIvarSize > MaxUnionSize) {
MaxUnionSize = UnionIvarSize;
MaxField = Field;
@@ -2100,19 +2101,18 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
// Last field was a bitfield. Must update the info.
uint64_t BitFieldSize
= LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext());
- CharUnits Size =
- CharUnits::fromQuantity(
- (BitFieldSize + ByteSizeInBits - 1) / ByteSizeInBits);
+ unsigned Size = (BitFieldSize / ByteSizeInBits) +
+ ((BitFieldSize % ByteSizeInBits) != 0);
Size += LastBitfieldOrUnnamedOffset;
UpdateRunSkipBlockVars(false,
getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->getType()),
BytePos + LastBitfieldOrUnnamedOffset,
- Size);
+ Size*ByteSizeInBits);
} else {
assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed");
// Last field was unnamed. Must update skip info.
- CharUnits FieldSize
- = CGM.getContext().getTypeSizeInChars(LastFieldBitfieldOrUnnamed->getType());
+ unsigned FieldSize
+ = CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType());
UpdateRunSkipBlockVars(false,
getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->getType()),
BytePos + LastBitfieldOrUnnamedOffset,
@@ -2128,7 +2128,7 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
}
void CGObjCCommonMac::BuildRCBlockVarRecordLayout(const RecordType *RT,
- CharUnits BytePos,
+ unsigned int BytePos,
bool &HasUnion) {
const RecordDecl *RD = RT->getDecl();
SmallVector<const FieldDecl*, 16> Fields;
@@ -2281,19 +2281,15 @@ llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM,
// Ignore constant captures.
if (capture.isConstant()) continue;
- CharUnits fieldOffset =
- CharUnits::fromQuantity(layout->getElementOffset(capture.getIndex()));
+ uint64_t fieldOffset = layout->getElementOffset(capture.getIndex());
assert(!type->isArrayType() && "array variable should not be caught");
if (const RecordType *record = type->getAs<RecordType>()) {
BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);
continue;
}
- CharUnits fieldSize;
- if (ci->isByRef())
- fieldSize = CharUnits::fromQuantity(WordSizeInBytes);
- else
- fieldSize = CGM.getContext().getTypeSizeInChars(type);
+ unsigned fieldSize = ci->isByRef() ? WordSizeInBits
+ : CGM.getContext().getTypeSize(type);
UpdateRunSkipBlockVars(ci->isByRef(), getBlockCaptureLifetime(type),
fieldOffset, fieldSize);
}
@@ -2307,10 +2303,12 @@ llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM,
SmallVector<unsigned char, 16> Layout;
unsigned size = RunSkipBlockVars.size();
+ unsigned int shift = (WordSizeInBytes == 8) ? 3 : 2;
+ unsigned int mask = (WordSizeInBytes == 8) ? 0x7 : 0x3;
for (unsigned i = 0; i < size; i++) {
enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;
- CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
- CharUnits end_byte_pos = start_byte_pos;
+ unsigned start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
+ unsigned end_byte_pos = start_byte_pos;
unsigned j = i+1;
while (j < size) {
if (opcode == RunSkipBlockVars[j].opcode) {
@@ -2320,22 +2318,22 @@ llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM,
else
break;
}
- CharUnits size_in_bytes =
+ unsigned size_in_bytes =
end_byte_pos - start_byte_pos + RunSkipBlockVars[j-1].block_var_size;
if (j < size) {
- CharUnits gap =
+ unsigned gap =
RunSkipBlockVars[j].block_var_bytepos -
RunSkipBlockVars[j-1].block_var_bytepos - RunSkipBlockVars[j-1].block_var_size;
size_in_bytes += gap;
}
- CharUnits residue_in_bytes = CharUnits::Zero();
+ unsigned residue_in_bytes = 0;
if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
- residue_in_bytes = size_in_bytes % WordSizeInBytes;
+ residue_in_bytes = size_in_bytes & mask;
size_in_bytes -= residue_in_bytes;
opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
}
- unsigned size_in_words = size_in_bytes.getQuantity() / WordSizeInBytes;
+ unsigned size_in_words = size_in_bytes >> shift;
while (size_in_words >= 16) {
// Note that value in imm. is one less that the actual
// value. So, 0xf means 16 words follow!
@@ -2349,10 +2347,9 @@ llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM,
unsigned char inst = (opcode << 4) | (size_in_words-1);
Layout.push_back(inst);
}
- if (residue_in_bytes > CharUnits::Zero()) {
+ if (residue_in_bytes > 0) {
unsigned char inst =
- (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) |
- (residue_in_bytes.getQuantity()-1);
+ (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) | (residue_in_bytes-1);
Layout.push_back(inst);
}
}
@@ -3229,7 +3226,7 @@ llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
GetMethodVarName(IVD->getIdentifier()),
GetMethodVarType(IVD),
llvm::ConstantInt::get(ObjCTypes.IntTy,
- ComputeIvarBaseOffset(CGM, OID, IVD).getQuantity())
+ ComputeIvarBaseOffset(CGM, OID, IVD))
};
Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar));
}
@@ -4175,8 +4172,10 @@ LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
const ObjCInterfaceDecl *Interface,
const ObjCIvarDecl *Ivar) {
- CharUnits Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
- return llvm::ConstantInt::get(ObjCTypes.LongTy, Offset.getQuantity());
+ uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
+ return llvm::ConstantInt::get(
+ CGM.getTypes().ConvertType(CGM.getContext().LongTy),
+ Offset);
}
/* *** Private Interface *** */
@@ -4398,7 +4397,7 @@ llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
}
void CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT,
- CharUnits BytePos,
+ unsigned int BytePos,
bool ForStrongLayout,
bool &HasUnion) {
const RecordDecl *RD = RT->getDecl();
@@ -4419,36 +4418,37 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
const llvm::StructLayout *Layout,
const RecordDecl *RD,
ArrayRef<const FieldDecl*> RecFields,
- CharUnits BytePos, bool ForStrongLayout,
+ unsigned int BytePos, bool ForStrongLayout,
bool &HasUnion) {
bool IsUnion = (RD && RD->isUnion());
- CharUnits MaxUnionIvarSize = CharUnits::Zero();
- CharUnits MaxSkippedUnionIvarSize = CharUnits::Zero();
+ uint64_t MaxUnionIvarSize = 0;
+ uint64_t MaxSkippedUnionIvarSize = 0;
const FieldDecl *MaxField = 0;
const FieldDecl *MaxSkippedField = 0;
const FieldDecl *LastFieldBitfieldOrUnnamed = 0;
- CharUnits MaxFieldOffset = CharUnits::Zero();
- CharUnits MaxSkippedFieldOffset = CharUnits::Zero();
- CharUnits LastBitfieldOrUnnamedOffset = CharUnits::Zero();
- CharUnits FirstFieldDelta = CharUnits::Zero();
+ uint64_t MaxFieldOffset = 0;
+ uint64_t MaxSkippedFieldOffset = 0;
+ uint64_t LastBitfieldOrUnnamedOffset = 0;
+ uint64_t FirstFieldDelta = 0;
if (RecFields.empty())
return;
+ unsigned WordSizeInBits = CGM.getContext().getTargetInfo().getPointerWidth(0);
unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth();
if (!RD && CGM.getLangOpts().ObjCAutoRefCount) {
- const ObjCIvarDecl *FirstField = cast<ObjCIvarDecl>(RecFields[0]);
- FirstFieldDelta = ComputeIvarBaseOffset(CGM, OI, FirstField);
+ const FieldDecl *FirstField = RecFields[0];
+ FirstFieldDelta =
+ ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(FirstField));
}
for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
const FieldDecl *Field = RecFields[i];
- CharUnits FieldOffset;
+ uint64_t FieldOffset;
if (RD) {
// Note that 'i' here is actually the field index inside RD of Field,
// although this dependency is hidden.
const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
- FieldOffset = CGM.getContext().toCharUnitsFromBits(RL.getFieldOffset(i)) -
- FirstFieldDelta;
+ FieldOffset = (RL.getFieldOffset(i) / ByteSizeInBits) - FirstFieldDelta;
} else
FieldOffset =
ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(Field)) - FirstFieldDelta;
@@ -4500,7 +4500,7 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
uint64_t ElIx = 1;
for (int FirstIndex = IvarsInfo.size() - 1,
FirstSkIndex = SkipIvars.size() - 1 ;ElIx < ElCount; ElIx++) {
- CharUnits Size = CGM.getContext().getTypeSizeInChars(RT);
+ uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits;
for (int i = OldIndex+1; i <= FirstIndex; ++i)
IvarsInfo.push_back(GC_IVAR(IvarsInfo[i].ivar_bytepos + Size*ElIx,
IvarsInfo[i].ivar_size));
@@ -4515,31 +4515,36 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
// For other arrays we are down to its element type.
Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), FQT);
- CharUnits FieldSize = CGM.getContext().getTypeSizeInChars(Field->getType());
+ unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType());
if ((ForStrongLayout && GCAttr == Qualifiers::Strong)
|| (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
if (IsUnion) {
- CharUnits UnionIvarSize = FieldSize;
+ uint64_t UnionIvarSize = FieldSize / WordSizeInBits;
if (UnionIvarSize > MaxUnionIvarSize) {
MaxUnionIvarSize = UnionIvarSize;
MaxField = Field;
MaxFieldOffset = FieldOffset;
}
} else {
- IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset, FieldSize));
+ IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset,
+ FieldSize / WordSizeInBits));
}
} else if ((ForStrongLayout &&
(GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak))
|| (!ForStrongLayout && GCAttr != Qualifiers::Weak)) {
if (IsUnion) {
- CharUnits UnionIvarSize = FieldSize;
+ // FIXME: Why the asymmetry? We divide by word size in bits on other
+ // side.
+ uint64_t UnionIvarSize = FieldSize / ByteSizeInBits;
if (UnionIvarSize > MaxSkippedUnionIvarSize) {
MaxSkippedUnionIvarSize = UnionIvarSize;
MaxSkippedField = Field;
MaxSkippedFieldOffset = FieldOffset;
}
} else {
- SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset, FieldSize));
+ // FIXME: Why the asymmetry, we divide by byte size in bits here?
+ SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset,
+ FieldSize / ByteSizeInBits));
}
}
}
@@ -4551,16 +4556,16 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
= LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext());
GC_IVAR skivar;
skivar.ivar_bytepos = BytePos + LastBitfieldOrUnnamedOffset;
- skivar.ivar_size = CharUnits::fromQuantity(
- (BitFieldSize + ByteSizeInBits - 1) / ByteSizeInBits);
+ skivar.ivar_size = (BitFieldSize / ByteSizeInBits)
+ + ((BitFieldSize % ByteSizeInBits) != 0);
SkipIvars.push_back(skivar);
} else {
assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed");
// Last field was unnamed. Must update skip info.
- CharUnits FieldSize
- = CGM.getContext().getTypeSizeInChars(LastFieldBitfieldOrUnnamed->getType());
+ unsigned FieldSize
+ = CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType());
SkipIvars.push_back(GC_IVAR(BytePos + LastBitfieldOrUnnamedOffset,
- FieldSize));
+ FieldSize / ByteSizeInBits));
}
}
@@ -4578,21 +4583,26 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
/// two containers, IvarsInfo and SkipIvars which are assumed to be
/// filled already by the caller.
llvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string &BitMap) {
+ unsigned int WordsToScan, WordsToSkip;
llvm::Type *PtrTy = CGM.Int8PtrTy;
// Build the string of skip/scan nibbles
SmallVector<SKIP_SCAN, 32> SkipScanIvars;
- CharUnits WordSize = CharUnits::fromQuantity(
- CGM.getTypes().getDataLayout().getTypeAllocSize(PtrTy));
- unsigned WordsToSkip = IvarsInfo[0].ivar_bytepos / WordSize;
- unsigned WordsToScan = IvarsInfo[0].ivar_size / WordSize;
-
+ unsigned int WordSize =
+ CGM.getTypes().getDataLayout().getTypeAllocSize(PtrTy);
+ if (IvarsInfo[0].ivar_bytepos == 0) {
+ WordsToSkip = 0;
+ WordsToScan = IvarsInfo[0].ivar_size;
+ } else {
+ WordsToSkip = IvarsInfo[0].ivar_bytepos/WordSize;
+ WordsToScan = IvarsInfo[0].ivar_size;
+ }
for (unsigned int i=1, Last=IvarsInfo.size(); i != Last; i++) {
- CharUnits TailPrevGCObjC =
- IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size;
+ unsigned int TailPrevGCObjC =
+ IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size * WordSize;
if (IvarsInfo[i].ivar_bytepos == TailPrevGCObjC) {
// consecutive 'scanned' object pointers.
- WordsToScan += IvarsInfo[i].ivar_size / WordSize;
+ WordsToScan += IvarsInfo[i].ivar_size;
} else {
// Skip over 'gc'able object pointer which lay over each other.
if (TailPrevGCObjC > IvarsInfo[i].ivar_bytepos)
@@ -4609,7 +4619,7 @@ llvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string &BitMap) {
SkScan.scan = 0;
SkipScanIvars.push_back(SkScan);
WordsToSkip = 0;
- WordsToScan = IvarsInfo[i].ivar_size / WordSize;
+ WordsToScan = IvarsInfo[i].ivar_size;
}
}
if (WordsToScan > 0) {
@@ -4621,19 +4631,17 @@ llvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string &BitMap) {
if (!SkipIvars.empty()) {
unsigned int LastIndex = SkipIvars.size()-1;
- CharUnits LastByteSkipped =
- SkipIvars[LastIndex].ivar_bytepos +
- SkipIvars[LastIndex].ivar_size;
+ int LastByteSkipped =
+ SkipIvars[LastIndex].ivar_bytepos + SkipIvars[LastIndex].ivar_size;
LastIndex = IvarsInfo.size()-1;
- CharUnits LastByteScanned =
- IvarsInfo[LastIndex].ivar_bytepos +
- IvarsInfo[LastIndex].ivar_size;
+ int LastByteScanned =
+ IvarsInfo[LastIndex].ivar_bytepos +
+ IvarsInfo[LastIndex].ivar_size * WordSize;
// Compute number of bytes to skip at the tail end of the last ivar scanned.
if (LastByteSkipped > LastByteScanned) {
- unsigned int TotalWords =
- (LastByteSkipped + (WordSize - CharUnits::One())) / WordSize;
+ unsigned int TotalWords = (LastByteSkipped + (WordSize -1)) / WordSize;
SKIP_SCAN SkScan;
- SkScan.skip = TotalWords - LastByteScanned / WordSize;
+ SkScan.skip = TotalWords - (LastByteScanned/WordSize);
SkScan.scan = 0;
SkipScanIvars.push_back(SkScan);
}
@@ -4746,8 +4754,7 @@ llvm::Constant *CGObjCCommonMac::BuildIvarLayout(
SkipIvars.clear();
IvarsInfo.clear();
- BuildAggrIvarLayout(OMD, 0, 0, RecFields, CharUnits::Zero(),
- ForStrongLayout, hasUnion);
+ BuildAggrIvarLayout(OMD, 0, 0, RecFields, 0, ForStrongLayout, hasUnion);
if (IvarsInfo.empty())
return llvm::Constant::getNullValue(PtrTy);
// Sort on byte position in case we encounterred a union nested in
@@ -6015,10 +6022,10 @@ CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
llvm::Constant *
CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
const ObjCIvarDecl *Ivar,
- CharUnits Offset) {
+ unsigned long int Offset) {
llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
IvarOffsetGV->setInitializer(llvm::ConstantInt::get(ObjCTypes.LongTy,
- Offset.getQuantity()));
+ Offset));
IvarOffsetGV->setAlignment(
CGM.getDataLayout().getABITypeAlignment(ObjCTypes.LongTy));
diff --git a/lib/CodeGen/CGObjCRuntime.cpp b/lib/CodeGen/CGObjCRuntime.cpp
index 71a3774ff8..9aa68376bc 100644
--- a/lib/CodeGen/CGObjCRuntime.cpp
+++ b/lib/CodeGen/CGObjCRuntime.cpp
@@ -64,18 +64,18 @@ static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM,
return RL->getFieldOffset(Index);
}
-CharUnits CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
- const ObjCInterfaceDecl *OID,
- const ObjCIvarDecl *Ivar) {
- return CGM.getContext().toCharUnitsFromBits(
- LookupFieldBitOffset(CGM, OID, 0, Ivar));
+uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
+ const ObjCInterfaceDecl *OID,
+ const ObjCIvarDecl *Ivar) {
+ return LookupFieldBitOffset(CGM, OID, 0, Ivar) /
+ CGM.getContext().getCharWidth();
}
-CharUnits CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
- const ObjCImplementationDecl *OID,
- const ObjCIvarDecl *Ivar) {
- return CGM.getContext().toCharUnitsFromBits(
- LookupFieldBitOffset(CGM, OID->getClassInterface(), OID, Ivar));
+uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
+ const ObjCImplementationDecl *OID,
+ const ObjCIvarDecl *Ivar) {
+ return LookupFieldBitOffset(CGM, OID->getClassInterface(), OID, Ivar) /
+ CGM.getContext().getCharWidth();
}
LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h
index 2178692854..bc6589dd69 100644
--- a/lib/CodeGen/CGObjCRuntime.h
+++ b/lib/CodeGen/CGObjCRuntime.h
@@ -76,12 +76,12 @@ protected:
///
/// The latter overload is suitable for computing the offset of a
/// sythesized ivar.
- CharUnits ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
- const ObjCInterfaceDecl *OID,
- const ObjCIvarDecl *Ivar);
- CharUnits ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
- const ObjCImplementationDecl *OID,
- const ObjCIvarDecl *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,