r338353 - Improve support of PDB as an external layout source
Aleksandr Urakov via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 31 01:27:06 PDT 2018
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)];
+}
More information about the cfe-commits
mailing list