P0840R2: support for [[no_unique_address]] attribute
Summary:
Add support for the C++2a [[no_unique_address]] attribute for targets using the Itanium C++ ABI.
This depends on D63371.
Reviewers: rjmccall, aaron.ballman
Subscribers: dschuff, aheejin, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D63451
llvm-svn: 363976
diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
index b5102bb..4de64a3 100644
--- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -347,18 +347,21 @@
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
@@ -590,10 +593,17 @@
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;
@@ -797,6 +807,10 @@
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()) {
@@ -810,10 +824,6 @@
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));