]> granicus.if.org Git - clang/commitdiff
Make std::initializer_list member initializers 'work'.
authorSebastian Redl <sebastian.redl@getdesigned.at>
Sun, 19 Feb 2012 15:41:54 +0000 (15:41 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Sun, 19 Feb 2012 15:41:54 +0000 (15:41 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150930 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGClass.cpp
test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp

index 7b492fba17afc8568bb552279343402de77a0b7a..f269b675a0d656dfbb7712a01cd2f737cb63fa77 100644 (file)
@@ -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);    
-
-      // Update the LValue.
-      LV.setAddress(Dest);
-      CharUnits Align = CGF.getContext().getTypeAlignInChars(T);
-      LV.setAlignment(std::min(Align, LV.getAlignment()));
-    }
+    { // 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()));
+      }
 
-    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;
   }
   
index 7dc5503c96910c7626c253b13d54e2b5943d9bbb..55e399223850b4d24c202c34d886919ebb82a6f9 100644 (file)
@@ -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
+}