Index: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp =================================================================== --- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp +++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp @@ -2677,7 +2677,7 @@ // Check to see if this bitfield fits into an existing allocation. Note: // MSVC refuses to pack bitfields of formal types with different sizes // into the same allocation. - if (!IsUnion && LastFieldIsNonZeroWidthBitfield && + if (!UseExternalLayout && !IsUnion && LastFieldIsNonZeroWidthBitfield && CurrentBitfieldSize == Info.Size && Width <= RemainingBitsInField) { placeFieldAtBitOffset(Context.toBits(Size) - RemainingBitsInField); RemainingBitsInField -= Width; @@ -2689,6 +2689,14 @@ placeFieldAtOffset(CharUnits::Zero()); Size = std::max(Size, Info.Size); // TODO: Add a Sema warning that MS ignores bitfield alignment in unions. + } else if (UseExternalLayout) { + auto FieldBitOffset = External.getExternalFieldOffset(FD); + placeFieldAtBitOffset(FieldBitOffset); + auto NewSize = Context.toCharUnitsFromBits( + llvm::alignTo(FieldBitOffset + Width, Context.getCharWidth())); + assert(NewSize >= Size && "bit field offset already allocated"); + Size = NewSize; + Alignment = std::max(Alignment, Info.Alignment); } else { // Allocate a new block of memory and place the bitfield in it. CharUnits FieldOffset = Size.alignTo(Info.Alignment); Index: cfe/trunk/test/CodeGenCXX/Inputs/override-bit-field-layout.layout =================================================================== --- cfe/trunk/test/CodeGenCXX/Inputs/override-bit-field-layout.layout +++ cfe/trunk/test/CodeGenCXX/Inputs/override-bit-field-layout.layout @@ -0,0 +1,16 @@ + +*** Dumping AST Record Layout +Type: struct S1 + +Layout: + +*** Dumping AST Record Layout +Type: struct S2 + +Layout: Index: cfe/trunk/test/CodeGenCXX/override-bit-field-layout.cpp =================================================================== --- cfe/trunk/test/CodeGenCXX/override-bit-field-layout.cpp +++ cfe/trunk/test/CodeGenCXX/override-bit-field-layout.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -w -fdump-record-layouts-simple -foverride-record-layout=%S/Inputs/override-bit-field-layout.layout %s | FileCheck %s + +// CHECK: Type: struct S1 +// CHECK: FieldOffsets: [0, 11] +struct S1 { + short a : 3; + short b : 5; +}; + +// CHECK: Type: struct S2 +// CHECK: FieldOffsets: [64] +struct S2 { + virtual ~S2() = default; + short a : 3; +}; + +void use_structs() { + S1 s1s[sizeof(S1)]; + S2 s2s[sizeof(S2)]; +}