summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGClass.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-06-12 22:31:48 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-06-12 22:31:48 +0000
commitcc1b96d356a0bd85c033309b8cfa965f36ae8aa6 (patch)
tree0494bcbc5d7f1e890c1c814a70b4ee0dd0a8352e /clang/lib/CodeGen/CGClass.cpp
parent6a0c9ae4f93fd29b7bae48513674ab18dda73f9e (diff)
downloadbcm5719-llvm-cc1b96d356a0bd85c033309b8cfa965f36ae8aa6.tar.gz
bcm5719-llvm-cc1b96d356a0bd85c033309b8cfa965f36ae8aa6.zip
PR12086, PR15117
Introduce CXXStdInitializerListExpr node, representing the implicit construction of a std::initializer_list<T> object from its underlying array. The AST representation of such an expression goes from an InitListExpr with a flag set, to a CXXStdInitializerListExpr containing a MaterializeTemporaryExpr containing an InitListExpr (possibly wrapped in a CXXBindTemporaryExpr). This more detailed representation has several advantages, the most important of which is that the new MaterializeTemporaryExpr allows us to directly model lifetime extension of the underlying temporary array. Using that, this patch *drastically* simplifies the IR generation of this construct, provides IR generation support for nested global initializer_list objects, fixes several bugs where the destructors for the underlying array would accidentally not get invoked, and provides constant expression evaluation support for std::initializer_list objects. llvm-svn: 183872
Diffstat (limited to 'clang/lib/CodeGen/CGClass.cpp')
-rw-r--r--clang/lib/CodeGen/CGClass.cpp93
1 files changed, 41 insertions, 52 deletions
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index b3a14772ad0..9d08d1c7f7a 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -433,52 +433,45 @@ static void EmitAggMemberInitializer(CodeGenFunction &CGF,
unsigned Index) {
if (Index == ArrayIndexes.size()) {
LValue LV = LHS;
- { // Scope for Cleanups.
- CodeGenFunction::RunCleanupsScope Cleanups(CGF);
-
- 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()));
- }
- switch (CGF.getEvaluationKind(T)) {
- case TEK_Scalar:
- CGF.EmitScalarInit(Init, /*decl*/ 0, LV, false);
- break;
- case TEK_Complex:
- CGF.EmitComplexExprIntoLValue(Init, LV, /*isInit*/ true);
- break;
- case TEK_Aggregate: {
- AggValueSlot Slot =
- AggValueSlot::forLValue(LV,
- AggValueSlot::IsDestructed,
- AggValueSlot::DoesNotNeedGCBarriers,
- AggValueSlot::IsNotAliased);
-
- CGF.EmitAggExpr(Init, Slot);
- break;
- }
- }
+ 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()));
}
- // Now, outside of the initializer cleanup scope, destroy the backing array
- // for a std::initializer_list member.
- CGF.MaybeEmitStdInitializerListCleanup(LV.getAddress(), Init);
+ switch (CGF.getEvaluationKind(T)) {
+ case TEK_Scalar:
+ CGF.EmitScalarInit(Init, /*decl*/ 0, LV, false);
+ break;
+ case TEK_Complex:
+ CGF.EmitComplexExprIntoLValue(Init, LV, /*isInit*/ true);
+ break;
+ case TEK_Aggregate: {
+ AggValueSlot Slot =
+ AggValueSlot::forLValue(LV,
+ AggValueSlot::IsDestructed,
+ AggValueSlot::DoesNotNeedGCBarriers,
+ AggValueSlot::IsNotAliased);
+
+ CGF.EmitAggExpr(Init, Slot);
+ break;
+ }
+ }
return;
}
-
+
const ConstantArrayType *Array = CGF.getContext().getAsConstantArrayType(T);
assert(Array && "Array initialization without the array type?");
llvm::Value *IndexVar
@@ -512,16 +505,12 @@ static void EmitAggMemberInitializer(CodeGenFunction &CGF,
CGF.EmitBlock(ForBody);
llvm::BasicBlock *ContinueBlock = CGF.createBasicBlock("for.inc");
-
- {
- CodeGenFunction::RunCleanupsScope Cleanups(CGF);
-
- // Inside the loop body recurse to emit the inner loop or, eventually, the
- // constructor call.
- EmitAggMemberInitializer(CGF, LHS, Init, ArrayIndexVar,
- Array->getElementType(), ArrayIndexes, Index + 1);
- }
-
+
+ // Inside the loop body recurse to emit the inner loop or, eventually, the
+ // constructor call.
+ EmitAggMemberInitializer(CGF, LHS, Init, ArrayIndexVar,
+ Array->getElementType(), ArrayIndexes, Index + 1);
+
CGF.EmitBlock(ContinueBlock);
// Emit the increment of the loop counter.
@@ -726,7 +715,7 @@ void CodeGenFunction::EmitConstructorBody(FunctionArgList &Args) {
if (IsTryBody)
EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true);
- EHScopeStack::stable_iterator CleanupDepth = EHStack.stable_begin();
+ RunCleanupsScope RunCleanups(*this);
// TODO: in restricted cases, we can emit the vbase initializers of
// a complete ctor and then delegate to the base ctor.
@@ -745,7 +734,7 @@ void CodeGenFunction::EmitConstructorBody(FunctionArgList &Args) {
// initializers, which includes (along the exceptional path) the
// destructors for those members and bases that were fully
// constructed.
- PopCleanupBlocks(CleanupDepth);
+ RunCleanups.ForceCleanup();
if (IsTryBody)
ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true);
OpenPOWER on IntegriCloud