diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-06-20 20:44:45 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-06-20 20:44:45 +0000 |
commit | 78b239ea67cf248a5c04031050c32f707f127a9d (patch) | |
tree | 23150096a3e3d50ec9a6285ddf6d170b6a61ac20 /clang/lib/AST/DeclCXX.cpp | |
parent | 60ca31a7ddabb46c9ea3762949629433c5eb4c8c (diff) | |
download | bcm5719-llvm-78b239ea67cf248a5c04031050c32f707f127a9d.tar.gz bcm5719-llvm-78b239ea67cf248a5c04031050c32f707f127a9d.zip |
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
Diffstat (limited to 'clang/lib/AST/DeclCXX.cpp')
-rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 48965966f09..6195d5fa664 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -605,14 +605,19 @@ bool CXXRecordDecl::hasSubobjectAtOffsetZeroOfEmptyBaseType( // that sure looks like a wording bug. // -- If X is a non-union class type with a non-static data member - // [recurse to] the first non-static data member of X + // [recurse to each field] that is either of zero size or is the + // first non-static data member of X // -- If X is a union type, [recurse to union members] + bool IsFirstField = true; for (auto *FD : X->fields()) { // FIXME: Should we really care about the type of the first non-static // data member of a non-union if there are preceding unnamed bit-fields? if (FD->isUnnamedBitfield()) continue; + if (!IsFirstField && !FD->isZeroSize(Ctx)) + continue; + // -- If X is n array type, [visit the element type] QualType T = Ctx.getBaseElementType(FD->getType()); if (auto *RD = T->getAsCXXRecordDecl()) @@ -620,7 +625,7 @@ bool CXXRecordDecl::hasSubobjectAtOffsetZeroOfEmptyBaseType( return true; if (!X->isUnion()) - break; + IsFirstField = false; } } @@ -1068,6 +1073,10 @@ void CXXRecordDecl::addedMember(Decl *D) { if (T->isReferenceType()) data().DefaultedMoveAssignmentIsDeleted = true; + // Bitfields of length 0 are also zero-sized, but we already bailed out for + // those because they are always unnamed. + bool IsZeroSize = Field->isZeroSize(Context); + if (const auto *RecordTy = T->getAs<RecordType>()) { auto *FieldRec = cast<CXXRecordDecl>(RecordTy->getDecl()); if (FieldRec->getDefinition()) { @@ -1183,7 +1192,8 @@ void CXXRecordDecl::addedMember(Decl *D) { // A standard-layout class is a class that: // [...] // -- has no element of the set M(S) of types as a base class. - if (data().IsStandardLayout && (isUnion() || IsFirstField) && + if (data().IsStandardLayout && + (isUnion() || IsFirstField || IsZeroSize) && hasSubobjectAtOffsetZeroOfEmptyBaseType(Context, FieldRec)) data().IsStandardLayout = false; @@ -1265,8 +1275,10 @@ void CXXRecordDecl::addedMember(Decl *D) { } // C++14 [meta.unary.prop]p4: - // T is a class type [...] with [...] no non-static data members - data().Empty = false; + // T is a class type [...] with [...] no non-static data members other + // than subobjects of zero size + if (data().Empty && !IsZeroSize) + data().Empty = false; } // Handle using declarations of conversion functions. |