diff options
Diffstat (limited to 'clang/lib/AST/DeclCXX.cpp')
-rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 5fd52c4243a..5f7dcd5d46a 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -50,7 +50,7 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D) Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false), Abstract(false), IsStandardLayout(true), HasNoNonEmptyBases(true), HasPrivateFields(false), HasProtectedFields(false), HasPublicFields(false), - HasMutableFields(false), HasOnlyCMembers(true), + HasMutableFields(false), HasVariantMembers(false), HasOnlyCMembers(true), HasInClassInitializer(false), HasUninitializedReferenceMember(false), NeedOverloadResolutionForMoveConstructor(false), NeedOverloadResolutionForMoveAssignment(false), @@ -653,7 +653,13 @@ void CXXRecordDecl::addedMember(Decl *D) { // Keep track of the presence of mutable fields. if (Field->isMutable()) data().HasMutableFields = true; - + + // C++11 [class.union]p8, DR1460: + // If X is a union, a non-static data member of X that is not an anonymous + // union is a variant member of X. + if (isUnion() && !Field->isAnonymousStructOrUnion()) + data().HasVariantMembers = true; + // C++0x [class]p9: // A POD struct is a class that is both a trivial class and a // standard-layout class, and has no non-static data members of type @@ -689,7 +695,9 @@ void CXXRecordDecl::addedMember(Decl *D) { if (!T->isLiteralType(Context) || T.isVolatileQualified()) data().HasNonLiteralTypeFieldsOrBases = true; - if (Field->hasInClassInitializer()) { + if (Field->hasInClassInitializer() || + (Field->isAnonymousStructOrUnion() && + Field->getType()->getAsCXXRecordDecl()->hasInClassInitializer())) { data().HasInClassInitializer = true; // C++11 [class]p5: @@ -806,7 +814,7 @@ void CXXRecordDecl::addedMember(Decl *D) { // Virtual bases and virtual methods make a class non-empty, but they // also make it non-standard-layout so we needn't check here. // A non-empty base class may leave the class standard-layout, but not - // if we have arrived here, and have at least on non-static data + // if we have arrived here, and have at least one non-static data // member. If IsStandardLayout remains true, then the first non-static // data member must come through here with Empty still true, and Empty // will subsequently be set to false below. @@ -859,6 +867,13 @@ void CXXRecordDecl::addedMember(Decl *D) { if (FieldRec->hasUninitializedReferenceMember() && !Field->hasInClassInitializer()) data().HasUninitializedReferenceMember = true; + + // C++11 [class.union]p8, DR1460: + // a non-static data member of an anonymous union that is a member of + // X is also a variant member of X. + if (FieldRec->hasVariantMembers() && + Field->isAnonymousStructOrUnion()) + data().HasVariantMembers = true; } } else { // Base element type of field is a non-class type. |