Add TargetInfo::useBitfieldTypeAlignment().

- Used to determine whether the alignment of the type in a bit-field is
   respected when laying out structures. The default is true, targets can
   override this as needed.

 - This is designed to correspond to the PCC_BITFIELD_TYPE_MATTERS macro in
   gcc. The AST/Sema implementation only affects one line, unless I have
   forgotten something. I'd appreciate further review.

 - IRgen still needs to be updated to fully support this (which is effectively
   PR5591).

llvm-svn: 101356
This commit is contained in:
Daniel Dunbar 2010-04-15 06:18:39 +00:00
parent 3245afdf05
commit 3d9289c736
3 changed files with 18 additions and 7 deletions

View File

@ -85,6 +85,14 @@ public:
protected:
IntType SizeType, IntMaxType, UIntMaxType, PtrDiffType, IntPtrType, WCharType,
WIntType, Char16Type, Char32Type, Int64Type, SigAtomicType;
/// Control whether the alignment of bit-field types is respected when laying
/// out structures. If true, then the alignment of the bit-field type will be
/// used to (a) impact the alignment of the containing structure, and (b)
/// ensure that the individual bit-field will not straddle an alignment
/// boundary.
unsigned UseBitfieldTypeAlignment : 1;
public:
IntType getSizeType() const { return SizeType; }
IntType getIntMaxType() const { return IntMaxType; }
@ -197,6 +205,10 @@ public:
return UserLabelPrefix;
}
bool useBitfieldTypeAlignment() const {
return UseBitfieldTypeAlignment;
}
/// getTypeName - Return the user string for the specified integer type enum.
/// For example, SignedShort -> "short".
static const char *getTypeName(IntType T);

View File

@ -585,7 +585,7 @@ void ASTRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
uint64_t TypeSize = FieldInfo.first;
unsigned FieldAlign = FieldInfo.second;
if (FieldPacked)
if (FieldPacked || !Ctx.Target.useBitfieldTypeAlignment())
FieldAlign = 1;
if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
FieldAlign = std::max(FieldAlign, AA->getMaxAlignment());
@ -594,12 +594,11 @@ void ASTRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
if (MaxFieldAlignment)
FieldAlign = std::min(FieldAlign, MaxFieldAlignment);
// Check if we need to add padding to give the field the correct
// alignment.
// Check if we need to add padding to give the field the correct alignment.
if (FieldSize == 0 || (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize)
FieldOffset = (FieldOffset + (FieldAlign-1)) & ~(FieldAlign-1);
// Padding members don't affect overall alignment
// Padding members don't affect overall alignment.
if (!D->getIdentifier())
FieldAlign = 1;

View File

@ -20,9 +20,8 @@ using namespace clang;
// TargetInfo Constructor.
TargetInfo::TargetInfo(const std::string &T) : Triple(T) {
// Set defaults. Defaults are set for a 32-bit RISC platform,
// like PPC or SPARC.
// These should be overridden by concrete targets as needed.
// Set defaults. Defaults are set for a 32-bit RISC platform, like PPC or
// SPARC. These should be overridden by concrete targets as needed.
TLSSupported = true;
PointerWidth = PointerAlign = 32;
IntWidth = IntAlign = 32;
@ -45,6 +44,7 @@ TargetInfo::TargetInfo(const std::string &T) : Triple(T) {
Char32Type = UnsignedInt;
Int64Type = SignedLongLong;
SigAtomicType = SignedInt;
UseBitfieldTypeAlignment = true;
FloatFormat = &llvm::APFloat::IEEEsingle;
DoubleFormat = &llvm::APFloat::IEEEdouble;
LongDoubleFormat = &llvm::APFloat::IEEEdouble;