Author: aleksandr.urakov Date: Tue Jul 31 01:27:06 2018 New Revision: 338353
URL: http://llvm.org/viewvc/llvm-project?rev=338353&view=rev Log: Improve support of PDB as an external layout source Summary: This patch improves support of PDB as an external layout source in the next cases: - Multiple non-virtual inheritance from packed base classes. When using external layout, there's no need to align `NonVirtualSize` of a base class. It may cause an overlapping when the next base classes will be layouted (but there is a slightly different case in the test because I can't find a way to specify a base offset); - Support of nameless structs and unions. There is no info about nameless child structs and unions in Microsoft cl-emitted PDBs. Instead all its fields are just treated as outer structure's (union's) fields. This also causes a fields overlapping, and makes it possible for unions to have fields located at a non-zero offset. Reviewers: rsmith, zturner, rnk, mstorsjo, majnemer Reviewed By: rnk Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D49871 Added: cfe/trunk/test/CodeGenCXX/Inputs/override-layout-nameless-struct-union.layout cfe/trunk/test/CodeGenCXX/Inputs/override-layout-packed-base.layout cfe/trunk/test/CodeGenCXX/override-layout-nameless-struct-union.cpp cfe/trunk/test/CodeGenCXX/override-layout-packed-base.cpp Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=338353&r1=338352&r2=338353&view=diff ============================================================================== --- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original) +++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Tue Jul 31 01:27:06 2018 @@ -2452,7 +2452,9 @@ void MicrosoftRecordLayoutBuilder::cxxLa auto RoundingAlignment = Alignment; if (!MaxFieldAlignment.isZero()) RoundingAlignment = std::min(RoundingAlignment, MaxFieldAlignment); - NonVirtualSize = Size = Size.alignTo(RoundingAlignment); + if (!UseExternalLayout) + Size = Size.alignTo(RoundingAlignment); + NonVirtualSize = Size; RequiredAlignment = std::max( RequiredAlignment, Context.toCharUnitsFromBits(RD->getMaxAlignment())); layoutVirtualBases(RD); @@ -2653,21 +2655,16 @@ void MicrosoftRecordLayoutBuilder::layou LastFieldIsNonZeroWidthBitfield = false; ElementInfo Info = getAdjustedElementInfo(FD); Alignment = std::max(Alignment, Info.Alignment); - if (IsUnion) { - placeFieldAtOffset(CharUnits::Zero()); - Size = std::max(Size, Info.Size); - } else { - CharUnits FieldOffset; - if (UseExternalLayout) { - FieldOffset = - Context.toCharUnitsFromBits(External.getExternalFieldOffset(FD)); - assert(FieldOffset >= Size && "field offset already allocated"); - } else { - FieldOffset = Size.alignTo(Info.Alignment); - } - placeFieldAtOffset(FieldOffset); - Size = FieldOffset + Info.Size; - } + CharUnits FieldOffset; + if (UseExternalLayout) + FieldOffset = + Context.toCharUnitsFromBits(External.getExternalFieldOffset(FD)); + else if (IsUnion) + FieldOffset = CharUnits::Zero(); + else + FieldOffset = Size.alignTo(Info.Alignment); + placeFieldAtOffset(FieldOffset); + Size = std::max(Size, FieldOffset + Info.Size); } void MicrosoftRecordLayoutBuilder::layoutBitField(const FieldDecl *FD) { @@ -2692,18 +2689,17 @@ void MicrosoftRecordLayoutBuilder::layou } LastFieldIsNonZeroWidthBitfield = true; CurrentBitfieldSize = Info.Size; - if (IsUnion) { - placeFieldAtOffset(CharUnits::Zero()); - Size = std::max(Size, Info.Size); - // TODO: Add a Sema warning that MS ignores bitfield alignment in unions. - } else if (UseExternalLayout) { + 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; + Size = std::max(Size, NewSize); Alignment = std::max(Alignment, Info.Alignment); + } else if (IsUnion) { + placeFieldAtOffset(CharUnits::Zero()); + Size = std::max(Size, Info.Size); + // TODO: Add a Sema warning that MS ignores bitfield alignment in unions. } else { // Allocate a new block of memory and place the bitfield in it. CharUnits FieldOffset = Size.alignTo(Info.Alignment); Added: cfe/trunk/test/CodeGenCXX/Inputs/override-layout-nameless-struct-union.layout URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/Inputs/override-layout-nameless-struct-union.layout?rev=338353&view=auto ============================================================================== --- cfe/trunk/test/CodeGenCXX/Inputs/override-layout-nameless-struct-union.layout (added) +++ cfe/trunk/test/CodeGenCXX/Inputs/override-layout-nameless-struct-union.layout Tue Jul 31 01:27:06 2018 @@ -0,0 +1,16 @@ + +*** Dumping AST Record Layout +Type: struct S + +Layout: <ASTRecordLayout + Size:64 + Alignment:32 + FieldOffsets: [0, 32, 32]> + +*** Dumping AST Record Layout +Type: union U + +Layout: <ASTRecordLayout + Size:96 + Alignment:32 + FieldOffsets: [0, 0, 32, 64, 68, 73]> Added: cfe/trunk/test/CodeGenCXX/Inputs/override-layout-packed-base.layout URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/Inputs/override-layout-packed-base.layout?rev=338353&view=auto ============================================================================== --- cfe/trunk/test/CodeGenCXX/Inputs/override-layout-packed-base.layout (added) +++ cfe/trunk/test/CodeGenCXX/Inputs/override-layout-packed-base.layout Tue Jul 31 01:27:06 2018 @@ -0,0 +1,18 @@ + +*** Dumping AST Record Layout +Type: class B<0> + +Layout: <ASTRecordLayout + FieldOffsets: [0, 32]> + +*** Dumping AST Record Layout +Type: class B<1> + +Layout: <ASTRecordLayout + FieldOffsets: [0, 32]> + +*** Dumping AST Record Layout +Type: class C + +Layout: <ASTRecordLayout + FieldOffsets: [80]> Added: cfe/trunk/test/CodeGenCXX/override-layout-nameless-struct-union.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/override-layout-nameless-struct-union.cpp?rev=338353&view=auto ============================================================================== --- cfe/trunk/test/CodeGenCXX/override-layout-nameless-struct-union.cpp (added) +++ cfe/trunk/test/CodeGenCXX/override-layout-nameless-struct-union.cpp Tue Jul 31 01:27:06 2018 @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -w -fdump-record-layouts-simple -foverride-record-layout=%S/Inputs/override-layout-nameless-struct-union.layout %s | FileCheck %s + +// CHECK: Type: struct S +// CHECK: Size:64 +// CHECK: Alignment:32 +// CHECK: FieldOffsets: [0, 32, 32] +struct S { + short _s; +//union { + int _su0; + char _su1; +//}; +}; + +// CHECK: Type: union U +// CHECK: Size:96 +// CHECK: Alignment:32 +// CHECK: FieldOffsets: [0, 0, 32, 64, 68, 73] +union U { + short _u; +//struct { + char _us0; + int _us1; + unsigned _us20 : 4; + unsigned _us21 : 5; + unsigned _us22 : 6; +//}; +}; + +void use_structs() { + S ss[sizeof(S)]; + U us[sizeof(U)]; +} Added: cfe/trunk/test/CodeGenCXX/override-layout-packed-base.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/override-layout-packed-base.cpp?rev=338353&view=auto ============================================================================== --- cfe/trunk/test/CodeGenCXX/override-layout-packed-base.cpp (added) +++ cfe/trunk/test/CodeGenCXX/override-layout-packed-base.cpp Tue Jul 31 01:27:06 2018 @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -w -fdump-record-layouts-simple -foverride-record-layout=%S/Inputs/override-layout-packed-base.layout %s | FileCheck %s + +// CHECK: Type: class B<0> +// CHECK: FieldOffsets: [0, 32] + +// CHECK: Type: class B<1> +// CHECK: FieldOffsets: [0, 32] + +//#pragma pack(push, 1) +template<int I> +class B { + int _b1; + char _b2; +}; +//#pragma pack(pop) + +// CHECK: Type: class C +// CHECK: FieldOffsets: [80] + +class C : B<0>, B<1> { + char _c; +}; + +void use_structs() { + C cs[sizeof(C)]; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits