diff options
-rw-r--r-- | lib/CodeGen/CGClass.cpp | 15 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 22 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 3 | ||||
-rw-r--r-- | test/CodeGenCXX/anonymous-union-member-initializer.cpp | 10 |
4 files changed, 19 insertions, 31 deletions
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index 332033cfc4..e37fa3ab72 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -563,16 +563,19 @@ static void EmitMemberInitializer(CodeGenFunction &CGF, llvm::Value *ThisPtr = CGF.LoadCXXThis(); QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl); - LValue LHS; + LValue LHS = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy); - // If we are initializing an anonymous union field, drill down to the field. if (MemberInit->isIndirectMemberInitializer()) { - LHS = CGF.EmitLValueForAnonRecordField(ThisPtr, - MemberInit->getIndirectMember(), 0); + // If we are initializing an anonymous union field, drill down to + // the field. + IndirectFieldDecl *IndirectField = MemberInit->getIndirectMember(); + IndirectFieldDecl::chain_iterator I = IndirectField->chain_begin(), + IEnd = IndirectField->chain_end(); + for ( ; I != IEnd; ++I) + LHS = CGF.EmitLValueForFieldInitialization(LHS, cast<FieldDecl>(*I)); FieldType = MemberInit->getIndirectMember()->getAnonField()->getType(); } else { - LValue ThisLHSLV = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy); - LHS = CGF.EmitLValueForFieldInitialization(ThisLHSLV, Field); + LHS = CGF.EmitLValueForFieldInitialization(LHS, Field); } // Special case: if we are in a copy or move constructor, and we are copying diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 7e5fdd044b..ecee7b4931 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -2056,28 +2056,6 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) { llvm_unreachable("Unhandled member declaration!"); } -/// EmitLValueForAnonRecordField - Given that the field is a member of -/// an anonymous struct or union buried inside a record, and given -/// that the base value is a pointer to the enclosing record, derive -/// an lvalue for the ultimate field. -LValue CodeGenFunction::EmitLValueForAnonRecordField(llvm::Value *BaseValue, - const IndirectFieldDecl *Field, - unsigned CVRQualifiers) { - IndirectFieldDecl::chain_iterator I = Field->chain_begin(), - IEnd = Field->chain_end(); - while (true) { - QualType RecordTy = - getContext().getTypeDeclType(cast<FieldDecl>(*I)->getParent()); - LValue LV = EmitLValueForField(MakeAddrLValue(BaseValue, RecordTy), - cast<FieldDecl>(*I)); - if (++I == IEnd) return LV; - - assert(LV.isSimple()); - BaseValue = LV.getAddress(); - CVRQualifiers |= LV.getVRQualifiers(); - } -} - LValue CodeGenFunction::EmitLValueForField(LValue base, const FieldDecl *field) { if (field->isBitField()) { diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 697571bf1e..ed3e43beb0 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -2162,9 +2162,6 @@ public: llvm::Value *EmitIvarOffset(const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar); - LValue EmitLValueForAnonRecordField(llvm::Value* Base, - const IndirectFieldDecl* Field, - unsigned CVRQualifiers); LValue EmitLValueForField(LValue Base, const FieldDecl* Field); /// EmitLValueForFieldInitialization - Like EmitLValueForField, except that diff --git a/test/CodeGenCXX/anonymous-union-member-initializer.cpp b/test/CodeGenCXX/anonymous-union-member-initializer.cpp index a12ae53f39..8dc4f4721d 100644 --- a/test/CodeGenCXX/anonymous-union-member-initializer.cpp +++ b/test/CodeGenCXX/anonymous-union-member-initializer.cpp @@ -179,3 +179,13 @@ namespace PR9683 { }; QueueEntry QE; } + +namespace PR13154 { + struct IndirectReferenceField { + struct { + float &x; + }; + IndirectReferenceField(float &x); + }; + IndirectReferenceField::IndirectReferenceField(float &xx) : x(xx) {} +} |