<div dir="ltr">Hi Richard,<div><br>It looks like this broke CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp<div style><br></div><div style>See - <a href="http://lab.llvm.org:8013/builders/clang-x86_64-darwin11-R/builds/1159">http://lab.llvm.org:8013/builders/clang-x86_64-darwin11-R/builds/1159</a></div>
</div><div style><br></div><div style>Cheers,</div><div style>Lang.</div><div style><br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Jun 12, 2013 at 3:31 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard-llvm@metafoo.co.uk" target="_blank">richard-llvm@metafoo.co.uk</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rsmith<br>
Date: Wed Jun 12 17:31:48 2013<br>
New Revision: 183872<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=183872&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=183872&view=rev</a><br>
Log:<br>
PR12086, PR15117<br>
<br>
Introduce CXXStdInitializerListExpr node, representing the implicit<br>
construction of a std::initializer_list<T> object from its underlying array.<br>
The AST representation of such an expression goes from an InitListExpr with a<br>
flag set, to a CXXStdInitializerListExpr containing a MaterializeTemporaryExpr<br>
containing an InitListExpr (possibly wrapped in a CXXBindTemporaryExpr).<br>
<br>
This more detailed representation has several advantages, the most important of<br>
which is that the new MaterializeTemporaryExpr allows us to directly model<br>
lifetime extension of the underlying temporary array. Using that, this patch<br>
*drastically* simplifies the IR generation of this construct, provides IR<br>
generation support for nested global initializer_list objects, fixes several<br>
bugs where the destructors for the underlying array would accidentally not get<br>
invoked, and provides constant expression evaluation support for<br>
std::initializer_list objects.<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/AST/Expr.h<br>
    cfe/trunk/include/clang/AST/ExprCXX.h<br>
    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h<br>
    cfe/trunk/include/clang/AST/Stmt.h<br>
    cfe/trunk/include/clang/Basic/StmtNodes.td<br>
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h<br>
    cfe/trunk/lib/AST/Expr.cpp<br>
    cfe/trunk/lib/AST/ExprClassification.cpp<br>
    cfe/trunk/lib/AST/ExprConstant.cpp<br>
    cfe/trunk/lib/AST/ItaniumMangle.cpp<br>
    cfe/trunk/lib/AST/StmtPrinter.cpp<br>
    cfe/trunk/lib/AST/StmtProfile.cpp<br>
    cfe/trunk/lib/CodeGen/CGClass.cpp<br>
    cfe/trunk/lib/CodeGen/CGDecl.cpp<br>
    cfe/trunk/lib/CodeGen/CGExpr.cpp<br>
    cfe/trunk/lib/CodeGen/CGExprAgg.cpp<br>
    cfe/trunk/lib/CodeGen/CGExprCXX.cpp<br>
    cfe/trunk/lib/CodeGen/CGExprConstant.cpp<br>
    cfe/trunk/lib/CodeGen/CodeGenFunction.h<br>
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp<br>
    cfe/trunk/lib/CodeGen/CodeGenModule.h<br>
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br>
    cfe/trunk/lib/Sema/SemaExceptionSpec.cpp<br>
    cfe/trunk/lib/Sema/SemaInit.cpp<br>
    cfe/trunk/lib/Sema/TreeTransform.h<br>
    cfe/trunk/lib/Serialization/ASTReaderStmt.cpp<br>
    cfe/trunk/lib/Serialization/ASTWriter.cpp<br>
    cfe/trunk/lib/Serialization/ASTWriterStmt.cpp<br>
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp<br>
    cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp<br>
    cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp<br>
    cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp<br>
    cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp<br>
    cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp<br>
    cfe/trunk/test/SemaCXX/constant-expression-cxx1y.cpp<br>
    cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp<br>
    cfe/trunk/tools/libclang/CXCursor.cpp<br>
    cfe/trunk/tools/libclang/RecursiveASTVisitor.h<br>
<br>
Modified: cfe/trunk/include/clang/AST/Expr.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/AST/Expr.h (original)<br>
+++ cfe/trunk/include/clang/AST/Expr.h Wed Jun 12 17:31:48 2013<br>
@@ -3794,13 +3794,6 @@ public:<br>
     InitListExprBits.HadArrayRangeDesignator = ARD;<br>
   }<br>
<br>
-  bool initializesStdInitializerList() const {<br>
-    return InitListExprBits.InitializesStdInitializerList != 0;<br>
-  }<br>
-  void setInitializesStdInitializerList(bool ISIL = true) {<br>
-    InitListExprBits.InitializesStdInitializerList = ISIL;<br>
-  }<br>
-<br>
   SourceLocation getLocStart() const LLVM_READONLY;<br>
   SourceLocation getLocEnd() const LLVM_READONLY;<br>
<br>
<br>
Modified: cfe/trunk/include/clang/AST/ExprCXX.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)<br>
+++ cfe/trunk/include/clang/AST/ExprCXX.h Wed Jun 12 17:31:48 2013<br>
@@ -474,6 +474,45 @@ public:<br>
   child_range children() { return child_range(); }<br>
 };<br>
<br>
+/// \brief Implicit construction of a std::initializer_list<T> object from an<br>
+/// array temporary within list-initialization (C++11 [dcl.init.list]p5).<br>
+class CXXStdInitializerListExpr : public Expr {<br>
+  Stmt *SubExpr;<br>
+<br>
+  CXXStdInitializerListExpr(EmptyShell Empty)<br>
+    : Expr(CXXStdInitializerListExprClass, Empty), SubExpr(0) {}<br>
+<br>
+public:<br>
+  CXXStdInitializerListExpr(QualType Ty, Expr *SubExpr)<br>
+    : Expr(CXXStdInitializerListExprClass, Ty, VK_RValue, OK_Ordinary,<br>
+           Ty->isDependentType(), SubExpr->isValueDependent(),<br>
+           SubExpr->isInstantiationDependent(),<br>
+           SubExpr->containsUnexpandedParameterPack()),<br>
+      SubExpr(SubExpr) {}<br>
+<br>
+  Expr *getSubExpr() { return static_cast<Expr*>(SubExpr); }<br>
+  const Expr *getSubExpr() const { return static_cast<const Expr*>(SubExpr); }<br>
+<br>
+  SourceLocation getLocStart() const LLVM_READONLY {<br>
+    return SubExpr->getLocStart();<br>
+  }<br>
+  SourceLocation getLocEnd() const LLVM_READONLY {<br>
+    return SubExpr->getLocEnd();<br>
+  }<br>
+  SourceRange getSourceRange() const LLVM_READONLY {<br>
+    return SubExpr->getSourceRange();<br>
+  }<br>
+<br>
+  static bool classof(const Stmt *S) {<br>
+    return S->getStmtClass() == CXXStdInitializerListExprClass;<br>
+  }<br>
+<br>
+  child_range children() { return child_range(&SubExpr, &SubExpr + 1); }<br>
+<br>
+  friend class ASTReader;<br>
+  friend class ASTStmtReader;<br>
+};<br>
+<br>
 /// CXXTypeidExpr - A C++ @c typeid expression (C++ [expr.typeid]), which gets<br>
 /// the type_info that corresponds to the supplied type, or the (possibly<br>
 /// dynamic) type of the supplied expression.<br>
<br>
Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)<br>
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Wed Jun 12 17:31:48 2013<br>
@@ -2177,6 +2177,7 @@ DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {<br>
 DEF_TRAVERSE_STMT(CXXDeleteExpr, { })<br>
 DEF_TRAVERSE_STMT(ExprWithCleanups, { })<br>
 DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, { })<br>
+DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, { })<br>
 DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {<br>
   TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));<br>
   if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())<br>
<br>
Modified: cfe/trunk/include/clang/AST/Stmt.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/AST/Stmt.h (original)<br>
+++ cfe/trunk/include/clang/AST/Stmt.h Wed Jun 12 17:31:48 2013<br>
@@ -266,10 +266,6 @@ protected:<br>
     /// Whether this initializer list originally had a GNU array-range<br>
     /// designator in it. This is a temporary marker used by CodeGen.<br>
     unsigned HadArrayRangeDesignator : 1;<br>
-<br>
-    /// Whether this initializer list initializes a std::initializer_list<br>
-    /// object.<br>
-    unsigned InitializesStdInitializerList : 1;<br>
   };<br>
<br>
   class TypeTraitExprBitfields {<br>
<br>
Modified: cfe/trunk/include/clang/Basic/StmtNodes.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/StmtNodes.td?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/StmtNodes.td?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Basic/StmtNodes.td (original)<br>
+++ cfe/trunk/include/clang/Basic/StmtNodes.td Wed Jun 12 17:31:48 2013<br>
@@ -110,6 +110,7 @@ def CXXThrowExpr : DStmt<Expr>;<br>
 def CXXDefaultArgExpr : DStmt<Expr>;<br>
 def CXXDefaultInitExpr : DStmt<Expr>;<br>
 def CXXScalarValueInitExpr : DStmt<Expr>;<br>
+def CXXStdInitializerListExpr : DStmt<Expr>;<br>
 def CXXNewExpr : DStmt<Expr>;<br>
 def CXXDeleteExpr : DStmt<Expr>;<br>
 def CXXPseudoDestructorExpr : DStmt<Expr>;<br>
<br>
Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)<br>
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Wed Jun 12 17:31:48 2013<br>
@@ -1259,6 +1259,8 @@ namespace clang {<br>
       EXPR_CXX_FUNCTIONAL_CAST,<br>
       /// \brief A UserDefinedLiteral record.<br>
       EXPR_USER_DEFINED_LITERAL,<br>
+      /// \brief A CXXStdInitializerListExpr record.<br>
+      EXPR_CXX_STD_INITIALIZER_LIST,<br>
       /// \brief A CXXBoolLiteralExpr record.<br>
       EXPR_CXX_BOOL_LITERAL,<br>
       EXPR_CXX_NULL_PTR_LITERAL,  // CXXNullPtrLiteralExpr<br>
<br>
Modified: cfe/trunk/lib/AST/Expr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/AST/Expr.cpp (original)<br>
+++ cfe/trunk/lib/AST/Expr.cpp Wed Jun 12 17:31:48 2013<br>
@@ -1789,7 +1789,6 @@ InitListExpr::InitListExpr(ASTContext &C<br>
     LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), AltForm(0, true)<br>
 {<br>
   sawArrayRangeDesignator(false);<br>
-  setInitializesStdInitializerList(false);<br>
   for (unsigned I = 0; I != initExprs.size(); ++I) {<br>
     if (initExprs[I]->isTypeDependent())<br>
       ExprBits.TypeDependent = true;<br>
@@ -2836,6 +2835,7 @@ bool Expr::HasSideEffects(const ASTConte<br>
   case DesignatedInitExprClass:<br>
   case ParenListExprClass:<br>
   case CXXPseudoDestructorExprClass:<br>
+  case CXXStdInitializerListExprClass:<br>
   case SubstNonTypeTemplateParmExprClass:<br>
   case MaterializeTemporaryExprClass:<br>
   case ShuffleVectorExprClass:<br>
<br>
Modified: cfe/trunk/lib/AST/ExprClassification.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprClassification.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprClassification.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/AST/ExprClassification.cpp (original)<br>
+++ cfe/trunk/lib/AST/ExprClassification.cpp Wed Jun 12 17:31:48 2013<br>
@@ -353,6 +353,7 @@ static Cl::Kinds ClassifyInternal(ASTCon<br>
   case Expr::CXXConstructExprClass:<br>
   case Expr::CXXTemporaryObjectExprClass:<br>
   case Expr::LambdaExprClass:<br>
+  case Expr::CXXStdInitializerListExprClass:<br>
     return Cl::CL_ClassTemporary;<br>
<br>
   case Expr::VAArgExprClass:<br>
<br>
Modified: cfe/trunk/lib/AST/ExprConstant.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)<br>
+++ cfe/trunk/lib/AST/ExprConstant.cpp Wed Jun 12 17:31:48 2013<br>
@@ -4576,6 +4576,7 @@ namespace {<br>
     bool VisitCastExpr(const CastExpr *E);<br>
     bool VisitInitListExpr(const InitListExpr *E);<br>
     bool VisitCXXConstructExpr(const CXXConstructExpr *E);<br>
+    bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr *E);<br>
   };<br>
 }<br>
<br>
@@ -4691,10 +4692,6 @@ bool RecordExprEvaluator::VisitCastExpr(<br>
 }<br>
<br>
 bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) {<br>
-  // Cannot constant-evaluate std::initializer_list inits.<br>
-  if (E->initializesStdInitializerList())<br>
-    return false;<br>
-<br>
   const RecordDecl *RD = E->getType()->castAs<RecordType>()->getDecl();<br>
   if (RD->isInvalidDecl()) return false;<br>
   const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);<br>
@@ -4810,6 +4807,58 @@ bool RecordExprEvaluator::VisitCXXConstr<br>
                                Result);<br>
 }<br>
