[cfe-commits] r101467 - in /cfe/trunk: lib/AST/RecordLayoutBuilder.cpp lib/AST/RecordLayoutBuilder.h test/SemaCXX/bitfield-layout.cpp
Anders Carlsson
andersca at mac.com
Fri Apr 16 08:57:11 PDT 2010
Author: andersca
Date: Fri Apr 16 10:57:11 2010
New Revision: 101467
URL: http://llvm.org/viewvc/llvm-project?rev=101467&view=rev
Log:
More work on wide bit-fields, WIP.
Modified:
cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
cfe/trunk/lib/AST/RecordLayoutBuilder.h
cfe/trunk/test/SemaCXX/bitfield-layout.cpp
Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=101467&r1=101466&r2=101467&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Fri Apr 16 10:57:11 2010
@@ -609,6 +609,66 @@
LayoutField(*Field);
}
+void ASTRecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize,
+ uint64_t TypeSize) {
+ assert(Context.getLangOptions().CPlusPlus &&
+ "Can only have wide bit-fields in C++!");
+
+ // Itanium C++ ABI 2.4:
+ // If sizeof(T)*8 < n, let T' be the largest integral POD type with
+ // sizeof(T')*8 <= n.
+
+ QualType IntegralPODTypes[] = {
+ Context.UnsignedCharTy, Context.UnsignedShortTy, Context.UnsignedIntTy,
+ Context.UnsignedLongTy, Context.UnsignedLongLongTy
+ };
+
+ printf("field sizes %llu type size %llu\n",
+ FieldSize, TypeSize);
+
+ QualType Type;
+ for (unsigned I = 0, E = llvm::array_lengthof(IntegralPODTypes);
+ I != E; ++I) {
+ uint64_t Size = Context.getTypeSize(IntegralPODTypes[I]);
+ printf("going to try %s %llu\n", IntegralPODTypes[I].getAsString().c_str(),
+ Size);
+
+ if (Size > FieldSize)
+ break;
+
+ Type = IntegralPODTypes[I];
+ }
+ assert(!Type.isNull() && "Did not find a type!");
+ printf("type should be %s\n", Type.getAsString().c_str());
+
+ unsigned TypeAlign = Context.getTypeAlign(Type);
+
+ // We're not going to use any of the unfilled bits in the last byte.
+ UnfilledBitsInLastByte = 0;
+
+ // The bitfield is allocated starting at the next offset aligned appropriately
+ // for T', with length n bits.
+ uint64_t FieldOffset = llvm::RoundUpToAlignment(DataSize, TypeAlign);
+
+ if (IsUnion) {
+ DataSize = std::max(DataSize, FieldSize);
+ } else {
+ uint64_t NewSizeInBits = FieldOffset + FieldSize;
+
+ DataSize = llvm::RoundUpToAlignment(NewSizeInBits, 8);
+ UnfilledBitsInLastByte = DataSize - NewSizeInBits;
+ }
+
+ // Place this field at the current location.
+ FieldOffsets.push_back(FieldOffset);
+
+ // Update the size.
+ Size = std::max(Size, DataSize);
+
+ // Remember max struct/class alignment.
+ UpdateAlignment(TypeAlign);
+}
+
void ASTRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
bool FieldPacked = Packed || D->hasAttr<PackedAttr>();
uint64_t FieldOffset = IsUnion ? 0 : (DataSize - UnfilledBitsInLastByte);
@@ -618,6 +678,11 @@
uint64_t TypeSize = FieldInfo.first;
unsigned FieldAlign = FieldInfo.second;
+ if (FieldSize > TypeSize) {
+ LayoutWideBitField(FieldSize, TypeSize);
+ return;
+ }
+
if (FieldPacked || !Context.Target.useBitFieldTypeAlignment())
FieldAlign = 1;
if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.h?rev=101467&r1=101466&r2=101467&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.h (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.h Fri Apr 16 10:57:11 2010
@@ -91,6 +91,7 @@
void LayoutFields(const RecordDecl *D);
void LayoutField(const FieldDecl *D);
+ void LayoutWideBitField(uint64_t FieldSize, uint64_t TypeSize);
void LayoutBitField(const FieldDecl *D);
/// DeterminePrimaryBase - Determine the primary base of the given class.
Modified: cfe/trunk/test/SemaCXX/bitfield-layout.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/bitfield-layout.cpp?rev=101467&r1=101466&r2=101467&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/bitfield-layout.cpp (original)
+++ cfe/trunk/test/SemaCXX/bitfield-layout.cpp Fri Apr 16 10:57:11 2010
@@ -3,10 +3,28 @@
#define CHECK_SIZE(name, size) extern int name##1[sizeof(name) == size ? 1 : -1];
#define CHECK_ALIGN(name, size) extern int name##2[__alignof(name) == size ? 1 : -1];
-// Simple test.
+// Simple tests.
struct Test1 {
char c : 9; // expected-warning {{size of bit-field 'c' (9 bits) exceeds the size of its type; value will be truncated to 8 bits}}
};
CHECK_SIZE(Test1, 2);
CHECK_ALIGN(Test1, 1);
+struct Test2 {
+ char c : 16; // expected-warning {{size of bit-field 'c' (16 bits) exceeds the size of its type; value will be truncated to 8 bits}}
+};
+CHECK_SIZE(Test2, 2);
+CHECK_ALIGN(Test2, 2);
+
+struct Test3 {
+ char c : 32; // expected-warning {{size of bit-field 'c' (32 bits) exceeds the size of its type; value will be truncated to 8 bits}}
+};
+CHECK_SIZE(Test3, 4);
+CHECK_ALIGN(Test3, 4);
+
+struct Test4 {
+ char c : 64; // expected-warning {{size of bit-field 'c' (64 bits) exceeds the size of its type; value will be truncated to 8 bits}}
+};
+CHECK_SIZE(Test4, 8);
+CHECK_ALIGN(Test4, 8);
+
More information about the cfe-commits
mailing list