summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/RecordLayoutBuilder.cpp
diff options
context:
space:
mode:
authorMomchil Velikov <momchil.velikov@arm.com>2018-07-30 17:48:23 +0000
committerMomchil Velikov <momchil.velikov@arm.com>2018-07-30 17:48:23 +0000
commit20208cc046c206a1436edb714e94bd52a0bc8572 (patch)
tree24548919809d313e32c81ace99e7da457dbf1d1b /clang/lib/AST/RecordLayoutBuilder.cpp
parentfa3bee47569b1583e4319bbdbcd3f129345caa25 (diff)
downloadbcm5719-llvm-20208cc046c206a1436edb714e94bd52a0bc8572.tar.gz
bcm5719-llvm-20208cc046c206a1436edb714e94bd52a0bc8572.zip
[ARM, AArch64]: Use unadjusted alignment when passing composites as arguments
The "Procedure Call Procedure Call Standard for the ARMĀ® Architecture" (https://static.docs.arm.com/ihi0042/f/IHI0042F_aapcs.pdf), specifies that composite types are passed according to their "natural alignment", i.e. the alignment before alignment adjustment on the entire composite is applied. The same applies for AArch64 ABI. Clang, however, used the adjusted alignment. GCC already implements the ABI correctly. With this patch Clang becomes compatible with GCC and passes such arguments in accordance with AAPCS. Differential Revision: https://reviews.llvm.org/D46013 llvm-svn: 338279
Diffstat (limited to 'clang/lib/AST/RecordLayoutBuilder.cpp')
-rw-r--r--clang/lib/AST/RecordLayoutBuilder.cpp20
1 files changed, 15 insertions, 5 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index b4b09c7cecd..c92ac20f1f3 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -582,6 +582,9 @@ protected:
/// The alignment if attribute packed is not used.
CharUnits UnpackedAlignment;
+ /// \brief The maximum of the alignments of top-level members.
+ CharUnits UnadjustedAlignment;
+
SmallVector<uint64_t, 16> FieldOffsets;
/// Whether the external AST source has provided a layout for this
@@ -662,6 +665,7 @@ protected:
EmptySubobjectMap *EmptySubobjects)
: Context(Context), EmptySubobjects(EmptySubobjects), Size(0),
Alignment(CharUnits::One()), UnpackedAlignment(CharUnits::One()),
+ UnadjustedAlignment(CharUnits::One()),
UseExternalLayout(false), InferAlignment(false), Packed(false),
IsUnion(false), IsMac68kAlign(false), IsMsStruct(false),
UnfilledBitsInLastUnit(0), LastBitfieldTypeSize(0),
@@ -1707,7 +1711,9 @@ void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
setSize(std::max(getSizeInBits(), getDataSizeInBits()));
// Remember max struct/class alignment.
- UpdateAlignment(Context.toCharUnitsFromBits(FieldAlign),
+ UnadjustedAlignment =
+ std::max(UnadjustedAlignment, Context.toCharUnitsFromBits(FieldAlign));
+ UpdateAlignment(Context.toCharUnitsFromBits(FieldAlign),
Context.toCharUnitsFromBits(UnpackedFieldAlign));
}
@@ -1862,6 +1868,7 @@ void ItaniumRecordLayoutBuilder::LayoutField(const FieldDecl *D,
setSize(std::max(getSizeInBits(), getDataSizeInBits()));
// Remember max struct/class alignment.
+ UnadjustedAlignment = std::max(UnadjustedAlignment, FieldAlign);
UpdateAlignment(FieldAlign, UnpackedFieldAlign);
}
@@ -2988,7 +2995,8 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const {
if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) {
Builder.cxxLayout(RD);
NewEntry = new (*this) ASTRecordLayout(
- *this, Builder.Size, Builder.Alignment, Builder.RequiredAlignment,
+ *this, Builder.Size, Builder.Alignment, Builder.Alignment,
+ Builder.RequiredAlignment,
Builder.HasOwnVFPtr, Builder.HasOwnVFPtr || Builder.PrimaryBase,
Builder.VBPtrOffset, Builder.DataSize, Builder.FieldOffsets,
Builder.NonVirtualSize, Builder.Alignment, CharUnits::Zero(),
@@ -2998,7 +3006,8 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const {
} else {
Builder.layout(D);
NewEntry = new (*this) ASTRecordLayout(
- *this, Builder.Size, Builder.Alignment, Builder.RequiredAlignment,
+ *this, Builder.Size, Builder.Alignment, Builder.Alignment,
+ Builder.RequiredAlignment,
Builder.Size, Builder.FieldOffsets);
}
} else {
@@ -3019,7 +3028,7 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const {
CharUnits NonVirtualSize =
skipTailPadding ? DataSize : Builder.NonVirtualSize;
NewEntry = new (*this) ASTRecordLayout(
- *this, Builder.getSize(), Builder.Alignment,
+ *this, Builder.getSize(), Builder.Alignment, Builder.UnadjustedAlignment,
/*RequiredAlignment : used by MS-ABI)*/
Builder.Alignment, Builder.HasOwnVFPtr, RD->isDynamicClass(),
CharUnits::fromQuantity(-1), DataSize, Builder.FieldOffsets,
@@ -3032,7 +3041,7 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const {
Builder.Layout(D);
NewEntry = new (*this) ASTRecordLayout(
- *this, Builder.getSize(), Builder.Alignment,
+ *this, Builder.getSize(), Builder.Alignment, Builder.UnadjustedAlignment,
/*RequiredAlignment : used by MS-ABI)*/
Builder.Alignment, Builder.getSize(), Builder.FieldOffsets);
}
@@ -3186,6 +3195,7 @@ ASTContext::getObjCLayout(const ObjCInterfaceDecl *D,
const ASTRecordLayout *NewEntry =
new (*this) ASTRecordLayout(*this, Builder.getSize(),
Builder.Alignment,
+ Builder.UnadjustedAlignment,
/*RequiredAlignment : used by MS-ABI)*/
Builder.Alignment,
Builder.getDataSize(),
OpenPOWER on IntegriCloud