<br>
+bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(<br>
+    const CXXStdInitializerListExpr *E) {<br>
+  const ConstantArrayType *ArrayType =<br>
+      Info.Ctx.getAsConstantArrayType(E->getSubExpr()->getType());<br>
+<br>
+  LValue Array;<br>
+  if (!EvaluateLValue(E->getSubExpr(), Array, Info))<br>
+    return false;<br>
+<br>
+  // Get a pointer to the first element of the array.<br>
+  Array.addArray(Info, E, ArrayType);<br>
+<br>
+  // FIXME: Perform the checks on the field types in SemaInit.<br>
+  RecordDecl *Record = E->getType()->castAs<RecordType>()->getDecl();<br>
+  RecordDecl::field_iterator Field = Record->field_begin();<br>
+  if (Field == Record->field_end())<br>
+    return Error(E);<br>
+<br>
+  // Start pointer.<br>
+  if (!Field->getType()->isPointerType() ||<br>
+      !Info.Ctx.hasSameType(Field->getType()->getPointeeType(),<br>
+                            ArrayType->getElementType()))<br>
+    return Error(E);<br>
+<br>
+  // FIXME: What if the initializer_list type has base classes, etc?<br>
+  Result = APValue(APValue::UninitStruct(), 0, 2);<br>
+  Array.moveInto(Result.getStructField(0));<br>
+<br>
+  if (++Field == Record->field_end())<br>
+    return Error(E);<br>
+<br>
+  if (Field->getType()->isPointerType() &&<br>
+      Info.Ctx.hasSameType(Field->getType()->getPointeeType(),<br>
+                           ArrayType->getElementType())) {<br>
+    // End pointer.<br>
+    if (!HandleLValueArrayAdjustment(Info, E, Array,<br>
+                                     ArrayType->getElementType(),<br>
+                                     ArrayType->getSize().getZExtValue()))<br>
+      return false;<br>
+    Array.moveInto(Result.getStructField(1));<br>
+  } else if (Info.Ctx.hasSameType(Field->getType(), Info.Ctx.getSizeType()))<br>
+    // Length.<br>
+    Result.getStructField(1) = APValue(APSInt(ArrayType->getSize()));<br>
+  else<br>
+    return Error(E);<br>
+<br>
+  if (++Field != Record->field_end())<br>
+    return Error(E);<br>
+<br>
+  return true;<br>
+}<br>
+<br>
 static bool EvaluateRecord(const Expr *E, const LValue &This,<br>
                            APValue &Result, EvalInfo &Info) {<br>
   assert(E->isRValue() && E->getType()->isRecordType() &&<br>
@@ -7762,6 +7811,7 @@ static ICEDiag CheckICE(const Expr* E, A<br>
   case Expr::UnresolvedLookupExprClass:<br>
   case Expr::DependentScopeDeclRefExprClass:<br>
   case Expr::CXXConstructExprClass:<br>
+  case Expr::CXXStdInitializerListExprClass:<br>
   case Expr::CXXBindTemporaryExprClass:<br>
   case Expr::ExprWithCleanupsClass:<br>
   case Expr::CXXTemporaryObjectExprClass:<br>
<br>
Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)<br>
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Wed Jun 12 17:31:48 2013<br>
@@ -2481,6 +2481,10 @@ recurse:<br>
     mangleExpression(cast<CXXDefaultInitExpr>(E)->getExpr(), Arity);<br>
     break;<br>
<br>
+  case Expr::CXXStdInitializerListExprClass:<br>
+    mangleExpression(cast<CXXStdInitializerListExpr>(E)->getSubExpr(), Arity);<br>
+    break;<br>
+<br>
   case Expr::SubstNonTypeTemplateParmExprClass:<br>
     mangleExpression(cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement(),<br>
                      Arity);<br>
<br>
Modified: cfe/trunk/lib/AST/StmtPrinter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)<br>
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Wed Jun 12 17:31:48 2013<br>
@@ -1534,6 +1534,10 @@ void StmtPrinter::VisitCXXConstructExpr(<br>
     OS << " }";<br>
 }<br>
<br>
+void StmtPrinter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {<br>
+  PrintExpr(E->getSubExpr());<br>
+}<br>
+<br>
 void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) {<br>
   // Just forward to the sub expression.<br>
   PrintExpr(E->getSubExpr());<br>
<br>
Modified: cfe/trunk/lib/AST/StmtProfile.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/AST/StmtProfile.cpp (original)<br>
+++ cfe/trunk/lib/AST/StmtProfile.cpp Wed Jun 12 17:31:48 2013<br>
@@ -758,6 +758,11 @@ void StmtProfiler::VisitCXXNullPtrLitera<br>
   VisitExpr(S);<br>
 }<br>
<br>
+void StmtProfiler::VisitCXXStdInitializerListExpr(<br>
+    const CXXStdInitializerListExpr *S) {<br>
+  VisitExpr(S);<br>
+}<br>
+<br>
 void StmtProfiler::VisitCXXTypeidExpr(const CXXTypeidExpr *S) {<br>
   VisitExpr(S);<br>
   if (S->isTypeOperand())<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGClass.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Wed Jun 12 17:31:48 2013<br>
@@ -433,52 +433,45 @@ static void EmitAggMemberInitializer(Cod<br>
                                      unsigned Index) {<br>
   if (Index == ArrayIndexes.size()) {<br>
     LValue LV = LHS;<br>
-    { // Scope for Cleanups.<br>
-      CodeGenFunction::RunCleanupsScope Cleanups(CGF);<br>
<br>
-      if (ArrayIndexVar) {<br>
-        // If we have an array index variable, load it and use it as an offset.<br>
-        // Then, increment the value.<br>
-        llvm::Value *Dest = LHS.getAddress();<br>
-        llvm::Value *ArrayIndex = CGF.Builder.CreateLoad(ArrayIndexVar);<br>
-        Dest = CGF.Builder.CreateInBoundsGEP(Dest, ArrayIndex, "destaddress");<br>
-        llvm::Value *Next = llvm::ConstantInt::get(ArrayIndex->getType(), 1);<br>
-        Next = CGF.Builder.CreateAdd(ArrayIndex, Next, "inc");<br>
-        CGF.Builder.CreateStore(Next, ArrayIndexVar);<br>
-<br>
-        // Update the LValue.<br>
-        LV.setAddress(Dest);<br>
-        CharUnits Align = CGF.getContext().getTypeAlignInChars(T);<br>
-        LV.setAlignment(std::min(Align, LV.getAlignment()));<br>
-      }<br>
-<br>
-      switch (CGF.getEvaluationKind(T)) {<br>
-      case TEK_Scalar:<br>
-        CGF.EmitScalarInit(Init, /*decl*/ 0, LV, false);<br>
-        break;<br>
-      case TEK_Complex:<br>
-        CGF.EmitComplexExprIntoLValue(Init, LV, /*isInit*/ true);<br>
-        break;<br>
-      case TEK_Aggregate: {<br>
-        AggValueSlot Slot =<br>
-          AggValueSlot::forLValue(LV,<br>
-                                  AggValueSlot::IsDestructed,<br>
-                                  AggValueSlot::DoesNotNeedGCBarriers,<br>
-                                  AggValueSlot::IsNotAliased);<br>
-<br>
-        CGF.EmitAggExpr(Init, Slot);<br>
-        break;<br>
-      }<br>
-      }<br>
+    if (ArrayIndexVar) {<br>
+      // If we have an array index variable, load it and use it as an offset.<br>
+      // Then, increment the value.<br>
+      llvm::Value *Dest = LHS.getAddress();<br>
+      llvm::Value *ArrayIndex = CGF.Builder.CreateLoad(ArrayIndexVar);<br>
+      Dest = CGF.Builder.CreateInBoundsGEP(Dest, ArrayIndex, "destaddress");<br>
+      llvm::Value *Next = llvm::ConstantInt::get(ArrayIndex->getType(), 1);<br>
+      Next = CGF.Builder.CreateAdd(ArrayIndex, Next, "inc");<br>
+      CGF.Builder.CreateStore(Next, ArrayIndexVar);<br>
+<br>
+      // Update the LValue.<br>
+      LV.setAddress(Dest);<br>
+      CharUnits Align = CGF.getContext().getTypeAlignInChars(T);<br>
+      LV.setAlignment(std::min(Align, LV.getAlignment()));<br>
     }<br>
<br>
-    // Now, outside of the initializer cleanup scope, destroy the backing array<br>
-    // for a std::initializer_list member.<br>
-    CGF.MaybeEmitStdInitializerListCleanup(LV.getAddress(), Init);<br>
+    switch (CGF.getEvaluationKind(T)) {<br>
+    case TEK_Scalar:<br>
+      CGF.EmitScalarInit(Init, /*decl*/ 0, LV, false);<br>
+      break;<br>
+    case TEK_Complex:<br>
+      CGF.EmitComplexExprIntoLValue(Init, LV, /*isInit*/ true);<br>
+      break;<br>
+    case TEK_Aggregate: {<br>
+      AggValueSlot Slot =<br>
+        AggValueSlot::forLValue(LV,<br>
+                                AggValueSlot::IsDestructed,<br>
+                                AggValueSlot::DoesNotNeedGCBarriers,<br>
+                                AggValueSlot::IsNotAliased);<br>
+<br>
+      CGF.EmitAggExpr(Init, Slot);<br>
+      break;<br>
+    }<br>
+    }<br>
<br>
     return;<br>
   }<br>
-<br>
+<br>
   const ConstantArrayType *Array = CGF.getContext().getAsConstantArrayType(T);<br>
   assert(Array && "Array initialization without the array type?");<br>
   llvm::Value *IndexVar<br>
@@ -512,16 +505,12 @@ static void EmitAggMemberInitializer(Cod<br>
<br>
   CGF.EmitBlock(ForBody);<br>
   llvm::BasicBlock *ContinueBlock = CGF.createBasicBlock("for.inc");<br>
-<br>
-  {<br>
-    CodeGenFunction::RunCleanupsScope Cleanups(CGF);<br>
-<br>
-    // Inside the loop body recurse to emit the inner loop or, eventually, the<br>
-    // constructor call.<br>
-    EmitAggMemberInitializer(CGF, LHS, Init, ArrayIndexVar,<br>
-                             Array->getElementType(), ArrayIndexes, Index + 1);<br>
-  }<br>
-<br>
+<br>
+  // Inside the loop body recurse to emit the inner loop or, eventually, the<br>
+  // constructor call.<br>
+  EmitAggMemberInitializer(CGF, LHS, Init, ArrayIndexVar,<br>
+                           Array->getElementType(), ArrayIndexes, Index + 1);<br>
+<br>
   CGF.EmitBlock(ContinueBlock);<br>
<br>
   // Emit the increment of the loop counter.<br>
@@ -726,7 +715,7 @@ void CodeGenFunction::EmitConstructorBod<br>
   if (IsTryBody)<br>
     EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true);<br>
<br>
-  EHScopeStack::stable_iterator CleanupDepth = EHStack.stable_begin();<br>
+  RunCleanupsScope RunCleanups(*this);<br>
<br>
   // TODO: in restricted cases, we can emit the vbase initializers of<br>
   // a complete ctor and then delegate to the base ctor.<br>
@@ -745,7 +734,7 @@ void CodeGenFunction::EmitConstructorBod<br>
   // initializers, which includes (along the exceptional path) the<br>
   // destructors for those members and bases that were fully<br>
   // constructed.<br>
-  PopCleanupBlocks(CleanupDepth);<br>
+  RunCleanups.ForceCleanup();<br>
<br>
   if (IsTryBody)<br>
     ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true);<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Wed Jun 12 17:31:48 2013<br>
@@ -1187,7 +1187,6 @@ void CodeGenFunction::EmitExprAsInit(con<br>
                                          AggValueSlot::DoesNotNeedGCBarriers,<br>
                                               AggValueSlot::IsNotAliased));<br>
     }<br>
