summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/DeclCXX.cpp5
-rw-r--r--clang/lib/CodeGen/CGCXX.cpp19
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp6
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp10
4 files changed, 26 insertions, 14 deletions
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index f85091e4f56..87a557d4df1 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -643,6 +643,11 @@ CXXConstructorDecl::setBaseOrMemberInitializers(
for(RecordDecl::field_iterator FA = FieldClassDecl->field_begin(),
EA = FieldClassDecl->field_end(); FA != EA; FA++) {
if (CXXBaseOrMemberInitializer *Value = AllBaseFields.lookup(*FA)) {
+ // 'Member' is the anonymous union field and 'AnonUnionMember' is
+ // set to the anonymous union data member used in the initializer
+ // list.
+ Value->setMember(*Field);
+ Value->setAnonUnionMember(*FA);
AllToInit.push_back(Value);
break;
}
diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp
index aff85fa5d44..e9ebf230d6b 100644
--- a/clang/lib/CodeGen/CGCXX.cpp
+++ b/clang/lib/CodeGen/CGCXX.cpp
@@ -874,8 +874,7 @@ void CodeGenFunction::SynthesizeCXXCopyConstructor(const CXXConstructorDecl *CD,
// FIXME. How about copying arrays!
assert(!getContext().getAsArrayType(FieldType) &&
"FIXME. Copying arrays NYI");
- assert(!Field->isAnonymousStructOrUnion() &&
- "FIXME. anonymous data member NYI in copy constructor synthesis");
+
if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
CXXRecordDecl *FieldClassDecl
= cast<CXXRecordDecl>(FieldClassType->getDecl());
@@ -924,23 +923,25 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) {
QualType FieldType = getContext().getCanonicalType((Field)->getType());
assert(!getContext().getAsArrayType(FieldType)
&& "FIXME. Field arrays initialization unsupported");
- DeclContext *Ctx = Field->getDeclContext();
- RecordDecl *Record = cast<RecordDecl>(Ctx);
- assert(!Record->isAnonymousStructOrUnion() &&
- "FIXME. anonymous union initializer NYI in default constructor");
- (void)Record;
LoadOfThis = LoadCXXThis();
LValue LHS = EmitLValueForField(LoadOfThis, Field, false, 0);
if (FieldType->getAs<RecordType>()) {
-
+ if (!Field->isAnonymousStructOrUnion()) {
assert(Member->getConstructor() &&
"EmitCtorPrologue - no constructor to initialize member");
EmitCXXConstructorCall(Member->getConstructor(),
Ctor_Complete, LHS.getAddress(),
Member->const_arg_begin(),
Member->const_arg_end());
- continue;
+ continue;
+ }
+ else {
+ // Initializing an anonymous union data member.
+ FieldDecl *anonMember = Member->getAnonUnionMember();
+ LHS = EmitLValueForField(LHS.getAddress(), anonMember, false, 0);
+ FieldType = anonMember->getType();
+ }
}
assert(Member->getNumArgs() == 1 && "Initializer count must be 1 only");
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 59f44de26ad..a642de9a464 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -699,14 +699,14 @@ void CodeGenModule::DeferredCopyConstructorToEmit(GlobalDecl CopyCtorDecl) {
for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
FieldEnd = ClassDecl->field_end();
Field != FieldEnd; ++Field) {
- assert(!(*Field)->isAnonymousStructOrUnion() &&
- "FIXME. Anonymous union NYI - DeferredCopyConstructorToEmit");
QualType FieldType = Context.getCanonicalType((*Field)->getType());
if (const ArrayType *Array = Context.getAsArrayType(FieldType))
FieldType = Array->getElementType();
if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
+ if ((*Field)->isAnonymousStructOrUnion())
+ continue;
CXXRecordDecl *FieldClassDecl
- = cast<CXXRecordDecl>(FieldClassType->getDecl());
+ = cast<CXXRecordDecl>(FieldClassType->getDecl());
if (CXXConstructorDecl *FieldCopyCtor =
FieldClassDecl->getCopyConstructor(Context, 0))
GetAddrOfCXXConstructor(FieldCopyCtor, Ctor_Complete);
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index a0bcfb2b780..a4005bae343 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -880,10 +880,16 @@ static void *GetKeyForTopLevelField(FieldDecl *Field) {
return static_cast<void *>(Field);
}
-static void *GetKeyForMember(CXXBaseOrMemberInitializer *Member) {
+static void *GetKeyForMember(CXXBaseOrMemberInitializer *Member,
+ bool MemberMaybeAnon=false) {
// For fields injected into the class via declaration of an anonymous union,
// use its anonymous union class declaration as the unique key.
if (FieldDecl *Field = Member->getMember()) {
+ // After BuildBaseOrMemberInitializers call, Field is the anonymous union
+ // data member of the class. Data member used in the initializer list is
+ // in AnonUnionMember field.
+ if (MemberMaybeAnon && Field->isAnonymousStructOrUnion())
+ Field = Member->getAnonUnionMember();
if (Field->getDeclContext()->isRecord()) {
RecordDecl *RD = cast<RecordDecl>(Field->getDeclContext());
if (RD->isAnonymousStructOrUnion())
@@ -973,7 +979,7 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl,
for (unsigned i = 0; i < NumMemInits; i++) {
CXXBaseOrMemberInitializer *Member =
static_cast<CXXBaseOrMemberInitializer*>(MemInits[i]);
- void *MemberInCtorList = GetKeyForMember(Member);
+ void *MemberInCtorList = GetKeyForMember(Member, true);
for (; curIndex < Last; curIndex++)
if (MemberInCtorList == AllBaseOrMembers[curIndex])
OpenPOWER on IntegriCloud