diff options
| author | Warren Hunt <whunt@google.com> | 2014-04-09 21:57:24 +0000 |
|---|---|---|
| committer | Warren Hunt <whunt@google.com> | 2014-04-09 21:57:24 +0000 |
| commit | 39a907b1c223c7503b905834f658622f56080c64 (patch) | |
| tree | 70e25416965c6d309dd763abb723edd6bf8f3deb /clang/lib/AST/RecordLayoutBuilder.cpp | |
| parent | 699e14f3ce28d759d71ce20c2c98a7396016fbef (diff) | |
| download | bcm5719-llvm-39a907b1c223c7503b905834f658622f56080c64.tar.gz bcm5719-llvm-39a907b1c223c7503b905834f658622f56080c64.zip | |
[MS-ABI] Update to alias-avoidance padding
This patch changes how we determine if padding is needed between two
bases in msvc compatibility mode. Test cases included.
In addition, a very minor change to the printing of structures to ease
lit testing.
llvm-svn: 205933
Diffstat (limited to 'clang/lib/AST/RecordLayoutBuilder.cpp')
| -rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.cpp | 31 |
1 files changed, 15 insertions, 16 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index ce55d2e49ab..8427eb5604d 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -2099,12 +2099,13 @@ static bool isMsLayout(const RecordDecl* D) { // * The ABI attempts to avoid aliasing of zero sized bases by adding padding // between bases or vbases with specific properties. The criteria for // additional padding between two bases is that the first base is zero sized -// or has a zero sized subobject and the second base is zero sized or leads -// with a zero sized base (sharing of vfptrs can reorder the layout of the -// so the leading base is not always the first one declared). The padding -// added for bases is 1 byte. The padding added for vbases depends on the -// alignment of the object but is at least 4 bytes (in both 32 and 64 bit -// modes). +// or ends with a zero sized subobject and the second base is zero sized or +// leads with a zero sized base (sharing of vfptrs can reorder the layout of +// the so the leading base is not always the first one declared). This rule +// is slightly buggy (conservative) because it doesn't take into account +// fields that are not records. The padding added for bases is 1 byte. The +// padding added for vbases depends on the alignment of the object but is at +// least 4 bytes (in both 32 and 64 bit modes). // * There is no concept of non-virtual alignment or any distinction between // data size and non-virtual size. // * __declspec(align) on bitfields has the effect of changing the bitfield's @@ -2213,9 +2214,10 @@ public: bool HasVBPtr : 1; /// \brief Lets us know if we're in 64-bit mode bool Is64BitMode : 1; - /// \brief True if this class contains a zero sized member or base or a base - /// with a zero sized member or base. Only used for MS-ABI. - bool HasZeroSizedSubObject : 1; + /// \brief True if the last sub-object within the type is zero sized or the + /// object itself is zero sized. This *does not* count members that are not + /// records. Only used for MS-ABI. + bool EndsWithZeroSizedObject : 1; /// \brief True if this class is zero sized or first base is zero sized or /// has this property. Only used for MS-ABI. bool LeadsWithZeroSizedBase : 1; @@ -2231,8 +2233,7 @@ MicrosoftRecordLayoutBuilder::getAdjustedElementInfo( if (!MaxFieldAlignment.isZero()) Info.Alignment = std::min(Info.Alignment, MaxFieldAlignment); // Track zero-sized subobjects here where it's already available. - if (Layout.hasZeroSizedSubObject()) - HasZeroSizedSubObject = true; + EndsWithZeroSizedObject = Layout.hasZeroSizedSubObject(); // Respect required alignment, this is necessary because we may have adjusted // the alignment in the case of pragam pack. Note that the required alignment // doesn't actually apply to the struct alignment at this point. @@ -2339,7 +2340,7 @@ void MicrosoftRecordLayoutBuilder::initializeLayout(const RecordDecl *RD) { void MicrosoftRecordLayoutBuilder::initializeCXXLayout(const CXXRecordDecl *RD) { - HasZeroSizedSubObject = false; + EndsWithZeroSizedObject = false; LeadsWithZeroSizedBase = false; HasOwnVFPtr = false; HasVBPtr = false; @@ -2617,7 +2618,6 @@ void MicrosoftRecordLayoutBuilder::layoutVirtualBases(const CXXRecordDecl *RD) { if (HasVtordisp) Size = Size.RoundUpToAlignment(VtorDispAlignment) + VtorDispSize; // Insert the virtual base. - HasZeroSizedSubObject = false; ElementInfo Info = getAdjustedElementInfo(BaseLayout); CharUnits BaseOffset = Size.RoundUpToAlignment(Info.Alignment); VBases.insert(std::make_pair(BaseDecl, @@ -2637,7 +2637,7 @@ void MicrosoftRecordLayoutBuilder::finalizeLayout(const RecordDecl *RD) { } // Zero-sized structures have size equal to their alignment. if (Size.isZero()) { - HasZeroSizedSubObject = true; + EndsWithZeroSizedObject = true; LeadsWithZeroSizedBase = true; Size = Alignment; } @@ -2750,7 +2750,7 @@ ASTContext::BuildMicrosoftASTRecordLayout(const RecordDecl *D) const { Builder.FieldOffsets.size(), Builder.NonVirtualSize, Builder.Alignment, CharUnits::Zero(), Builder.PrimaryBase, false, Builder.SharedVBPtrBase, - Builder.HasZeroSizedSubObject, Builder.LeadsWithZeroSizedBase, + Builder.EndsWithZeroSizedObject, Builder.LeadsWithZeroSizedBase, Builder.Bases, Builder.VBases); } else { Builder.layout(D); @@ -3078,7 +3078,6 @@ static void DumpCXXRecordLayout(raw_ostream &OS, PrintIndentNoOffset(OS, IndentLevel - 1); OS << " nvsize=" << Layout.getNonVirtualSize().getQuantity(); OS << ", nvalign=" << Layout.getNonVirtualAlignment().getQuantity() << "]\n"; - OS << '\n'; } void ASTContext::DumpRecordLayout(const RecordDecl *RD, |

