summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-12-10 08:25:00 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-12-10 08:25:00 +0000
commitab44d5badf576b5e823a6d78e5972f9ca6a99d68 (patch)
treeb35a52e3442bc48e623cc31728c86e303271f8d1 /clang/lib/AST
parent27964e663b3fced13dab38cb5af3d33823f340b6 (diff)
downloadbcm5719-llvm-ab44d5badf576b5e823a6d78e5972f9ca6a99d68.tar.gz
bcm5719-llvm-ab44d5badf576b5e823a6d78e5972f9ca6a99d68.zip
Implement DR1460: fix handling of default initializers in unions; don't allow
more than one such initializer in a union, make mem-initializers override default initializers for other union members, handle anonymous unions with anonymous struct members better. Fix a couple of semi-related bugs exposed by the tests for same. llvm-svn: 196892
Diffstat (limited to 'clang/lib/AST')
-rw-r--r--clang/lib/AST/ASTImporter.cpp1
-rw-r--r--clang/lib/AST/DeclCXX.cpp23
2 files changed, 20 insertions, 4 deletions
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 4292d358164..cb967b3fb23 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -1947,6 +1947,7 @@ bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
ToData.HasProtectedFields = FromData.HasProtectedFields;
ToData.HasPublicFields = FromData.HasPublicFields;
ToData.HasMutableFields = FromData.HasMutableFields;
+ ToData.HasVariantMembers = FromData.HasVariantMembers;
ToData.HasOnlyCMembers = FromData.HasOnlyCMembers;
ToData.HasInClassInitializer = FromData.HasInClassInitializer;
ToData.HasUninitializedReferenceMember
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.
OpenPOWER on IntegriCloud