r289413 - Add two new AST nodes to represent initialization of an array in terms of
Mike Aizatsky via cfe-commits
cfe-commits at lists.llvm.org
Mon Dec 12 16:16:31 PST 2016
Richard,
I'm not really sure since I don't have access to windows machine but this
or http://llvm.org/viewvc/llvm-project?revision=289412&view=revision has
broken sanitizer-windows bot. Sorry if this is a false alarm.
http://lab.llvm.org:8011/builders/sanitizer-windows/builds/2786
FAILED:
projects/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cc.i386.o
cmd.exe /C "cd /D
C:\b\slave\sanitizer-windows\build\projects\compiler-rt\lib\sanitizer_common\tests
&& C:\b\slave\sanitizer-windows\build\.\bin\clang.exe -DWIN32 -D_WINDOWS
-Wno-unknown-warning-option -fms-compatibility-version=19.00.24215.1
-D_HAS_EXCEPTIONS=0 -Wno-undefined-inline -DGTEST_NO_LLVM_RAW_OSTREAM=1
-DGTEST_HAS_RTTI=0
-IC:/b/slave/sanitizer-windows/llvm/utils/unittest/googletest/include
-IC:/b/slave/sanitizer-windows/llvm/utils/unittest/googletest
-DGTEST_HAS_SEH=0 -Wno-deprecated-declarations
-IC:/b/slave/sanitizer-windows/llvm/projects/compiler-rt/include
-IC:/b/slave/sanitizer-windows/llvm/projects/compiler-rt/lib
-IC:/b/slave/sanitizer-windows/llvm/projects/compiler-rt/lib/sanitizer_common
-fno-rtti -O2 -Werror=sign-compare -Wno-non-virtual-dtor -fno-exceptions
-DGTEST_HAS_SEH=0 -gline-tables-only -gcodeview -c -o
sanitizer_stacktrace_test.cc.i386.o
C:/b/slave/sanitizer-windows/llvm/projects/compiler-rt/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cc"
Assertion failed: (PtrWord & ~PointerBitMask) == 0 && "Pointer is not
sufficiently aligned", file
C:\b\slave\sanitizer-windows\llvm\include\llvm/ADT/PointerIntPair.h, line
160
Wrote crash dump file
"C:\Users\buildbot\AppData\Local\Temp\clang.exe-692761.dmp"
#0 0x01f8dd87 (C:\b\slave\sanitizer-windows\build\bin\clang.exe+0xd4dd87)
#1 0x70a64672 (C:\windows\SYSTEM32\ucrtbase.DLL+0x84672)
#2 0x70a65cab (C:\windows\SYSTEM32\ucrtbase.DLL+0x85cab)
#3 0x70a650e8 (C:\windows\SYSTEM32\ucrtbase.DLL+0x850e8)
#4 0x70a65da6 (C:\windows\SYSTEM32\ucrtbase.DLL+0x85da6)
#5 0x02ff860d (C:\b\slave\sanitizer-windows\build\bin\clang.exe+0x1db860d)
clang.exe: error: clang frontend command failed due to signal (use -v to
see invocation)
clang version 4.0.0 (trunk 289413)
Target: i686-pc-windows-msvc
Thread model: posix
InstalledDir: C:\b\slave\sanitizer-windows\build\bin
clang.exe: note: diagnostic msg: PLEASE submit a bug report to
http://llvm.org/bugs/ and include the crash backtrace, preprocessed source,
and associated run script.
clang.exe: note: diagnostic msg:
********************
On Sun, Dec 11, 2016 at 7:03 PM Richard Smith via cfe-commits <
cfe-commits at lists.llvm.org> wrote:
> Author: rsmith
> Date: Sun Dec 11 20:53:20 2016
> New Revision: 289413
>
> URL: http://llvm.org/viewvc/llvm-project?rev=289413&view=rev
> Log:
> Add two new AST nodes to represent initialization of an array in terms of
> initialization of each array element:
>
> * ArrayInitLoopExpr is a prvalue of array type with two subexpressions:
> a common expression (an OpaqueValueExpr) that represents the up-front
> computation of the source of the initialization, and a subexpression
> representing a per-element initializer
> * ArrayInitIndexExpr is a prvalue of type size_t representing the current
> position in the loop
>
> This will be used to replace the creation of explicit index variables in
> lambda
> capture of arrays and copy/move construction of classes with array
> elements,
> and also C++17 structured bindings of arrays by value (which inexplicably
> allow
> copying an array by value, unlike all of C++'s other array declarations).
>
> No uses of these nodes are introduced by this change, however.
>
> Modified:
> cfe/trunk/include/clang/AST/Expr.h
> cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
> cfe/trunk/include/clang/Basic/StmtNodes.td
> cfe/trunk/include/clang/Sema/Initialization.h
> cfe/trunk/include/clang/Serialization/ASTBitCodes.h
> cfe/trunk/lib/AST/ASTDumper.cpp
> 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/CGExprAgg.cpp
> cfe/trunk/lib/CodeGen/CGExprScalar.cpp
> cfe/trunk/lib/CodeGen/CodeGenFunction.h
> 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/ASTWriterStmt.cpp
> cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
> cfe/trunk/tools/libclang/CXCursor.cpp
>
> Modified: cfe/trunk/include/clang/AST/Expr.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=289413&r1=289412&r2=289413&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/AST/Expr.h (original)
> +++ cfe/trunk/include/clang/AST/Expr.h Sun Dec 11 20:53:20 2016
> @@ -4333,6 +4333,98 @@ public:
> }
> };
>
> +/// \brief Represents a loop initializing the elements of an array.
> +///
> +/// The need to initialize the elements of an array occurs in a number of
> +/// contexts:
> +///
> +/// * in the implicit copy/move constructor for a class with an array
> member
> +/// * when a lambda-expression captures an array by value
> +/// * when a decomposition declaration decomposes an array
> +///
> +/// There are two subexpressions: a common expression (the source array)
> +/// that is evaluated once up-front, and a per-element initializer that
> +/// runs once for each array element.
> +///
> +/// Within the per-element initializer, the common expression may be
> referenced
> +/// via an OpaqueValueExpr, and the current index may be obtained via an
> +/// ArrayInitIndexExpr.
> +class ArrayInitLoopExpr : public Expr {
> + Stmt *SubExprs[2];
> +
> + explicit ArrayInitLoopExpr(EmptyShell Empty)
> + : Expr(ArrayInitLoopExprClass, Empty), SubExprs{} {}
> +
> +public:
> + explicit ArrayInitLoopExpr(QualType T, Expr *CommonInit, Expr
> *ElementInit)
> + : Expr(ArrayInitLoopExprClass, T, VK_RValue, OK_Ordinary, false,
> + CommonInit->isValueDependent() ||
> ElementInit->isValueDependent(),
> + T->isInstantiationDependentType(),
> + CommonInit->containsUnexpandedParameterPack() ||
> + ElementInit->containsUnexpandedParameterPack()),
> + SubExprs{CommonInit, ElementInit} {}
> +
> + /// Get the common subexpression shared by all initializations (the
> source
> + /// array).
> + OpaqueValueExpr *getCommonExpr() const {
> + return cast<OpaqueValueExpr>(SubExprs[0]);
> + }
> +
> + /// Get the initializer to use for each array element.
> + Expr *getSubExpr() const { return cast<Expr>(SubExprs[1]); }
> +
> + llvm::APInt getArraySize() const {
> + return cast<ConstantArrayType>(getType()->castAsArrayTypeUnsafe())
> + ->getSize();
> + }
> +
> + static bool classof(const Stmt *S) {
> + return S->getStmtClass() == ArrayInitLoopExprClass;
> + }
> +
> + SourceLocation getLocStart() const LLVM_READONLY {
> + return getCommonExpr()->getLocStart();
> + }
> + SourceLocation getLocEnd() const LLVM_READONLY {
> + return getCommonExpr()->getLocEnd();
> + }
> +
> + child_range children() {
> + return child_range(SubExprs, SubExprs + 2);
> + }
> +
> + friend class ASTReader;
> + friend class ASTStmtReader;
> + friend class ASTStmtWriter;
> +};
> +
> +/// \brief Represents the index of the current element of an array being
> +/// initialized by an ArrayInitLoopExpr. This can only appear within the
> +/// subexpression of an ArrayInitLoopExpr.
> +class ArrayInitIndexExpr : public Expr {
> + explicit ArrayInitIndexExpr(EmptyShell Empty)
> + : Expr(ArrayInitIndexExprClass, Empty) {}
> +
> +public:
> + explicit ArrayInitIndexExpr(QualType T)
> + : Expr(ArrayInitIndexExprClass, T, VK_RValue, OK_Ordinary,
> + false, false, false, false) {}
> +
> + static bool classof(const Stmt *S) {
> + return S->getStmtClass() == ArrayInitIndexExprClass;
> + }
> +
> + SourceLocation getLocStart() const LLVM_READONLY { return
> SourceLocation(); }
> + SourceLocation getLocEnd() const LLVM_READONLY { return
> SourceLocation(); }
> +
> + child_range children() {
> + return child_range(child_iterator(), child_iterator());
> + }
> +
> + friend class ASTReader;
> + friend class ASTStmtReader;
> +};
> +
> /// \brief Represents an implicitly-generated value initialization of
> /// an object of a given type.
> ///
>
> Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=289413&r1=289412&r2=289413&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
> +++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Sun Dec 11 20:53:20
> 2016
> @@ -2399,6 +2399,8 @@ DEF_TRAVERSE_STMT(ExtVectorElementExpr,
> DEF_TRAVERSE_STMT(GNUNullExpr, {})
> DEF_TRAVERSE_STMT(ImplicitValueInitExpr, {})
> DEF_TRAVERSE_STMT(NoInitExpr, {})
> +DEF_TRAVERSE_STMT(ArrayInitLoopExpr, {})
> +DEF_TRAVERSE_STMT(ArrayInitIndexExpr, {})
> DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, {})
>
> DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
>
> Modified: cfe/trunk/include/clang/Basic/StmtNodes.td
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/StmtNodes.td?rev=289413&r1=289412&r2=289413&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/StmtNodes.td (original)
> +++ cfe/trunk/include/clang/Basic/StmtNodes.td Sun Dec 11 20:53:20 2016
> @@ -85,6 +85,8 @@ def DesignatedInitExpr : DStmt<Expr>;
> def DesignatedInitUpdateExpr : DStmt<Expr>;
> def ImplicitValueInitExpr : DStmt<Expr>;
> def NoInitExpr : DStmt<Expr>;
> +def ArrayInitLoopExpr : DStmt<Expr>;
> +def ArrayInitIndexExpr : DStmt<Expr>;
> def ParenListExpr : DStmt<Expr>;
> def VAArgExpr : DStmt<Expr>;
> def GenericSelectionExpr : DStmt<Expr>;
>
> Modified: cfe/trunk/include/clang/Sema/Initialization.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Initialization.h?rev=289413&r1=289412&r2=289413&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Sema/Initialization.h (original)
> +++ cfe/trunk/include/clang/Sema/Initialization.h Sun Dec 11 20:53:20 2016
> @@ -120,6 +120,16 @@ private:
> bool NRVO;
> };
>
> + struct VD {
> + /// \brief The VarDecl, FieldDecl, or BindingDecl being initialized.
> + ValueDecl *VariableOrMember;
> +
> + /// \brief When Kind == EK_Member, whether this is an implicit member
> + /// initialization in a copy or move constructor. These can perform
> array
> + /// copies.
> + bool IsImplicitFieldInit;
> + };
> +
> struct C {
> /// \brief The name of the variable being captured by an
> EK_LambdaCapture.
> IdentifierInfo *VarID;
> @@ -129,9 +139,8 @@ private:
> };
>
> union {
> - /// \brief When Kind == EK_Variable, EK_Member or EK_Binding, the
> VarDecl,
> - /// FieldDecl or BindingDecl, respectively.
> - ValueDecl *VariableOrMember;
> + /// \brief When Kind == EK_Variable, EK_Member or EK_Binding, the
> variable.
> + VD Variable;
>
> /// \brief When Kind == EK_RelatedResult, the ObjectiveC method where
> /// result type was implicitly changed to accommodate ARC semantics.
> @@ -165,7 +174,7 @@ private:
> /// \brief Create the initialization entity for a variable.
> InitializedEntity(VarDecl *Var, EntityKind EK = EK_Variable)
> : Kind(EK), Parent(nullptr), Type(Var->getType()),
> - ManglingNumber(0), VariableOrMember(Var) { }
> + ManglingNumber(0), Variable{Var, false} { }
>
> /// \brief Create the initialization entity for the result of a
> /// function, throwing an object, performing an explicit cast, or
> @@ -179,9 +188,11 @@ private:
> }
>
> /// \brief Create the initialization entity for a member subobject.
> - InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent)
> + InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent,
> + bool Implicit)
> : Kind(EK_Member), Parent(Parent), Type(Member->getType()),
> - ManglingNumber(0), VariableOrMember(Member) { }
> + ManglingNumber(0), Variable{Member, Implicit} {
> + }
>
> /// \brief Create the initialization entity for an array element.
> InitializedEntity(ASTContext &Context, unsigned Index,
> @@ -299,15 +310,17 @@ public:
> /// \brief Create the initialization entity for a member subobject.
> static InitializedEntity
> InitializeMember(FieldDecl *Member,
> - const InitializedEntity *Parent = nullptr) {
> - return InitializedEntity(Member, Parent);
> + const InitializedEntity *Parent = nullptr,
> + bool Implicit = false) {
> + return InitializedEntity(Member, Parent, Implicit);
> }
>
> /// \brief Create the initialization entity for a member subobject.
> static InitializedEntity
> InitializeMember(IndirectFieldDecl *Member,
> - const InitializedEntity *Parent = nullptr) {
> - return InitializedEntity(Member->getAnonField(), Parent);
> + const InitializedEntity *Parent = nullptr,
> + bool Implicit = false) {
> + return InitializedEntity(Member->getAnonField(), Parent, Implicit);
> }
>
> /// \brief Create the initialization entity for an array element.
> @@ -401,6 +414,12 @@ public:
> getType()->getAsArrayTypeUnsafe());
> }
>
> + /// \brief Is this the implicit initialization of a member of a class
> from
> + /// a defaulted constructor?
> + bool isImplicitMemberInitializer() const {
> + return getKind() == EK_Member && Variable.IsImplicitFieldInit;
> + }
> +
> /// \brief Determine the location of the 'return' keyword when
> initializing
> /// the result of a function call.
> SourceLocation getReturnLoc() const {
> @@ -708,6 +727,10 @@ public:
> /// \brief An initialization that "converts" an Objective-C object
> /// (not a point to an object) to another Objective-C object type.
> SK_ObjCObjectConversion,
> + /// \brief Array indexing for initialization by elementwise copy.
> + SK_ArrayLoopIndex,
> + /// \brief Array initialization by elementwise copy.
> + SK_ArrayLoopInit,
> /// \brief Array initialization (from an array rvalue).
> /// This is a GNU C extension.
> SK_ArrayInit,
> @@ -1096,6 +1119,9 @@ public:
> /// always a no-op.
> void AddObjCObjectConversionStep(QualType T);
>
> + /// \brief Add an array initialization loop step.
> + void AddArrayInitLoopStep(QualType T, QualType EltTy);
> +
> /// \brief Add an array initialization step.
> void AddArrayInitStep(QualType T);
>
>
> Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=289413&r1=289412&r2=289413&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
> +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Sun Dec 11
> 20:53:20 2016
> @@ -1292,10 +1292,14 @@ namespace clang {
> EXPR_DESIGNATED_INIT,
> /// \brief A DesignatedInitUpdateExpr record.
> EXPR_DESIGNATED_INIT_UPDATE,
> - /// \brief An ImplicitValueInitExpr record.
> - EXPR_IMPLICIT_VALUE_INIT,
> /// \brief An NoInitExpr record.
> EXPR_NO_INIT,
> + /// \brief An ArrayInitLoopExpr record.
> + EXPR_ARRAY_INIT_LOOP,
> + /// \brief An ArrayInitIndexExpr record.
> + EXPR_ARRAY_INIT_INDEX,
> + /// \brief An ImplicitValueInitExpr record.
> + EXPR_IMPLICIT_VALUE_INIT,
> /// \brief A VAArgExpr record.
> EXPR_VA_ARG,
> /// \brief An AddrLabelExpr record.
>
> Modified: cfe/trunk/lib/AST/ASTDumper.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDumper.cpp?rev=289413&r1=289412&r2=289413&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/ASTDumper.cpp (original)
> +++ cfe/trunk/lib/AST/ASTDumper.cpp Sun Dec 11 20:53:20 2016
> @@ -517,6 +517,8 @@ namespace {
> void VisitFloatingLiteral(const FloatingLiteral *Node);
> void VisitStringLiteral(const StringLiteral *Str);
> void VisitInitListExpr(const InitListExpr *ILE);
> + void VisitArrayInitLoopExpr(const ArrayInitLoopExpr *ILE);
> + void VisitArrayInitIndexExpr(const ArrayInitIndexExpr *ILE);
> void VisitUnaryOperator(const UnaryOperator *Node);
> void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr
> *Node);
> void VisitMemberExpr(const MemberExpr *Node);
> @@ -2024,6 +2026,14 @@ void ASTDumper::VisitInitListExpr(const
> }
> }
>
> +void ASTDumper::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E) {
> + VisitExpr(E);
> +}
> +
> +void ASTDumper::VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E) {
> + VisitExpr(E);
> +}
> +
> void ASTDumper::VisitUnaryOperator(const UnaryOperator *Node) {
> VisitExpr(Node);
> OS << " " << (Node->isPostfix() ? "postfix" : "prefix")
>
> Modified: cfe/trunk/lib/AST/Expr.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=289413&r1=289412&r2=289413&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/Expr.cpp (original)
> +++ cfe/trunk/lib/AST/Expr.cpp Sun Dec 11 20:53:20 2016
> @@ -2899,6 +2899,7 @@ bool Expr::HasSideEffects(const ASTConte
> case UnaryExprOrTypeTraitExprClass:
> case AddrLabelExprClass:
> case GNUNullExprClass:
> + case ArrayInitIndexExprClass:
> case NoInitExprClass:
> case CXXBoolLiteralExprClass:
> case CXXNullPtrLiteralExprClass:
> @@ -2975,6 +2976,7 @@ bool Expr::HasSideEffects(const ASTConte
> case ExtVectorElementExprClass:
> case DesignatedInitExprClass:
> case DesignatedInitUpdateExprClass:
> + case ArrayInitLoopExprClass:
> case ParenListExprClass:
> case CXXPseudoDestructorExprClass:
> case CXXStdInitializerListExprClass:
>
> Modified: cfe/trunk/lib/AST/ExprClassification.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprClassification.cpp?rev=289413&r1=289412&r2=289413&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/ExprClassification.cpp (original)
> +++ cfe/trunk/lib/AST/ExprClassification.cpp Sun Dec 11 20:53:20 2016
> @@ -185,6 +185,8 @@ static Cl::Kinds ClassifyInternal(ASTCon
> case Expr::ObjCIndirectCopyRestoreExprClass:
> case Expr::AtomicExprClass:
> case Expr::CXXFoldExprClass:
> + case Expr::ArrayInitLoopExprClass:
> + case Expr::ArrayInitIndexExprClass:
> case Expr::NoInitExprClass:
> case Expr::DesignatedInitUpdateExprClass:
> case Expr::CoyieldExprClass:
>
> Modified: cfe/trunk/lib/AST/ExprConstant.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=289413&r1=289412&r2=289413&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/ExprConstant.cpp (original)
> +++ cfe/trunk/lib/AST/ExprConstant.cpp Sun Dec 11 20:53:20 2016
> @@ -469,6 +469,10 @@ namespace {
> /// declaration whose initializer is being evaluated, if any.
> APValue *EvaluatingDeclValue;
>
> + /// The current array initialization index, if we're performing array
> + /// initialization.
> + uint64_t ArrayInitIndex = -1;
> +
> /// HasActiveDiagnostic - Was the previous diagnostic stored? If so,
> further
> /// notes attached to it will also be stored, otherwise they will not
> be.
> bool HasActiveDiagnostic;
> @@ -803,6 +807,20 @@ namespace {
> bool allowInvalidBaseExpr() const {
> return EvalMode == EM_DesignatorFold;
> }
> +
> + class ArrayInitLoopIndex {
> + EvalInfo &Info;
> + uint64_t OuterIndex;
> +
> + public:
> + ArrayInitLoopIndex(EvalInfo &Info)
> + : Info(Info), OuterIndex(Info.ArrayInitIndex) {
> + Info.ArrayInitIndex = 0;
> + }
> + ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
> +
> + operator uint64_t&() { return Info.ArrayInitIndex; }
> + };
> };
>
> /// Object used to treat all foldable expressions as constant
> expressions.
> @@ -6190,6 +6208,7 @@ namespace {
> return handleCallExpr(E, Result, &This);
> }
> bool VisitInitListExpr(const InitListExpr *E);
> + bool VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E);
> bool VisitCXXConstructExpr(const CXXConstructExpr *E);
> bool VisitCXXConstructExpr(const CXXConstructExpr *E,
> const LValue &Subobject,
> @@ -6272,6 +6291,35 @@ bool ArrayExprEvaluator::VisitInitListEx
> FillerExpr) && Success;
> }
>
> +bool ArrayExprEvaluator::VisitArrayInitLoopExpr(const ArrayInitLoopExpr
> *E) {
> + if (E->getCommonExpr() &&
> + !Evaluate(Info.CurrentCall->createTemporary(E->getCommonExpr(),
> false),
> + Info, E->getCommonExpr()->getSourceExpr()))
> + return false;
> +
> + auto *CAT =
> cast<ConstantArrayType>(E->getType()->castAsArrayTypeUnsafe());
> +
> + uint64_t Elements = CAT->getSize().getZExtValue();
> + Result = APValue(APValue::UninitArray(), Elements, Elements);
> +
> + LValue Subobject = This;
> + Subobject.addArray(Info, E, CAT);
> +
> + bool Success = true;
> + for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements;
> ++Index) {
> + if (!EvaluateInPlace(Result.getArrayInitializedElt(Index),
> + Info, Subobject, E->getSubExpr()) ||
> + !HandleLValueArrayAdjustment(Info, E, Subobject,
> + CAT->getElementType(), 1)) {
> + if (!Info.noteFailure())
> + return false;
> + Success = false;
> + }
> + }
> +
> + return Success;
> +}
> +
> bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E)
> {
> return VisitCXXConstructExpr(E, This, &Result, E->getType());
> }
> @@ -6427,6 +6475,16 @@ public:
> bool VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *E) {
> return Success(E->getValue(), E);
> }
> +
> + bool VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E) {
> + if (Info.ArrayInitIndex == uint64_t(-1)) {
> + // We were asked to evaluate this subexpression independent of the
> + // enclosing ArrayInitLoopExpr. We can't do that.
> + Info.FFDiag(E);
> + return false;
> + }
> + return Success(Info.ArrayInitIndex, E);
> + }
>
> // Note, GNU defines __null as an integer, not a pointer.
> bool VisitGNUNullExpr(const GNUNullExpr *E) {
> @@ -9590,6 +9648,8 @@ static ICEDiag CheckICE(const Expr* E, c
> case Expr::CompoundLiteralExprClass:
> case Expr::ExtVectorElementExprClass:
> case Expr::DesignatedInitExprClass:
> + case Expr::ArrayInitLoopExprClass:
> + case Expr::ArrayInitIndexExprClass:
> case Expr::NoInitExprClass:
> case Expr::DesignatedInitUpdateExprClass:
> case Expr::ImplicitValueInitExprClass:
>
> Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=289413&r1=289412&r2=289413&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
> +++ cfe/trunk/lib/AST/ItaniumMangle.cpp Sun Dec 11 20:53:20 2016
> @@ -3301,6 +3301,8 @@ recurse:
> case Expr::AddrLabelExprClass:
> case Expr::DesignatedInitUpdateExprClass:
> case Expr::ImplicitValueInitExprClass:
> + case Expr::ArrayInitLoopExprClass:
> + case Expr::ArrayInitIndexExprClass:
> case Expr::NoInitExprClass:
> case Expr::ParenListExprClass:
> case Expr::LambdaExprClass:
>
> Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=289413&r1=289412&r2=289413&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
> +++ cfe/trunk/lib/AST/StmtPrinter.cpp Sun Dec 11 20:53:20 2016
> @@ -1705,6 +1705,18 @@ void StmtPrinter::VisitInitListExpr(Init
> OS << "}";
> }
>
> +void StmtPrinter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *Node) {
> + // There's no way to express this expression in any of our supported
> + // languages, so just emit something terse and (hopefully) clear.
> + OS << "{";
> + PrintExpr(Node->getSubExpr());
> + OS << "}";
> +}
> +
> +void StmtPrinter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *Node) {
> + OS << "*";
> +}
> +
> void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
> OS << "(";
> for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {
>
> Modified: cfe/trunk/lib/AST/StmtProfile.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=289413&r1=289412&r2=289413&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/StmtProfile.cpp (original)
> +++ cfe/trunk/lib/AST/StmtProfile.cpp Sun Dec 11 20:53:20 2016
> @@ -972,6 +972,14 @@ void StmtProfiler::VisitDesignatedInitUp
> "initializer");
> }
>
> +void StmtProfiler::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *S) {
> + VisitExpr(S);
> +}
> +
> +void StmtProfiler::VisitArrayInitIndexExpr(const ArrayInitIndexExpr *S) {
> + VisitExpr(S);
> +}
> +
> void StmtProfiler::VisitNoInitExpr(const NoInitExpr *S) {
> llvm_unreachable("Unexpected NoInitExpr in syntactic form of
> initializer");
> }
>
> Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=289413&r1=289412&r2=289413&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Sun Dec 11 20:53:20 2016
> @@ -164,6 +164,7 @@ public:
> void VisitAbstractConditionalOperator(const AbstractConditionalOperator
> *CO);
> void VisitChooseExpr(const ChooseExpr *CE);
> void VisitInitListExpr(InitListExpr *E);
> + void VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E);
> void VisitImplicitValueInitExpr(ImplicitValueInitExpr *E);
> void VisitNoInitExpr(NoInitExpr *E) { } // Do nothing.
> void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
> @@ -1308,6 +1309,85 @@ void AggExprEmitter::VisitInitListExpr(I
> cleanupDominator->eraseFromParent();
> }
>
> +void AggExprEmitter::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E) {
> + // Emit the common subexpression.
> + CodeGenFunction::OpaqueValueMapping binding(CGF, E->getCommonExpr());
> +
> + Address destPtr = EnsureSlot(E->getType()).getAddress();
> + uint64_t numElements = E->getArraySize().getZExtValue();
> +
> + if (!numElements)
> + return;
> +
> + // FIXME: Dig through nested ArrayInitLoopExprs to find the overall
> array
> + // size, and only emit a single loop for a multidimensional array.
> +
> + // destPtr is an array*. Construct an elementType* by drilling down a
> level.
> + llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0);
> + llvm::Value *indices[] = {zero, zero};
> + llvm::Value *begin = Builder.CreateInBoundsGEP(destPtr.getPointer(),
> indices,
> + "arrayinit.begin");
> +
> + QualType elementType = E->getSubExpr()->getType();
> + CharUnits elementSize =
> CGF.getContext().getTypeSizeInChars(elementType);
> + CharUnits elementAlign =
> + destPtr.getAlignment().alignmentOfArrayElement(elementSize);
> +
> + // Prepare for a cleanup.
> + QualType::DestructionKind dtorKind = elementType.isDestructedType();
> + Address endOfInit = Address::invalid();
> + EHScopeStack::stable_iterator cleanup;
> + llvm::Instruction *cleanupDominator = nullptr;
> + if (CGF.needsEHCleanup(dtorKind)) {
> + endOfInit = CGF.CreateTempAlloca(begin->getType(),
> CGF.getPointerAlign(),
> + "arrayinit.endOfInit");
> + CGF.pushIrregularPartialArrayCleanup(begin, endOfInit, elementType,
> + elementAlign,
> + CGF.getDestroyer(dtorKind));
> + cleanup = CGF.EHStack.stable_begin();
> + } else {
> + dtorKind = QualType::DK_none;
> + }
> +
> + llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
> + llvm::BasicBlock *bodyBB = CGF.createBasicBlock("arrayinit.body");
> +
> + // Jump into the body.
> + CGF.EmitBlock(bodyBB);
> + llvm::PHINode *index =
> + Builder.CreatePHI(zero->getType(), 2, "arrayinit.index");
> + index->addIncoming(zero, entryBB);
> + llvm::Value *element = Builder.CreateInBoundsGEP(begin, index);
> +
> + // Tell the EH cleanup that we finished with the last element.
> + if (endOfInit.isValid()) Builder.CreateStore(element, endOfInit);
> +
> + // Emit the actual filler expression.
> + {
> + CodeGenFunction::ArrayInitLoopExprScope Scope(CGF, index);
> + LValue elementLV =
> + CGF.MakeAddrLValue(Address(element, elementAlign), elementType);
> + EmitInitializationToLValue(E->getSubExpr(), elementLV);
> + }
> +
> + // Move on to the next element.
> + llvm::Value *nextIndex = Builder.CreateNUWAdd(
> + index, llvm::ConstantInt::get(CGF.SizeTy, 1), "arrayinit.next");
> + index->addIncoming(nextIndex, Builder.GetInsertBlock());
> +
> + // Leave the loop if we're done.
> + llvm::Value *done = Builder.CreateICmpEQ(
> + nextIndex, llvm::ConstantInt::get(CGF.SizeTy, numElements),
> + "arrayinit.done");
> + llvm::BasicBlock *endBB = CGF.createBasicBlock("arrayinit.end");
> + Builder.CreateCondBr(done, endBB, bodyBB);
> +
> + CGF.EmitBlock(endBB);
> +
> + // Leave the partial-array cleanup if we entered one.
> + if (dtorKind) CGF.DeactivateCleanupBlock(cleanup, cleanupDominator);
> +}
> +
> void
> AggExprEmitter::VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E) {
> AggValueSlot Dest = EnsureSlot(E->getType());
>
>
> Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=289413&r1=289412&r2=289413&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Sun Dec 11 20:53:20 2016
> @@ -311,6 +311,12 @@ public:
>
> Value *VisitInitListExpr(InitListExpr *E);
>
> + Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
> + assert(CGF.getArrayInitIndex() &&
> + "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
> + return CGF.getArrayInitIndex();
> + }
> +
> Value *VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
> return EmitNullValue(E->getType());
> }
>
> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=289413&r1=289412&r2=289413&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Sun Dec 11 20:53:20 2016
> @@ -918,6 +918,17 @@ public:
> e->getCommon());
> }
>
> + /// Build the opaque value mapping for an OpaqueValueExpr whose source
> + /// expression is set to the expression the OVE represents.
> + OpaqueValueMapping(CodeGenFunction &CGF, const OpaqueValueExpr *OV)
> + : CGF(CGF) {
> + if (OV) {
> + assert(OV->getSourceExpr() && "wrong form of OpaqueValueMapping
> used "
> + "for OVE with no source
> expression");
> + Data = OpaqueValueMappingData::bind(CGF, OV, OV->getSourceExpr());
> + }
> + }
> +
> OpaqueValueMapping(CodeGenFunction &CGF,
> const OpaqueValueExpr *opaqueValue,
> LValue lvalue)
> @@ -1183,6 +1194,23 @@ public:
> CharUnits OldCXXThisAlignment;
> };
>
> + /// The scope of an ArrayInitLoopExpr. Within this scope, the value of
> the
> + /// current loop index is overridden.
> + class ArrayInitLoopExprScope {
> + public:
> + ArrayInitLoopExprScope(CodeGenFunction &CGF, llvm::Value *Index)
> + : CGF(CGF), OldArrayInitIndex(CGF.ArrayInitIndex) {
> + CGF.ArrayInitIndex = Index;
> + }
> + ~ArrayInitLoopExprScope() {
> + CGF.ArrayInitIndex = OldArrayInitIndex;
> + }
> +
> + private:
> + CodeGenFunction &CGF;
> + llvm::Value *OldArrayInitIndex;
> + };
> +
> class InlinedInheritingConstructorScope {
> public:
> InlinedInheritingConstructorScope(CodeGenFunction &CGF, GlobalDecl GD)
> @@ -1251,6 +1279,10 @@ private:
> /// this expression.
> Address CXXDefaultInitExprThis = Address::invalid();
>
> + /// The current array initialization index when evaluating an
> + /// ArrayInitIndexExpr within an ArrayInitLoopExpr.
> + llvm::Value *ArrayInitIndex = nullptr;
> +
> /// The values of function arguments to use when evaluating
> /// CXXInheritedCtorInitExprs within this context.
> CallArgList CXXInheritedCtorInitExprArgs;
> @@ -1953,6 +1985,9 @@ public:
> return it->second;
> }
>
> + /// Get the index of the current ArrayInitLoopExpr, if any.
> + llvm::Value *getArrayInitIndex() { return ArrayInitIndex; }
> +
> /// getAccessedFieldNo - Given an encoded value and a result number,
> return
> /// the input field number being accessed.
> static unsigned getAccessedFieldNo(unsigned Idx, const llvm::Constant
> *Elts);
>
> Modified: cfe/trunk/lib/Sema/SemaExceptionSpec.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExceptionSpec.cpp?rev=289413&r1=289412&r2=289413&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaExceptionSpec.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExceptionSpec.cpp Sun Dec 11 20:53:20 2016
> @@ -1166,6 +1166,7 @@ CanThrowResult Sema::canThrow(const Expr
> case Expr::ExprWithCleanupsClass:
> case Expr::ExtVectorElementExprClass:
> case Expr::InitListExprClass:
> + case Expr::ArrayInitLoopExprClass:
> case Expr::MemberExprClass:
> case Expr::ObjCIsaExprClass:
> case Expr::ObjCIvarRefExprClass:
> @@ -1259,6 +1260,7 @@ CanThrowResult Sema::canThrow(const Expr
> case Expr::ImaginaryLiteralClass:
> case Expr::ImplicitValueInitExprClass:
> case Expr::IntegerLiteralClass:
> + case Expr::ArrayInitIndexExprClass:
> case Expr::NoInitExprClass:
> case Expr::ObjCEncodeExprClass:
> case Expr::ObjCStringLiteralClass:
>
> Modified: cfe/trunk/lib/Sema/SemaInit.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=289413&r1=289412&r2=289413&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaInit.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaInit.cpp Sun Dec 11 20:53:20 2016
> @@ -2910,7 +2910,7 @@ DeclarationName InitializedEntity::getNa
> case EK_Variable:
> case EK_Member:
> case EK_Binding:
> - return VariableOrMember->getDeclName();
> + return Variable.VariableOrMember->getDeclName();
>
> case EK_LambdaCapture:
> return DeclarationName(Capture.VarID);
> @@ -2938,7 +2938,7 @@ ValueDecl *InitializedEntity::getDecl()
> case EK_Variable:
> case EK_Member:
> case EK_Binding:
> - return VariableOrMember;
> + return Variable.VariableOrMember;
>
> case EK_Parameter:
> case EK_Parameter_CF_Audited:
> @@ -3065,6 +3065,8 @@ void InitializationSequence::Step::Destr
> case SK_CAssignment:
> case SK_StringInit:
> case SK_ObjCObjectConversion:
> + case SK_ArrayLoopIndex:
> + case SK_ArrayLoopInit:
> case SK_ArrayInit:
> case SK_ParenthesizedArrayInit:
> case SK_PassByIndirectCopyRestore:
> @@ -3307,6 +3309,17 @@ void InitializationSequence::AddArrayIni
> Steps.push_back(S);
> }
>
> +void InitializationSequence::AddArrayInitLoopStep(QualType T, QualType
> EltT) {
> + Step S;
> + S.Kind = SK_ArrayLoopIndex;
> + S.Type = EltT;
> + Steps.insert(Steps.begin(), S);
> +
> + S.Kind = SK_ArrayLoopInit;
> + S.Type = T;
> + Steps.push_back(S);
> +}
> +
> void InitializationSequence::AddParenthesizedArrayInitStep(QualType T) {
> Step S;
> S.Kind = SK_ParenthesizedArrayInit;
> @@ -3552,6 +3565,9 @@ ResolveConstructorOverload(Sema &S, Sour
> /// \brief Attempt initialization by constructor (C++ [dcl.init]), which
> /// enumerates the constructors of the initialized entity and performs
> overload
> /// resolution to select the best.
> +/// \param DestType The destination class type.
> +/// \param DestArrayType The destination type, which is either DestType
> or
> +/// a (possibly multidimensional) array of DestType.
> /// \param IsListInit Is this list-initialization?
> /// \param IsInitListCopy Is this non-list-initialization resulting from a
> /// list-initialization from {x} where x is the same
> @@ -3560,6 +3576,7 @@ static void TryConstructorInitialization
> const InitializedEntity &Entity,
> const InitializationKind &Kind,
> MultiExprArg Args, QualType
> DestType,
> + QualType DestArrayType,
> InitializationSequence &Sequence,
> bool IsListInit = false,
> bool IsInitListCopy = false) {
> @@ -3703,7 +3720,7 @@ static void TryConstructorInitialization
> // subsumed by the initialization.
> bool HadMultipleCandidates = (CandidateSet.size() > 1);
> Sequence.AddConstructorInitializationStep(
> - Best->FoundDecl, CtorDecl, DestType, HadMultipleCandidates,
> + Best->FoundDecl, CtorDecl, DestArrayType, HadMultipleCandidates,
> IsListInit | IsInitListCopy, AsInitializerList);
> }
>
> @@ -3871,8 +3888,9 @@ static void TryListInitialization(Sema &
> S.IsDerivedFrom(InitList->getLocStart(), InitType, DestType)) {
> Expr *InitListAsExpr = InitList;
> TryConstructorInitialization(S, Entity, Kind, InitListAsExpr,
> DestType,
> - Sequence, /*InitListSyntax*/ false,
> - /*IsInitListCopy*/ true);
> + DestType, Sequence,
> + /*InitListSyntax*/false,
> + /*IsInitListCopy*/true);
> return;
> }
> }
> @@ -3927,7 +3945,7 @@ static void TryListInitialization(Sema &
> // - Otherwise, if T is a class type, constructors are considered.
> Expr *InitListAsExpr = InitList;
> TryConstructorInitialization(S, Entity, Kind, InitListAsExpr,
> DestType,
> - Sequence, /*InitListSyntax*/ true);
> + DestType, Sequence,
> /*InitListSyntax*/true);
> } else
>
> Sequence.SetFailed(InitializationSequence::FK_InitListBadDestinationType);
> return;
> @@ -4580,8 +4598,10 @@ static void TryValueInitialization(Sema
> MultiExprArg Args(&InitListAsExpr, InitList ? 1 : 0);
> bool InitListSyntax = InitList;
>
> - return TryConstructorInitialization(S, Entity, Kind, Args, T,
> Sequence,
> - InitListSyntax);
> + // FIXME: Instead of creating a CXXConstructExpr of non-array type
> here,
> + // wrap a class-typed CXXConstructExpr in an ArrayInitLoopExpr.
> + return TryConstructorInitialization(
> + S, Entity, Kind, Args, T, Entity.getType(), Sequence,
> InitListSyntax);
> }
> }
>
> @@ -4604,7 +4624,8 @@ static void TryDefaultInitialization(Sem
> // constructor for T is called (and the initialization is
> ill-formed if
> // T has no accessible default constructor);
> if (DestType->isRecordType() && S.getLangOpts().CPlusPlus) {
> - TryConstructorInitialization(S, Entity, Kind, None, DestType,
> Sequence);
> + TryConstructorInitialization(S, Entity, Kind, None, DestType,
> + Entity.getType(), Sequence);
> return;
> }
>
> @@ -5030,6 +5051,42 @@ static bool isExprAnUnaddressableFunctio
> cast<FunctionDecl>(DRE->getDecl()));
> }
>
> +/// Determine whether we can perform an elementwise array copy for this
> kind
> +/// of entity.
> +static bool canPerformArrayCopy(const InitializedEntity &Entity) {
> + switch (Entity.getKind()) {
> + case InitializedEntity::EK_LambdaCapture:
> + // C++ [expr.prim.lambda]p24:
> + // For array members, the array elements are direct-initialized in
> + // increasing subscript order.
> + return true;
> +
> + case InitializedEntity::EK_Variable:
> + // C++ [dcl.decomp]p1:
> + // [...] each element is copy-initialized or direct-initialized
> from the
> + // corresponding element of the assignment-expression [...]
> + return isa<DecompositionDecl>(Entity.getDecl());
> +
> + case InitializedEntity::EK_Member:
> + // C++ [class.copy.ctor]p14:
> + // - if the member is an array, each element is direct-initialized
> with
> + // the corresponding subobject of x
> + return Entity.isImplicitMemberInitializer();
> +
> + case InitializedEntity::EK_ArrayElement:
> + // All the above cases are intended to apply recursively, even though
> none
> + // of them actually say that.
> + if (auto *E = Entity.getParent())
> + return canPerformArrayCopy(*E);
> + break;
> +
> + default:
> + break;
> + }
> +
> + return false;
> +}
> +
> void InitializationSequence::InitializeFrom(Sema &S,
> const InitializedEntity
> &Entity,
> const InitializationKind
> &Kind,
> @@ -5152,6 +5209,34 @@ void InitializationSequence::InitializeF
> }
> }
>
> + // Some kinds of initialization permit an array to be initialized from
> + // another array of the same type, and perform elementwise
> initialization.
> + if (Initializer && isa<ConstantArrayType>(DestAT) &&
> + S.Context.hasSameUnqualifiedType(Initializer->getType(),
> + Entity.getType()) &&
> + canPerformArrayCopy(Entity)) {
> + // If source is a prvalue, use it directly.
> + if (Initializer->getValueKind() == VK_RValue) {
> + // FIXME: This produces a bogus extwarn
> + AddArrayInitStep(DestType);
> + return;
> + }
> +
> + // Emit element-at-a-time copy loop.
> + InitializedEntity Element =
> + InitializedEntity::InitializeElement(S.Context, 0, Entity);
> + QualType InitEltT =
> +
> Context.getAsArrayType(Initializer->getType())->getElementType();
> + OpaqueValueExpr OVE(SourceLocation(), InitEltT,
> + Initializer->getValueKind());
> + Expr *OVEAsExpr = &OVE;
> + InitializeFrom(S, Element, Kind, OVEAsExpr, TopLevelOfInitList,
> + TreatUnavailableAsInvalid);
> + if (!Failed())
> + AddArrayInitLoopStep(Entity.getType(), InitEltT);
> + return;
> + }
> +
> // Note: as an GNU C extension, we allow initialization of an
> // array from a compound literal that creates an array of the same
> // type, so long as the initializer has no side effects.
> @@ -5225,7 +5310,7 @@ void InitializationSequence::InitializeF
> (Context.hasSameUnqualifiedType(SourceType, DestType) ||
> S.IsDerivedFrom(Initializer->getLocStart(), SourceType,
> DestType))))
> TryConstructorInitialization(S, Entity, Kind, Args,
> - DestType, *this);
> + DestType, DestType, *this);
> // - Otherwise (i.e., for the remaining copy-initialization
> cases),
> // user-defined conversion sequences that can convert from the
> source
> // type to the destination type or (when a conversion function
> is
> @@ -5842,7 +5927,7 @@ PerformConstructorInitialization(Sema &S
> // If the entity allows NRVO, mark the construction as elidable
> // unconditionally.
> if (Entity.allowsNRVO())
> - CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(),
> + CurInit = S.BuildCXXConstructExpr(Loc, Step.Type,
> Step.Function.FoundDecl,
> Constructor, /*Elidable=*/true,
> ConstructorArgs,
> @@ -5853,7 +5938,7 @@ PerformConstructorInitialization(Sema &S
> ConstructKind,
> ParenOrBraceRange);
> else
> - CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(),
> + CurInit = S.BuildCXXConstructExpr(Loc, Step.Type,
> Step.Function.FoundDecl,
> Constructor,
> ConstructorArgs,
> @@ -6403,6 +6488,7 @@ InitializationSequence::Perform(Sema &S,
> Entity.getType();
>
> ExprResult CurInit((Expr *)nullptr);
> + SmallVector<Expr*, 4> ArrayLoopCommonExprs;
>
> // For initialization steps that start with a single initializer,
> // grab the only argument out the Args and place it into the "current"
> @@ -6430,6 +6516,8 @@ InitializationSequence::Perform(Sema &S,
> case SK_CAssignment:
> case SK_StringInit:
> case SK_ObjCObjectConversion:
> + case SK_ArrayLoopIndex:
> + case SK_ArrayLoopInit:
> case SK_ArrayInit:
> case SK_ParenthesizedArrayInit:
> case SK_PassByIndirectCopyRestore:
> @@ -6813,13 +6901,15 @@ InitializationSequence::Perform(Sema &S,
> bool UseTemporary = Entity.getType()->isReferenceType();
> bool IsStdInitListInit =
> Step->Kind == SK_StdInitializerListConstructorCall;
> + Expr *Source = CurInit.get();
> CurInit = PerformConstructorInitialization(
> - S, UseTemporary ? TempEntity : Entity, Kind, Args, *Step,
> + S, UseTemporary ? TempEntity : Entity, Kind,
> + Source ? MultiExprArg(Source) : Args, *Step,
> ConstructorInitRequiresZeroInit,
> - /*IsListInitialization*/IsStdInitListInit,
> - /*IsStdInitListInitialization*/IsStdInitListInit,
> - /*LBraceLoc*/SourceLocation(),
> - /*RBraceLoc*/SourceLocation());
> + /*IsListInitialization*/ IsStdInitListInit,
> + /*IsStdInitListInitialization*/ IsStdInitListInit,
> + /*LBraceLoc*/ SourceLocation(),
> + /*RBraceLoc*/ SourceLocation());
> break;
> }
>
> @@ -6898,6 +6988,28 @@ InitializationSequence::Perform(Sema &S,
> CurInit.get()->getValueKind());
> break;
>
> + case SK_ArrayLoopIndex: {
> + Expr *Cur = CurInit.get();
> + Expr *BaseExpr = new (S.Context)
> + OpaqueValueExpr(Cur->getExprLoc(), Cur->getType(),
> + Cur->getValueKind(), Cur->getObjectKind(), Cur);
> + Expr *IndexExpr =
> + new (S.Context) ArrayInitIndexExpr(S.Context.getSizeType());
> + CurInit = S.CreateBuiltinArraySubscriptExpr(
> + BaseExpr, Kind.getLocation(), IndexExpr, Kind.getLocation());
> + ArrayLoopCommonExprs.push_back(BaseExpr);
> + break;
> + }
> +
> + case SK_ArrayLoopInit: {
> + assert(!ArrayLoopCommonExprs.empty() &&
> + "mismatched SK_ArrayLoopIndex and SK_ArrayLoopInit");
> + Expr *Common = ArrayLoopCommonExprs.pop_back_val();
> + CurInit = new (S.Context) ArrayInitLoopExpr(Step->Type, Common,
> + CurInit.get());
> + break;
> + }
> +
> case SK_ArrayInit:
> // Okay: we checked everything before creating this step. Note that
> // this is a GNU extension.
> @@ -7851,6 +7963,14 @@ void InitializationSequence::dump(raw_os
> OS << "Objective-C object conversion";
> break;
>
> + case SK_ArrayLoopIndex:
> + OS << "indexing for array initialization loop";
> + break;
> +
> + case SK_ArrayLoopInit:
> + OS << "array initialization loop";
> + break;
> +
> case SK_ArrayInit:
> OS << "array initialization";
> break;
>
> Modified: cfe/trunk/lib/Sema/TreeTransform.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=289413&r1=289412&r2=289413&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/TreeTransform.h (original)
> +++ cfe/trunk/lib/Sema/TreeTransform.h Sun Dec 11 20:53:20 2016
> @@ -3221,6 +3221,9 @@ ExprResult TreeTransform<Derived>::Trans
> if (ExprWithCleanups *ExprTemp = dyn_cast<ExprWithCleanups>(Init))
> Init = ExprTemp->getSubExpr();
>
> + if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Init))
> + Init = AIL->getCommonExpr();
> +
> if (MaterializeTemporaryExpr *MTE =
> dyn_cast<MaterializeTemporaryExpr>(Init))
> Init = MTE->GetTemporaryExpr();
>
> @@ -9045,6 +9048,20 @@ TreeTransform<Derived>::TransformNoInitE
> return ExprError();
> }
>
> +template<typename Derived>
> +ExprResult
> +TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
> + llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
> + return ExprError();
> +}
> +
> +template<typename Derived>
> +ExprResult
> +TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr
> *E) {
> + llvm_unreachable("Unexpected ArrayInitIndexExpr outside of
> initializer");
> + return ExprError();
> +}
> +
> template<typename Derived>
> ExprResult
> TreeTransform<Derived>::TransformImplicitValueInitExpr(
>
> Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=289413&r1=289412&r2=289413&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Sun Dec 11 20:53:20 2016
> @@ -845,6 +845,16 @@ void ASTStmtReader::VisitNoInitExpr(NoIn
> VisitExpr(E);
> }
>
> +void ASTStmtReader::VisitArrayInitLoopExpr(ArrayInitLoopExpr *E) {
> + VisitExpr(E);
> + E->SubExprs[0] = Reader.ReadSubExpr();
> + E->SubExprs[1] = Reader.ReadSubExpr();
> +}
> +
> +void ASTStmtReader::VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
> + VisitExpr(E);
> +}
> +
> void ASTStmtReader::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
> VisitExpr(E);
> }
> @@ -3231,6 +3241,14 @@ Stmt *ASTReader::ReadStmtFromStream(Modu
> S = new (Context) NoInitExpr(Empty);
> break;
>
> + case EXPR_ARRAY_INIT_LOOP:
> + S = new (Context) ArrayInitLoopExpr(Empty);
> + break;
> +
> + case EXPR_ARRAY_INIT_INDEX:
> + S = new (Context) ArrayInitIndexExpr(Empty);
> + break;
> +
> case EXPR_VA_ARG:
> S = new (Context) VAArgExpr(Empty);
> break;
>
> Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=289413&r1=289412&r2=289413&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Sun Dec 11 20:53:20 2016
> @@ -792,6 +792,18 @@ void ASTStmtWriter::VisitNoInitExpr(NoIn
> Code = serialization::EXPR_NO_INIT;
> }
>
> +void ASTStmtWriter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *E) {
> + VisitExpr(E);
> + Record.AddStmt(E->SubExprs[0]);
> + Record.AddStmt(E->SubExprs[1]);
> + Code = serialization::EXPR_ARRAY_INIT_LOOP;
> +}
> +
> +void ASTStmtWriter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
> + VisitExpr(E);
> + Code = serialization::EXPR_ARRAY_INIT_INDEX;
> +}
> +
> void ASTStmtWriter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
> VisitExpr(E);
> Code = serialization::EXPR_IMPLICIT_VALUE_INIT;
>
> Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=289413&r1=289412&r2=289413&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
> +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Sun Dec 11 20:53:20
> 2016
> @@ -905,6 +905,8 @@ void ExprEngine::Visit(const Stmt *S, Ex
> // Cases not handled yet; but will handle some day.
> case Stmt::DesignatedInitExprClass:
> case Stmt::DesignatedInitUpdateExprClass:
> + case Stmt::ArrayInitLoopExprClass:
> + case Stmt::ArrayInitIndexExprClass:
> case Stmt::ExtVectorElementExprClass:
> case Stmt::ImaginaryLiteralClass:
> case Stmt::ObjCAtCatchStmtClass:
>
> Modified: cfe/trunk/tools/libclang/CXCursor.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.cpp?rev=289413&r1=289412&r2=289413&view=diff
>
> ==============================================================================
> --- cfe/trunk/tools/libclang/CXCursor.cpp (original)
> +++ cfe/trunk/tools/libclang/CXCursor.cpp Sun Dec 11 20:53:20 2016
> @@ -243,6 +243,8 @@ CXCursor cxcursor::MakeCXCursor(const St
> case Stmt::ChooseExprClass:
> case Stmt::DesignatedInitExprClass:
> case Stmt::DesignatedInitUpdateExprClass:
> + case Stmt::ArrayInitLoopExprClass:
> + case Stmt::ArrayInitIndexExprClass:
> case Stmt::ExprWithCleanupsClass:
> case Stmt::ExpressionTraitExprClass:
> case Stmt::ExtVectorElementExprClass:
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
--
Mike
Sent from phone
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20161213/340c5866/attachment-0001.html>
More information about the cfe-commits
mailing list