-    MaybeEmitStdInitializerListCleanup(lvalue.getAddress(), init);<br>
     return;<br>
   }<br>
   llvm_unreachable("bad evaluation kind");<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Wed Jun 12 17:31:48 2013<br>
@@ -240,15 +240,6 @@ pushTemporaryCleanup(CodeGenFunction &CG<br>
     }<br>
   }<br>
<br>
-  if (const InitListExpr *ILE = dyn_cast<InitListExpr>(E)) {<br>
-    if (ILE->initializesStdInitializerList()) {<br>
-      // FIXME: This is wrong if the temporary has static or thread storage<br>
-      // duration.<br>
-      CGF.EmitStdInitializerListCleanup(ReferenceTemporary, ILE);<br>
-      return;<br>
-    }<br>
-  }<br>
-<br>
   CXXDestructorDecl *ReferenceTemporaryDtor = 0;<br>
   if (const RecordType *RT =<br>
           E->getType()->getBaseElementTypeUnsafe()->getAs<RecordType>()) {<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Wed Jun 12 17:31:48 2013<br>
@@ -91,7 +91,6 @@ public:<br>
<br>
   void EmitMoveFromReturnSlot(const Expr *E, RValue Src);<br>
<br>
-  void EmitStdInitializerList(llvm::Value *DestPtr, InitListExpr *InitList);<br>
   void EmitArrayInit(llvm::Value *DestPtr, llvm::ArrayType *AType,<br>
                      QualType elementType, InitListExpr *E);<br>
<br>
@@ -177,6 +176,7 @@ public:<br>
   void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);<br>
   void VisitCXXConstructExpr(const CXXConstructExpr *E);<br>
   void VisitLambdaExpr(LambdaExpr *E);<br>
+  void VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E);<br>
   void VisitExprWithCleanups(ExprWithCleanups *E);<br>
   void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);<br>
   void VisitCXXTypeidExpr(CXXTypeidExpr *E) { EmitAggLoadOfLValue(E); }<br>
@@ -345,89 +345,70 @@ void AggExprEmitter::EmitCopy(QualType t<br>
                         std::min(dest.getAlignment(), src.getAlignment()));<br>
 }<br>
<br>
-static QualType GetStdInitializerListElementType(QualType T) {<br>
-  // Just assume that this is really std::initializer_list.<br>
-  ClassTemplateSpecializationDecl *specialization =<br>
-      cast<ClassTemplateSpecializationDecl>(T->castAs<RecordType>()->getDecl());<br>
-  return specialization->getTemplateArgs()[0].getAsType();<br>
-}<br>
-<br>
-/// \brief Prepare cleanup for the temporary array.<br>
-static void EmitStdInitializerListCleanup(CodeGenFunction &CGF,<br>
-                                          QualType arrayType,<br>
-                                          llvm::Value *addr,<br>
-                                          const InitListExpr *initList) {<br>
-  QualType::DestructionKind dtorKind = arrayType.isDestructedType();<br>
-  if (!dtorKind)<br>
-    return; // Type doesn't need destroying.<br>
-  if (dtorKind != QualType::DK_cxx_destructor) {<br>
-    CGF.ErrorUnsupported(initList, "ObjC ARC type in initializer_list");<br>
-    return;<br>
-  }<br>
-<br>
-  CodeGenFunction::Destroyer *destroyer = CGF.getDestroyer(dtorKind);<br>
-  CGF.pushDestroy(NormalAndEHCleanup, addr, arrayType, destroyer,<br>
-                  /*EHCleanup=*/true);<br>
-}<br>
-<br>
 /// \brief Emit the initializer for a std::initializer_list initialized with a<br>
 /// real initializer list.<br>
-void AggExprEmitter::EmitStdInitializerList(llvm::Value *destPtr,<br>
-                                            InitListExpr *initList) {<br>
-  // We emit an array containing the elements, then have the init list point<br>
-  // at the array.<br>
-  ASTContext &ctx = CGF.getContext();<br>
-  unsigned numInits = initList->getNumInits();<br>
-  QualType element = GetStdInitializerListElementType(initList->getType());<br>
-  llvm::APInt size(ctx.getTypeSize(ctx.getSizeType()), numInits);<br>
-  QualType array = ctx.getConstantArrayType(element, size, ArrayType::Normal,0);<br>
-  llvm::Type *LTy = CGF.ConvertTypeForMem(array);<br>
-  llvm::AllocaInst *alloc = CGF.CreateTempAlloca(LTy);<br>
-  alloc->setAlignment(ctx.getTypeAlignInChars(array).getQuantity());<br>
-  alloc->setName(".initlist.");<br>
-<br>
-  EmitArrayInit(alloc, cast<llvm::ArrayType>(LTy), element, initList);<br>
-<br>
-  // FIXME: The diagnostics are somewhat out of place here.<br>
-  RecordDecl *record = initList->getType()->castAs<RecordType>()->getDecl();<br>
-  RecordDecl::field_iterator field = record->field_begin();<br>
-  if (field == record->field_end()) {<br>
-    CGF.ErrorUnsupported(initList, "weird std::initializer_list");<br>
+void<br>
+AggExprEmitter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {<br>
+  // Emit an array containing the elements.  The array is externally destructed<br>
+  // if the std::initializer_list object is.<br>
+  ASTContext &Ctx = CGF.getContext();<br>
+  LValue Array = CGF.EmitLValue(E->getSubExpr());<br>
+  assert(Array.isSimple() && "initializer_list array not a simple lvalue");<br>
+  llvm::Value *ArrayPtr = Array.getAddress();<br>
+<br>
+  const ConstantArrayType *ArrayType =<br>
+      Ctx.getAsConstantArrayType(E->getSubExpr()->getType());<br>
+  assert(ArrayType && "std::initializer_list constructed from non-array");<br>
+<br>
+  // FIXME: Perform the checks on the field types in SemaInit.<br>
+  RecordDecl *Record = E->getType()->castAs<RecordType>()->getDecl();<br>
+  RecordDecl::field_iterator Field = Record->field_begin();<br>
+  if (Field == Record->field_end()) {<br>
+    CGF.ErrorUnsupported(E, "weird std::initializer_list");<br>
     return;<br>
   }<br>
<br>
-  QualType elementPtr = ctx.getPointerType(element.withConst());<br>
-<br>
   // Start pointer.<br>
-  if (!ctx.hasSameType(field->getType(), elementPtr)) {<br>
-    CGF.ErrorUnsupported(initList, "weird std::initializer_list");<br>
+  if (!Field->getType()->isPointerType() ||<br>
+      !Ctx.hasSameType(Field->getType()->getPointeeType(),<br>
+                       ArrayType->getElementType())) {<br>
+    CGF.ErrorUnsupported(E, "weird std::initializer_list");<br>
     return;<br>
   }<br>
-  LValue DestLV = CGF.MakeNaturalAlignAddrLValue(destPtr, initList->getType());<br>
-  LValue start = CGF.EmitLValueForFieldInitialization(DestLV, *field);<br>
-  llvm::Value *arrayStart = Builder.CreateStructGEP(alloc, 0, "arraystart");<br>
-  CGF.EmitStoreThroughLValue(RValue::get(arrayStart), start);<br>
-  ++field;<br>
<br>
-  if (field == record->field_end()) {<br>
-    CGF.ErrorUnsupported(initList, "weird std::initializer_list");<br>
+  AggValueSlot Dest = EnsureSlot(E->getType());<br>
+  LValue DestLV = CGF.MakeAddrLValue(Dest.getAddr(), E->getType(),<br>
+                                     Dest.getAlignment());<br>
+  LValue Start = CGF.EmitLValueForFieldInitialization(DestLV, *Field);<br>
+  llvm::Value *Zero = llvm::ConstantInt::get(CGF.PtrDiffTy, 0);<br>
+  llvm::Value *IdxStart[] = { Zero, Zero };<br>
+  llvm::Value *ArrayStart =<br>
+      Builder.CreateInBoundsGEP(ArrayPtr, IdxStart, "arraystart");<br>
+  CGF.EmitStoreThroughLValue(RValue::get(ArrayStart), Start);<br>
+  ++Field;<br>
+<br>
+  if (Field == Record->field_end()) {<br>
+    CGF.ErrorUnsupported(E, "weird std::initializer_list");<br>
     return;<br>
   }<br>
-  LValue endOrLength = CGF.EmitLValueForFieldInitialization(DestLV, *field);<br>
-  if (ctx.hasSameType(field->getType(), elementPtr)) {<br>
+<br>
+  llvm::Value *Size = Builder.getInt(ArrayType->getSize());<br>
+  LValue EndOrLength = CGF.EmitLValueForFieldInitialization(DestLV, *Field);<br>
+  if (Field->getType()->isPointerType() &&<br>
+      Ctx.hasSameType(Field->getType()->getPointeeType(),<br>
+                      ArrayType->getElementType())) {<br>
     // End pointer.<br>
-    llvm::Value *arrayEnd = Builder.CreateStructGEP(alloc,numInits, "arrayend");<br>
-    CGF.EmitStoreThroughLValue(RValue::get(arrayEnd), endOrLength);<br>
-  } else if(ctx.hasSameType(field->getType(), ctx.getSizeType())) {<br>
+    llvm::Value *IdxEnd[] = { Zero, Size };<br>
+    llvm::Value *ArrayEnd =<br>
+        Builder.CreateInBoundsGEP(ArrayPtr, IdxEnd, "arrayend");<br>
+    CGF.EmitStoreThroughLValue(RValue::get(ArrayEnd), EndOrLength);<br>
+  } else if (Ctx.hasSameType(Field->getType(), Ctx.getSizeType())) {<br>
     // Length.<br>
-    CGF.EmitStoreThroughLValue(RValue::get(Builder.getInt(size)), endOrLength);<br>
+    CGF.EmitStoreThroughLValue(RValue::get(Size), EndOrLength);<br>
   } else {<br>
-    CGF.ErrorUnsupported(initList, "weird std::initializer_list");<br>
+    CGF.ErrorUnsupported(E, "weird std::initializer_list");<br>
     return;<br>
   }<br>
-<br>
-  if (!Dest.isExternallyDestructed())<br>
-    EmitStdInitializerListCleanup(CGF, array, alloc, initList);<br>
 }<br>
<br>
 /// \brief Emit initialization of an array from an initializer list.<br>
@@ -490,15 +471,8 @@ void AggExprEmitter::EmitArrayInit(llvm:<br>
       if (endOfInit) Builder.CreateStore(element, endOfInit);<br>
     }<br>
<br>
-    // If these are nested std::initializer_list inits, do them directly,<br>
-    // because they are conceptually the same "location".<br>
-    InitListExpr *initList = dyn_cast<InitListExpr>(E->getInit(i));<br>
-    if (initList && initList->initializesStdInitializerList()) {<br>
-      EmitStdInitializerList(element, initList);<br>
-    } else {<br>
-      LValue elementLV = CGF.MakeAddrLValue(element, elementType);<br>
-      EmitInitializationToLValue(E->getInit(i), elementLV);<br>
-    }<br>
+    LValue elementLV = CGF.MakeAddrLValue(element, elementType);<br>
+    EmitInitializationToLValue(E->getInit(i), elementLV);<br>
   }<br>
<br>
   // Check whether there's a non-trivial array-fill expression.<br>
@@ -1161,11 +1135,6 @@ void AggExprEmitter::VisitInitListExpr(I<br>
<br>
   AggValueSlot Dest = EnsureSlot(E->getType());<br>
<br>
-  if (E->initializesStdInitializerList()) {<br>
-    EmitStdInitializerList(Dest.getAddr(), E);<br>
-    return;<br>
-  }<br>
-<br>
   LValue DestLV = CGF.MakeAddrLValue(Dest.getAddr(), E->getType(),<br>
                                      Dest.getAlignment());<br>
<br>
@@ -1546,58 +1515,3 @@ void CodeGenFunction::EmitAggregateCopy(<br>
                        alignment.getQuantity(), isVolatile,<br>
                        /*TBAATag=*/0, TBAAStructTag);<br>
 }<br>
-<br>
-void CodeGenFunction::MaybeEmitStdInitializerListCleanup(llvm::Value *loc,<br>
-                                                         const Expr *init) {<br>
-  const ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(init);<br>
-  if (cleanups)<br>
-    init = cleanups->getSubExpr();<br>
-<br>
-  if (isa<InitListExpr>(init) &&<br>
-      cast<InitListExpr>(init)->initializesStdInitializerList()) {<br>
-    // We initialized this std::initializer_list with an initializer list.<br>
-    // A backing array was created. Push a cleanup for it.<br>
-    EmitStdInitializerListCleanup(loc, cast<InitListExpr>(init));<br>
-  }<br>
-}<br>
-<br>
-static void EmitRecursiveStdInitializerListCleanup(CodeGenFunction &CGF,<br>
-                                                   llvm::Value *arrayStart,<br>
-                                                   const InitListExpr *init) {<br>
-  // Check if there are any recursive cleanups to do, i.e. if we have<br>
-  //   std::initializer_list<std::initializer_list<obj>> list = {{obj()}};<br>
-  // then we need to destroy the inner array as well.<br>
-  for (unsigned i = 0, e = init->getNumInits(); i != e; ++i) {<br>
-    const InitListExpr *subInit = dyn_cast<InitListExpr>(init->getInit(i));<br>
-    if (!subInit || !subInit->initializesStdInitializerList())<br>
-      continue;<br>
-<br>
-    // This one needs to be destroyed. Get the address of the std::init_list.<br>
-    llvm::Value *offset = llvm::ConstantInt::get(CGF.SizeTy, i);<br>
-    llvm::Value *loc = CGF.Builder.CreateInBoundsGEP(arrayStart, offset,<br>
-                                                 "std.initlist");<br>
-    CGF.EmitStdInitializerListCleanup(loc, subInit);<br>
-  }<br>
-}<br>
-<br>
-void CodeGenFunction::EmitStdInitializerListCleanup(llvm::Value *loc,<br>
-                                                    const InitListExpr *init) {<br>
-  ASTContext &ctx = getContext();<br>
-  QualType element = GetStdInitializerListElementType(init->getType());<br>
-  unsigned numInits = init->getNumInits();<br>
-  llvm::APInt size(ctx.getTypeSize(ctx.getSizeType()), numInits);<br>
-  QualType array =ctx.getConstantArrayType(element, size, ArrayType::Normal, 0);<br>
-  QualType arrayPtr = ctx.getPointerType(array);<br>
-  llvm::Type *arrayPtrType = ConvertType(arrayPtr);<br>
-<br>
-  // lvalue is the location of a std::initializer_list, which as its first<br>
-  // element has a pointer to the array we want to destroy.<br>
-  llvm::Value *startPointer = Builder.CreateStructGEP(loc, 0, "startPointer");<br>
-  llvm::Value *startAddress = Builder.CreateLoad(startPointer, "startAddress");<br>
-<br>
-  ::EmitRecursiveStdInitializerListCleanup(*this, startAddress, init);<br>
-<br>
-  llvm::Value *arrayAddress =<br>
-      Builder.CreateBitCast(startAddress, arrayPtrType, "arrayAddress");<br>
-  ::EmitStdInitializerListCleanup(*this, array, arrayAddress, init);<br>
-}<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Wed Jun 12 17:31:48 2013<br>
@@ -838,8 +838,6 @@ static void StoreAnyExprIntoOneUnit(Code<br>
                               AggValueSlot::DoesNotNeedGCBarriers,<br>
                               AggValueSlot::IsNotAliased);<br>
     CGF.EmitAggExpr(Init, Slot);<br>
-<br>
-    CGF.MaybeEmitStdInitializerListCleanup(NewPtr, Init);<br>
     return;<br>
   }<br>
   }<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Wed Jun 12 17:31:48 2013<br>
@@ -368,11 +368,6 @@ void ConstStructBuilder::ConvertStructTo<br>
 }<br>
<br>
 bool ConstStructBuilder::Build(InitListExpr *ILE) {<br>
-  if (ILE->initializesStdInitializerList()) {<br>
-    //CGM.ErrorUnsupported(ILE, "global std::initializer_list");<br>
-    return false;<br>
-  }<br>
-<br>
   RecordDecl *RD = ILE->getType()->getAs<RecordType>()->getDecl();<br>
   const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);<br>
<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)<br>
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Wed Jun 12 17:31:48 2013<br>
@@ -1631,10 +1631,6 @@ public:<br>
   llvm::Value *EmitDynamicCast(llvm::Value *V, const CXXDynamicCastExpr *DCE);<br>
   llvm::Value* EmitCXXUuidofExpr(const CXXUuidofExpr *E);<br>
