[ms-abi] Reordering __declspec(align) pragma pack handling

This patch moves the check for pragma pack until after the application 
of __declspec align to before pragma pack.  This causes observable 
changes in the use of tail padding for bases.  A test case is included.

llvm-svn: 199154
This commit is contained in:
Warren Hunt 2014-01-13 22:25:55 +00:00
parent 859422a867
commit 4c73e59475
2 changed files with 34 additions and 5 deletions

View File

@ -2186,9 +2186,6 @@ MicrosoftRecordLayoutBuilder::getAdjustedElementInfo(
Context.getTypeInfoInChars(FD->getType());
if (FD->isBitField() && FD->getMaxAlignment() != 0)
Info.Alignment = std::max(Info.Alignment, FieldRequiredAlignment);
// Respect pragma pack.
if (!MaxFieldAlignment.isZero())
Info.Alignment = std::min(Info.Alignment, MaxFieldAlignment);
}
// Respect packed field attribute.
if (FD->hasAttr<PackedAttr>())
@ -2200,6 +2197,9 @@ MicrosoftRecordLayoutBuilder::getAdjustedElementInfo(
// Capture required alignment as a side-effect.
RequiredAlignment = std::max(RequiredAlignment, FieldRequiredAlignment);
}
// Respect pragma pack.
if (!MaxFieldAlignment.isZero())
Info.Alignment = std::min(Info.Alignment, MaxFieldAlignment);
// TODO: Add a Sema warning that MS ignores bitfield alignment in unions.
if (!(FD->isBitField() && IsUnion))
Alignment = std::max(Alignment, Info.Alignment);

View File

@ -43,7 +43,7 @@ struct X {
// CHECK: 8 | char b
// CHECK-NEXT: 10 | int c
// CHECK-NEXT: | [sizeof=16, align=4
// CHECK-NEXT: | nvsize=16, nvalign=4]
// CHECK-NEXT: | nvsize=14, nvalign=4]
// CHECK-X64: *** Dumping AST Record Layout
// CHECK-X64: *** Dumping AST Record Layout
// CHECK-X64-NEXT: 0 | struct X
@ -52,7 +52,7 @@ struct X {
// CHECK-X64: 8 | char b
// CHECK-X64-NEXT: 10 | int c
// CHECK-X64-NEXT: | [sizeof=16, align=4
// CHECK-X64-NEXT: | nvsize=16, nvalign=4]
// CHECK-X64-NEXT: | nvsize=14, nvalign=4]
struct Y : A, B {
char a;
@ -321,6 +321,34 @@ struct D2 : D1 { char a; };
// CHECK-X64-NEXT: | [sizeof=16, align=16
// CHECK-X64-NEXT: | nvsize=16, nvalign=16]
#pragma pack()
struct JA { char a; };
#pragma pack(1)
struct JB { __declspec(align(4)) char a; };
#pragma pack()
struct JC : JB, JA { };
// CHECK: *** Dumping AST Record Layout
// CHECK: *** Dumping AST Record Layout
// CHECK: *** Dumping AST Record Layout
// CHECK-NEXT: 0 | struct JC
// CHECK-NEXT: 0 | struct JB (base)
// CHECK-NEXT: 0 | char a
// CHECK-NEXT: 1 | struct JA (base)
// CHECK-NEXT: 1 | char a
// CHECK-NEXT: | [sizeof=4, align=4
// CHECK-NEXT: | nvsize=4, nvalign=4]
// CHECK-X64: *** Dumping AST Record Layout
// CHECK-X64: *** Dumping AST Record Layout
// CHECK-X64: *** Dumping AST Record Layout
// CHECK-X64-NEXT: 0 | struct JC
// CHECK-X64-NEXT: 0 | struct JB (base)
// CHECK-X64-NEXT: 0 | char a
// CHECK-X64-NEXT: 1 | struct JA (base)
// CHECK-X64-NEXT: 1 | char a
// CHECK-X64-NEXT: | [sizeof=4, align=4
// CHECK-X64-NEXT: | nvsize=4, nvalign=4]
int a[
sizeof(X)+
sizeof(Y)+
@ -335,4 +363,5 @@ sizeof(YE)+
sizeof(YF)+
sizeof(YF)+
sizeof(D2)+
sizeof(JC)+
0];