forked from OSchip/llvm-project
Fix up EmitMemberInitializer to handle many more cases.
llvm-svn: 88999
This commit is contained in:
parent
b43e1ff236
commit
e85ef718d5
|
@ -1543,6 +1543,18 @@ static void EmitMemberInitializer(CodeGenFunction &CGF,
|
||||||
if (Array)
|
if (Array)
|
||||||
FieldType = CGF.getContext().getBaseElementType(FieldType);
|
FieldType = CGF.getContext().getBaseElementType(FieldType);
|
||||||
|
|
||||||
|
// We lose the constructor for anonymous union members, so handle them
|
||||||
|
// explicitly.
|
||||||
|
// FIXME: This is somwhat ugly.
|
||||||
|
if (MemberInit->getAnonUnionMember() && FieldType->getAs<RecordType>()) {
|
||||||
|
if (MemberInit->getNumArgs())
|
||||||
|
CGF.EmitAggExpr(*MemberInit->arg_begin(), LHS.getAddress(),
|
||||||
|
LHS.isVolatileQualified());
|
||||||
|
else
|
||||||
|
CGF.EmitAggregateClear(LHS.getAddress(), Field->getType());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (FieldType->getAs<RecordType>()) {
|
if (FieldType->getAs<RecordType>()) {
|
||||||
assert(MemberInit->getConstructor() &&
|
assert(MemberInit->getConstructor() &&
|
||||||
"EmitCtorPrologue - no constructor to initialize member");
|
"EmitCtorPrologue - no constructor to initialize member");
|
||||||
|
@ -1565,21 +1577,22 @@ static void EmitMemberInitializer(CodeGenFunction &CGF,
|
||||||
assert(MemberInit->getNumArgs() == 1 && "Initializer count must be 1 only");
|
assert(MemberInit->getNumArgs() == 1 && "Initializer count must be 1 only");
|
||||||
Expr *RhsExpr = *MemberInit->arg_begin();
|
Expr *RhsExpr = *MemberInit->arg_begin();
|
||||||
RValue RHS;
|
RValue RHS;
|
||||||
if (FieldType->isReferenceType())
|
if (FieldType->isReferenceType()) {
|
||||||
RHS = CGF.EmitReferenceBindingToExpr(RhsExpr, FieldType,
|
RHS = CGF.EmitReferenceBindingToExpr(RhsExpr, FieldType,
|
||||||
/*IsInitializer=*/true);
|
/*IsInitializer=*/true);
|
||||||
else if (FieldType->isMemberFunctionPointerType())
|
|
||||||
RHS = RValue::get(CGF.CGM.EmitConstantExpr(RhsExpr, FieldType, &CGF));
|
|
||||||
else
|
|
||||||
RHS = RValue::get(CGF.EmitScalarExpr(RhsExpr, true));
|
|
||||||
if (Array && !FieldType->getAs<RecordType>()) {
|
|
||||||
// value initialize a non-class array data member using arr() syntax in
|
|
||||||
// initializer list.
|
|
||||||
QualType Ty = CGF.getContext().getCanonicalType((Field)->getType());
|
|
||||||
CGF.EmitMemSetToZero(LHS.getAddress(), Ty);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
CGF.EmitStoreThroughLValue(RHS, LHS, FieldType);
|
CGF.EmitStoreThroughLValue(RHS, LHS, FieldType);
|
||||||
|
} else if (Array) {
|
||||||
|
CGF.EmitMemSetToZero(LHS.getAddress(), Field->getType());
|
||||||
|
} else if (!CGF.hasAggregateLLVMType(RhsExpr->getType())) {
|
||||||
|
RHS = RValue::get(CGF.EmitScalarExpr(RhsExpr, true));
|
||||||
|
CGF.EmitStoreThroughLValue(RHS, LHS, FieldType);
|
||||||
|
} else if (RhsExpr->getType()->isAnyComplexType()) {
|
||||||
|
CGF.EmitComplexExprIntoAddr(RhsExpr, LHS.getAddress(),
|
||||||
|
LHS.isVolatileQualified());
|
||||||
|
} else {
|
||||||
|
// Handle member function pointers; other aggregates shouldn't get this far.
|
||||||
|
CGF.EmitAggExpr(RhsExpr, LHS.getAddress(), LHS.isVolatileQualified());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// EmitCtorPrologue - This routine generates necessary code to initialize
|
/// EmitCtorPrologue - This routine generates necessary code to initialize
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
// RUN: clang-cc %s -emit-llvm-only -verify
|
||||||
|
|
||||||
|
struct A {int a;};
|
||||||
|
struct B {float a;};
|
||||||
|
struct C {
|
||||||
|
union {
|
||||||
|
A a;
|
||||||
|
B b[10];
|
||||||
|
};
|
||||||
|
_Complex float c;
|
||||||
|
int d[10];
|
||||||
|
void (C::*e)();
|
||||||
|
C() : a(), c(), d(), e() {}
|
||||||
|
C(A x) : a(x) {}
|
||||||
|
C(void (C::*x)(), int y) : b(), c(y), e(x) {}
|
||||||
|
};
|
||||||
|
A x;
|
||||||
|
C a, b(x), c(0, 2);
|
Loading…
Reference in New Issue