forked from OSchip/llvm-project
Make std::initializer_list member initializers 'work'.
llvm-svn: 150930
This commit is contained in:
parent
7c24d8e70b
commit
4e04dd1979
|
@ -418,40 +418,46 @@ static void EmitAggMemberInitializer(CodeGenFunction &CGF,
|
|||
ArrayRef<VarDecl *> ArrayIndexes,
|
||||
unsigned Index) {
|
||||
if (Index == ArrayIndexes.size()) {
|
||||
CodeGenFunction::RunCleanupsScope Cleanups(CGF);
|
||||
|
||||
LValue LV = LHS;
|
||||
if (ArrayIndexVar) {
|
||||
// If we have an array index variable, load it and use it as an offset.
|
||||
// Then, increment the value.
|
||||
llvm::Value *Dest = LHS.getAddress();
|
||||
llvm::Value *ArrayIndex = CGF.Builder.CreateLoad(ArrayIndexVar);
|
||||
Dest = CGF.Builder.CreateInBoundsGEP(Dest, ArrayIndex, "destaddress");
|
||||
llvm::Value *Next = llvm::ConstantInt::get(ArrayIndex->getType(), 1);
|
||||
Next = CGF.Builder.CreateAdd(ArrayIndex, Next, "inc");
|
||||
CGF.Builder.CreateStore(Next, ArrayIndexVar);
|
||||
{ // Scope for Cleanups.
|
||||
CodeGenFunction::RunCleanupsScope Cleanups(CGF);
|
||||
|
||||
// Update the LValue.
|
||||
LV.setAddress(Dest);
|
||||
CharUnits Align = CGF.getContext().getTypeAlignInChars(T);
|
||||
LV.setAlignment(std::min(Align, LV.getAlignment()));
|
||||
if (ArrayIndexVar) {
|
||||
// If we have an array index variable, load it and use it as an offset.
|
||||
// Then, increment the value.
|
||||
llvm::Value *Dest = LHS.getAddress();
|
||||
llvm::Value *ArrayIndex = CGF.Builder.CreateLoad(ArrayIndexVar);
|
||||
Dest = CGF.Builder.CreateInBoundsGEP(Dest, ArrayIndex, "destaddress");
|
||||
llvm::Value *Next = llvm::ConstantInt::get(ArrayIndex->getType(), 1);
|
||||
Next = CGF.Builder.CreateAdd(ArrayIndex, Next, "inc");
|
||||
CGF.Builder.CreateStore(Next, ArrayIndexVar);
|
||||
|
||||
// Update the LValue.
|
||||
LV.setAddress(Dest);
|
||||
CharUnits Align = CGF.getContext().getTypeAlignInChars(T);
|
||||
LV.setAlignment(std::min(Align, LV.getAlignment()));
|
||||
}
|
||||
|
||||
if (!CGF.hasAggregateLLVMType(T)) {
|
||||
CGF.EmitScalarInit(Init, /*decl*/ 0, LV, false);
|
||||
} else if (T->isAnyComplexType()) {
|
||||
CGF.EmitComplexExprIntoAddr(Init, LV.getAddress(),
|
||||
LV.isVolatileQualified());
|
||||
} else {
|
||||
AggValueSlot Slot =
|
||||
AggValueSlot::forLValue(LV,
|
||||
AggValueSlot::IsDestructed,
|
||||
AggValueSlot::DoesNotNeedGCBarriers,
|
||||
AggValueSlot::IsNotAliased);
|
||||
|
||||
CGF.EmitAggExpr(Init, Slot);
|
||||
}
|
||||
}
|
||||
|
||||
if (!CGF.hasAggregateLLVMType(T)) {
|
||||
CGF.EmitScalarInit(Init, /*decl*/ 0, LV, false);
|
||||
} else if (T->isAnyComplexType()) {
|
||||
CGF.EmitComplexExprIntoAddr(Init, LV.getAddress(),
|
||||
LV.isVolatileQualified());
|
||||
} else {
|
||||
AggValueSlot Slot =
|
||||
AggValueSlot::forLValue(LV,
|
||||
AggValueSlot::IsDestructed,
|
||||
AggValueSlot::DoesNotNeedGCBarriers,
|
||||
AggValueSlot::IsNotAliased);
|
||||
|
||||
CGF.EmitAggExpr(Init, Slot);
|
||||
}
|
||||
|
||||
// Now, outside of the initializer cleanup scope, destroy the backing array
|
||||
// for a std::initializer_list member.
|
||||
CGF.MaybeEmitStdInitializerListCleanup(LV, Init);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -164,3 +164,34 @@ void fn9() {
|
|||
// CHECK-NOT: call void @_ZN10destroyme1D1Ev
|
||||
// CHECK: ret void
|
||||
}
|
||||
|
||||
struct haslist1 {
|
||||
std::initializer_list<int> il;
|
||||
haslist1();
|
||||
};
|
||||
|
||||
// CHECK: define void @_ZN8haslist1C2Ev
|
||||
haslist1::haslist1()
|
||||
// CHECK: alloca [3 x i32]
|
||||
// CHECK: store i32 1
|
||||
// CHECK: store i32 2
|
||||
// CHECK: store i32 3
|
||||
// CHECK: store i{{32|64}} 3
|
||||
: il{1, 2, 3}
|
||||
{
|
||||
destroyme2 dm2;
|
||||
}
|
||||
|
||||
struct haslist2 {
|
||||
std::initializer_list<destroyme1> il;
|
||||
haslist2();
|
||||
};
|
||||
|
||||
// CHECK: define void @_ZN8haslist2C2Ev
|
||||
haslist2::haslist2()
|
||||
: il{destroyme1(), destroyme1()}
|
||||
{
|
||||
destroyme2 dm2;
|
||||
// CHECK: call void @_ZN10destroyme2D1Ev
|
||||
// CHECK: call void @_ZN10destroyme1D1Ev
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue