llvm::Value *Res = 0;
for (unsigned i = 0, e = Info.getNumComponents(); i != e; ++i) {
const CGBitFieldInfo::AccessInfo &AI = Info.getComponent(i);
+ CharUnits AccessAlignment = AI.AccessAlignment;
+ if (!LV.getAlignment().isZero())
+ AccessAlignment = std::min(AccessAlignment, LV.getAlignment());
// Get the field pointer.
llvm::Value *Ptr = LV.getBitFieldBaseAddr();
// Perform the load.
llvm::LoadInst *Load = Builder.CreateLoad(Ptr, LV.isVolatileQualified());
- if (!AI.AccessAlignment.isZero())
- Load->setAlignment(AI.AccessAlignment.getQuantity());
+ Load->setAlignment(AccessAlignment.getQuantity());
// Shift out unused low bits and mask out unused high bits.
llvm::Value *Val = Load;
// Iterate over the components, writing each piece to memory.
for (unsigned i = 0, e = Info.getNumComponents(); i != e; ++i) {
const CGBitFieldInfo::AccessInfo &AI = Info.getComponent(i);
+ CharUnits AccessAlignment = AI.AccessAlignment;
+ if (!Dst.getAlignment().isZero())
+ AccessAlignment = std::min(AccessAlignment, Dst.getAlignment());
// Get the field pointer.
llvm::Value *Ptr = Dst.getBitFieldBaseAddr();
// If necessary, load and OR in bits that are outside of the bit-field.
if (AI.TargetBitWidth != AI.AccessWidth) {
llvm::LoadInst *Load = Builder.CreateLoad(Ptr, Dst.isVolatileQualified());
- if (!AI.AccessAlignment.isZero())
- Load->setAlignment(AI.AccessAlignment.getQuantity());
+ Load->setAlignment(AccessAlignment.getQuantity());
// Compute the mask for zeroing the bits that are part of the bit-field.
llvm::APInt InvMask =
// Write the value.
llvm::StoreInst *Store = Builder.CreateStore(Val, Ptr,
Dst.isVolatileQualified());
- if (!AI.AccessAlignment.isZero())
- Store->setAlignment(AI.AccessAlignment.getQuantity());
+ Store->setAlignment(AccessAlignment.getQuantity());
}
}
llvm_unreachable("Unhandled member declaration!");
}
-LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value *BaseValue,
- const FieldDecl *Field,
- unsigned CVRQualifiers) {
- const CGRecordLayout &RL =
- CGM.getTypes().getCGRecordLayout(Field->getParent());
- const CGBitFieldInfo &Info = RL.getBitFieldInfo(Field);
- return LValue::MakeBitfield(BaseValue, Info,
- Field->getType().withCVRQualifiers(CVRQualifiers));
-}
-
/// EmitLValueForAnonRecordField - Given that the field is a member of
/// an anonymous struct or union buried inside a record, and given
/// that the base value is a pointer to the enclosing record, derive
LValue CodeGenFunction::EmitLValueForField(LValue base,
const FieldDecl *field) {
- if (field->isBitField())
- return EmitLValueForBitfield(base.getAddress(), field,
- base.getVRQualifiers());
+ if (field->isBitField()) {
+ const CGRecordLayout &RL =
+ CGM.getTypes().getCGRecordLayout(field->getParent());
+ const CGBitFieldInfo &Info = RL.getBitFieldInfo(field);
+ QualType fieldType =
+ field->getType().withCVRQualifiers(base.getVRQualifiers());
+ return LValue::MakeBitfield(base.getAddress(), Info, fieldType,
+ base.getAlignment());
+ }
const RecordDecl *rec = field->getParent();
QualType type = field->getType();
uint64_t ContainingTypeAlign = CGF.CGM.getContext().getTargetInfo().getCharAlign();
uint64_t ContainingTypeSize = TypeSizeInBits - (FieldBitOffset - BitOffset);
uint64_t BitFieldSize = Ivar->getBitWidthValue(CGF.getContext());
+ CharUnits ContainingTypeAlignCharUnits =
+ CGF.CGM.getContext().toCharUnitsFromBits(ContainingTypeAlign);
// Allocate a new CGBitFieldInfo object to describe this access.
//
ContainingTypeSize, ContainingTypeAlign));
return LValue::MakeBitfield(V, *Info,
- IvarTy.withCVRQualifiers(CVRQualifiers));
+ IvarTy.withCVRQualifiers(CVRQualifiers),
+ ContainingTypeAlignCharUnits);
}
namespace {