diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index e0935ac0397f..892e9a345847 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -726,9 +726,10 @@ RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV, Ptr = Builder.CreateStructGEP(Ptr, AI.FieldIndex, "bf.field"); // Offset by the byte offset, if used. - if (AI.FieldByteOffset) { + if (!AI.FieldByteOffset.isZero()) { Ptr = EmitCastToVoidPtr(Ptr); - Ptr = Builder.CreateConstGEP1_32(Ptr, AI.FieldByteOffset,"bf.field.offs"); + Ptr = Builder.CreateConstGEP1_32(Ptr, AI.FieldByteOffset.getQuantity(), + "bf.field.offs"); } // Cast to the access type. @@ -929,9 +930,10 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, Ptr = Builder.CreateStructGEP(Ptr, AI.FieldIndex, "bf.field"); // Offset by the byte offset, if used. - if (AI.FieldByteOffset) { + if (!AI.FieldByteOffset.isZero()) { Ptr = EmitCastToVoidPtr(Ptr); - Ptr = Builder.CreateConstGEP1_32(Ptr, AI.FieldByteOffset,"bf.field.offs"); + Ptr = Builder.CreateConstGEP1_32(Ptr, AI.FieldByteOffset.getQuantity(), + "bf.field.offs"); } // Cast to the access type. diff --git a/clang/lib/CodeGen/CGRecordLayout.h b/clang/lib/CodeGen/CGRecordLayout.h index 30da05f421fe..245e74ce76a3 100644 --- a/clang/lib/CodeGen/CGRecordLayout.h +++ b/clang/lib/CodeGen/CGRecordLayout.h @@ -12,6 +12,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/DerivedTypes.h" +#include "clang/AST/CharUnits.h" #include "clang/AST/Decl.h" namespace llvm { class raw_ostream; @@ -53,7 +54,7 @@ public: /// unused as the cleanest IR comes from having a well-constructed LLVM type /// with proper GEP instructions, but sometimes its use is required, for /// example if an access is intended to straddle an LLVM field boundary. - unsigned FieldByteOffset; + CharUnits FieldByteOffset; /// Bit offset in the accessed value to use. The width is implied by \see /// TargetBitWidth. diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp index 5a8115639d3f..7f52e3106800 100644 --- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -309,9 +309,10 @@ CGBitFieldInfo CGBitFieldInfo::MakeInfo(CodeGenTypes &Types, // in higher bits. But this also reverts the bytes, so fix this here by reverting // the byte offset on big-endian machines. if (Types.getTargetData().isBigEndian()) { - AI.FieldByteOffset = (ContainingTypeSizeInBits - AccessStart - AccessWidth )/8; + AI.FieldByteOffset = Types.getContext().toCharUnitsFromBits( + ContainingTypeSizeInBits - AccessStart - AccessWidth); } else { - AI.FieldByteOffset = AccessStart / 8; + AI.FieldByteOffset = Types.getContext().toCharUnitsFromBits(AccessStart); } AI.FieldBitStart = AccessBitsInFieldStart - AccessStart; AI.AccessWidth = AccessWidth; @@ -978,7 +979,7 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D) { // Verify that every component access is within the structure. uint64_t FieldOffset = SL->getElementOffsetInBits(AI.FieldIndex); uint64_t AccessBitOffset = FieldOffset + - getContext().toBits(CharUnits::fromQuantity(AI.FieldByteOffset)); + getContext().toBits(AI.FieldByteOffset); assert(AccessBitOffset + AI.AccessWidth <= TypeSizeInBits && "Invalid bit-field access (out of range)!"); } @@ -1037,7 +1038,7 @@ void CGBitFieldInfo::print(llvm::raw_ostream &OS) const { OS.indent(8); OS << "