<br>
-  void MaybeEmitStdInitializerListCleanup(llvm::Value *loc, const Expr *init);<br>
-  void EmitStdInitializerListCleanup(llvm::Value *loc,<br>
-                                     const InitListExpr *init);<br>
-<br>
   /// \brief Situations in which we might emit a check for the suitability of a<br>
   ///        pointer or glvalue.<br>
   enum TypeCheckKind {<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Wed Jun 12 17:31:48 2013<br>
@@ -1628,125 +1628,6 @@ CharUnits CodeGenModule::GetTargetTypeSt<br>
       TheDataLayout.getTypeStoreSizeInBits(Ty));<br>
 }<br>
<br>
-llvm::Constant *<br>
-CodeGenModule::MaybeEmitGlobalStdInitializerListInitializer(const VarDecl *D,<br>
-                                                       const Expr *rawInit) {<br>
-  ArrayRef<ExprWithCleanups::CleanupObject> cleanups;<br>
-  if (const ExprWithCleanups *withCleanups =<br>
-          dyn_cast<ExprWithCleanups>(rawInit)) {<br>
-    cleanups = withCleanups->getObjects();<br>
-    rawInit = withCleanups->getSubExpr();<br>
-  }<br>
-<br>
-  const InitListExpr *init = dyn_cast<InitListExpr>(rawInit);<br>
-  if (!init || !init->initializesStdInitializerList() ||<br>
-      init->getNumInits() == 0)<br>
-    return 0;<br>
-<br>
-  ASTContext &ctx = getContext();<br>
-  unsigned numInits = init->getNumInits();<br>
-  // FIXME: This check is here because we would otherwise silently miscompile<br>
-  // nested global std::initializer_lists. Better would be to have a real<br>
-  // implementation.<br>
-  for (unsigned i = 0; i < numInits; ++i) {<br>
-    const InitListExpr *inner = dyn_cast<InitListExpr>(init->getInit(i));<br>
-    if (inner && inner->initializesStdInitializerList()) {<br>
-      ErrorUnsupported(inner, "nested global std::initializer_list");<br>
-      return 0;<br>
-    }<br>
-  }<br>
-<br>
-  // Synthesize a fake VarDecl for the array and initialize that.<br>
-  QualType elementType = init->getInit(0)->getType();<br>
-  llvm::APInt numElements(ctx.getTypeSize(ctx.getSizeType()), numInits);<br>
-  QualType arrayType = ctx.getConstantArrayType(elementType, numElements,<br>
-                                                ArrayType::Normal, 0);<br>
-<br>
-  IdentifierInfo *name = &ctx.Idents.get(D->getNameAsString() + "__initlist");<br>
-  TypeSourceInfo *sourceInfo = ctx.getTrivialTypeSourceInfo(<br>
-                                              arrayType, D->getLocation());<br>
-  VarDecl *backingArray = VarDecl::Create(ctx, const_cast<DeclContext*>(<br>
-                                                          D->getDeclContext()),<br>
-                                          D->getLocStart(), D->getLocation(),<br>
-                                          name, arrayType, sourceInfo,<br>
-                                          SC_Static);<br>
-  backingArray->setTSCSpec(D->getTSCSpec());<br>
-<br>
-  // Now clone the InitListExpr to initialize the array instead.<br>
-  // Incredible hack: we want to use the existing InitListExpr here, so we need<br>
-  // to tell it that it no longer initializes a std::initializer_list.<br>
-  ArrayRef<Expr*> Inits(const_cast<InitListExpr*>(init)->getInits(),<br>
-                        init->getNumInits());<br>
-  Expr *arrayInit = new (ctx) InitListExpr(ctx, init->getLBraceLoc(), Inits,<br>
-                                           init->getRBraceLoc());<br>
-  arrayInit->setType(arrayType);<br>
-<br>
-  if (!cleanups.empty())<br>
-    arrayInit = ExprWithCleanups::Create(ctx, arrayInit, cleanups);<br>
-<br>
-  backingArray->setInit(arrayInit);<br>
-<br>
-  // Emit the definition of the array.<br>
-  EmitGlobalVarDefinition(backingArray);<br>
-<br>
-  // Inspect the initializer list to validate it and determine its type.<br>
-  // FIXME: doing this every time is probably inefficient; caching would be nice<br>
-  RecordDecl *record = init->getType()->castAs<RecordType>()->getDecl();<br>
-  RecordDecl::field_iterator field = record->field_begin();<br>
-  if (field == record->field_end()) {<br>
-    ErrorUnsupported(D, "weird std::initializer_list");<br>
-    return 0;<br>
-  }<br>
-  QualType elementPtr = ctx.getPointerType(elementType.withConst());<br>
-  // Start pointer.<br>
-  if (!ctx.hasSameType(field->getType(), elementPtr)) {<br>
-    ErrorUnsupported(D, "weird std::initializer_list");<br>
-    return 0;<br>
-  }<br>
-  ++field;<br>
-  if (field == record->field_end()) {<br>
-    ErrorUnsupported(D, "weird std::initializer_list");<br>
-    return 0;<br>
-  }<br>
-  bool isStartEnd = false;<br>
-  if (ctx.hasSameType(field->getType(), elementPtr)) {<br>
-    // End pointer.<br>
-    isStartEnd = true;<br>
-  } else if(!ctx.hasSameType(field->getType(), ctx.getSizeType())) {<br>
-    ErrorUnsupported(D, "weird std::initializer_list");<br>
-    return 0;<br>
-  }<br>
-<br>
-  // Now build an APValue representing the std::initializer_list.<br>
-  APValue initListValue(APValue::UninitStruct(), 0, 2);<br>
-  APValue &startField = initListValue.getStructField(0);<br>
-  APValue::LValuePathEntry startOffsetPathEntry;<br>
-  startOffsetPathEntry.ArrayIndex = 0;<br>
-  startField = APValue(APValue::LValueBase(backingArray),<br>
-                       CharUnits::fromQuantity(0),<br>
-                       llvm::makeArrayRef(startOffsetPathEntry),<br>
-                       /*IsOnePastTheEnd=*/false, 0);<br>
-<br>
-  if (isStartEnd) {<br>
-    APValue &endField = initListValue.getStructField(1);<br>
-    APValue::LValuePathEntry endOffsetPathEntry;<br>
-    endOffsetPathEntry.ArrayIndex = numInits;<br>
-    endField = APValue(APValue::LValueBase(backingArray),<br>
-                       ctx.getTypeSizeInChars(elementType) * numInits,<br>
-                       llvm::makeArrayRef(endOffsetPathEntry),<br>
-                       /*IsOnePastTheEnd=*/true, 0);<br>
-  } else {<br>
-    APValue &sizeField = initListValue.getStructField(1);<br>
-    sizeField = APValue(llvm::APSInt(numElements));<br>
-  }<br>
-<br>
-  // Emit the constant for the initializer_list.<br>
-  llvm::Constant *llvmInit =<br>
-      EmitConstantValueForMemory(initListValue, D->getType());<br>
-  assert(llvmInit && "failed to initialize as constant");<br>
-  return llvmInit;<br>
-}<br>
-<br>
 unsigned CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D,<br>
                                                  unsigned AddrSpace) {<br>
   if (LangOpts.CUDA && CodeGenOpts.CUDAIsDevice) {<br>
@@ -1817,18 +1698,10 @@ void CodeGenModule::EmitGlobalVarDefinit<br>
     assert(!ASTTy->isIncompleteType() && "Unexpected incomplete type");<br>
     Init = EmitNullConstant(D->getType());<br>
   } else {<br>
-    // If this is a std::initializer_list, emit the special initializer.<br>
-    Init = MaybeEmitGlobalStdInitializerListInitializer(D, InitExpr);<br>
-    // An empty init list will perform zero-initialization, which happens<br>
-    // to be exactly what we want.<br>
-    // FIXME: It does so in a global constructor, which is *not* what we<br>
-    // want.<br>
+    initializedGlobalDecl = GlobalDecl(D);<br>
+    Init = EmitConstantInit(*InitDecl);<br>
<br>
     if (!Init) {<br>
-      initializedGlobalDecl = GlobalDecl(D);<br>
-      Init = EmitConstantInit(*InitDecl);<br>
-    }<br>
-    if (!Init) {<br>
       QualType T = InitExpr->getType();<br>
       if (D->getType()->isReferenceType())<br>
         T = D->getType();<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)<br>
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Wed Jun 12 17:31:48 2013<br>
@@ -1020,8 +1020,6 @@ private:<br>
<br>
   void EmitGlobalFunctionDefinition(GlobalDecl GD);<br>
   void EmitGlobalVarDefinition(const VarDecl *D);<br>
-  llvm::Constant *MaybeEmitGlobalStdInitializerListInitializer(const VarDecl *D,<br>
-                                                              const Expr *init);<br>
   void EmitAliasDefinition(GlobalDecl GD);<br>
   void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D);<br>
   void EmitObjCIvarInitializations(ObjCImplementationDecl *D);<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Jun 12 17:31:48 2013<br>
@@ -2153,10 +2153,6 @@ Sema::ActOnCXXInClassMemberInitializer(D<br>
<br>
   ExprResult Init = InitExpr;<br>
   if (!FD->getType()->isDependentType() && !InitExpr->isTypeDependent()) {<br>
-    if (isa<InitListExpr>(InitExpr) && isStdInitializerList(FD->getType(), 0)) {<br>
-      Diag(FD->getLocation(), diag::warn_dangling_std_initializer_list)<br>
-        << /*at end of ctor*/1 << InitExpr->getSourceRange();<br>
-    }<br>
     InitializedEntity Entity = InitializedEntity::InitializeMember(FD);<br>
     InitializationKind Kind = FD->getInClassInitStyle() == ICIS_ListInit<br>
         ? InitializationKind::CreateDirectList(InitExpr->getLocStart())<br>
@@ -2550,11 +2546,6 @@ Sema::BuildMemberInitializer(ValueDecl *<br>
     if (isa<InitListExpr>(Init)) {<br>
       InitList = true;<br>
       Args = Init;<br>
-<br>
-      if (isStdInitializerList(Member->getType(), 0)) {<br>
-        Diag(IdLoc, diag::warn_dangling_std_initializer_list)<br>
-            << /*at end of ctor*/1 << InitRange;<br>
-      }<br>
     }<br>
<br>
     // Initialize the member.<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExceptionSpec.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExceptionSpec.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExceptionSpec.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaExceptionSpec.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExceptionSpec.cpp Wed Jun 12 17:31:48 2013<br>
@@ -1006,6 +1006,7 @@ CanThrowResult Sema::canThrow(const Expr<br>
   case Expr::CompoundLiteralExprClass:<br>
   case Expr::CXXConstCastExprClass:<br>
   case Expr::CXXReinterpretCastExprClass:<br>
+  case Expr::CXXStdInitializerListExprClass:<br>
   case Expr::DesignatedInitExprClass:<br>
   case Expr::ExprWithCleanupsClass:<br>
   case Expr::ExtVectorElementExprClass:<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaInit.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaInit.cpp Wed Jun 12 17:31:48 2013<br>
@@ -2937,6 +2937,12 @@ static void MaybeProduceObjCObject(Sema<br>
   }<br>
 }<br>
<br>
+static void TryListInitialization(Sema &S,<br>
+                                  const InitializedEntity &Entity,<br>
+                                  const InitializationKind &Kind,<br>
+                                  InitListExpr *InitList,<br>
+                                  InitializationSequence &Sequence);<br>
+<br>
 /// \brief When initializing from init list via constructor, handle<br>
 /// initialization of an object of type std::initializer_list<T>.<br>
 ///<br>
@@ -2950,25 +2956,23 @@ static bool TryInitializerListConstructi<br>
   if (!S.isStdInitializerList(DestType, &E))<br>
     return false;<br>
<br>
-  // Check that each individual element can be copy-constructed. But since we<br>
-  // have no place to store further information, we'll recalculate everything<br>
-  // later.<br>
-  InitializedEntity HiddenArray = InitializedEntity::InitializeTemporary(<br>
-      S.Context.getConstantArrayType(E,<br>
-          llvm::APInt(S.Context.getTypeSize(S.Context.getSizeType()),<br>
-                      List->getNumInits()),<br>
-          ArrayType::Normal, 0));<br>
-  InitializedEntity Element = InitializedEntity::InitializeElement(S.Context,<br>
-      0, HiddenArray);<br>
-  for (unsigned i = 0, n = List->getNumInits(); i < n; ++i) {<br>
-    Element.setElementIndex(i);<br>
-    if (!S.CanPerformCopyInitialization(Element, List->getInit(i))) {<br>
-      Sequence.SetFailed(<br>
-          InitializationSequence::FK_InitListElementCopyFailure);<br>
-      return true;<br>
-    }<br>
+  if (S.RequireCompleteType(List->getExprLoc(), E, 0)) {<br>
+    Sequence.setIncompleteTypeFailure(E);<br>
+    return true;<br>
   }<br>
-  Sequence.AddStdInitializerListConstructionStep(DestType);<br>
+<br>
+  // Try initializing a temporary array from the init list.<br>
+  QualType ArrayType = S.Context.getConstantArrayType(<br>
+      E.withConst(), llvm::APInt(S.Context.getTypeSize(S.Context.getSizeType()),<br>
+                                 List->getNumInits()),<br>
+      clang::ArrayType::Normal, 0);<br>
+  InitializedEntity HiddenArray =<br>
+      InitializedEntity::InitializeTemporary(ArrayType);<br>
+  InitializationKind Kind =<br>
+      InitializationKind::CreateDirectList(List->getExprLoc());<br>
+  TryListInitialization(S, HiddenArray, Kind, List, Sequence);<br>
+  if (Sequence)<br>
+    Sequence.AddStdInitializerListConstructionStep(DestType);<br>
   return true;<br>
 }<br>
<br>
@@ -3198,12 +3202,6 @@ static void TryValueInitialization(Sema<br>
                                    InitializationSequence &Sequence,<br>
                                    InitListExpr *InitList = 0);<br>
<br>
-static void TryListInitialization(Sema &S,<br>
-                                  const InitializedEntity &Entity,<br>
-                                  const InitializationKind &Kind,<br>
-                                  InitListExpr *InitList,<br>
-                                  InitializationSequence &Sequence);<br>
-<br>
 /// \brief Attempt list initialization of a reference.<br>
 static void TryReferenceListInitialization(Sema &S,<br>
                                            const InitializedEntity &Entity,<br>
@@ -5135,7 +5133,7 @@ PerformConstructorInitialization(Sema &S<br>
     return ExprError();<br>
<br>
   if (shouldBindAsTemporary(Entity))<br>
-    CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());<br>
+    CurInit = S.MaybeBindToTemporary(CurInit.take());<br>
<br>
   return CurInit;<br>
 }<br>
@@ -5277,19 +5275,18 @@ static void performLifetimeExtension(Exp<br>
   if (CXXBindTemporaryExpr *BTE = dyn_cast<CXXBindTemporaryExpr>(Init))<br>
     Init = BTE->getSubExpr();<br>
<br>
+  if (CXXStdInitializerListExpr *ILE =<br>
+          dyn_cast<CXXStdInitializerListExpr>(Init))<br>
+    return performReferenceExtension(ILE->getSubExpr(), ExtendingD);<br>
+<br>
   if (InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {<br>
-    if (ILE->initializesStdInitializerList() || ILE->getType()->isArrayType()) {<br>
-      // FIXME: If this is an InitListExpr which creates a std::initializer_list<br>
-      //        object, we also need to lifetime-extend the underlying array<br>
-      //        itself. Fix the representation to explicitly materialize an<br>
-      //        array temporary so we can model this properly.<br>
+    if (ILE->getType()->isArrayType()) {<br>
       for (unsigned I = 0, N = ILE->getNumInits(); I != N; ++I)<br>
         performLifetimeExtension(ILE->getInit(I), ExtendingD);<br>
       return;<br>
     }<br>
<br>
-    CXXRecordDecl *RD = ILE->getType()->getAsCXXRecordDecl();<br>
-    if (RD) {<br>
+    if (CXXRecordDecl *RD = ILE->getType()->getAsCXXRecordDecl()) {<br>
       assert(RD->isAggregate() && "aggregate init on non-aggregate");<br>
<br>
       // If we lifetime-extend a braced initializer which is initializing an<br>
@@ -5319,6 +5316,39 @@ static void performLifetimeExtension(Exp<br>
   }<br>
 }<br>
<br>
+static void warnOnLifetimeExtension(Sema &S, const InitializedEntity &Entity,<br>
+                                    const Expr *Init, bool IsInitializerList,<br>
+                                    const ValueDecl *ExtendingDecl) {<br>
+  // Warn if a field lifetime-extends a temporary.<br>
+  if (isa<FieldDecl>(ExtendingDecl)) {<br>
+    if (IsInitializerList) {<br>
+      S.Diag(Init->getExprLoc(), diag::warn_dangling_std_initializer_list)<br>
+        << /*at end of constructor*/true;<br>
+      return;<br>
+    }<br>
+<br>
+    bool IsSubobjectMember = false;<br>
+    for (const InitializedEntity *Ent = Entity.getParent(); Ent;<br>
+         Ent = Ent->getParent()) {<br>
+      if (Ent->getKind() != InitializedEntity::EK_Base) {<br>
+        IsSubobjectMember = true;<br>
+        break;<br>
+      }<br>
+    }<br>
+    S.Diag(Init->getExprLoc(),<br>
+           diag::warn_bind_ref_member_to_temporary)<br>
+      << ExtendingDecl << Init->getSourceRange()<br>
+      << IsSubobjectMember << IsInitializerList;<br>
+    if (IsSubobjectMember)<br>
+      S.Diag(ExtendingDecl->getLocation(),<br>
+             diag::note_ref_subobject_of_member_declared_here);<br>
+    else<br>
+      S.Diag(ExtendingDecl->getLocation(),<br>
+             diag::note_ref_or_ptr_member_declared_here)<br>
+        << /*is pointer*/false;<br>
+  }<br>
+}<br>
+<br>
 ExprResult<br>
 InitializationSequence::Perform(Sema &S,<br>
                                 const InitializedEntity &Entity,<br>
@@ -5570,29 +5600,7 @@ InitializationSequence::Perform(Sema &S,<br>
           getDeclForTemporaryLifetimeExtension(Entity);<br>
       if (ExtendingDecl) {<br>
         performLifetimeExtension(CurInit.get(), ExtendingDecl);<br>
-<br>
-        // Warn if a field lifetime-extends a temporary.<br>
-        if (isa<FieldDecl>(ExtendingDecl)) {<br>
-          bool IsSubobjectMember = false;<br>
-          for (const InitializedEntity *Ent = Entity.getParent(); Ent;<br>
-               Ent = Ent->getParent()) {<br>
-            if (Ent->getKind() != InitializedEntity::EK_Base) {<br>
-              IsSubobjectMember = true;<br>
-              break;<br>
-            }<br>
-          }<br>
-          S.Diag(CurInit.get()->getExprLoc(),<br>
-                 diag::warn_bind_ref_member_to_temporary)<br>
-            << ExtendingDecl << CurInit.get()->getSourceRange()<br>
-            << IsSubobjectMember;<br>
-          if (IsSubobjectMember)<br>
-            S.Diag(ExtendingDecl->getLocation(),<br>
-                   diag::note_ref_subobject_of_member_declared_here);<br>
-          else<br>
-            S.Diag(ExtendingDecl->getLocation(),<br>
-                   diag::note_ref_or_ptr_member_declared_here)<br>
-              << /*IsPointer*/false;<br>
-        }<br>
+        warnOnLifetimeExtension(S, Entity, CurInit.get(), false, ExtendingDecl);<br>
       }<br>
<br>
       // Materialize the temporary into memory.<br>
@@ -5763,16 +5771,10 @@ InitializationSequence::Perform(Sema &S,<br>
<br>
     case SK_ListInitialization: {<br>
       InitListExpr *InitList = cast<InitListExpr>(CurInit.get());<br>
-      // Hack: We must pass *ResultType if available in order to set the type<br>
-      // of arrays, e.g. in 'int ar[] = {1, 2, 3};'.<br>
-      // But in 'const X &x = {1, 2, 3};' we're supposed to initialize a<br>
-      // temporary, not a reference, so we should pass Ty.<br>
-      // Worst case: 'const int (&arref)[] = {1, 2, 3};'.<br>
-      // Since this step is never used for a reference directly, we explicitly<br>
-      // unwrap references here and rewrap them afterwards.<br>
-      // We also need to create a InitializeTemporary entity for this.<br>
-      QualType Ty = ResultType ? ResultType->getNonReferenceType() : Step->Type;<br>
-      bool IsTemporary = Entity.getType()->isReferenceType();<br>
+      // If we're not initializing the top-level entity, we need to create an<br>
+      // InitializeTemporary entity for our target type.<br>
+      QualType Ty = Step->Type;<br>
+      bool IsTemporary = !S.Context.hasSameType(Entity.getType(), Ty);<br>
       InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(Ty);<br>
       InitializedEntity InitEntity = IsTemporary ? TempEntity : Entity;<br>
       InitListChecker PerformInitList(S, InitEntity,<br>
@@ -5780,7 +5782,11 @@ InitializationSequence::Perform(Sema &S,<br>
       if (PerformInitList.HadError())<br>
         return ExprError();<br>
<br>
-      if (ResultType) {<br>
+      // Hack: We must update *ResultType if available in order to set the<br>
+      // bounds of arrays, e.g. in 'int ar[] = {1, 2, 3};'.<br>
+      // Worst case: 'const int (&arref)[] = {1, 2, 3};'.<br>
+      if (ResultType &&<br>
+          ResultType->getNonReferenceType()->isIncompleteArrayType()) {<br>
         if ((*ResultType)->isRValueReferenceType())<br>
           Ty = S.Context.getRValueReferenceType(Ty);<br>
         else if ((*ResultType)->isLValueReferenceType())<br>
@@ -5973,56 +5979,35 @@ InitializationSequence::Perform(Sema &S,<br>
       break;<br>
<br>
     case SK_StdInitializerList: {<br>
-      QualType Dest = Step->Type;<br>
-      QualType E;<br>
-      bool Success = S.isStdInitializerList(Dest.getNonReferenceType(), &E);<br>
-      (void)Success;<br>
-      assert(Success && "Destination type changed?");<br>
-<br>
-      // If the element type has a destructor, check it.<br>
-      if (CXXRecordDecl *RD = E->getAsCXXRecordDecl()) {<br>
-        if (!RD->hasIrrelevantDestructor()) {<br>
-          if (CXXDestructorDecl *Destructor = S.LookupDestructor(RD)) {<br>
-            S.MarkFunctionReferenced(Kind.getLocation(), Destructor);<br>
-            S.CheckDestructorAccess(Kind.getLocation(), Destructor,<br>
-                                    S.PDiag(diag::err_access_dtor_temp) << E);<br>
-            if (S.DiagnoseUseOfDecl(Destructor, Kind.getLocation()))<br>
-              return ExprError();<br>
-          }<br>
-        }<br>
-      }<br>
+      S.Diag(CurInit.get()->getExprLoc(),<br>
+             diag::warn_cxx98_compat_initializer_list_init)<br>
+        << CurInit.get()->getSourceRange();<br>
<br>
-      InitListExpr *ILE = cast<InitListExpr>(CurInit.take());<br>
-      S.Diag(ILE->getExprLoc(), diag::warn_cxx98_compat_initializer_list_init)<br>
-        << ILE->getSourceRange();<br>
-      unsigned NumInits = ILE->getNumInits();<br>
-      SmallVector<Expr*, 16> Converted(NumInits);<br>
-      InitializedEntity HiddenArray = InitializedEntity::InitializeTemporary(<br>
-          S.Context.getConstantArrayType(E,<br>
-              llvm::APInt(S.Context.getTypeSize(S.Context.getSizeType()),<br>
-                          NumInits),<br>
-              ArrayType::Normal, 0));<br>
-      InitializedEntity Element =InitializedEntity::InitializeElement(S.Context,<br>
-          0, HiddenArray);<br>
-      for (unsigned i = 0; i < NumInits; ++i) {<br>
-        Element.setElementIndex(i);<br>
-        ExprResult Init = S.Owned(ILE->getInit(i));<br>
-        ExprResult Res = S.PerformCopyInitialization(<br>
-                             Element, Init.get()->getExprLoc(), Init,<br>
-                             /*TopLevelOfInitList=*/ true);<br>
-        if (Res.isInvalid())<br>
-          return ExprError();<br>
-        Converted[i] = Res.take();<br>
+      // Maybe lifetime-extend the array temporary's subobjects to match the<br>
+      // entity's lifetime.<br>
+      const ValueDecl *ExtendingDecl =<br>
+          getDeclForTemporaryLifetimeExtension(Entity);<br>
+      if (ExtendingDecl) {<br>
+        performLifetimeExtension(CurInit.get(), ExtendingDecl);<br>
+        warnOnLifetimeExtension(S, Entity, CurInit.get(), true, ExtendingDecl);<br>
       }<br>
-      InitListExpr *Semantic = new (S.Context)<br>
-          InitListExpr(S.Context, ILE->getLBraceLoc(),<br>
-                       Converted, ILE->getRBraceLoc());<br>
-      Semantic->setSyntacticForm(ILE);<br>
-      Semantic->setType(Dest);<br>
-      Semantic->setInitializesStdInitializerList();<br>
-      CurInit = S.Owned(Semantic);<br>
+<br>
+      // Materialize the temporary into memory.<br>
+      MaterializeTemporaryExpr *MTE = new (S.Context)<br>
+          MaterializeTemporaryExpr(CurInit.get()->getType(), CurInit.get(),<br>
+                                   /*lvalue reference*/ false, ExtendingDecl);<br>
+<br>
+      // Wrap it in a construction of a std::initializer_list<T>.<br>
+      CurInit = S.Owned(<br>
+          new (S.Context) CXXStdInitializerListExpr(Step->Type, MTE));<br>
+<br>
+      // Bind the result, in case the library has given initializer_list a<br>
+      // non-trivial destructor.<br>
+      if (shouldBindAsTemporary(Entity))<br>
+        CurInit = S.MaybeBindToTemporary(CurInit.take());<br>
       break;<br>
     }<br>
+<br>
     case SK_OCLSamplerInit: {<br>
       assert(Step->Type->isSamplerT() &&<br>
              "Sampler initialization on non sampler type.");<br>
<br>
Modified: cfe/trunk/lib/Sema/TreeTransform.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/TreeTransform.h (original)<br>
+++ cfe/trunk/lib/Sema/TreeTransform.h Wed Jun 12 17:31:48 2013<br>
@@ -2639,6 +2639,10 @@ ExprResult TreeTransform<Derived>::Trans<br>
   if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))<br>
     Init = ICE->getSubExprAsWritten();<br>
<br>
+  if (CXXStdInitializerListExpr *ILE =<br>
+          dyn_cast<CXXStdInitializerListExpr>(Init))<br>
+    return TransformInitializer(ILE->getSubExpr(), CXXDirectInit);<br>
+<br>
   // If this is not a direct-initializer, we only need to reconstruct<br>
   // InitListExprs. Other forms of copy-initialization will be a no-op if<br>
   // the initializer is already the right type.<br>
@@ -8548,6 +8552,13 @@ TreeTransform<Derived>::TransformMateria<br>
 }<br>
<br>
 template<typename Derived><br>
+ExprResult<br>
+TreeTransform<Derived>::TransformCXXStdInitializerListExpr(<br>
+    CXXStdInitializerListExpr *E) {<br>
+  return getDerived().TransformExpr(E->getSubExpr());<br>
+}<br>
+<br>
+template<typename Derived><br>
 ExprResult<br>
 TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {<br>
   return SemaRef.MaybeBindToTemporary(E);<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Wed Jun 12 17:31:48 2013<br>
@@ -723,7 +723,6 @@ void ASTStmtReader::VisitInitListExpr(In<br>
   } else<br>
     E->ArrayFillerOrUnionFieldInit = ReadDeclAs<FieldDecl>(Record, Idx);<br>
   E->sawArrayRangeDesignator(Record[Idx++]);<br>
-  E->setInitializesStdInitializerList(Record[Idx++]);<br>
   unsigned NumInits = Record[Idx++];<br>
   E->reserveInits(Reader.getContext(), NumInits);<br>
   if (isArrayFiller) {<br>
@@ -1227,6 +1226,12 @@ void ASTStmtReader::VisitLambdaExpr(Lamb<br>
   }<br>
 }<br>
<br>
+void<br>
+ASTStmtReader::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {<br>
+  VisitExpr(E);<br>
+  E->SubExpr = Reader.ReadSubExpr();<br>
+}<br>
+<br>
 void ASTStmtReader::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {<br>
   VisitExplicitCastExpr(E);<br>
   SourceRange R = ReadSourceRange(Record, Idx);<br>
@@ -2161,6 +2166,10 @@ Stmt *ASTReader::ReadStmtFromStream(Modu<br>
       S = new (Context) UserDefinedLiteral(Context, Empty);<br>
       break;<br>
<br>
+    case EXPR_CXX_STD_INITIALIZER_LIST:<br>
+      S = new (Context) CXXStdInitializerListExpr(Empty);<br>
+      break;<br>
+<br>
     case EXPR_CXX_BOOL_LITERAL:<br>
       S = new (Context) CXXBoolLiteralExpr(Empty);<br>
       break;<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Wed Jun 12 17:31:48 2013<br>
@@ -735,6 +735,7 @@ static void AddStmtsExprs(llvm::Bitstrea<br>
   RECORD(EXPR_CXX_CONST_CAST);<br>
   RECORD(EXPR_CXX_FUNCTIONAL_CAST);<br>
   RECORD(EXPR_USER_DEFINED_LITERAL);<br>
+  RECORD(EXPR_CXX_STD_INITIALIZER_LIST);<br>
   RECORD(EXPR_CXX_BOOL_LITERAL);<br>
   RECORD(EXPR_CXX_NULL_PTR_LITERAL);<br>
   RECORD(EXPR_CXX_TYPEID_EXPR);<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Wed Jun 12 17:31:48 2013<br>
@@ -683,7 +683,6 @@ void ASTStmtWriter::VisitInitListExpr(In<br>
   else<br>
     Writer.AddDeclRef(E->getInitializedFieldInUnion(), Record);<br>
   Record.push_back(E->hadArrayRangeDesignator());<br>
-  Record.push_back(E->initializesStdInitializerList());<br>
   Record.push_back(E->getNumInits());<br>
   if (isArrayFiller) {<br>
     // ArrayFiller may have filled "holes" due to designated initializer.<br>
@@ -1187,6 +1186,12 @@ void ASTStmtWriter::VisitLambdaExpr(Lamb<br>
   Code = serialization::EXPR_LAMBDA;<br>
 }<br>
<br>
+void ASTStmtWriter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {<br>
+  VisitExpr(E);<br>
+  Writer.AddStmt(E->getSubExpr());<br>
+  Code = serialization::EXPR_CXX_STD_INITIALIZER_LIST;<br>
+}<br>
+<br>
 void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {<br>
   VisitExplicitCastExpr(E);<br>
   Writer.AddSourceRange(SourceRange(E->getOperatorLoc(), E->getRParenLoc()),<br>
<br>
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)<br>
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Wed Jun 12 17:31:48 2013<br>
@@ -607,6 +607,7 @@ void ExprEngine::Visit(const Stmt *S, Ex<br>
     case Stmt::CXXDefaultInitExprClass:<br>
     case Stmt::CXXDependentScopeMemberExprClass:<br>
     case Stmt::CXXPseudoDestructorExprClass:<br>
+    case Stmt::CXXStdInitializerListExprClass:<br>
     case Stmt::CXXTryStmtClass:<br>
     case Stmt::CXXTypeidExprClass:<br>
     case Stmt::CXXUuidofExprClass:<br>
<br>
Modified: cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp (original)<br>
+++ cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp Wed Jun 12 17:31:48 2013<br>
@@ -4,7 +4,7 @@ namespace std {<br>
   typedef decltype(sizeof(int)) size_t;<br>
<br>
   template <typename E><br>
-  struct initializer_list<br>
+  struct initializer_list // expected-note 2{{candidate}}<br>
   {<br>
     const E *p;<br>
     size_t n;<br>
@@ -113,10 +113,14 @@ namespace bullet8 {<br>
<br>
 namespace rdar13395022 {<br>
   struct MoveOnly {<br>
-    MoveOnly(MoveOnly&&); // expected-note{{copy constructor is implicitly deleted because 'MoveOnly' has a user-declared move constructor}}<br>
+    MoveOnly(MoveOnly&&);<br>
   };<br>
<br>
   void test(MoveOnly mo) {<br>
-    auto &&list = {mo}; // expected-error{{call to implicitly-deleted copy constructor of 'rdar13395022::MoveOnly'}}<br>
+    // FIXME: These diagnostics are poor.<br>
+    auto &&list1 = {mo}; // expected-error{{no viable conversion}}<br>
+    MoveOnly (&&list2)[1] = {mo}; // expected-error{{no viable conversion}}<br>
+    std::initializer_list<MoveOnly> &&list3 = {};<br>
+    MoveOnly (&&list4)[1] = {}; // expected-error{{uninitialized}}<br>
   }<br>
 }<br>
<br>
Modified: cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp Wed Jun 12 17:31:48 2013<br>
@@ -1,18 +1,28 @@<br>
-// RUN: %clang_cc1 -std=c++11 -emit-llvm -o - -verify %s<br>
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-STATIC-BL<br>
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -emit-llvm -o - %s -Dconstexpr= | FileCheck %s --check-prefix=CHECK-DYNAMIC-BL<br>
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -emit-llvm -o - %s -DUSE_END | FileCheck %s --check-prefix=CHECK-STATIC-BE<br>
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -emit-llvm -o - %s -DUSE_END -Dconstexpr= | FileCheck %s --check-prefix=CHECK-DYNAMIC-BE<br>
<br>
 namespace std {<br>
   typedef decltype(sizeof(int)) size_t;<br>
<br>
-  // libc++'s implementation<br>
   template <class _E><br>
   class initializer_list<br>
   {<br>
     const _E* __begin_;<br>
+#ifdef USE_END<br>
+    const _E* __end_;<br>
+#else<br>
     size_t    __size_;<br>
+#endif<br>
<br>
-    initializer_list(const _E* __b, size_t __s)<br>
+    constexpr initializer_list(const _E* __b, size_t __s)<br>
       : __begin_(__b),<br>
+#ifdef USE_END<br>
+        __end_(__b + __s)<br>
+#else<br>
         __size_(__s)<br>
+#endif<br>
     {}<br>
<br>
   public:<br>
@@ -24,14 +34,98 @@ namespace std {<br>
     typedef const _E* iterator;<br>
     typedef const _E* const_iterator;<br>
<br>
-    initializer_list() : __begin_(nullptr), __size_(0) {}<br>
+#ifdef USE_END<br>
+    constexpr initializer_list() : __begin_(nullptr), __end_(nullptr) {}<br>
+<br>
+    size_t    size()  const {return __end_ - __begin_;}<br>
+    const _E* begin() const {return __begin_;}<br>
+    const _E* end()   const {return __end_;}<br>
+#else<br>
+    constexpr initializer_list() : __begin_(nullptr), __size_(0) {}<br>
<br>
     size_t    size()  const {return __size_;}<br>
     const _E* begin() const {return __begin_;}<br>
     const _E* end()   const {return __begin_ + __size_;}<br>
+#endif<br>
   };<br>
 }<br>
<br>
-std::initializer_list<std::initializer_list<int>> pleasefail = {<br>
-  {1, 2}, {3, 4}, {5, 6} // expected-error {{cannot compile}}<br>
+std::initializer_list<std::initializer_list<int>> nested = {<br>
+  {1, 2}, {3, 4}, {5, 6}<br>
 };<br>
+<br>
+// CHECK-STATIC-BL: @_ZGR6nested = private constant [2 x i32] [i32 1, i32 2], align 4<br>
+// CHECK-STATIC-BL: @_ZGR6nested1 = private constant [2 x i32] [i32 3, i32 4], align 4<br>
+// CHECK-STATIC-BL: @_ZGR6nested2 = private constant [2 x i32] [i32 5, i32 6], align 4<br>
+// CHECK-STATIC-BL: @_ZGR6nested3 = private constant [3 x {{.*}}] [<br>
+// CHECK-STATIC-BL:   {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested, i32 0, i32 0), i64 2 },<br>
+// CHECK-STATIC-BL:   {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i32 0, i32 0), i64 2 },<br>
+// CHECK-STATIC-BL:   {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i32 0, i32 0), i64 2 }<br>
+// CHECK-STATIC-BL: ], align 8<br>
+// CHECK-STATIC-BL: @nested = global {{.*}} { {{.*}} getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested3, i32 0, i32 0), i64 3 }, align 8<br>
+<br>
+// CHECK-DYNAMIC-BL: @nested = global<br>
+// CHECK-DYNAMIC-BL: @_ZGR6nested = private global [3 x<br>
+// CHECK-DYNAMIC-BL: @_ZGR6nested1 = private global [2 x i32] zeroinitializer<br>
+// CHECK-DYNAMIC-BL: @_ZGR6nested2 = private global [2 x i32] zeroinitializer<br>
+// CHECK-DYNAMIC-BL: @_ZGR6nested3 = private global [2 x i32] zeroinitializer<br>
+// CHECK-DYNAMIC-BL: store i32 1, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0)<br>
+// CHECK-DYNAMIC-BL: store i32 2, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 1)<br>
+// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0),<br>
+// CHECK-DYMAMIC-BL:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0, i32 0), align 8<br>
+// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0, i32 1), align 8<br>
+// CHECK-DYNAMIC-BL: store i32 3, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0)<br>
+// CHECK-DYNAMIC-BL: store i32 4, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 1)<br>
+// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0),<br>
+// CHECK-DYNAMIC-BL:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 1, i32 0), align 8<br>
+// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 1, i32 1), align 8<br>
+// CHECK-DYNAMIC-BL: store i32 5, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 0)<br>
+// CHECK-DYNAMIC-BL: store i32 6, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 1)<br>
+// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 0),<br>
+// CHECK-DYNAMIC-BL:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 2, i32 0), align 8<br>
+// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 2, i32 1), align 8<br>
+// CHECK-DYNAMIC-BL: store {{.*}}* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0),<br>
+// CHECK-DYNAMIC-BL:       {{.*}}** getelementptr inbounds ({{.*}}* @nested, i32 0, i32 0), align 8<br>
+// CHECK-DYNAMIC-BL: store i64 3, i64* getelementptr inbounds ({{.*}}* @nested, i32 0, i32 1), align 8<br>
+<br>
+// CHECK-STATIC-BE: @_ZGR6nested = private constant [2 x i32] [i32 1, i32 2], align 4<br>
+// CHECK-STATIC-BE: @_ZGR6nested1 = private constant [2 x i32] [i32 3, i32 4], align 4<br>
+// CHECK-STATIC-BE: @_ZGR6nested2 = private constant [2 x i32] [i32 5, i32 6], align 4<br>
+// CHECK-STATIC-BE: @_ZGR6nested3 = private constant [3 x {{.*}}] [<br>
+// CHECK-STATIC-BE:   {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested, i32 0, i32 0),<br>
+// CHECK-STATIC-BE:            i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @_ZGR6nested to i8*), i64 8) to i32*) }<br>
+// CHECK-STATIC-BE:   {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i32 0, i32 0),<br>
+// CHECK-STATIC-BE:            i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @_ZGR6nested1 to i8*), i64 8) to i32*) }<br>
+// CHECK-STATIC-BE:   {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i32 0, i32 0),<br>
+// CHECK-STATIC-BE:            i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @_ZGR6nested2 to i8*), i64 8) to i32*) }<br>
+// CHECK-STATIC-BE: ], align 8<br>
+// CHECK-STATIC-BE: @nested = global {{.*}} { {{.*}} getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested3, i32 0, i32 0),<br>
+// CHECK-STATIC-BE:                           {{.*}} bitcast ({{.*}}* getelementptr (i8* bitcast ([3 x {{.*}}]* @_ZGR6nested3 to i8*), i64 48) to {{.*}}*) }<br>
+<br>
+// CHECK-DYNAMIC-BE: @nested = global<br>
+// CHECK-DYNAMIC-BE: @_ZGR6nested = private global [3 x<br>
+// CHECK-DYNAMIC-BE: @_ZGR6nested1 = private global [2 x i32] zeroinitializer<br>
+// CHECK-DYNAMIC-BE: @_ZGR6nested2 = private global [2 x i32] zeroinitializer<br>
+// CHECK-DYNAMIC-BE: @_ZGR6nested3 = private global [2 x i32] zeroinitializer<br>
+// CHECK-DYNAMIC-BE: store i32 1, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0)<br>
+// CHECK-DYNAMIC-BE: store i32 2, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 1)<br>
+// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0),<br>
+// CHECK-DYMAMIC-BE:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0, i32 0), align 8<br>
+// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 1, i64 0),<br>
+// CHECK-DYMAMIC-BE:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0, i32 1), align 8<br>
+// CHECK-DYNAMIC-BE: store i32 3, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0)<br>
+// CHECK-DYNAMIC-BE: store i32 4, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 1)<br>
+// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0),<br>
+// CHECK-DYNAMIC-BE:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 1, i32 0), align 8<br>
+// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 1, i64 0),<br>
+// CHECK-DYNAMIC-BE:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 1, i32 1), align 8<br>
+// CHECK-DYNAMIC-BE: store i32 5, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 0)<br>
+// CHECK-DYNAMIC-BE: store i32 6, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 1)<br>
+// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 0),<br>
+// CHECK-DYNAMIC-BE:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 2, i32 0), align 8<br>
+// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 1, i64 0),<br>
+// CHECK-DYNAMIC-BE:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 2, i32 1), align 8<br>
+// CHECK-DYNAMIC-BE: store {{.*}}* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0),<br>
+// CHECK-DYNAMIC-BE:       {{.*}}** getelementptr inbounds ({{.*}}* @nested, i32 0, i32 0), align 8<br>
+// CHECK-DYNAMIC-BE: store {{.*}}* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 1, i64 0),<br>
+// CHECK-DYNAMIC-BE:       {{.*}}** getelementptr inbounds ({{.*}}* @nested, i32 0, i32 1), align 8<br>
<br>
Modified: cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp Wed Jun 12 17:31:48 2013<br>
@@ -32,8 +32,8 @@ namespace std {<br>
   };<br>
 }<br>
<br>
-// CHECK: @_ZL25globalInitList1__initlist = internal global [3 x i32] [i32 1, i32 2, i32 3]<br>
-// CHECK: @globalInitList1 = global {{[^ ]+}} { i32* getelementptr inbounds ([3 x i32]* @_ZL25globalInitList1__initlist, {{[^)]*}}), i32*<br>
+// CHECK: @_ZGR15globalInitList1 = private constant [3 x i32] [i32 1, i32 2, i32 3]<br>
+// CHECK: @globalInitList1 = global {{[^ ]+}} { i32* getelementptr inbounds ([3 x i32]* @_ZGR15globalInitList1, {{[^)]*}}), i32*<br>
 std::initializer_list<int> globalInitList1 = {1, 2, 3};<br>
<br>
 void fn1(int i) {<br>
<br>
Modified: cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp Wed Jun 12 17:31:48 2013<br>
@@ -47,23 +47,43 @@ struct wantslist1 {<br>
   ~wantslist1();<br>
 };<br>
<br>
-// CHECK: @_ZL25globalInitList1__initlist = internal global [3 x i32] [i32 1, i32 2, i32 3]<br>
-// CHECK: @globalInitList1 = global %{{[^ ]+}} { i32* getelementptr inbounds ([3 x i32]* @_ZL25globalInitList1__initlist, i32 0, i32 0), i{{32|64}} 3 }<br>
+// CHECK: @_ZGR15globalInitList1 = private constant [3 x i32] [i32 1, i32 2, i32 3]<br>
+// CHECK: @globalInitList1 = global %{{[^ ]+}} { i32* getelementptr inbounds ([3 x i32]* @_ZGR15globalInitList1, i32 0, i32 0), i{{32|64}} 3 }<br>
 std::initializer_list<int> globalInitList1 = {1, 2, 3};<br>
<br>
 namespace thread_local_global_array {<br>
-  // CHECK: @_ZN25thread_local_global_arrayL11x__initlistE = internal thread_local global [4 x i32] [i32 1, i32 2, i32 3, i32 4]<br>
-  // CHECK: @_ZN25thread_local_global_array1xE = thread_local global {{.*}} @_ZN25thread_local_global_arrayL11x__initlistE, {{.*}} i64 4<br>
+  // FIXME: We should be able to constant-evaluate this even though the<br>
+  // initializer is not a constant expression (pointers to thread_local<br>
+  // objects aren't really a problem).<br>
+  //<br>
+  // CHECK: @_ZN25thread_local_global_array1xE = thread_local global<br>
+  // CHECK: @_ZGRN25thread_local_global_array1xE = private thread_local global [4 x i32]<br>
   std::initializer_list<int> thread_local x = { 1, 2, 3, 4 };<br>
 }<br>
<br>
-// CHECK: @_ZL25globalInitList2__initlist = internal global [2 x %{{[^ ]*}}] zeroinitializer<br>
-// CHECK: @globalInitList2 = global %{{[^ ]+}} { %[[WITHARG:[^ *]+]]* getelementptr inbounds ([2 x<br>
+// CHECK: @globalInitList2 = global %{{[^ ]+}} zeroinitializer<br>
+// CHECK: @_ZGR15globalInitList2 = private global [2 x %[[WITHARG:[^ ]*]]] zeroinitializer<br>
 // CHECK: appending global<br>
+<br>
+<br>
+// thread_local initializer:<br>
+// CHECK: define internal void<br>
+// CHECK: store i32 1, i32* getelementptr inbounds ([4 x i32]* @_ZGRN25thread_local_global_array1xE, i64 0, i64 0)<br>
+// CHECK: store i32 2, i32* getelementptr inbounds ([4 x i32]* @_ZGRN25thread_local_global_array1xE, i64 0, i64 1)<br>
+// CHECK: store i32 3, i32* getelementptr inbounds ([4 x i32]* @_ZGRN25thread_local_global_array1xE, i64 0, i64 2)<br>
+// CHECK: store i32 4, i32* getelementptr inbounds ([4 x i32]* @_ZGRN25thread_local_global_array1xE, i64 0, i64 3)<br>
+// CHECK: store i32* getelementptr inbounds ([4 x i32]* @_ZGRN25thread_local_global_array1xE, i64 0, i64 0),<br>
+// CHECK:       i32** getelementptr inbounds ({{.*}}* @_ZN25thread_local_global_array1xE, i32 0, i32 0), align 8<br>
+// CHECK: store i64 4, i64* getelementptr inbounds ({{.*}}* @_ZN25thread_local_global_array1xE, i32 0, i32 1), align 8<br>
+<br>
+<br>
 // CHECK: define internal void<br>
-// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZL25globalInitList2__initlist, i{{32|64}} 0, i{{32|64}} 0<br>
-// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZL25globalInitList2__initlist, i{{32|64}} 0, i{{32|64}} 1<br>
+// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZGR15globalInitList2, i{{32|64}} 0, i{{32|64}} 0<br>
+// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZGR15globalInitList2, i{{32|64}} 0, i{{32|64}} 1<br>
 // CHECK: __cxa_atexit<br>
+// CHECK: store %[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZGR15globalInitList2, i64 0, i64 0),<br>
+// CHECK:       %[[WITHARG]]** getelementptr inbounds (%{{.*}}* @globalInitList2, i32 0, i32 0), align 8<br>
+// CHECK: store i64 2, i64* getelementptr inbounds (%{{.*}}* @globalInitList2, i32 0, i32 1), align 8<br>
 // CHECK: call void @_ZN10destroyme1D1Ev<br>
 // CHECK: call void @_ZN10destroyme1D1Ev<br>
 std::initializer_list<witharg1> globalInitList2 = {<br>
@@ -281,10 +301,56 @@ namespace dtors {<br>
     S();<br>
     ~S();<br>
   };<br>
+  void z();<br>
+<br>
+  // CHECK: define void @_ZN5dtors1fEv(<br>
   void f() {<br>
+    // CHECK: call void @_ZN5dtors1SC1Ev(%"struct.dtors::S"* %arrayinit.begin)<br>
+    // CHECK: call void @_ZN5dtors1SC1Ev(%"struct.dtors::S"* %arrayinit.element)<br>
     std::initializer_list<S>{ S(), S() };<br>
+<br>
+    // Destruction loop for underlying array.<br>
+    // CHECK: br label<br>
+    // CHECK: call void @_ZN5dtors1SD1Ev(<br>
+    // CHECK: br i1<br>
+<br>
+    // CHECK: call void @_ZN5dtors1zEv(<br>
+    z();<br>
+<br>
+    // CHECK-NOT: call void @_ZN5dtors1SD1Ev(<br>
   }<br>
+<br>
+  // CHECK: define void @_ZN5dtors1gEv(<br>
   void g() {<br>
+    // CHECK: call void @_ZN5dtors1SC1Ev(%"struct.dtors::S"* %arrayinit.begin)<br>
+    // CHECK: call void @_ZN5dtors1SC1Ev(%"struct.dtors::S"* %arrayinit.element)<br>
     auto x = std::initializer_list<S>{ S(), S() };<br>
+<br>
+    // Destruction loop for underlying array.<br>
+    // CHECK: br label<br>
+    // CHECK: call void @_ZN5dtors1SD1Ev(<br>
+    // CHECK: br i1<br>
+<br>
+    // CHECK: call void @_ZN5dtors1zEv(<br>
+    z();<br>
+<br>
+    // CHECK-NOT: call void @_ZN5dtors1SD1Ev(<br>
+  }<br>
+<br>
+  // CHECK: define void @_ZN5dtors1hEv(<br>
+  void h() {<br>
+    // CHECK: call void @_ZN5dtors1SC1Ev(%"struct.dtors::S"* %arrayinit.begin)<br>
+    // CHECK: call void @_ZN5dtors1SC1Ev(%"struct.dtors::S"* %arrayinit.element)<br>
+    std::initializer_list<S> x = { S(), S() };<br>
+<br>
+    // CHECK-NOT: call void @_ZN5dtors1SD1Ev(<br>
+<br>
+    // CHECK: call void @_ZN5dtors1zEv(<br>
+    z();<br>
+<br>
+    // Destruction loop for underlying array.<br>
+    // CHECK: br label<br>
+    // CHECK: call void @_ZN5dtors1SD1Ev(<br>
+    // CHECK: br i1<br>
   }<br>
 }<br>
<br>
Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Wed Jun 12 17:31:48 2013<br>
@@ -1596,3 +1596,44 @@ namespace AfterError {<br>
   }<br>
   constexpr int k = error(); // expected-error {{must be initialized by a constant expression}}<br>
 }<br>
+<br>
+namespace std {<br>
+  typedef decltype(sizeof(int)) size_t;<br>
+<br>
+  template <class _E><br>
+  class initializer_list<br>
+  {<br>
+    const _E* __begin_;<br>
+    size_t    __size_;<br>
+<br>
+    constexpr initializer_list(const _E* __b, size_t __s)<br>
+      : __begin_(__b),<br>
+        __size_(__s)<br>
+    {}<br>
+<br>
+  public:<br>
+    typedef _E        value_type;<br>
+    typedef const _E& reference;<br>
+    typedef const _E& const_reference;<br>
+    typedef size_t    size_type;<br>
+<br>
+    typedef const _E* iterator;<br>
+    typedef const _E* const_iterator;<br>
+<br>
+    constexpr initializer_list() : __begin_(nullptr), __size_(0) {}<br>
+<br>
+    constexpr size_t    size()  const {return __size_;}<br>
+    constexpr const _E* begin() const {return __begin_;}<br>
+    constexpr const _E* end()   const {return __begin_ + __size_;}<br>
+  };<br>
+}<br>
+<br>
+namespace InitializerList {<br>
+  constexpr int sum(const int *b, const int *e) {<br>
+    return b != e ? *b + sum(b+1, e) : 0;<br>
+  }<br>
+  constexpr int sum(std::initializer_list<int> ints) {<br>
+    return sum(ints.begin(), ints.end());<br>
+  }<br>
+  static_assert(sum({1, 2, 3, 4, 5}) == 15, "");<br>
+}<br>
<br>
Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx1y.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx1y.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx1y.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/SemaCXX/constant-expression-cxx1y.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx1y.cpp Wed Jun 12 17:31:48 2013<br>
@@ -725,3 +725,43 @@ namespace modify_temporary_during_constr<br>
   static_assert(a.y == 54, "");<br>
   constexpr int k = a.temporary++; // expected-error {{constant expression}} expected-note {{outside the expression that created the temporary}}<br>
 }<br>
+<br>
+namespace std {<br>
+  typedef decltype(sizeof(int)) size_t;<br>
+<br>
+  template <class _E><br>
+  class initializer_list<br>
+  {<br>
+    const _E* __begin_;<br>
+    size_t    __size_;<br>
+<br>
+    constexpr initializer_list(const _E* __b, size_t __s)<br>
+      : __begin_(__b),<br>
+        __size_(__s)<br>
+    {}<br>
+<br>
+  public:<br>
+    typedef _E        value_type;<br>
+    typedef const _E& reference;<br>
+    typedef const _E& const_reference;<br>
+    typedef size_t    size_type;<br>
+<br>
+    typedef const _E* iterator;<br>
+    typedef const _E* const_iterator;<br>
+<br>
+    constexpr initializer_list() : __begin_(nullptr), __size_(0) {}<br>
+<br>
+    constexpr size_t    size()  const {return __size_;}<br>
+    constexpr const _E* begin() const {return __begin_;}<br>
+    constexpr const _E* end()   const {return __begin_ + __size_;}<br>
+  };<br>
+}<br>
+<br>
+namespace InitializerList {<br>
+  constexpr int sum(std::initializer_list<int> ints) {<br>
+    int total = 0;<br>
+    for (int n : ints) total += n;<br>
+    return total;<br>
+  }<br>
+  static_assert(sum({1, 2, 3, 4, 5}) == 15, "");<br>
+}<br>
<br>
Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp Wed Jun 12 17:31:48 2013<br>
@@ -144,7 +144,7 @@ namespace PR12119 {<br>
   template<typename T> void g(std::initializer_list<std::initializer_list<T>>);<br>
<br>
   void foo() {<br>
-    f({0, {1}});<br>
+    f({0, {1}}); // expected-warning{{braces around scalar initializer}}<br>
     g({{0, 1}, {2, 3}});<br>
     std::initializer_list<int> il = {1, 2};<br>
     g({il, {2, 3}});<br>
<br>
Modified: cfe/trunk/tools/libclang/CXCursor.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.cpp?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.cpp?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/tools/libclang/CXCursor.cpp (original)<br>
+++ cfe/trunk/tools/libclang/CXCursor.cpp Wed Jun 12 17:31:48 2013<br>
@@ -216,6 +216,7 @@ CXCursor cxcursor::MakeCXCursor(const St<br>
   case Stmt::CXXBindTemporaryExprClass:<br>
   case Stmt::CXXDefaultArgExprClass:<br>
   case Stmt::CXXDefaultInitExprClass:<br>
+  case Stmt::CXXStdInitializerListExprClass:<br>
   case Stmt::CXXScalarValueInitExprClass:<br>
   case Stmt::CXXUuidofExprClass:<br>
   case Stmt::ChooseExprClass:<br>
<br>
Modified: cfe/trunk/tools/libclang/RecursiveASTVisitor.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/RecursiveASTVisitor.h?rev=183872&r1=183871&r2=183872&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/RecursiveASTVisitor.h?rev=183872&r1=183871&r2=183872&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/tools/libclang/RecursiveASTVisitor.h (original)<br>
+++ cfe/trunk/tools/libclang/RecursiveASTVisitor.h Wed Jun 12 17:31:48 2013<br>
@@ -2095,6 +2095,7 @@ DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {<br>
 DEF_TRAVERSE_STMT(CXXDeleteExpr, { })<br>
 DEF_TRAVERSE_STMT(ExprWithCleanups, { })<br>
 DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, { })<br>
+DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, { })<br>
 DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {<br>
   TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));<br>
   if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>