r183872 - PR12086, PR15117
Lang Hames
lhames at gmail.com
Thu Jun 13 15:18:20 PDT 2013
Great - thanks Richard Sorry for the false alarm. :)
- Lang.
On Thu, Jun 13, 2013 at 3:03 PM, Richard Smith <richard at metafoo.co.uk>wrote:
> This is already fixed (r183924). It seems we don't have any buildbots
> which build with NDEBUG and are set up to send mail ;( ... or, if we
> do, they're super low.
>
> On Thu, Jun 13, 2013 at 2:58 PM, Lang Hames <lhames at gmail.com> wrote:
> > Hi Richard,
> >
> > It looks like this broke
> CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
> >
> > See -
> http://lab.llvm.org:8013/builders/clang-x86_64-darwin11-R/builds/1159
> >
> > Cheers,
> > Lang.
> >
> >
> >
> > On Wed, Jun 12, 2013 at 3:31 PM, Richard Smith <
> richard-llvm at metafoo.co.uk>
> > wrote:
> >>
> >> Author: rsmith
> >> Date: Wed Jun 12 17:31:48 2013
> >> New Revision: 183872
> >>
> >> URL: http://llvm.org/viewvc/llvm-project?rev=183872&view=rev
> >> Log:
> >> PR12086, PR15117
> >>
> >> Introduce CXXStdInitializerListExpr node, representing the implicit
> >> construction of a std::initializer_list<T> object from its underlying
> >> array.
> >> The AST representation of such an expression goes from an InitListExpr
> >> with a
> >> flag set, to a CXXStdInitializerListExpr containing a
> >> MaterializeTemporaryExpr
> >> containing an InitListExpr (possibly wrapped in a CXXBindTemporaryExpr).
> >>
> >> This more detailed representation has several advantages, the most
> >> important of
> >> which is that the new MaterializeTemporaryExpr allows us to directly
> model
> >> lifetime extension of the underlying temporary array. Using that, this
> >> patch
> >> *drastically* simplifies the IR generation of this construct, provides
> IR
> >> generation support for nested global initializer_list objects, fixes
> >> several
> >> bugs where the destructors for the underlying array would accidentally
> not
> >> get
> >> invoked, and provides constant expression evaluation support for
> >> std::initializer_list objects.
> >>
> >> Modified:
> >> cfe/trunk/include/clang/AST/Expr.h
> >> cfe/trunk/include/clang/AST/ExprCXX.h
> >> cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
> >> cfe/trunk/include/clang/AST/Stmt.h
> >> cfe/trunk/include/clang/Basic/StmtNodes.td
> >> cfe/trunk/include/clang/Serialization/ASTBitCodes.h
> >> cfe/trunk/lib/AST/Expr.cpp
> >> cfe/trunk/lib/AST/ExprClassification.cpp
> >> cfe/trunk/lib/AST/ExprConstant.cpp
> >> cfe/trunk/lib/AST/ItaniumMangle.cpp
> >> cfe/trunk/lib/AST/StmtPrinter.cpp
> >> cfe/trunk/lib/AST/StmtProfile.cpp
> >> cfe/trunk/lib/CodeGen/CGClass.cpp
> >> cfe/trunk/lib/CodeGen/CGDecl.cpp
> >> cfe/trunk/lib/CodeGen/CGExpr.cpp
> >> cfe/trunk/lib/CodeGen/CGExprAgg.cpp
> >> cfe/trunk/lib/CodeGen/CGExprCXX.cpp
> >> cfe/trunk/lib/CodeGen/CGExprConstant.cpp
> >> cfe/trunk/lib/CodeGen/CodeGenFunction.h
> >> cfe/trunk/lib/CodeGen/CodeGenModule.cpp
> >> cfe/trunk/lib/CodeGen/CodeGenModule.h
> >> cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> >> cfe/trunk/lib/Sema/SemaExceptionSpec.cpp
> >> cfe/trunk/lib/Sema/SemaInit.cpp
> >> cfe/trunk/lib/Sema/TreeTransform.h
> >> cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
> >> cfe/trunk/lib/Serialization/ASTWriter.cpp
> >> cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
> >> cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
> >> cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp
> >>
> >>
> cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp
> >>
> >>
> cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp
> >> cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
> >> cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
> >> cfe/trunk/test/SemaCXX/constant-expression-cxx1y.cpp
> >> cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
> >> cfe/trunk/tools/libclang/CXCursor.cpp
> >> cfe/trunk/tools/libclang/RecursiveASTVisitor.h
> >>
> >> Modified: cfe/trunk/include/clang/AST/Expr.h
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/include/clang/AST/Expr.h (original)
> >> +++ cfe/trunk/include/clang/AST/Expr.h Wed Jun 12 17:31:48 2013
> >> @@ -3794,13 +3794,6 @@ public:
> >> InitListExprBits.HadArrayRangeDesignator = ARD;
> >> }
> >>
> >> - bool initializesStdInitializerList() const {
> >> - return InitListExprBits.InitializesStdInitializerList != 0;
> >> - }
> >> - void setInitializesStdInitializerList(bool ISIL = true) {
> >> - InitListExprBits.InitializesStdInitializerList = ISIL;
> >> - }
> >> -
> >> SourceLocation getLocStart() const LLVM_READONLY;
> >> SourceLocation getLocEnd() const LLVM_READONLY;
> >>
> >>
> >> Modified: cfe/trunk/include/clang/AST/ExprCXX.h
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/include/clang/AST/ExprCXX.h (original)
> >> +++ cfe/trunk/include/clang/AST/ExprCXX.h Wed Jun 12 17:31:48 2013
> >> @@ -474,6 +474,45 @@ public:
> >> child_range children() { return child_range(); }
> >> };
> >>
> >> +/// \brief Implicit construction of a std::initializer_list<T> object
> >> from an
> >> +/// array temporary within list-initialization (C++11
> [dcl.init.list]p5).
> >> +class CXXStdInitializerListExpr : public Expr {
> >> + Stmt *SubExpr;
> >> +
> >> + CXXStdInitializerListExpr(EmptyShell Empty)
> >> + : Expr(CXXStdInitializerListExprClass, Empty), SubExpr(0) {}
> >> +
> >> +public:
> >> + CXXStdInitializerListExpr(QualType Ty, Expr *SubExpr)
> >> + : Expr(CXXStdInitializerListExprClass, Ty, VK_RValue, OK_Ordinary,
> >> + Ty->isDependentType(), SubExpr->isValueDependent(),
> >> + SubExpr->isInstantiationDependent(),
> >> + SubExpr->containsUnexpandedParameterPack()),
> >> + SubExpr(SubExpr) {}
> >> +
> >> + Expr *getSubExpr() { return static_cast<Expr*>(SubExpr); }
> >> + const Expr *getSubExpr() const { return static_cast<const
> >> Expr*>(SubExpr); }
> >> +
> >> + SourceLocation getLocStart() const LLVM_READONLY {
> >> + return SubExpr->getLocStart();
> >> + }
> >> + SourceLocation getLocEnd() const LLVM_READONLY {
> >> + return SubExpr->getLocEnd();
> >> + }
> >> + SourceRange getSourceRange() const LLVM_READONLY {
> >> + return SubExpr->getSourceRange();
> >> + }
> >> +
> >> + static bool classof(const Stmt *S) {
> >> + return S->getStmtClass() == CXXStdInitializerListExprClass;
> >> + }
> >> +
> >> + child_range children() { return child_range(&SubExpr, &SubExpr + 1);
> }
> >> +
> >> + friend class ASTReader;
> >> + friend class ASTStmtReader;
> >> +};
> >> +
> >> /// CXXTypeidExpr - A C++ @c typeid expression (C++ [expr.typeid]),
> which
> >> gets
> >> /// the type_info that corresponds to the supplied type, or the
> (possibly
> >> /// dynamic) type of the supplied expression.
> >>
> >> Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
> >> +++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Wed Jun 12
> 17:31:48
> >> 2013
> >> @@ -2177,6 +2177,7 @@ DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {
> >> DEF_TRAVERSE_STMT(CXXDeleteExpr, { })
> >> DEF_TRAVERSE_STMT(ExprWithCleanups, { })
> >> DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, { })
> >> +DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, { })
> >> DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {
> >> TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
> >> if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
> >>
> >> Modified: cfe/trunk/include/clang/AST/Stmt.h
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/include/clang/AST/Stmt.h (original)
> >> +++ cfe/trunk/include/clang/AST/Stmt.h Wed Jun 12 17:31:48 2013
> >> @@ -266,10 +266,6 @@ protected:
> >> /// Whether this initializer list originally had a GNU array-range
> >> /// designator in it. This is a temporary marker used by CodeGen.
> >> unsigned HadArrayRangeDesignator : 1;
> >> -
> >> - /// Whether this initializer list initializes a
> std::initializer_list
> >> - /// object.
> >> - unsigned InitializesStdInitializerList : 1;
> >> };
> >>
> >> class TypeTraitExprBitfields {
> >>
> >> Modified: cfe/trunk/include/clang/Basic/StmtNodes.td
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/StmtNodes.td?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/include/clang/Basic/StmtNodes.td (original)
> >> +++ cfe/trunk/include/clang/Basic/StmtNodes.td Wed Jun 12 17:31:48 2013
> >> @@ -110,6 +110,7 @@ def CXXThrowExpr : DStmt<Expr>;
> >> def CXXDefaultArgExpr : DStmt<Expr>;
> >> def CXXDefaultInitExpr : DStmt<Expr>;
> >> def CXXScalarValueInitExpr : DStmt<Expr>;
> >> +def CXXStdInitializerListExpr : DStmt<Expr>;
> >> def CXXNewExpr : DStmt<Expr>;
> >> def CXXDeleteExpr : DStmt<Expr>;
> >> def CXXPseudoDestructorExpr : DStmt<Expr>;
> >>
> >> Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
> >> +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Wed Jun 12
> >> 17:31:48 2013
> >> @@ -1259,6 +1259,8 @@ namespace clang {
> >> EXPR_CXX_FUNCTIONAL_CAST,
> >> /// \brief A UserDefinedLiteral record.
> >> EXPR_USER_DEFINED_LITERAL,
> >> + /// \brief A CXXStdInitializerListExpr record.
> >> + EXPR_CXX_STD_INITIALIZER_LIST,
> >> /// \brief A CXXBoolLiteralExpr record.
> >> EXPR_CXX_BOOL_LITERAL,
> >> EXPR_CXX_NULL_PTR_LITERAL, // CXXNullPtrLiteralExpr
> >>
> >> Modified: cfe/trunk/lib/AST/Expr.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/AST/Expr.cpp (original)
> >> +++ cfe/trunk/lib/AST/Expr.cpp Wed Jun 12 17:31:48 2013
> >> @@ -1789,7 +1789,6 @@ InitListExpr::InitListExpr(ASTContext &C
> >> LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), AltForm(0, true)
> >> {
> >> sawArrayRangeDesignator(false);
> >> - setInitializesStdInitializerList(false);
> >> for (unsigned I = 0; I != initExprs.size(); ++I) {
> >> if (initExprs[I]->isTypeDependent())
> >> ExprBits.TypeDependent = true;
> >> @@ -2836,6 +2835,7 @@ bool Expr::HasSideEffects(const ASTConte
> >> case DesignatedInitExprClass:
> >> case ParenListExprClass:
> >> case CXXPseudoDestructorExprClass:
> >> + case CXXStdInitializerListExprClass:
> >> case SubstNonTypeTemplateParmExprClass:
> >> case MaterializeTemporaryExprClass:
> >> case ShuffleVectorExprClass:
> >>
> >> Modified: cfe/trunk/lib/AST/ExprClassification.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprClassification.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/AST/ExprClassification.cpp (original)
> >> +++ cfe/trunk/lib/AST/ExprClassification.cpp Wed Jun 12 17:31:48 2013
> >> @@ -353,6 +353,7 @@ static Cl::Kinds ClassifyInternal(ASTCon
> >> case Expr::CXXConstructExprClass:
> >> case Expr::CXXTemporaryObjectExprClass:
> >> case Expr::LambdaExprClass:
> >> + case Expr::CXXStdInitializerListExprClass:
> >> return Cl::CL_ClassTemporary;
> >>
> >> case Expr::VAArgExprClass:
> >>
> >> Modified: cfe/trunk/lib/AST/ExprConstant.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/AST/ExprConstant.cpp (original)
> >> +++ cfe/trunk/lib/AST/ExprConstant.cpp Wed Jun 12 17:31:48 2013
> >> @@ -4576,6 +4576,7 @@ namespace {
> >> bool VisitCastExpr(const CastExpr *E);
> >> bool VisitInitListExpr(const InitListExpr *E);
> >> bool VisitCXXConstructExpr(const CXXConstructExpr *E);
> >> + bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr
> >> *E);
> >> };
> >> }
> >>
> >> @@ -4691,10 +4692,6 @@ bool RecordExprEvaluator::VisitCastExpr(
> >> }
> >>
> >> bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
> >> - // Cannot constant-evaluate std::initializer_list inits.
> >> - if (E->initializesStdInitializerList())
> >> - return false;
> >> -
> >> const RecordDecl *RD = E->getType()->castAs<RecordType>()->getDecl();
> >> if (RD->isInvalidDecl()) return false;
> >> const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
> >> @@ -4810,6 +4807,58 @@ bool RecordExprEvaluator::VisitCXXConstr
> >> Result);
> >> }
> >>
> >> +bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
> >> + const CXXStdInitializerListExpr *E) {
> >> + const ConstantArrayType *ArrayType =
> >> + Info.Ctx.getAsConstantArrayType(E->getSubExpr()->getType());
> >> +
> >> + LValue Array;
> >> + if (!EvaluateLValue(E->getSubExpr(), Array, Info))
> >> + return false;
> >> +
> >> + // Get a pointer to the first element of the array.
> >> + Array.addArray(Info, E, ArrayType);
> >> +
> >> + // FIXME: Perform the checks on the field types in SemaInit.
> >> + RecordDecl *Record = E->getType()->castAs<RecordType>()->getDecl();
> >> + RecordDecl::field_iterator Field = Record->field_begin();
> >> + if (Field == Record->field_end())
> >> + return Error(E);
> >> +
> >> + // Start pointer.
> >> + if (!Field->getType()->isPointerType() ||
> >> + !Info.Ctx.hasSameType(Field->getType()->getPointeeType(),
> >> + ArrayType->getElementType()))
> >> + return Error(E);
> >> +
> >> + // FIXME: What if the initializer_list type has base classes, etc?
> >> + Result = APValue(APValue::UninitStruct(), 0, 2);
> >> + Array.moveInto(Result.getStructField(0));
> >> +
> >> + if (++Field == Record->field_end())
> >> + return Error(E);
> >> +
> >> + if (Field->getType()->isPointerType() &&
> >> + Info.Ctx.hasSameType(Field->getType()->getPointeeType(),
> >> + ArrayType->getElementType())) {
> >> + // End pointer.
> >> + if (!HandleLValueArrayAdjustment(Info, E, Array,
> >> + ArrayType->getElementType(),
> >> +
> >> ArrayType->getSize().getZExtValue()))
> >> + return false;
> >> + Array.moveInto(Result.getStructField(1));
> >> + } else if (Info.Ctx.hasSameType(Field->getType(),
> >> Info.Ctx.getSizeType()))
> >> + // Length.
> >> + Result.getStructField(1) = APValue(APSInt(ArrayType->getSize()));
> >> + else
> >> + return Error(E);
> >> +
> >> + if (++Field != Record->field_end())
> >> + return Error(E);
> >> +
> >> + return true;
> >> +}
> >> +
> >> static bool EvaluateRecord(const Expr *E, const LValue &This,
> >> APValue &Result, EvalInfo &Info) {
> >> assert(E->isRValue() && E->getType()->isRecordType() &&
> >> @@ -7762,6 +7811,7 @@ static ICEDiag CheckICE(const Expr* E, A
> >> case Expr::UnresolvedLookupExprClass:
> >> case Expr::DependentScopeDeclRefExprClass:
> >> case Expr::CXXConstructExprClass:
> >> + case Expr::CXXStdInitializerListExprClass:
> >> case Expr::CXXBindTemporaryExprClass:
> >> case Expr::ExprWithCleanupsClass:
> >> case Expr::CXXTemporaryObjectExprClass:
> >>
> >> Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
> >> +++ cfe/trunk/lib/AST/ItaniumMangle.cpp Wed Jun 12 17:31:48 2013
> >> @@ -2481,6 +2481,10 @@ recurse:
> >> mangleExpression(cast<CXXDefaultInitExpr>(E)->getExpr(), Arity);
> >> break;
> >>
> >> + case Expr::CXXStdInitializerListExprClass:
> >> + mangleExpression(cast<CXXStdInitializerListExpr>(E)->getSubExpr(),
> >> Arity);
> >> + break;
> >> +
> >> case Expr::SubstNonTypeTemplateParmExprClass:
> >>
> >>
> mangleExpression(cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement(),
> >> Arity);
> >>
> >> Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
> >> +++ cfe/trunk/lib/AST/StmtPrinter.cpp Wed Jun 12 17:31:48 2013
> >> @@ -1534,6 +1534,10 @@ void StmtPrinter::VisitCXXConstructExpr(
> >> OS << " }";
> >> }
> >>
> >> +void
> >> StmtPrinter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr
> *E) {
> >> + PrintExpr(E->getSubExpr());
> >> +}
> >> +
> >> void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) {
> >> // Just forward to the sub expression.
> >> PrintExpr(E->getSubExpr());
> >>
> >> Modified: cfe/trunk/lib/AST/StmtProfile.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/AST/StmtProfile.cpp (original)
> >> +++ cfe/trunk/lib/AST/StmtProfile.cpp Wed Jun 12 17:31:48 2013
> >> @@ -758,6 +758,11 @@ void StmtProfiler::VisitCXXNullPtrLitera
> >> VisitExpr(S);
> >> }
> >>
> >> +void StmtProfiler::VisitCXXStdInitializerListExpr(
> >> + const CXXStdInitializerListExpr *S) {
> >> + VisitExpr(S);
> >> +}
> >> +
> >> void StmtProfiler::VisitCXXTypeidExpr(const CXXTypeidExpr *S) {
> >> VisitExpr(S);
> >> if (S->isTypeOperand())
> >>
> >> Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
> >> +++ cfe/trunk/lib/CodeGen/CGClass.cpp Wed Jun 12 17:31:48 2013
> >> @@ -433,52 +433,45 @@ static void EmitAggMemberInitializer(Cod
> >> unsigned Index) {
> >> if (Index == ArrayIndexes.size()) {
> >> LValue LV = LHS;
> >> - { // Scope for Cleanups.
> >> - CodeGenFunction::RunCleanupsScope Cleanups(CGF);
> >>
> >> - if (ArrayIndexVar) {
> >> - // If we have an array index variable, load it and use it as an
> >> offset.
> >> - // Then, increment the value.
> >> - llvm::Value *Dest = LHS.getAddress();
> >> - llvm::Value *ArrayIndex =
> CGF.Builder.CreateLoad(ArrayIndexVar);
> >> - Dest = CGF.Builder.CreateInBoundsGEP(Dest, ArrayIndex,
> >> "destaddress");
> >> - llvm::Value *Next =
> llvm::ConstantInt::get(ArrayIndex->getType(),
> >> 1);
> >> - Next = CGF.Builder.CreateAdd(ArrayIndex, Next, "inc");
> >> - CGF.Builder.CreateStore(Next, ArrayIndexVar);
> >> -
> >> - // Update the LValue.
> >> - LV.setAddress(Dest);
> >> - CharUnits Align = CGF.getContext().getTypeAlignInChars(T);
> >> - LV.setAlignment(std::min(Align, LV.getAlignment()));
> >> - }
> >> -
> >> - switch (CGF.getEvaluationKind(T)) {
> >> - case TEK_Scalar:
> >> - CGF.EmitScalarInit(Init, /*decl*/ 0, LV, false);
> >> - break;
> >> - case TEK_Complex:
> >> - CGF.EmitComplexExprIntoLValue(Init, LV, /*isInit*/ true);
> >> - break;
> >> - case TEK_Aggregate: {
> >> - AggValueSlot Slot =
> >> - AggValueSlot::forLValue(LV,
> >> - AggValueSlot::IsDestructed,
> >> - AggValueSlot::DoesNotNeedGCBarriers,
> >> - AggValueSlot::IsNotAliased);
> >> -
> >> - CGF.EmitAggExpr(Init, Slot);
> >> - break;
> >> - }
> >> - }
> >> + if (ArrayIndexVar) {
> >> + // If we have an array index variable, load it and use it as an
> >> offset.
> >> + // Then, increment the value.
> >> + llvm::Value *Dest = LHS.getAddress();
> >> + llvm::Value *ArrayIndex = CGF.Builder.CreateLoad(ArrayIndexVar);
> >> + Dest = CGF.Builder.CreateInBoundsGEP(Dest, ArrayIndex,
> >> "destaddress");
> >> + llvm::Value *Next = llvm::ConstantInt::get(ArrayIndex->getType(),
> >> 1);
> >> + Next = CGF.Builder.CreateAdd(ArrayIndex, Next, "inc");
> >> + CGF.Builder.CreateStore(Next, ArrayIndexVar);
> >> +
> >> + // Update the LValue.
> >> + LV.setAddress(Dest);
> >> + CharUnits Align = CGF.getContext().getTypeAlignInChars(T);
> >> + LV.setAlignment(std::min(Align, LV.getAlignment()));
> >> }
> >>
> >> - // Now, outside of the initializer cleanup scope, destroy the
> backing
> >> array
> >> - // for a std::initializer_list member.
> >> - CGF.MaybeEmitStdInitializerListCleanup(LV.getAddress(), Init);
> >> + switch (CGF.getEvaluationKind(T)) {
> >> + case TEK_Scalar:
> >> + CGF.EmitScalarInit(Init, /*decl*/ 0, LV, false);
> >> + break;
> >> + case TEK_Complex:
> >> + CGF.EmitComplexExprIntoLValue(Init, LV, /*isInit*/ true);
> >> + break;
> >> + case TEK_Aggregate: {
> >> + AggValueSlot Slot =
> >> + AggValueSlot::forLValue(LV,
> >> + AggValueSlot::IsDestructed,
> >> + AggValueSlot::DoesNotNeedGCBarriers,
> >> + AggValueSlot::IsNotAliased);
> >> +
> >> + CGF.EmitAggExpr(Init, Slot);
> >> + break;
> >> + }
> >> + }
> >>
> >> return;
> >> }
> >> -
> >> +
> >> const ConstantArrayType *Array =
> >> CGF.getContext().getAsConstantArrayType(T);
> >> assert(Array && "Array initialization without the array type?");
> >> llvm::Value *IndexVar
> >> @@ -512,16 +505,12 @@ static void EmitAggMemberInitializer(Cod
> >>
> >> CGF.EmitBlock(ForBody);
> >> llvm::BasicBlock *ContinueBlock = CGF.createBasicBlock("for.inc");
> >> -
> >> - {
> >> - CodeGenFunction::RunCleanupsScope Cleanups(CGF);
> >> -
> >> - // Inside the loop body recurse to emit the inner loop or,
> >> eventually, the
> >> - // constructor call.
> >> - EmitAggMemberInitializer(CGF, LHS, Init, ArrayIndexVar,
> >> - Array->getElementType(), ArrayIndexes,
> Index
> >> + 1);
> >> - }
> >> -
> >> +
> >> + // Inside the loop body recurse to emit the inner loop or,
> eventually,
> >> the
> >> + // constructor call.
> >> + EmitAggMemberInitializer(CGF, LHS, Init, ArrayIndexVar,
> >> + Array->getElementType(), ArrayIndexes,
> Index +
> >> 1);
> >> +
> >> CGF.EmitBlock(ContinueBlock);
> >>
> >> // Emit the increment of the loop counter.
> >> @@ -726,7 +715,7 @@ void CodeGenFunction::EmitConstructorBod
> >> if (IsTryBody)
> >> EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true);
> >>
> >> - EHScopeStack::stable_iterator CleanupDepth = EHStack.stable_begin();
> >> + RunCleanupsScope RunCleanups(*this);
> >>
> >> // TODO: in restricted cases, we can emit the vbase initializers of
> >> // a complete ctor and then delegate to the base ctor.
> >> @@ -745,7 +734,7 @@ void CodeGenFunction::EmitConstructorBod
> >> // initializers, which includes (along the exceptional path) the
> >> // destructors for those members and bases that were fully
> >> // constructed.
> >> - PopCleanupBlocks(CleanupDepth);
> >> + RunCleanups.ForceCleanup();
> >>
> >> if (IsTryBody)
> >> ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true);
> >>
> >> Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
> >> +++ cfe/trunk/lib/CodeGen/CGDecl.cpp Wed Jun 12 17:31:48 2013
> >> @@ -1187,7 +1187,6 @@ void CodeGenFunction::EmitExprAsInit(con
> >>
> >> AggValueSlot::DoesNotNeedGCBarriers,
> >>
> >> AggValueSlot::IsNotAliased));
> >> }
> >> - MaybeEmitStdInitializerListCleanup(lvalue.getAddress(), init);
> >> return;
> >> }
> >> llvm_unreachable("bad evaluation kind");
> >>
> >> Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
> >> +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Wed Jun 12 17:31:48 2013
> >> @@ -240,15 +240,6 @@ pushTemporaryCleanup(CodeGenFunction &CG
> >> }
> >> }
> >>
> >> - if (const InitListExpr *ILE = dyn_cast<InitListExpr>(E)) {
> >> - if (ILE->initializesStdInitializerList()) {
> >> - // FIXME: This is wrong if the temporary has static or thread
> >> storage
> >> - // duration.
> >> - CGF.EmitStdInitializerListCleanup(ReferenceTemporary, ILE);
> >> - return;
> >> - }
> >> - }
> >> -
> >> CXXDestructorDecl *ReferenceTemporaryDtor = 0;
> >> if (const RecordType *RT =
> >>
> E->getType()->getBaseElementTypeUnsafe()->getAs<RecordType>())
> >> {
> >>
> >> Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
> >> +++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Wed Jun 12 17:31:48 2013
> >> @@ -91,7 +91,6 @@ public:
> >>
> >> void EmitMoveFromReturnSlot(const Expr *E, RValue Src);
> >>
> >> - void EmitStdInitializerList(llvm::Value *DestPtr, InitListExpr
> >> *InitList);
> >> void EmitArrayInit(llvm::Value *DestPtr, llvm::ArrayType *AType,
> >> QualType elementType, InitListExpr *E);
> >>
> >> @@ -177,6 +176,7 @@ public:
> >> void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
> >> void VisitCXXConstructExpr(const CXXConstructExpr *E);
> >> void VisitLambdaExpr(LambdaExpr *E);
> >> + void VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E);
> >> void VisitExprWithCleanups(ExprWithCleanups *E);
> >> void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
> >> void VisitCXXTypeidExpr(CXXTypeidExpr *E) { EmitAggLoadOfLValue(E); }
> >> @@ -345,89 +345,70 @@ void AggExprEmitter::EmitCopy(QualType t
> >> std::min(dest.getAlignment(),
> >> src.getAlignment()));
> >> }
> >>
> >> -static QualType GetStdInitializerListElementType(QualType T) {
> >> - // Just assume that this is really std::initializer_list.
> >> - ClassTemplateSpecializationDecl *specialization =
> >> -
> >>
> cast<ClassTemplateSpecializationDecl>(T->castAs<RecordType>()->getDecl());
> >> - return specialization->getTemplateArgs()[0].getAsType();
> >> -}
> >> -
> >> -/// \brief Prepare cleanup for the temporary array.
> >> -static void EmitStdInitializerListCleanup(CodeGenFunction &CGF,
> >> - QualType arrayType,
> >> - llvm::Value *addr,
> >> - const InitListExpr
> *initList) {
> >> - QualType::DestructionKind dtorKind = arrayType.isDestructedType();
> >> - if (!dtorKind)
> >> - return; // Type doesn't need destroying.
> >> - if (dtorKind != QualType::DK_cxx_destructor) {
> >> - CGF.ErrorUnsupported(initList, "ObjC ARC type in
> initializer_list");
> >> - return;
> >> - }
> >> -
> >> - CodeGenFunction::Destroyer *destroyer = CGF.getDestroyer(dtorKind);
> >> - CGF.pushDestroy(NormalAndEHCleanup, addr, arrayType, destroyer,
> >> - /*EHCleanup=*/true);
> >> -}
> >> -
> >> /// \brief Emit the initializer for a std::initializer_list initialized
> >> with a
> >> /// real initializer list.
> >> -void AggExprEmitter::EmitStdInitializerList(llvm::Value *destPtr,
> >> - InitListExpr *initList) {
> >> - // We emit an array containing the elements, then have the init list
> >> point
> >> - // at the array.
> >> - ASTContext &ctx = CGF.getContext();
> >> - unsigned numInits = initList->getNumInits();
> >> - QualType element =
> >> GetStdInitializerListElementType(initList->getType());
> >> - llvm::APInt size(ctx.getTypeSize(ctx.getSizeType()), numInits);
> >> - QualType array = ctx.getConstantArrayType(element, size,
> >> ArrayType::Normal,0);
> >> - llvm::Type *LTy = CGF.ConvertTypeForMem(array);
> >> - llvm::AllocaInst *alloc = CGF.CreateTempAlloca(LTy);
> >> - alloc->setAlignment(ctx.getTypeAlignInChars(array).getQuantity());
> >> - alloc->setName(".initlist.");
> >> -
> >> - EmitArrayInit(alloc, cast<llvm::ArrayType>(LTy), element, initList);
> >> -
> >> - // FIXME: The diagnostics are somewhat out of place here.
> >> - RecordDecl *record =
> >> initList->getType()->castAs<RecordType>()->getDecl();
> >> - RecordDecl::field_iterator field = record->field_begin();
> >> - if (field == record->field_end()) {
> >> - CGF.ErrorUnsupported(initList, "weird std::initializer_list");
> >> +void
> >>
> +AggExprEmitter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr
> >> *E) {
> >> + // Emit an array containing the elements. The array is externally
> >> destructed
> >> + // if the std::initializer_list object is.
> >> + ASTContext &Ctx = CGF.getContext();
> >> + LValue Array = CGF.EmitLValue(E->getSubExpr());
> >> + assert(Array.isSimple() && "initializer_list array not a simple
> >> lvalue");
> >> + llvm::Value *ArrayPtr = Array.getAddress();
> >> +
> >> + const ConstantArrayType *ArrayType =
> >> + Ctx.getAsConstantArrayType(E->getSubExpr()->getType());
> >> + assert(ArrayType && "std::initializer_list constructed from
> >> non-array");
> >> +
> >> + // FIXME: Perform the checks on the field types in SemaInit.
> >> + RecordDecl *Record = E->getType()->castAs<RecordType>()->getDecl();
> >> + RecordDecl::field_iterator Field = Record->field_begin();
> >> + if (Field == Record->field_end()) {
> >> + CGF.ErrorUnsupported(E, "weird std::initializer_list");
> >> return;
> >> }
> >>
> >> - QualType elementPtr = ctx.getPointerType(element.withConst());
> >> -
> >> // Start pointer.
> >> - if (!ctx.hasSameType(field->getType(), elementPtr)) {
> >> - CGF.ErrorUnsupported(initList, "weird std::initializer_list");
> >> + if (!Field->getType()->isPointerType() ||
> >> + !Ctx.hasSameType(Field->getType()->getPointeeType(),
> >> + ArrayType->getElementType())) {
> >> + CGF.ErrorUnsupported(E, "weird std::initializer_list");
> >> return;
> >> }
> >> - LValue DestLV = CGF.MakeNaturalAlignAddrLValue(destPtr,
> >> initList->getType());
> >> - LValue start = CGF.EmitLValueForFieldInitialization(DestLV, *field);
> >> - llvm::Value *arrayStart = Builder.CreateStructGEP(alloc, 0,
> >> "arraystart");
> >> - CGF.EmitStoreThroughLValue(RValue::get(arrayStart), start);
> >> - ++field;
> >>
> >> - if (field == record->field_end()) {
> >> - CGF.ErrorUnsupported(initList, "weird std::initializer_list");
> >> + AggValueSlot Dest = EnsureSlot(E->getType());
> >> + LValue DestLV = CGF.MakeAddrLValue(Dest.getAddr(), E->getType(),
> >> + Dest.getAlignment());
> >> + LValue Start = CGF.EmitLValueForFieldInitialization(DestLV, *Field);
> >> + llvm::Value *Zero = llvm::ConstantInt::get(CGF.PtrDiffTy, 0);
> >> + llvm::Value *IdxStart[] = { Zero, Zero };
> >> + llvm::Value *ArrayStart =
> >> + Builder.CreateInBoundsGEP(ArrayPtr, IdxStart, "arraystart");
> >> + CGF.EmitStoreThroughLValue(RValue::get(ArrayStart), Start);
> >> + ++Field;
> >> +
> >> + if (Field == Record->field_end()) {
> >> + CGF.ErrorUnsupported(E, "weird std::initializer_list");
> >> return;
> >> }
> >> - LValue endOrLength = CGF.EmitLValueForFieldInitialization(DestLV,
> >> *field);
> >> - if (ctx.hasSameType(field->getType(), elementPtr)) {
> >> +
> >> + llvm::Value *Size = Builder.getInt(ArrayType->getSize());
> >> + LValue EndOrLength = CGF.EmitLValueForFieldInitialization(DestLV,
> >> *Field);
> >> + if (Field->getType()->isPointerType() &&
> >> + Ctx.hasSameType(Field->getType()->getPointeeType(),
> >> + ArrayType->getElementType())) {
> >> // End pointer.
> >> - llvm::Value *arrayEnd = Builder.CreateStructGEP(alloc,numInits,
> >> "arrayend");
> >> - CGF.EmitStoreThroughLValue(RValue::get(arrayEnd), endOrLength);
> >> - } else if(ctx.hasSameType(field->getType(), ctx.getSizeType())) {
> >> + llvm::Value *IdxEnd[] = { Zero, Size };
> >> + llvm::Value *ArrayEnd =
> >> + Builder.CreateInBoundsGEP(ArrayPtr, IdxEnd, "arrayend");
> >> + CGF.EmitStoreThroughLValue(RValue::get(ArrayEnd), EndOrLength);
> >> + } else if (Ctx.hasSameType(Field->getType(), Ctx.getSizeType())) {
> >> // Length.
> >> - CGF.EmitStoreThroughLValue(RValue::get(Builder.getInt(size)),
> >> endOrLength);
> >> + CGF.EmitStoreThroughLValue(RValue::get(Size), EndOrLength);
> >> } else {
> >> - CGF.ErrorUnsupported(initList, "weird std::initializer_list");
> >> + CGF.ErrorUnsupported(E, "weird std::initializer_list");
> >> return;
> >> }
> >> -
> >> - if (!Dest.isExternallyDestructed())
> >> - EmitStdInitializerListCleanup(CGF, array, alloc, initList);
> >> }
> >>
> >> /// \brief Emit initialization of an array from an initializer list.
> >> @@ -490,15 +471,8 @@ void AggExprEmitter::EmitArrayInit(llvm:
> >> if (endOfInit) Builder.CreateStore(element, endOfInit);
> >> }
> >>
> >> - // If these are nested std::initializer_list inits, do them
> directly,
> >> - // because they are conceptually the same "location".
> >> - InitListExpr *initList = dyn_cast<InitListExpr>(E->getInit(i));
> >> - if (initList && initList->initializesStdInitializerList()) {
> >> - EmitStdInitializerList(element, initList);
> >> - } else {
> >> - LValue elementLV = CGF.MakeAddrLValue(element, elementType);
> >> - EmitInitializationToLValue(E->getInit(i), elementLV);
> >> - }
> >> + LValue elementLV = CGF.MakeAddrLValue(element, elementType);
> >> + EmitInitializationToLValue(E->getInit(i), elementLV);
> >> }
> >>
> >> // Check whether there's a non-trivial array-fill expression.
> >> @@ -1161,11 +1135,6 @@ void AggExprEmitter::VisitInitListExpr(I
> >>
> >> AggValueSlot Dest = EnsureSlot(E->getType());
> >>
> >> - if (E->initializesStdInitializerList()) {
> >> - EmitStdInitializerList(Dest.getAddr(), E);
> >> - return;
> >> - }
> >> -
> >> LValue DestLV = CGF.MakeAddrLValue(Dest.getAddr(), E->getType(),
> >> Dest.getAlignment());
> >>
> >> @@ -1546,58 +1515,3 @@ void CodeGenFunction::EmitAggregateCopy(
> >> alignment.getQuantity(), isVolatile,
> >> /*TBAATag=*/0, TBAAStructTag);
> >> }
> >> -
> >> -void CodeGenFunction::MaybeEmitStdInitializerListCleanup(llvm::Value
> >> *loc,
> >> - const Expr
> >> *init) {
> >> - const ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(init);
> >> - if (cleanups)
> >> - init = cleanups->getSubExpr();
> >> -
> >> - if (isa<InitListExpr>(init) &&
> >> - cast<InitListExpr>(init)->initializesStdInitializerList()) {
> >> - // We initialized this std::initializer_list with an initializer
> >> list.
> >> - // A backing array was created. Push a cleanup for it.
> >> - EmitStdInitializerListCleanup(loc, cast<InitListExpr>(init));
> >> - }
> >> -}
> >> -
> >> -static void EmitRecursiveStdInitializerListCleanup(CodeGenFunction
> &CGF,
> >> - llvm::Value
> >> *arrayStart,
> >> - const InitListExpr
> >> *init) {
> >> - // Check if there are any recursive cleanups to do, i.e. if we have
> >> - // std::initializer_list<std::initializer_list<obj>> list =
> >> {{obj()}};
> >> - // then we need to destroy the inner array as well.
> >> - for (unsigned i = 0, e = init->getNumInits(); i != e; ++i) {
> >> - const InitListExpr *subInit =
> >> dyn_cast<InitListExpr>(init->getInit(i));
> >> - if (!subInit || !subInit->initializesStdInitializerList())
> >> - continue;
> >> -
> >> - // This one needs to be destroyed. Get the address of the
> >> std::init_list.
> >> - llvm::Value *offset = llvm::ConstantInt::get(CGF.SizeTy, i);
> >> - llvm::Value *loc = CGF.Builder.CreateInBoundsGEP(arrayStart,
> offset,
> >> - "std.initlist");
> >> - CGF.EmitStdInitializerListCleanup(loc, subInit);
> >> - }
> >> -}
> >> -
> >> -void CodeGenFunction::EmitStdInitializerListCleanup(llvm::Value *loc,
> >> - const InitListExpr
> >> *init) {
> >> - ASTContext &ctx = getContext();
> >> - QualType element = GetStdInitializerListElementType(init->getType());
> >> - unsigned numInits = init->getNumInits();
> >> - llvm::APInt size(ctx.getTypeSize(ctx.getSizeType()), numInits);
> >> - QualType array =ctx.getConstantArrayType(element, size,
> >> ArrayType::Normal, 0);
> >> - QualType arrayPtr = ctx.getPointerType(array);
> >> - llvm::Type *arrayPtrType = ConvertType(arrayPtr);
> >> -
> >> - // lvalue is the location of a std::initializer_list, which as its
> >> first
> >> - // element has a pointer to the array we want to destroy.
> >> - llvm::Value *startPointer = Builder.CreateStructGEP(loc, 0,
> >> "startPointer");
> >> - llvm::Value *startAddress = Builder.CreateLoad(startPointer,
> >> "startAddress");
> >> -
> >> - ::EmitRecursiveStdInitializerListCleanup(*this, startAddress, init);
> >> -
> >> - llvm::Value *arrayAddress =
> >> - Builder.CreateBitCast(startAddress, arrayPtrType,
> "arrayAddress");
> >> - ::EmitStdInitializerListCleanup(*this, array, arrayAddress, init);
> >> -}
> >>
> >> Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
> >> +++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Wed Jun 12 17:31:48 2013
> >> @@ -838,8 +838,6 @@ static void StoreAnyExprIntoOneUnit(Code
> >> AggValueSlot::DoesNotNeedGCBarriers,
> >> AggValueSlot::IsNotAliased);
> >> CGF.EmitAggExpr(Init, Slot);
> >> -
> >> - CGF.MaybeEmitStdInitializerListCleanup(NewPtr, Init);
> >> return;
> >> }
> >> }
> >>
> >> Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
> >> +++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Wed Jun 12 17:31:48 2013
> >> @@ -368,11 +368,6 @@ void ConstStructBuilder::ConvertStructTo
> >> }
> >>
> >> bool ConstStructBuilder::Build(InitListExpr *ILE) {
> >> - if (ILE->initializesStdInitializerList()) {
> >> - //CGM.ErrorUnsupported(ILE, "global std::initializer_list");
> >> - return false;
> >> - }
> >> -
> >> RecordDecl *RD = ILE->getType()->getAs<RecordType>()->getDecl();
> >> const ASTRecordLayout &Layout =
> >> CGM.getContext().getASTRecordLayout(RD);
> >>
> >>
> >> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
> >> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Wed Jun 12 17:31:48 2013
> >> @@ -1631,10 +1631,6 @@ public:
> >> llvm::Value *EmitDynamicCast(llvm::Value *V, const CXXDynamicCastExpr
> >> *DCE);
> >> llvm::Value* EmitCXXUuidofExpr(const CXXUuidofExpr *E);
> >>
> >> - void MaybeEmitStdInitializerListCleanup(llvm::Value *loc, const Expr
> >> *init);
> >> - void EmitStdInitializerListCleanup(llvm::Value *loc,
> >> - const InitListExpr *init);
> >> -
> >> /// \brief Situations in which we might emit a check for the
> >> suitability of a
> >> /// pointer or glvalue.
> >> enum TypeCheckKind {
> >>
> >> Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
> >> +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Wed Jun 12 17:31:48 2013
> >> @@ -1628,125 +1628,6 @@ CharUnits CodeGenModule::GetTargetTypeSt
> >> TheDataLayout.getTypeStoreSizeInBits(Ty));
> >> }
> >>
> >> -llvm::Constant *
> >> -CodeGenModule::MaybeEmitGlobalStdInitializerListInitializer(const
> VarDecl
> >> *D,
> >> - const Expr
> >> *rawInit) {
> >> - ArrayRef<ExprWithCleanups::CleanupObject> cleanups;
> >> - if (const ExprWithCleanups *withCleanups =
> >> - dyn_cast<ExprWithCleanups>(rawInit)) {
> >> - cleanups = withCleanups->getObjects();
> >> - rawInit = withCleanups->getSubExpr();
> >> - }
> >> -
> >> - const InitListExpr *init = dyn_cast<InitListExpr>(rawInit);
> >> - if (!init || !init->initializesStdInitializerList() ||
> >> - init->getNumInits() == 0)
> >> - return 0;
> >> -
> >> - ASTContext &ctx = getContext();
> >> - unsigned numInits = init->getNumInits();
> >> - // FIXME: This check is here because we would otherwise silently
> >> miscompile
> >> - // nested global std::initializer_lists. Better would be to have a
> real
> >> - // implementation.
> >> - for (unsigned i = 0; i < numInits; ++i) {
> >> - const InitListExpr *inner =
> dyn_cast<InitListExpr>(init->getInit(i));
> >> - if (inner && inner->initializesStdInitializerList()) {
> >> - ErrorUnsupported(inner, "nested global std::initializer_list");
> >> - return 0;
> >> - }
> >> - }
> >> -
> >> - // Synthesize a fake VarDecl for the array and initialize that.
> >> - QualType elementType = init->getInit(0)->getType();
> >> - llvm::APInt numElements(ctx.getTypeSize(ctx.getSizeType()),
> numInits);
> >> - QualType arrayType = ctx.getConstantArrayType(elementType,
> numElements,
> >> - ArrayType::Normal, 0);
> >> -
> >> - IdentifierInfo *name = &ctx.Idents.get(D->getNameAsString() +
> >> "__initlist");
> >> - TypeSourceInfo *sourceInfo = ctx.getTrivialTypeSourceInfo(
> >> - arrayType,
> >> D->getLocation());
> >> - VarDecl *backingArray = VarDecl::Create(ctx,
> const_cast<DeclContext*>(
> >> -
> >> D->getDeclContext()),
> >> - D->getLocStart(),
> >> D->getLocation(),
> >> - name, arrayType, sourceInfo,
> >> - SC_Static);
> >> - backingArray->setTSCSpec(D->getTSCSpec());
> >> -
> >> - // Now clone the InitListExpr to initialize the array instead.
> >> - // Incredible hack: we want to use the existing InitListExpr here, so
> >> we need
> >> - // to tell it that it no longer initializes a std::initializer_list.
> >> - ArrayRef<Expr*> Inits(const_cast<InitListExpr*>(init)->getInits(),
> >> - init->getNumInits());
> >> - Expr *arrayInit = new (ctx) InitListExpr(ctx, init->getLBraceLoc(),
> >> Inits,
> >> - init->getRBraceLoc());
> >> - arrayInit->setType(arrayType);
> >> -
> >> - if (!cleanups.empty())
> >> - arrayInit = ExprWithCleanups::Create(ctx, arrayInit, cleanups);
> >> -
> >> - backingArray->setInit(arrayInit);
> >> -
> >> - // Emit the definition of the array.
> >> - EmitGlobalVarDefinition(backingArray);
> >> -
> >> - // Inspect the initializer list to validate it and determine its
> type.
> >> - // FIXME: doing this every time is probably inefficient; caching
> would
> >> be nice
> >> - RecordDecl *record =
> init->getType()->castAs<RecordType>()->getDecl();
> >> - RecordDecl::field_iterator field = record->field_begin();
> >> - if (field == record->field_end()) {
> >> - ErrorUnsupported(D, "weird std::initializer_list");
> >> - return 0;
> >> - }
> >> - QualType elementPtr = ctx.getPointerType(elementType.withConst());
> >> - // Start pointer.
> >> - if (!ctx.hasSameType(field->getType(), elementPtr)) {
> >> - ErrorUnsupported(D, "weird std::initializer_list");
> >> - return 0;
> >> - }
> >> - ++field;
> >> - if (field == record->field_end()) {
> >> - ErrorUnsupported(D, "weird std::initializer_list");
> >> - return 0;
> >> - }
> >> - bool isStartEnd = false;
> >> - if (ctx.hasSameType(field->getType(), elementPtr)) {
> >> - // End pointer.
> >> - isStartEnd = true;
> >> - } else if(!ctx.hasSameType(field->getType(), ctx.getSizeType())) {
> >> - ErrorUnsupported(D, "weird std::initializer_list");
> >> - return 0;
> >> - }
> >> -
> >> - // Now build an APValue representing the std::initializer_list.
> >> - APValue initListValue(APValue::UninitStruct(), 0, 2);
> >> - APValue &startField = initListValue.getStructField(0);
> >> - APValue::LValuePathEntry startOffsetPathEntry;
> >> - startOffsetPathEntry.ArrayIndex = 0;
> >> - startField = APValue(APValue::LValueBase(backingArray),
> >> - CharUnits::fromQuantity(0),
> >> - llvm::makeArrayRef(startOffsetPathEntry),
> >> - /*IsOnePastTheEnd=*/false, 0);
> >> -
> >> - if (isStartEnd) {
> >> - APValue &endField = initListValue.getStructField(1);
> >> - APValue::LValuePathEntry endOffsetPathEntry;
> >> - endOffsetPathEntry.ArrayIndex = numInits;
> >> - endField = APValue(APValue::LValueBase(backingArray),
> >> - ctx.getTypeSizeInChars(elementType) * numInits,
> >> - llvm::makeArrayRef(endOffsetPathEntry),
> >> - /*IsOnePastTheEnd=*/true, 0);
> >> - } else {
> >> - APValue &sizeField = initListValue.getStructField(1);
> >> - sizeField = APValue(llvm::APSInt(numElements));
> >> - }
> >> -
> >> - // Emit the constant for the initializer_list.
> >> - llvm::Constant *llvmInit =
> >> - EmitConstantValueForMemory(initListValue, D->getType());
> >> - assert(llvmInit && "failed to initialize as constant");
> >> - return llvmInit;
> >> -}
> >> -
> >> unsigned CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D,
> >> unsigned AddrSpace) {
> >> if (LangOpts.CUDA && CodeGenOpts.CUDAIsDevice) {
> >> @@ -1817,18 +1698,10 @@ void CodeGenModule::EmitGlobalVarDefinit
> >> assert(!ASTTy->isIncompleteType() && "Unexpected incomplete type");
> >> Init = EmitNullConstant(D->getType());
> >> } else {
> >> - // If this is a std::initializer_list, emit the special
> initializer.
> >> - Init = MaybeEmitGlobalStdInitializerListInitializer(D, InitExpr);
> >> - // An empty init list will perform zero-initialization, which
> happens
> >> - // to be exactly what we want.
> >> - // FIXME: It does so in a global constructor, which is *not* what
> we
> >> - // want.
> >> + initializedGlobalDecl = GlobalDecl(D);
> >> + Init = EmitConstantInit(*InitDecl);
> >>
> >> if (!Init) {
> >> - initializedGlobalDecl = GlobalDecl(D);
> >> - Init = EmitConstantInit(*InitDecl);
> >> - }
> >> - if (!Init) {
> >> QualType T = InitExpr->getType();
> >> if (D->getType()->isReferenceType())
> >> T = D->getType();
> >>
> >> Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
> >> +++ cfe/trunk/lib/CodeGen/CodeGenModule.h Wed Jun 12 17:31:48 2013
> >> @@ -1020,8 +1020,6 @@ private:
> >>
> >> void EmitGlobalFunctionDefinition(GlobalDecl GD);
> >> void EmitGlobalVarDefinition(const VarDecl *D);
> >> - llvm::Constant *MaybeEmitGlobalStdInitializerListInitializer(const
> >> VarDecl *D,
> >> - const
> Expr
> >> *init);
> >> void EmitAliasDefinition(GlobalDecl GD);
> >> void EmitObjCPropertyImplementations(const ObjCImplementationDecl
> *D);
> >> void EmitObjCIvarInitializations(ObjCImplementationDecl *D);
> >>
> >> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
> >> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Jun 12 17:31:48 2013
> >> @@ -2153,10 +2153,6 @@ Sema::ActOnCXXInClassMemberInitializer(D
> >>
> >> ExprResult Init = InitExpr;
> >> if (!FD->getType()->isDependentType() &&
> !InitExpr->isTypeDependent())
> >> {
> >> - if (isa<InitListExpr>(InitExpr) &&
> >> isStdInitializerList(FD->getType(), 0)) {
> >> - Diag(FD->getLocation(), diag::warn_dangling_std_initializer_list)
> >> - << /*at end of ctor*/1 << InitExpr->getSourceRange();
> >> - }
> >> InitializedEntity Entity = InitializedEntity::InitializeMember(FD);
> >> InitializationKind Kind = FD->getInClassInitStyle() ==
> ICIS_ListInit
> >> ? InitializationKind::CreateDirectList(InitExpr->getLocStart())
> >> @@ -2550,11 +2546,6 @@ Sema::BuildMemberInitializer(ValueDecl *
> >> if (isa<InitListExpr>(Init)) {
> >> InitList = true;
> >> Args = Init;
> >> -
> >> - if (isStdInitializerList(Member->getType(), 0)) {
> >> - Diag(IdLoc, diag::warn_dangling_std_initializer_list)
> >> - << /*at end of ctor*/1 << InitRange;
> >> - }
> >> }
> >>
> >> // Initialize the member.
> >>
> >> Modified: cfe/trunk/lib/Sema/SemaExceptionSpec.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExceptionSpec.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/Sema/SemaExceptionSpec.cpp (original)
> >> +++ cfe/trunk/lib/Sema/SemaExceptionSpec.cpp Wed Jun 12 17:31:48 2013
> >> @@ -1006,6 +1006,7 @@ CanThrowResult Sema::canThrow(const Expr
> >> case Expr::CompoundLiteralExprClass:
> >> case Expr::CXXConstCastExprClass:
> >> case Expr::CXXReinterpretCastExprClass:
> >> + case Expr::CXXStdInitializerListExprClass:
> >> case Expr::DesignatedInitExprClass:
> >> case Expr::ExprWithCleanupsClass:
> >> case Expr::ExtVectorElementExprClass:
> >>
> >> Modified: cfe/trunk/lib/Sema/SemaInit.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/Sema/SemaInit.cpp (original)
> >> +++ cfe/trunk/lib/Sema/SemaInit.cpp Wed Jun 12 17:31:48 2013
> >> @@ -2937,6 +2937,12 @@ static void MaybeProduceObjCObject(Sema
> >> }
> >> }
> >>
> >> +static void TryListInitialization(Sema &S,
> >> + const InitializedEntity &Entity,
> >> + const InitializationKind &Kind,
> >> + InitListExpr *InitList,
> >> + InitializationSequence &Sequence);
> >> +
> >> /// \brief When initializing from init list via constructor, handle
> >> /// initialization of an object of type std::initializer_list<T>.
> >> ///
> >> @@ -2950,25 +2956,23 @@ static bool TryInitializerListConstructi
> >> if (!S.isStdInitializerList(DestType, &E))
> >> return false;
> >>
> >> - // Check that each individual element can be copy-constructed. But
> >> since we
> >> - // have no place to store further information, we'll recalculate
> >> everything
> >> - // later.
> >> - InitializedEntity HiddenArray =
> InitializedEntity::InitializeTemporary(
> >> - S.Context.getConstantArrayType(E,
> >> - llvm::APInt(S.Context.getTypeSize(S.Context.getSizeType()),
> >> - List->getNumInits()),
> >> - ArrayType::Normal, 0));
> >> - InitializedEntity Element =
> >> InitializedEntity::InitializeElement(S.Context,
> >> - 0, HiddenArray);
> >> - for (unsigned i = 0, n = List->getNumInits(); i < n; ++i) {
> >> - Element.setElementIndex(i);
> >> - if (!S.CanPerformCopyInitialization(Element, List->getInit(i))) {
> >> - Sequence.SetFailed(
> >> - InitializationSequence::FK_InitListElementCopyFailure);
> >> - return true;
> >> - }
> >> + if (S.RequireCompleteType(List->getExprLoc(), E, 0)) {
> >> + Sequence.setIncompleteTypeFailure(E);
> >> + return true;
> >> }
> >> - Sequence.AddStdInitializerListConstructionStep(DestType);
> >> +
> >> + // Try initializing a temporary array from the init list.
> >> + QualType ArrayType = S.Context.getConstantArrayType(
> >> + E.withConst(),
> >> llvm::APInt(S.Context.getTypeSize(S.Context.getSizeType()),
> >> + List->getNumInits()),
> >> + clang::ArrayType::Normal, 0);
> >> + InitializedEntity HiddenArray =
> >> + InitializedEntity::InitializeTemporary(ArrayType);
> >> + InitializationKind Kind =
> >> + InitializationKind::CreateDirectList(List->getExprLoc());
> >> + TryListInitialization(S, HiddenArray, Kind, List, Sequence);
> >> + if (Sequence)
> >> + Sequence.AddStdInitializerListConstructionStep(DestType);
> >> return true;
> >> }
> >>
> >> @@ -3198,12 +3202,6 @@ static void TryValueInitialization(Sema
> >> InitializationSequence &Sequence,
> >> InitListExpr *InitList = 0);
> >>
> >> -static void TryListInitialization(Sema &S,
> >> - const InitializedEntity &Entity,
> >> - const InitializationKind &Kind,
> >> - InitListExpr *InitList,
> >> - InitializationSequence &Sequence);
> >> -
> >> /// \brief Attempt list initialization of a reference.
> >> static void TryReferenceListInitialization(Sema &S,
> >> const InitializedEntity
> >> &Entity,
> >> @@ -5135,7 +5133,7 @@ PerformConstructorInitialization(Sema &S
> >> return ExprError();
> >>
> >> if (shouldBindAsTemporary(Entity))
> >> - CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());
> >> + CurInit = S.MaybeBindToTemporary(CurInit.take());
> >>
> >> return CurInit;
> >> }
> >> @@ -5277,19 +5275,18 @@ static void performLifetimeExtension(Exp
> >> if (CXXBindTemporaryExpr *BTE = dyn_cast<CXXBindTemporaryExpr>(Init))
> >> Init = BTE->getSubExpr();
> >>
> >> + if (CXXStdInitializerListExpr *ILE =
> >> + dyn_cast<CXXStdInitializerListExpr>(Init))
> >> + return performReferenceExtension(ILE->getSubExpr(), ExtendingD);
> >> +
> >> if (InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {
> >> - if (ILE->initializesStdInitializerList() ||
> >> ILE->getType()->isArrayType()) {
> >> - // FIXME: If this is an InitListExpr which creates a
> >> std::initializer_list
> >> - // object, we also need to lifetime-extend the underlying
> >> array
> >> - // itself. Fix the representation to explicitly
> materialize
> >> an
> >> - // array temporary so we can model this properly.
> >> + if (ILE->getType()->isArrayType()) {
> >> for (unsigned I = 0, N = ILE->getNumInits(); I != N; ++I)
> >> performLifetimeExtension(ILE->getInit(I), ExtendingD);
> >> return;
> >> }
> >>
> >> - CXXRecordDecl *RD = ILE->getType()->getAsCXXRecordDecl();
> >> - if (RD) {
> >> + if (CXXRecordDecl *RD = ILE->getType()->getAsCXXRecordDecl()) {
> >> assert(RD->isAggregate() && "aggregate init on non-aggregate");
> >>
> >> // If we lifetime-extend a braced initializer which is
> initializing
> >> an
> >> @@ -5319,6 +5316,39 @@ static void performLifetimeExtension(Exp
> >> }
> >> }
> >>
> >> +static void warnOnLifetimeExtension(Sema &S, const InitializedEntity
> >> &Entity,
> >> + const Expr *Init, bool
> >> IsInitializerList,
> >> + const ValueDecl *ExtendingDecl) {
> >> + // Warn if a field lifetime-extends a temporary.
> >> + if (isa<FieldDecl>(ExtendingDecl)) {
> >> + if (IsInitializerList) {
> >> + S.Diag(Init->getExprLoc(),
> >> diag::warn_dangling_std_initializer_list)
> >> + << /*at end of constructor*/true;
> >> + return;
> >> + }
> >> +
> >> + bool IsSubobjectMember = false;
> >> + for (const InitializedEntity *Ent = Entity.getParent(); Ent;
> >> + Ent = Ent->getParent()) {
> >> + if (Ent->getKind() != InitializedEntity::EK_Base) {
> >> + IsSubobjectMember = true;
> >> + break;
> >> + }
> >> + }
> >> + S.Diag(Init->getExprLoc(),
> >> + diag::warn_bind_ref_member_to_temporary)
> >> + << ExtendingDecl << Init->getSourceRange()
> >> + << IsSubobjectMember << IsInitializerList;
> >> + if (IsSubobjectMember)
> >> + S.Diag(ExtendingDecl->getLocation(),
> >> + diag::note_ref_subobject_of_member_declared_here);
> >> + else
> >> + S.Diag(ExtendingDecl->getLocation(),
> >> + diag::note_ref_or_ptr_member_declared_here)
> >> + << /*is pointer*/false;
> >> + }
> >> +}
> >> +
> >> ExprResult
> >> InitializationSequence::Perform(Sema &S,
> >> const InitializedEntity &Entity,
> >> @@ -5570,29 +5600,7 @@ InitializationSequence::Perform(Sema &S,
> >> getDeclForTemporaryLifetimeExtension(Entity);
> >> if (ExtendingDecl) {
> >> performLifetimeExtension(CurInit.get(), ExtendingDecl);
> >> -
> >> - // Warn if a field lifetime-extends a temporary.
> >> - if (isa<FieldDecl>(ExtendingDecl)) {
> >> - bool IsSubobjectMember = false;
> >> - for (const InitializedEntity *Ent = Entity.getParent(); Ent;
> >> - Ent = Ent->getParent()) {
> >> - if (Ent->getKind() != InitializedEntity::EK_Base) {
> >> - IsSubobjectMember = true;
> >> - break;
> >> - }
> >> - }
> >> - S.Diag(CurInit.get()->getExprLoc(),
> >> - diag::warn_bind_ref_member_to_temporary)
> >> - << ExtendingDecl << CurInit.get()->getSourceRange()
> >> - << IsSubobjectMember;
> >> - if (IsSubobjectMember)
> >> - S.Diag(ExtendingDecl->getLocation(),
> >> - diag::note_ref_subobject_of_member_declared_here);
> >> - else
> >> - S.Diag(ExtendingDecl->getLocation(),
> >> - diag::note_ref_or_ptr_member_declared_here)
> >> - << /*IsPointer*/false;
> >> - }
> >> + warnOnLifetimeExtension(S, Entity, CurInit.get(), false,
> >> ExtendingDecl);
> >> }
> >>
> >> // Materialize the temporary into memory.
> >> @@ -5763,16 +5771,10 @@ InitializationSequence::Perform(Sema &S,
> >>
> >> case SK_ListInitialization: {
> >> InitListExpr *InitList = cast<InitListExpr>(CurInit.get());
> >> - // Hack: We must pass *ResultType if available in order to set
> the
> >> type
> >> - // of arrays, e.g. in 'int ar[] = {1, 2, 3};'.
> >> - // But in 'const X &x = {1, 2, 3};' we're supposed to initialize
> a
> >> - // temporary, not a reference, so we should pass Ty.
> >> - // Worst case: 'const int (&arref)[] = {1, 2, 3};'.
> >> - // Since this step is never used for a reference directly, we
> >> explicitly
> >> - // unwrap references here and rewrap them afterwards.
> >> - // We also need to create a InitializeTemporary entity for this.
> >> - QualType Ty = ResultType ? ResultType->getNonReferenceType() :
> >> Step->Type;
> >> - bool IsTemporary = Entity.getType()->isReferenceType();
> >> + // If we're not initializing the top-level entity, we need to
> >> create an
> >> + // InitializeTemporary entity for our target type.
> >> + QualType Ty = Step->Type;
> >> + bool IsTemporary = !S.Context.hasSameType(Entity.getType(), Ty);
> >> InitializedEntity TempEntity =
> >> InitializedEntity::InitializeTemporary(Ty);
> >> InitializedEntity InitEntity = IsTemporary ? TempEntity : Entity;
> >> InitListChecker PerformInitList(S, InitEntity,
> >> @@ -5780,7 +5782,11 @@ InitializationSequence::Perform(Sema &S,
> >> if (PerformInitList.HadError())
> >> return ExprError();
> >>
> >> - if (ResultType) {
> >> + // Hack: We must update *ResultType if available in order to set
> >> the
> >> + // bounds of arrays, e.g. in 'int ar[] = {1, 2, 3};'.
> >> + // Worst case: 'const int (&arref)[] = {1, 2, 3};'.
> >> + if (ResultType &&
> >> + ResultType->getNonReferenceType()->isIncompleteArrayType()) {
> >> if ((*ResultType)->isRValueReferenceType())
> >> Ty = S.Context.getRValueReferenceType(Ty);
> >> else if ((*ResultType)->isLValueReferenceType())
> >> @@ -5973,56 +5979,35 @@ InitializationSequence::Perform(Sema &S,
> >> break;
> >>
> >> case SK_StdInitializerList: {
> >> - QualType Dest = Step->Type;
> >> - QualType E;
> >> - bool Success = S.isStdInitializerList(Dest.getNonReferenceType(),
> >> &E);
> >> - (void)Success;
> >> - assert(Success && "Destination type changed?");
> >> -
> >> - // If the element type has a destructor, check it.
> >> - if (CXXRecordDecl *RD = E->getAsCXXRecordDecl()) {
> >> - if (!RD->hasIrrelevantDestructor()) {
> >> - if (CXXDestructorDecl *Destructor = S.LookupDestructor(RD)) {
> >> - S.MarkFunctionReferenced(Kind.getLocation(), Destructor);
> >> - S.CheckDestructorAccess(Kind.getLocation(), Destructor,
> >> - S.PDiag(diag::err_access_dtor_temp)
> >> << E);
> >> - if (S.DiagnoseUseOfDecl(Destructor, Kind.getLocation()))
> >> - return ExprError();
> >> - }
> >> - }
> >> - }
> >> + S.Diag(CurInit.get()->getExprLoc(),
> >> + diag::warn_cxx98_compat_initializer_list_init)
> >> + << CurInit.get()->getSourceRange();
> >>
> >> - InitListExpr *ILE = cast<InitListExpr>(CurInit.take());
> >> - S.Diag(ILE->getExprLoc(),
> >> diag::warn_cxx98_compat_initializer_list_init)
> >> - << ILE->getSourceRange();
> >> - unsigned NumInits = ILE->getNumInits();
> >> - SmallVector<Expr*, 16> Converted(NumInits);
> >> - InitializedEntity HiddenArray =
> >> InitializedEntity::InitializeTemporary(
> >> - S.Context.getConstantArrayType(E,
> >> -
> llvm::APInt(S.Context.getTypeSize(S.Context.getSizeType()),
> >> - NumInits),
> >> - ArrayType::Normal, 0));
> >> - InitializedEntity Element
> >> =InitializedEntity::InitializeElement(S.Context,
> >> - 0, HiddenArray);
> >> - for (unsigned i = 0; i < NumInits; ++i) {
> >> - Element.setElementIndex(i);
> >> - ExprResult Init = S.Owned(ILE->getInit(i));
> >> - ExprResult Res = S.PerformCopyInitialization(
> >> - Element, Init.get()->getExprLoc(), Init,
> >> - /*TopLevelOfInitList=*/ true);
> >> - if (Res.isInvalid())
> >> - return ExprError();
> >> - Converted[i] = Res.take();
> >> + // Maybe lifetime-extend the array temporary's subobjects to
> match
> >> the
> >> + // entity's lifetime.
> >> + const ValueDecl *ExtendingDecl =
> >> + getDeclForTemporaryLifetimeExtension(Entity);
> >> + if (ExtendingDecl) {
> >> + performLifetimeExtension(CurInit.get(), ExtendingDecl);
> >> + warnOnLifetimeExtension(S, Entity, CurInit.get(), true,
> >> ExtendingDecl);
> >> }
> >> - InitListExpr *Semantic = new (S.Context)
> >> - InitListExpr(S.Context, ILE->getLBraceLoc(),
> >> - Converted, ILE->getRBraceLoc());
> >> - Semantic->setSyntacticForm(ILE);
> >> - Semantic->setType(Dest);
> >> - Semantic->setInitializesStdInitializerList();
> >> - CurInit = S.Owned(Semantic);
> >> +
> >> + // Materialize the temporary into memory.
> >> + MaterializeTemporaryExpr *MTE = new (S.Context)
> >> + MaterializeTemporaryExpr(CurInit.get()->getType(),
> >> CurInit.get(),
> >> + /*lvalue reference*/ false,
> >> ExtendingDecl);
> >> +
> >> + // Wrap it in a construction of a std::initializer_list<T>.
> >> + CurInit = S.Owned(
> >> + new (S.Context) CXXStdInitializerListExpr(Step->Type, MTE));
> >> +
> >> + // Bind the result, in case the library has given
> initializer_list
> >> a
> >> + // non-trivial destructor.
> >> + if (shouldBindAsTemporary(Entity))
> >> + CurInit = S.MaybeBindToTemporary(CurInit.take());
> >> break;
> >> }
> >> +
> >> case SK_OCLSamplerInit: {
> >> assert(Step->Type->isSamplerT() &&
> >> "Sampler initialization on non sampler type.");
> >>
> >> Modified: cfe/trunk/lib/Sema/TreeTransform.h
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/Sema/TreeTransform.h (original)
> >> +++ cfe/trunk/lib/Sema/TreeTransform.h Wed Jun 12 17:31:48 2013
> >> @@ -2639,6 +2639,10 @@ ExprResult TreeTransform<Derived>::Trans
> >> if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))
> >> Init = ICE->getSubExprAsWritten();
> >>
> >> + if (CXXStdInitializerListExpr *ILE =
> >> + dyn_cast<CXXStdInitializerListExpr>(Init))
> >> + return TransformInitializer(ILE->getSubExpr(), CXXDirectInit);
> >> +
> >> // If this is not a direct-initializer, we only need to reconstruct
> >> // InitListExprs. Other forms of copy-initialization will be a no-op
> if
> >> // the initializer is already the right type.
> >> @@ -8548,6 +8552,13 @@ TreeTransform<Derived>::TransformMateria
> >> }
> >>
> >> template<typename Derived>
> >> +ExprResult
> >> +TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
> >> + CXXStdInitializerListExpr *E) {
> >> + return getDerived().TransformExpr(E->getSubExpr());
> >> +}
> >> +
> >> +template<typename Derived>
> >> ExprResult
> >> TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral
> *E)
> >> {
> >> return SemaRef.MaybeBindToTemporary(E);
> >>
> >> Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
> >> +++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Wed Jun 12 17:31:48
> 2013
> >> @@ -723,7 +723,6 @@ void ASTStmtReader::VisitInitListExpr(In
> >> } else
> >> E->ArrayFillerOrUnionFieldInit = ReadDeclAs<FieldDecl>(Record,
> Idx);
> >> E->sawArrayRangeDesignator(Record[Idx++]);
> >> - E->setInitializesStdInitializerList(Record[Idx++]);
> >> unsigned NumInits = Record[Idx++];
> >> E->reserveInits(Reader.getContext(), NumInits);
> >> if (isArrayFiller) {
> >> @@ -1227,6 +1226,12 @@ void ASTStmtReader::VisitLambdaExpr(Lamb
> >> }
> >> }
> >>
> >> +void
> >> +ASTStmtReader::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr
> >> *E) {
> >> + VisitExpr(E);
> >> + E->SubExpr = Reader.ReadSubExpr();
> >> +}
> >> +
> >> void ASTStmtReader::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
> >> VisitExplicitCastExpr(E);
> >> SourceRange R = ReadSourceRange(Record, Idx);
> >> @@ -2161,6 +2166,10 @@ Stmt *ASTReader::ReadStmtFromStream(Modu
> >> S = new (Context) UserDefinedLiteral(Context, Empty);
> >> break;
> >>
> >> + case EXPR_CXX_STD_INITIALIZER_LIST:
> >> + S = new (Context) CXXStdInitializerListExpr(Empty);
> >> + break;
> >> +
> >> case EXPR_CXX_BOOL_LITERAL:
> >> S = new (Context) CXXBoolLiteralExpr(Empty);
> >> break;
> >>
> >> Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
> >> +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Wed Jun 12 17:31:48 2013
> >> @@ -735,6 +735,7 @@ static void AddStmtsExprs(llvm::Bitstrea
> >> RECORD(EXPR_CXX_CONST_CAST);
> >> RECORD(EXPR_CXX_FUNCTIONAL_CAST);
> >> RECORD(EXPR_USER_DEFINED_LITERAL);
> >> + RECORD(EXPR_CXX_STD_INITIALIZER_LIST);
> >> RECORD(EXPR_CXX_BOOL_LITERAL);
> >> RECORD(EXPR_CXX_NULL_PTR_LITERAL);
> >> RECORD(EXPR_CXX_TYPEID_EXPR);
> >>
> >> Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
> >> +++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Wed Jun 12 17:31:48
> 2013
> >> @@ -683,7 +683,6 @@ void ASTStmtWriter::VisitInitListExpr(In
> >> else
> >> Writer.AddDeclRef(E->getInitializedFieldInUnion(), Record);
> >> Record.push_back(E->hadArrayRangeDesignator());
> >> - Record.push_back(E->initializesStdInitializerList());
> >> Record.push_back(E->getNumInits());
> >> if (isArrayFiller) {
> >> // ArrayFiller may have filled "holes" due to designated
> initializer.
> >> @@ -1187,6 +1186,12 @@ void ASTStmtWriter::VisitLambdaExpr(Lamb
> >> Code = serialization::EXPR_LAMBDA;
> >> }
> >>
> >> +void
> >> ASTStmtWriter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr
> *E)
> >> {
> >> + VisitExpr(E);
> >> + Writer.AddStmt(E->getSubExpr());
> >> + Code = serialization::EXPR_CXX_STD_INITIALIZER_LIST;
> >> +}
> >> +
> >> void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
> >> VisitExplicitCastExpr(E);
> >> Writer.AddSourceRange(SourceRange(E->getOperatorLoc(),
> >> E->getRParenLoc()),
> >>
> >> Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
> >> +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Wed Jun 12 17:31:48
> >> 2013
> >> @@ -607,6 +607,7 @@ void ExprEngine::Visit(const Stmt *S, Ex
> >> case Stmt::CXXDefaultInitExprClass:
> >> case Stmt::CXXDependentScopeMemberExprClass:
> >> case Stmt::CXXPseudoDestructorExprClass:
> >> + case Stmt::CXXStdInitializerListExprClass:
> >> case Stmt::CXXTryStmtClass:
> >> case Stmt::CXXTypeidExprClass:
> >> case Stmt::CXXUuidofExprClass:
> >>
> >> Modified: cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp
> >> URL:
> >>
> 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
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp
> >> (original)
> >> +++ cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp Wed Jun
> >> 12 17:31:48 2013
> >> @@ -4,7 +4,7 @@ namespace std {
> >> typedef decltype(sizeof(int)) size_t;
> >>
> >> template <typename E>
> >> - struct initializer_list
> >> + struct initializer_list // expected-note 2{{candidate}}
> >> {
> >> const E *p;
> >> size_t n;
> >> @@ -113,10 +113,14 @@ namespace bullet8 {
> >>
> >> namespace rdar13395022 {
> >> struct MoveOnly {
> >> - MoveOnly(MoveOnly&&); // expected-note{{copy constructor is
> >> implicitly deleted because 'MoveOnly' has a user-declared move
> constructor}}
> >> + MoveOnly(MoveOnly&&);
> >> };
> >>
> >> void test(MoveOnly mo) {
> >> - auto &&list = {mo}; // expected-error{{call to implicitly-deleted
> >> copy constructor of 'rdar13395022::MoveOnly'}}
> >> + // FIXME: These diagnostics are poor.
> >> + auto &&list1 = {mo}; // expected-error{{no viable conversion}}
> >> + MoveOnly (&&list2)[1] = {mo}; // expected-error{{no viable
> >> conversion}}
> >> + std::initializer_list<MoveOnly> &&list3 = {};
> >> + MoveOnly (&&list4)[1] = {}; // expected-error{{uninitialized}}
> >> }
> >> }
> >>
> >> Modified:
> >>
> cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> ---
> >>
> cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp
> >> (original)
> >> +++
> >>
> cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp
> >> Wed Jun 12 17:31:48 2013
> >> @@ -1,18 +1,28 @@
> >> -// RUN: %clang_cc1 -std=c++11 -emit-llvm -o - -verify %s
> >> +// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -emit-llvm -o -
> %s
> >> | FileCheck %s --check-prefix=CHECK-STATIC-BL
> >> +// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -emit-llvm -o -
> %s
> >> -Dconstexpr= | FileCheck %s --check-prefix=CHECK-DYNAMIC-BL
> >> +// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -emit-llvm -o -
> %s
> >> -DUSE_END | FileCheck %s --check-prefix=CHECK-STATIC-BE
> >> +// 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
> >>
> >> namespace std {
> >> typedef decltype(sizeof(int)) size_t;
> >>
> >> - // libc++'s implementation
> >> template <class _E>
> >> class initializer_list
> >> {
> >> const _E* __begin_;
> >> +#ifdef USE_END
> >> + const _E* __end_;
> >> +#else
> >> size_t __size_;
> >> +#endif
> >>
> >> - initializer_list(const _E* __b, size_t __s)
> >> + constexpr initializer_list(const _E* __b, size_t __s)
> >> : __begin_(__b),
> >> +#ifdef USE_END
> >> + __end_(__b + __s)
> >> +#else
> >> __size_(__s)
> >> +#endif
> >> {}
> >>
> >> public:
> >> @@ -24,14 +34,98 @@ namespace std {
> >> typedef const _E* iterator;
> >> typedef const _E* const_iterator;
> >>
> >> - initializer_list() : __begin_(nullptr), __size_(0) {}
> >> +#ifdef USE_END
> >> + constexpr initializer_list() : __begin_(nullptr), __end_(nullptr)
> {}
> >> +
> >> + size_t size() const {return __end_ - __begin_;}
> >> + const _E* begin() const {return __begin_;}
> >> + const _E* end() const {return __end_;}
> >> +#else
> >> + constexpr initializer_list() : __begin_(nullptr), __size_(0) {}
> >>
> >> size_t size() const {return __size_;}
> >> const _E* begin() const {return __begin_;}
> >> const _E* end() const {return __begin_ + __size_;}
> >> +#endif
> >> };
> >> }
> >>
> >> -std::initializer_list<std::initializer_list<int>> pleasefail = {
> >> - {1, 2}, {3, 4}, {5, 6} // expected-error {{cannot compile}}
> >> +std::initializer_list<std::initializer_list<int>> nested = {
> >> + {1, 2}, {3, 4}, {5, 6}
> >> };
> >> +
> >> +// CHECK-STATIC-BL: @_ZGR6nested = private constant [2 x i32] [i32 1,
> i32
> >> 2], align 4
> >> +// CHECK-STATIC-BL: @_ZGR6nested1 = private constant [2 x i32] [i32 3,
> >> i32 4], align 4
> >> +// CHECK-STATIC-BL: @_ZGR6nested2 = private constant [2 x i32] [i32 5,
> >> i32 6], align 4
> >> +// CHECK-STATIC-BL: @_ZGR6nested3 = private constant [3 x {{.*}}] [
> >> +// CHECK-STATIC-BL: {{.*}} { i32* getelementptr inbounds ([2 x i32]*
> >> @_ZGR6nested, i32 0, i32 0), i64 2 },
> >> +// CHECK-STATIC-BL: {{.*}} { i32* getelementptr inbounds ([2 x i32]*
> >> @_ZGR6nested1, i32 0, i32 0), i64 2 },
> >> +// CHECK-STATIC-BL: {{.*}} { i32* getelementptr inbounds ([2 x i32]*
> >> @_ZGR6nested2, i32 0, i32 0), i64 2 }
> >> +// CHECK-STATIC-BL: ], align 8
> >> +// CHECK-STATIC-BL: @nested = global {{.*}} { {{.*}} getelementptr
> >> inbounds ([3 x {{.*}}]* @_ZGR6nested3, i32 0, i32 0), i64 3 }, align 8
> >> +
> >> +// CHECK-DYNAMIC-BL: @nested = global
> >> +// CHECK-DYNAMIC-BL: @_ZGR6nested = private global [3 x
> >> +// CHECK-DYNAMIC-BL: @_ZGR6nested1 = private global [2 x i32]
> >> zeroinitializer
> >> +// CHECK-DYNAMIC-BL: @_ZGR6nested2 = private global [2 x i32]
> >> zeroinitializer
> >> +// CHECK-DYNAMIC-BL: @_ZGR6nested3 = private global [2 x i32]
> >> zeroinitializer
> >> +// CHECK-DYNAMIC-BL: store i32 1, i32* getelementptr inbounds ([2 x
> i32]*
> >> @_ZGR6nested1, i64 0, i64 0)
> >> +// CHECK-DYNAMIC-BL: store i32 2, i32* getelementptr inbounds ([2 x
> i32]*
> >> @_ZGR6nested1, i64 0, i64 1)
> >> +// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]*
> >> @_ZGR6nested1, i64 0, i64 0),
> >> +// CHECK-DYMAMIC-BL: i32** getelementptr inbounds ([3 x {{.*}}]*
> >> @_ZGR6nested, i64 0, i64 0, i32 0), align 8
> >> +// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x
> >> {{.*}}]* @_ZGR6nested, i64 0, i64 0, i32 1), align 8
> >> +// CHECK-DYNAMIC-BL: store i32 3, i32* getelementptr inbounds ([2 x
> i32]*
> >> @_ZGR6nested2, i64 0, i64 0)
> >> +// CHECK-DYNAMIC-BL: store i32 4, i32* getelementptr inbounds ([2 x
> i32]*
> >> @_ZGR6nested2, i64 0, i64 1)
> >> +// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]*
> >> @_ZGR6nested2, i64 0, i64 0),
> >> +// CHECK-DYNAMIC-BL: i32** getelementptr inbounds ([3 x {{.*}}]*
> >> @_ZGR6nested, i64 0, i64 1, i32 0), align 8
> >> +// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x
> >> {{.*}}]* @_ZGR6nested, i64 0, i64 1, i32 1), align 8
> >> +// CHECK-DYNAMIC-BL: store i32 5, i32* getelementptr inbounds ([2 x
> i32]*
> >> @_ZGR6nested3, i64 0, i64 0)
> >> +// CHECK-DYNAMIC-BL: store i32 6, i32* getelementptr inbounds ([2 x
> i32]*
> >> @_ZGR6nested3, i64 0, i64 1)
> >> +// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]*
> >> @_ZGR6nested3, i64 0, i64 0),
> >> +// CHECK-DYNAMIC-BL: i32** getelementptr inbounds ([3 x {{.*}}]*
> >> @_ZGR6nested, i64 0, i64 2, i32 0), align 8
> >> +// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x
> >> {{.*}}]* @_ZGR6nested, i64 0, i64 2, i32 1), align 8
> >> +// CHECK-DYNAMIC-BL: store {{.*}}* getelementptr inbounds ([3 x
> {{.*}}]*
> >> @_ZGR6nested, i64 0, i64 0),
> >> +// CHECK-DYNAMIC-BL: {{.*}}** getelementptr inbounds ({{.*}}*
> >> @nested, i32 0, i32 0), align 8
> >> +// CHECK-DYNAMIC-BL: store i64 3, i64* getelementptr inbounds ({{.*}}*
> >> @nested, i32 0, i32 1), align 8
> >> +
> >> +// CHECK-STATIC-BE: @_ZGR6nested = private constant [2 x i32] [i32 1,
> i32
> >> 2], align 4
> >> +// CHECK-STATIC-BE: @_ZGR6nested1 = private constant [2 x i32] [i32 3,
> >> i32 4], align 4
> >> +// CHECK-STATIC-BE: @_ZGR6nested2 = private constant [2 x i32] [i32 5,
> >> i32 6], align 4
> >> +// CHECK-STATIC-BE: @_ZGR6nested3 = private constant [3 x {{.*}}] [
> >> +// CHECK-STATIC-BE: {{.*}} { i32* getelementptr inbounds ([2 x i32]*
> >> @_ZGR6nested, i32 0, i32 0),
> >> +// CHECK-STATIC-BE: i32* bitcast (i8* getelementptr (i8*
> >> bitcast ([2 x i32]* @_ZGR6nested to i8*), i64 8) to i32*) }
> >> +// CHECK-STATIC-BE: {{.*}} { i32* getelementptr inbounds ([2 x i32]*
> >> @_ZGR6nested1, i32 0, i32 0),
> >> +// CHECK-STATIC-BE: i32* bitcast (i8* getelementptr (i8*
> >> bitcast ([2 x i32]* @_ZGR6nested1 to i8*), i64 8) to i32*) }
> >> +// CHECK-STATIC-BE: {{.*}} { i32* getelementptr inbounds ([2 x i32]*
> >> @_ZGR6nested2, i32 0, i32 0),
> >> +// CHECK-STATIC-BE: i32* bitcast (i8* getelementptr (i8*
> >> bitcast ([2 x i32]* @_ZGR6nested2 to i8*), i64 8) to i32*) }
> >> +// CHECK-STATIC-BE: ], align 8
> >> +// CHECK-STATIC-BE: @nested = global {{.*}} { {{.*}} getelementptr
> >> inbounds ([3 x {{.*}}]* @_ZGR6nested3, i32 0, i32 0),
> >> +// CHECK-STATIC-BE: {{.*}} bitcast ({{.*}}*
> >> getelementptr (i8* bitcast ([3 x {{.*}}]* @_ZGR6nested3 to i8*), i64
> 48) to
> >> {{.*}}*) }
> >> +
> >> +// CHECK-DYNAMIC-BE: @nested = global
> >> +// CHECK-DYNAMIC-BE: @_ZGR6nested = private global [3 x
> >> +// CHECK-DYNAMIC-BE: @_ZGR6nested1 = private global [2 x i32]
> >> zeroinitializer
> >> +// CHECK-DYNAMIC-BE: @_ZGR6nested2 = private global [2 x i32]
> >> zeroinitializer
> >> +// CHECK-DYNAMIC-BE: @_ZGR6nested3 = private global [2 x i32]
> >> zeroinitializer
> >> +// CHECK-DYNAMIC-BE: store i32 1, i32* getelementptr inbounds ([2 x
> i32]*
> >> @_ZGR6nested1, i64 0, i64 0)
> >> +// CHECK-DYNAMIC-BE: store i32 2, i32* getelementptr inbounds ([2 x
> i32]*
> >> @_ZGR6nested1, i64 0, i64 1)
> >> +// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]*
> >> @_ZGR6nested1, i64 0, i64 0),
> >> +// CHECK-DYMAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]*
> >> @_ZGR6nested, i64 0, i64 0, i32 0), align 8
> >> +// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]*
> >> @_ZGR6nested1, i64 1, i64 0),
> >> +// CHECK-DYMAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]*
> >> @_ZGR6nested, i64 0, i64 0, i32 1), align 8
> >> +// CHECK-DYNAMIC-BE: store i32 3, i32* getelementptr inbounds ([2 x
> i32]*
> >> @_ZGR6nested2, i64 0, i64 0)
> >> +// CHECK-DYNAMIC-BE: store i32 4, i32* getelementptr inbounds ([2 x
> i32]*
> >> @_ZGR6nested2, i64 0, i64 1)
> >> +// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]*
> >> @_ZGR6nested2, i64 0, i64 0),
> >> +// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]*
> >> @_ZGR6nested, i64 0, i64 1, i32 0), align 8
> >> +// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]*
> >> @_ZGR6nested2, i64 1, i64 0),
> >> +// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]*
> >> @_ZGR6nested, i64 0, i64 1, i32 1), align 8
> >> +// CHECK-DYNAMIC-BE: store i32 5, i32* getelementptr inbounds ([2 x
> i32]*
> >> @_ZGR6nested3, i64 0, i64 0)
> >> +// CHECK-DYNAMIC-BE: store i32 6, i32* getelementptr inbounds ([2 x
> i32]*
> >> @_ZGR6nested3, i64 0, i64 1)
> >> +// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]*
> >> @_ZGR6nested3, i64 0, i64 0),
> >> +// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]*
> >> @_ZGR6nested, i64 0, i64 2, i32 0), align 8
> >> +// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]*
> >> @_ZGR6nested3, i64 1, i64 0),
> >> +// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]*
> >> @_ZGR6nested, i64 0, i64 2, i32 1), align 8
> >> +// CHECK-DYNAMIC-BE: store {{.*}}* getelementptr inbounds ([3 x
> {{.*}}]*
> >> @_ZGR6nested, i64 0, i64 0),
> >> +// CHECK-DYNAMIC-BE: {{.*}}** getelementptr inbounds ({{.*}}*
> >> @nested, i32 0, i32 0), align 8
> >> +// CHECK-DYNAMIC-BE: store {{.*}}* getelementptr inbounds ([3 x
> {{.*}}]*
> >> @_ZGR6nested, i64 1, i64 0),
> >> +// CHECK-DYNAMIC-BE: {{.*}}** getelementptr inbounds ({{.*}}*
> >> @nested, i32 0, i32 1), align 8
> >>
> >> Modified:
> >>
> cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> ---
> >>
> cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp
> >> (original)
> >> +++
> >>
> cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp
> >> Wed Jun 12 17:31:48 2013
> >> @@ -32,8 +32,8 @@ namespace std {
> >> };
> >> }
> >>
> >> -// CHECK: @_ZL25globalInitList1__initlist = internal global [3 x i32]
> >> [i32 1, i32 2, i32 3]
> >> -// CHECK: @globalInitList1 = global {{[^ ]+}} { i32* getelementptr
> >> inbounds ([3 x i32]* @_ZL25globalInitList1__initlist, {{[^)]*}}), i32*
> >> +// CHECK: @_ZGR15globalInitList1 = private constant [3 x i32] [i32 1,
> i32
> >> 2, i32 3]
> >> +// CHECK: @globalInitList1 = global {{[^ ]+}} { i32* getelementptr
> >> inbounds ([3 x i32]* @_ZGR15globalInitList1, {{[^)]*}}), i32*
> >> std::initializer_list<int> globalInitList1 = {1, 2, 3};
> >>
> >> void fn1(int i) {
> >>
> >> Modified:
> >> cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
> >> (original)
> >> +++ cfe/trunk/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
> Wed
> >> Jun 12 17:31:48 2013
> >> @@ -47,23 +47,43 @@ struct wantslist1 {
> >> ~wantslist1();
> >> };
> >>
> >> -// CHECK: @_ZL25globalInitList1__initlist = internal global [3 x i32]
> >> [i32 1, i32 2, i32 3]
> >> -// CHECK: @globalInitList1 = global %{{[^ ]+}} { i32* getelementptr
> >> inbounds ([3 x i32]* @_ZL25globalInitList1__initlist, i32 0, i32 0),
> >> i{{32|64}} 3 }
> >> +// CHECK: @_ZGR15globalInitList1 = private constant [3 x i32] [i32 1,
> i32
> >> 2, i32 3]
> >> +// CHECK: @globalInitList1 = global %{{[^ ]+}} { i32* getelementptr
> >> inbounds ([3 x i32]* @_ZGR15globalInitList1, i32 0, i32 0), i{{32|64}}
> 3 }
> >> std::initializer_list<int> globalInitList1 = {1, 2, 3};
> >>
> >> namespace thread_local_global_array {
> >> - // CHECK: @_ZN25thread_local_global_arrayL11x__initlistE = internal
> >> thread_local global [4 x i32] [i32 1, i32 2, i32 3, i32 4]
> >> - // CHECK: @_ZN25thread_local_global_array1xE = thread_local global
> >> {{.*}} @_ZN25thread_local_global_arrayL11x__initlistE, {{.*}} i64 4
> >> + // FIXME: We should be able to constant-evaluate this even though the
> >> + // initializer is not a constant expression (pointers to thread_local
> >> + // objects aren't really a problem).
> >> + //
> >> + // CHECK: @_ZN25thread_local_global_array1xE = thread_local global
> >> + // CHECK: @_ZGRN25thread_local_global_array1xE = private thread_local
> >> global [4 x i32]
> >> std::initializer_list<int> thread_local x = { 1, 2, 3, 4 };
> >> }
> >>
> >> -// CHECK: @_ZL25globalInitList2__initlist = internal global [2 x %{{[^
> >> ]*}}] zeroinitializer
> >> -// CHECK: @globalInitList2 = global %{{[^ ]+}} { %[[WITHARG:[^ *]+]]*
> >> getelementptr inbounds ([2 x
> >> +// CHECK: @globalInitList2 = global %{{[^ ]+}} zeroinitializer
> >> +// CHECK: @_ZGR15globalInitList2 = private global [2 x %[[WITHARG:[^
> >> ]*]]] zeroinitializer
> >> // CHECK: appending global
> >> +
> >> +
> >> +// thread_local initializer:
> >> +// CHECK: define internal void
> >> +// CHECK: store i32 1, i32* getelementptr inbounds ([4 x i32]*
> >> @_ZGRN25thread_local_global_array1xE, i64 0, i64 0)
> >> +// CHECK: store i32 2, i32* getelementptr inbounds ([4 x i32]*
> >> @_ZGRN25thread_local_global_array1xE, i64 0, i64 1)
> >> +// CHECK: store i32 3, i32* getelementptr inbounds ([4 x i32]*
> >> @_ZGRN25thread_local_global_array1xE, i64 0, i64 2)
> >> +// CHECK: store i32 4, i32* getelementptr inbounds ([4 x i32]*
> >> @_ZGRN25thread_local_global_array1xE, i64 0, i64 3)
> >> +// CHECK: store i32* getelementptr inbounds ([4 x i32]*
> >> @_ZGRN25thread_local_global_array1xE, i64 0, i64 0),
> >> +// CHECK: i32** getelementptr inbounds ({{.*}}*
> >> @_ZN25thread_local_global_array1xE, i32 0, i32 0), align 8
> >> +// CHECK: store i64 4, i64* getelementptr inbounds ({{.*}}*
> >> @_ZN25thread_local_global_array1xE, i32 0, i32 1), align 8
> >> +
> >> +
> >> // CHECK: define internal void
> >> -// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]*
> >> getelementptr inbounds ([2 x %[[WITHARG]]]*
> @_ZL25globalInitList2__initlist,
> >> i{{32|64}} 0, i{{32|64}} 0
> >> -// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]*
> >> getelementptr inbounds ([2 x %[[WITHARG]]]*
> @_ZL25globalInitList2__initlist,
> >> i{{32|64}} 0, i{{32|64}} 1
> >> +// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]*
> >> getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZGR15globalInitList2,
> >> i{{32|64}} 0, i{{32|64}} 0
> >> +// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]*
> >> getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZGR15globalInitList2,
> >> i{{32|64}} 0, i{{32|64}} 1
> >> // CHECK: __cxa_atexit
> >> +// CHECK: store %[[WITHARG]]* getelementptr inbounds ([2 x
> %[[WITHARG]]]*
> >> @_ZGR15globalInitList2, i64 0, i64 0),
> >> +// CHECK: %[[WITHARG]]** getelementptr inbounds (%{{.*}}*
> >> @globalInitList2, i32 0, i32 0), align 8
> >> +// CHECK: store i64 2, i64* getelementptr inbounds (%{{.*}}*
> >> @globalInitList2, i32 0, i32 1), align 8
> >> // CHECK: call void @_ZN10destroyme1D1Ev
> >> // CHECK: call void @_ZN10destroyme1D1Ev
> >> std::initializer_list<witharg1> globalInitList2 = {
> >> @@ -281,10 +301,56 @@ namespace dtors {
> >> S();
> >> ~S();
> >> };
> >> + void z();
> >> +
> >> + // CHECK: define void @_ZN5dtors1fEv(
> >> void f() {
> >> + // CHECK: call void @_ZN5dtors1SC1Ev(%"struct.dtors::S"*
> >> %arrayinit.begin)
> >> + // CHECK: call void @_ZN5dtors1SC1Ev(%"struct.dtors::S"*
> >> %arrayinit.element)
> >> std::initializer_list<S>{ S(), S() };
> >> +
> >> + // Destruction loop for underlying array.
> >> + // CHECK: br label
> >> + // CHECK: call void @_ZN5dtors1SD1Ev(
> >> + // CHECK: br i1
> >> +
> >> + // CHECK: call void @_ZN5dtors1zEv(
> >> + z();
> >> +
> >> + // CHECK-NOT: call void @_ZN5dtors1SD1Ev(
> >> }
> >> +
> >> + // CHECK: define void @_ZN5dtors1gEv(
> >> void g() {
> >> + // CHECK: call void @_ZN5dtors1SC1Ev(%"struct.dtors::S"*
> >> %arrayinit.begin)
> >> + // CHECK: call void @_ZN5dtors1SC1Ev(%"struct.dtors::S"*
> >> %arrayinit.element)
> >> auto x = std::initializer_list<S>{ S(), S() };
> >> +
> >> + // Destruction loop for underlying array.
> >> + // CHECK: br label
> >> + // CHECK: call void @_ZN5dtors1SD1Ev(
> >> + // CHECK: br i1
> >> +
> >> + // CHECK: call void @_ZN5dtors1zEv(
> >> + z();
> >> +
> >> + // CHECK-NOT: call void @_ZN5dtors1SD1Ev(
> >> + }
> >> +
> >> + // CHECK: define void @_ZN5dtors1hEv(
> >> + void h() {
> >> + // CHECK: call void @_ZN5dtors1SC1Ev(%"struct.dtors::S"*
> >> %arrayinit.begin)
> >> + // CHECK: call void @_ZN5dtors1SC1Ev(%"struct.dtors::S"*
> >> %arrayinit.element)
> >> + std::initializer_list<S> x = { S(), S() };
> >> +
> >> + // CHECK-NOT: call void @_ZN5dtors1SD1Ev(
> >> +
> >> + // CHECK: call void @_ZN5dtors1zEv(
> >> + z();
> >> +
> >> + // Destruction loop for underlying array.
> >> + // CHECK: br label
> >> + // CHECK: call void @_ZN5dtors1SD1Ev(
> >> + // CHECK: br i1
> >> }
> >> }
> >>
> >> Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
> >> +++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Wed Jun 12
> >> 17:31:48 2013
> >> @@ -1596,3 +1596,44 @@ namespace AfterError {
> >> }
> >> constexpr int k = error(); // expected-error {{must be initialized
> by a
> >> constant expression}}
> >> }
> >> +
> >> +namespace std {
> >> + typedef decltype(sizeof(int)) size_t;
> >> +
> >> + template <class _E>
> >> + class initializer_list
> >> + {
> >> + const _E* __begin_;
> >> + size_t __size_;
> >> +
> >> + constexpr initializer_list(const _E* __b, size_t __s)
> >> + : __begin_(__b),
> >> + __size_(__s)
> >> + {}
> >> +
> >> + public:
> >> + typedef _E value_type;
> >> + typedef const _E& reference;
> >> + typedef const _E& const_reference;
> >> + typedef size_t size_type;
> >> +
> >> + typedef const _E* iterator;
> >> + typedef const _E* const_iterator;
> >> +
> >> + constexpr initializer_list() : __begin_(nullptr), __size_(0) {}
> >> +
> >> + constexpr size_t size() const {return __size_;}
> >> + constexpr const _E* begin() const {return __begin_;}
> >> + constexpr const _E* end() const {return __begin_ + __size_;}
> >> + };
> >> +}
> >> +
> >> +namespace InitializerList {
> >> + constexpr int sum(const int *b, const int *e) {
> >> + return b != e ? *b + sum(b+1, e) : 0;
> >> + }
> >> + constexpr int sum(std::initializer_list<int> ints) {
> >> + return sum(ints.begin(), ints.end());
> >> + }
> >> + static_assert(sum({1, 2, 3, 4, 5}) == 15, "");
> >> +}
> >>
> >> Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx1y.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx1y.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/test/SemaCXX/constant-expression-cxx1y.cpp (original)
> >> +++ cfe/trunk/test/SemaCXX/constant-expression-cxx1y.cpp Wed Jun 12
> >> 17:31:48 2013
> >> @@ -725,3 +725,43 @@ namespace modify_temporary_during_constr
> >> static_assert(a.y == 54, "");
> >> constexpr int k = a.temporary++; // expected-error {{constant
> >> expression}} expected-note {{outside the expression that created the
> >> temporary}}
> >> }
> >> +
> >> +namespace std {
> >> + typedef decltype(sizeof(int)) size_t;
> >> +
> >> + template <class _E>
> >> + class initializer_list
> >> + {
> >> + const _E* __begin_;
> >> + size_t __size_;
> >> +
> >> + constexpr initializer_list(const _E* __b, size_t __s)
> >> + : __begin_(__b),
> >> + __size_(__s)
> >> + {}
> >> +
> >> + public:
> >> + typedef _E value_type;
> >> + typedef const _E& reference;
> >> + typedef const _E& const_reference;
> >> + typedef size_t size_type;
> >> +
> >> + typedef const _E* iterator;
> >> + typedef const _E* const_iterator;
> >> +
> >> + constexpr initializer_list() : __begin_(nullptr), __size_(0) {}
> >> +
> >> + constexpr size_t size() const {return __size_;}
> >> + constexpr const _E* begin() const {return __begin_;}
> >> + constexpr const _E* end() const {return __begin_ + __size_;}
> >> + };
> >> +}
> >> +
> >> +namespace InitializerList {
> >> + constexpr int sum(std::initializer_list<int> ints) {
> >> + int total = 0;
> >> + for (int n : ints) total += n;
> >> + return total;
> >> + }
> >> + static_assert(sum({1, 2, 3, 4, 5}) == 15, "");
> >> +}
> >>
> >> Modified:
> cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
> >> (original)
> >> +++ cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp Wed
> >> Jun 12 17:31:48 2013
> >> @@ -144,7 +144,7 @@ namespace PR12119 {
> >> template<typename T> void
> >> g(std::initializer_list<std::initializer_list<T>>);
> >>
> >> void foo() {
> >> - f({0, {1}});
> >> + f({0, {1}}); // expected-warning{{braces around scalar
> initializer}}
> >> g({{0, 1}, {2, 3}});
> >> std::initializer_list<int> il = {1, 2};
> >> g({il, {2, 3}});
> >>
> >> Modified: cfe/trunk/tools/libclang/CXCursor.cpp
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.cpp?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/tools/libclang/CXCursor.cpp (original)
> >> +++ cfe/trunk/tools/libclang/CXCursor.cpp Wed Jun 12 17:31:48 2013
> >> @@ -216,6 +216,7 @@ CXCursor cxcursor::MakeCXCursor(const St
> >> case Stmt::CXXBindTemporaryExprClass:
> >> case Stmt::CXXDefaultArgExprClass:
> >> case Stmt::CXXDefaultInitExprClass:
> >> + case Stmt::CXXStdInitializerListExprClass:
> >> case Stmt::CXXScalarValueInitExprClass:
> >> case Stmt::CXXUuidofExprClass:
> >> case Stmt::ChooseExprClass:
> >>
> >> Modified: cfe/trunk/tools/libclang/RecursiveASTVisitor.h
> >> URL:
> >>
> http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/RecursiveASTVisitor.h?rev=183872&r1=183871&r2=183872&view=diff
> >>
> >>
> ==============================================================================
> >> --- cfe/trunk/tools/libclang/RecursiveASTVisitor.h (original)
> >> +++ cfe/trunk/tools/libclang/RecursiveASTVisitor.h Wed Jun 12 17:31:48
> >> 2013
> >> @@ -2095,6 +2095,7 @@ DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {
> >> DEF_TRAVERSE_STMT(CXXDeleteExpr, { })
> >> DEF_TRAVERSE_STMT(ExprWithCleanups, { })
> >> DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, { })
> >> +DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, { })
> >> DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {
> >> TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
> >> if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
> >>
> >>
> >> _______________________________________________
> >> cfe-commits mailing list
> >> cfe-commits at cs.uiuc.edu
> >> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
> >
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130613/4e51a678/attachment.html>
More information about the cfe-commits
mailing list