summaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGRecordLayoutBuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGRecordLayoutBuilder.cpp')
-rw-r--r--lib/CodeGen/CGRecordLayoutBuilder.cpp39
1 files changed, 24 insertions, 15 deletions
diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp
index c754541ac121..4de64a32f2ac 100644
--- a/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -1,9 +1,8 @@
//===--- CGRecordLayoutBuilder.cpp - CGRecordLayout builder ----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -274,7 +273,7 @@ void CGRecordLowering::lower(bool NVBaseType) {
if (!NVBaseType)
accumulateVBases();
}
- std::stable_sort(Members.begin(), Members.end());
+ llvm::stable_sort(Members);
Members.push_back(StorageInfo(Size, getIntNType(8)));
clipTailPadding();
determinePacked(NVBaseType);
@@ -348,18 +347,21 @@ void CGRecordLowering::lowerUnion() {
void CGRecordLowering::accumulateFields() {
for (RecordDecl::field_iterator Field = D->field_begin(),
FieldEnd = D->field_end();
- Field != FieldEnd;)
+ Field != FieldEnd;) {
if (Field->isBitField()) {
RecordDecl::field_iterator Start = Field;
// Iterate to gather the list of bitfields.
for (++Field; Field != FieldEnd && Field->isBitField(); ++Field);
accumulateBitFields(Start, Field);
- } else {
+ } else if (!Field->isZeroSize(Context)) {
Members.push_back(MemberInfo(
bitsToCharUnits(getFieldBitOffset(*Field)), MemberInfo::Field,
getStorageType(*Field), *Field));
++Field;
+ } else {
+ ++Field;
}
+ }
}
void
@@ -591,10 +593,17 @@ void CGRecordLowering::clipTailPadding() {
if (!Member->Data && Member->Kind != MemberInfo::Scissor)
continue;
if (Member->Offset < Tail) {
- assert(Prior->Kind == MemberInfo::Field && !Prior->FD &&
+ assert(Prior->Kind == MemberInfo::Field &&
"Only storage fields have tail padding!");
- Prior->Data = getByteArrayType(bitsToCharUnits(llvm::alignTo(
- cast<llvm::IntegerType>(Prior->Data)->getIntegerBitWidth(), 8)));
+ if (!Prior->FD || Prior->FD->isBitField())
+ Prior->Data = getByteArrayType(bitsToCharUnits(llvm::alignTo(
+ cast<llvm::IntegerType>(Prior->Data)->getIntegerBitWidth(), 8)));
+ else {
+ assert(Prior->FD->hasAttr<NoUniqueAddressAttr>() &&
+ "should not have reused this field's tail padding");
+ Prior->Data = getByteArrayType(
+ Context.getTypeInfoDataSizeInChars(Prior->FD->getType()).first);
+ }
}
if (Member->Data)
Prior = Member;
@@ -659,7 +668,7 @@ void CGRecordLowering::insertPadding() {
Pad = Padding.begin(), PadEnd = Padding.end();
Pad != PadEnd; ++Pad)
Members.push_back(StorageInfo(Pad->first, getByteArrayType(Pad->second)));
- std::stable_sort(Members.begin(), Members.end());
+ llvm::stable_sort(Members);
}
void CGRecordLowering::fillOutputFields() {
@@ -798,6 +807,10 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D,
for (unsigned i = 0, e = AST_RL.getFieldCount(); i != e; ++i, ++it) {
const FieldDecl *FD = *it;
+ // Ignore zero-sized fields.
+ if (FD->isZeroSize(getContext()))
+ continue;
+
// For non-bit-fields, just check that the LLVM struct offset matches the
// AST offset.
if (!FD->isBitField()) {
@@ -811,10 +824,6 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D,
if (!FD->getDeclName())
continue;
- // Don't inspect zero-length bitfields.
- if (FD->isZeroLengthBitField(getContext()))
- continue;
-
const CGBitFieldInfo &Info = RL->getBitFieldInfo(FD);
llvm::Type *ElementTy = ST->getTypeAtIndex(RL->getLLVMFieldNo(FD));