return EmitLoadOfKVCRefLValue(LV, ExprType);
}
+static llvm::Value *getBitFieldAddr(LValue LV, CGBuilderTy &Builder) {
+ const CGBitFieldInfo &Info = LV.getBitFieldInfo();
+
+ llvm::Value *BaseValue = LV.getBitFieldBaseAddr();
+ const llvm::PointerType *BaseTy =
+ cast<llvm::PointerType>(BaseValue->getType());
+
+ // Cast to the type of the access we will perform.
+ llvm::Value *V = Builder.CreateBitCast(
+ BaseValue, llvm::PointerType::get(Info.FieldTy, BaseTy->getAddressSpace()));
+
+ // Offset by the access index.
+ return Builder.CreateConstGEP1_32(V, Info.FieldNo);
+}
+
RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV,
QualType ExprType) {
const CGBitFieldInfo &Info = LV.getBitFieldInfo();
unsigned StartBit = Info.Start;
unsigned BitfieldSize = Info.Size;
- llvm::Value *Ptr = LV.getBitFieldAddr();
+ llvm::Value *Ptr = getBitFieldAddr(LV, Builder);
const llvm::Type *EltTy =
cast<llvm::PointerType>(Ptr->getType())->getElementType();
const CGBitFieldInfo &Info = Dst.getBitFieldInfo();
unsigned StartBit = Info.Start;
unsigned BitfieldSize = Info.Size;
- llvm::Value *Ptr = Dst.getBitFieldAddr();
+ llvm::Value *Ptr = getBitFieldAddr(Dst, Builder);
const llvm::Type *EltTy =
cast<llvm::PointerType>(Ptr->getType())->getElementType();
const CGRecordLayout &RL =
CGM.getTypes().getCGRecordLayout(Field->getParent());
const CGBitFieldInfo &Info = RL.getBitFieldInfo(Field);
-
- // FIXME: CodeGenTypes should expose a method to get the appropriate type for
- // FieldTy (the appropriate type is ABI-dependent).
- const llvm::Type *FieldTy =
- CGM.getTypes().ConvertTypeForMem(Field->getType());
- const llvm::PointerType *BaseTy =
- cast<llvm::PointerType>(BaseValue->getType());
- unsigned AS = BaseTy->getAddressSpace();
- BaseValue = Builder.CreateBitCast(BaseValue,
- llvm::PointerType::get(FieldTy, AS));
- llvm::Value *V = Builder.CreateConstGEP1_32(BaseValue, Info.FieldNo);
-
- return LValue::MakeBitfield(V, Info,
+ return LValue::MakeBitfield(BaseValue, Info,
Field->getType().getCVRQualifiers()|CVRQualifiers);
}
// objects.
unsigned FieldNo = 0; // This value is unused.
CGBitFieldInfo *Info =
- new (CGF.CGM.getContext()) CGBitFieldInfo(FieldNo, BitOffset, BitFieldSize,
- IvarTy->isSignedIntegerType());
+ new (CGF.CGM.getContext()) CGBitFieldInfo(
+ LTy, FieldNo, BitOffset, BitFieldSize, IvarTy->isSignedIntegerType());
// FIXME: We need to set a very conservative alignment on this, or make sure
// that the runtime is doing the right thing.
class CGBitFieldInfo {
public:
- CGBitFieldInfo(unsigned FieldNo, unsigned Start, unsigned Size,
- bool IsSigned)
- : FieldNo(FieldNo), Start(Start), Size(Size), IsSigned(IsSigned) {}
+ CGBitFieldInfo(const llvm::Type *FieldTy, unsigned FieldNo,
+ unsigned Start, unsigned Size, bool IsSigned)
+ : FieldTy(FieldTy), FieldNo(FieldNo),
+ Start(Start), Size(Size), IsSigned(IsSigned) {}
+ const llvm::Type *FieldTy;
unsigned FieldNo;
+
unsigned Start;
unsigned Size;
bool IsSigned : 1;
bool IsSigned = D->getType()->isSignedIntegerType();
LLVMBitFields.push_back(LLVMBitFieldInfo(
- D, CGBitFieldInfo(FieldOffset / TypeSizeInBits,
+ D, CGBitFieldInfo(Ty, FieldOffset / TypeSizeInBits,
FieldOffset % TypeSizeInBits,
FieldSize, IsSigned)));
FieldEnd = D->field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
assert(Layout.getFieldOffset(FieldNo) == 0 &&
"Union field offset did not start at the beginning of record!");
+ const llvm::Type *FieldTy =
+ Types.ConvertTypeForMemRecursive(Field->getType());
if (Field->isBitField()) {
uint64_t FieldSize =
// Add the bit field info.
bool IsSigned = Field->getType()->isSignedIntegerType();
LLVMBitFields.push_back(LLVMBitFieldInfo(
- *Field, CGBitFieldInfo(0, 0, FieldSize,
+ *Field, CGBitFieldInfo(FieldTy, 0, 0, FieldSize,
IsSigned)));
} else {
LLVMFields.push_back(LLVMFieldInfo(*Field, 0));
HasOnlyZeroSizedBitFields = false;
- const llvm::Type *FieldTy =
- Types.ConvertTypeForMemRecursive(Field->getType());
unsigned FieldAlign = Types.getTargetData().getABITypeAlignment(FieldTy);
uint64_t FieldSize = Types.getTargetData().getTypeAllocSize(FieldTy);
}
// bitfield lvalue
- llvm::Value *getBitFieldAddr() const {
+ llvm::Value *getBitFieldBaseAddr() const {
assert(isBitField());
return V;
}
return R;
}
- static LValue MakeBitfield(llvm::Value *V, const CGBitFieldInfo &Info,
+ /// \brief Create a new object to represent a bit-field access.
+ ///
+ /// \param BaseValue - The base address of the structure containing the
+ /// bit-field.
+ /// \param Info - The information describing how to perform the bit-field
+ /// access.
+ static LValue MakeBitfield(llvm::Value *BaseValue, const CGBitFieldInfo &Info,
unsigned CVR) {
LValue R;
R.LVType = BitField;
- R.V = V;
+ R.V = BaseValue;
R.BitFieldInfo = &Info;
R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
return R;