r289413 - Add two new AST nodes to represent initialization of an array in terms of

Reid Kleckner via cfe-commits cfe-commits at lists.llvm.org
Tue Dec 13 11:43:28 PST 2016


It's probably this change:

$ "C:/src/llvm/build_x86/./bin/clang.EXE" "-cc1" "-internal-isystem"
"C:\src\llvm\build_x86\bin\..\lib\clang\4.0.0\include" "-nostdsysteminc"
"-fsyntax-only" "-Wno-everything" "-Wobjc-literal-compare" "-Dnil=(id)0"
"-verify" "C:\src\llvm\tools\clang\test\SemaObjC\objc-literal-comparison.m"
# command stderr:
Assertion failed: (PtrWord & ~PointerBitMask) == 0 && "Pointer is not
sufficiently aligned", file C:\src\llvm\include\llvm/ADT/PointerIntPair.h,
line 160
#0 0x02519d87 HandleAbort c:\src\llvm\lib\support\windows\signals.inc:404:0
#1 0x04061684 raise
d:\th\minkernel\crts\ucrt\src\appcrt\misc\signal.cpp:516:0
#2 0x0403a662 abort
d:\th\minkernel\crts\ucrt\src\appcrt\startup\abort.cpp:64:0
#3 0x04039381 common_assert_to_stderr<wchar_t>
d:\th\minkernel\crts\ucrt\src\appcrt\startup\assert.cpp:149:0
#4 0x04039ab0 _wassert
d:\th\minkernel\crts\ucrt\src\appcrt\startup\assert.cpp:404:0
#5 0x03e2737c `anonymous
namespace'::SpeculativeEvaluationRAII::SpeculativeEvaluationRAII
c:\src\llvm\tools\clang\lib\ast\exprconstant.cpp:897:0
#6 0x03e86937 `anonymous
namespace'::DataRecursiveIntBinOpEvaluator::Job::startSpeculativeEval
c:\src\llvm\tools\clang\lib\ast\exprconstant.cpp:7468:0
#7 0x03e85e36 `anonymous
namespace'::DataRecursiveIntBinOpEvaluator::process
c:\src\llvm\tools\clang\lib\ast\exprconstant.cpp:7725:0
#8 0x03e3418c `anonymous
namespace'::DataRecursiveIntBinOpEvaluator::Traverse
c:\src\llvm\tools\clang\lib\ast\exprconstant.cpp:7501:0
#9 0x03e455c9 `anonymous namespace'::IntExprEvaluator::VisitBinaryOperator
c:\src\llvm\tools\clang\lib\ast\exprconstant.cpp:7773:0
#10 0x03e375da clang::StmtVisitorBase<struct clang::make_const_ptr,class
`anonymous namespace'::IntExprEvaluator,bool>::Visit(class clang::Stmt
const *) c:\src\llvm\tools\clang\include\clang\ast\stmtvisitor.h:47:0
#11 0x03e2bb5e Evaluate
c:\src\llvm\tools\clang\lib\ast\exprconstant.cpp:9303:0
#12 0x03e2cc01 EvaluateAsRValue
c:\src\llvm\tools\clang\lib\ast\exprconstant.cpp:9392:0
#13 0x03e2da6f clang::Expr::EvaluateForOverflow(class clang::ASTContext
const &)const  c:\src\llvm\tools\clang\lib\ast\exprconstant.cpp:9571:0
#14 0x039a63e1 clang::Sema::CheckForIntOverflow(class clang::Expr *)
c:\src\llvm\tools\clang\lib\sema\semachecking.cpp:9706:0
#15 0x039a5ebb clang::Sema::CheckCompletedExpr(class clang::Expr *,class
clang::SourceLocation,bool)
c:\src\llvm\tools\clang\lib\sema\semachecking.cpp:10212:0
#16 0x035ff150 clang::Sema::ActOnFinishFullExpr(class clang::Expr *,class
clang::SourceLocation,bool,bool,bool)
c:\src\llvm\tools\clang\lib\sema\semaexprcxx.cpp:7399:0
#17 0x037008a9 clang::Sema::ActOnCondition(class clang::Scope *,class
clang::SourceLocation,class clang::Expr *,enum clang::Sema::ConditionKind)
c:\src\llvm\tools\clang\lib\sema\semaexpr.cpp:14670:0
#18 0x03312c61 clang::Parser::ParseParenExprOrCondition(class
clang::ActionResult<class clang::Stmt *,1> *,class
clang::Sema::ConditionResult &,class clang::SourceLocation,enum
clang::Sema::ConditionKind)
c:\src\llvm\tools\clang\lib\parse\parsestmt.cpp:1072:0
#19 0x03311f8e clang::Parser::ParseIfStatement(class clang::SourceLocation
*) c:\src\llvm\tools\clang\lib\parse\parsestmt.cpp:1146:0
#20 0x033143e2
clang::Parser::ParseStatementOrDeclarationAfterAttributes(class
llvm::SmallVector<class clang::Stmt *,32> &,enum
clang::Parser::AllowedContsructsKind,class clang::SourceLocation *,struct
clang::Parser::ParsedAttributesWithRange &)
c:\src\llvm\tools\clang\lib\parse\parsestmt.cpp:239:0
#21 0x03314045 clang::Parser::ParseStatementOrDeclaration(class
llvm::SmallVector<class clang::Stmt *,32> &,enum
clang::Parser::AllowedContsructsKind,class clang::SourceLocation *)
c:\src\llvm\tools\clang\lib\parse\parsestmt.cpp:113:0
#22 0x0330f906 clang::Parser::ParseCompoundStatementBody(bool)
c:\src\llvm\tools\clang\lib\parse\parsestmt.cpp:987:0
#23 0x0331190d clang::Parser::ParseFunctionStatementBody(class clang::Decl
*,class clang::Parser::ParseScope &)
c:\src\llvm\tools\clang\lib\parse\parsestmt.cpp:1954:0
#24 0x032b3abe clang::Parser::ParseFunctionDefinition(class
clang::ParsingDeclarator &,struct clang::Parser::ParsedTemplateInfo const
&,class clang::Parser::LateParsedAttrList *)
c:\src\llvm\tools\clang\lib\parse\parser.cpp:1216:0
#25 0x032cbf4d clang::Parser::ParseDeclGroup(class clang::ParsingDeclSpec
&,unsigned int,class clang::SourceLocation *,struct
clang::Parser::ForRangeInit *)
c:\src\llvm\tools\clang\lib\parse\parsedecl.cpp:1814:0
#26 0x032b255a clang::Parser::ParseDeclOrFunctionDefInternal(struct
clang::Parser::ParsedAttributesWithRange &,class clang::ParsingDeclSpec
&,enum clang::AccessSpecifier)
c:\src\llvm\tools\clang\lib\parse\parser.cpp:984:0
#27 0x032b26af clang::Parser::ParseDeclarationOrFunctionDefinition(struct
clang::Parser::ParsedAttributesWithRange &,class clang::ParsingDeclSpec
*,enum clang::AccessSpecifier)
c:\src\llvm\tools\clang\lib\parse\parser.cpp:999:0
#28 0x032b2e46 clang::Parser::ParseExternalDeclaration(struct
clang::Parser::ParsedAttributesWithRange &,class clang::ParsingDeclSpec *)
c:\src\llvm\tools\clang\lib\parse\parser.cpp:851:0
#29 0x032b5600 clang::Parser::ParseTopLevelDecl(class
clang::OpaquePtr<class clang::DeclGroupRef> &)
c:\src\llvm\tools\clang\lib\parse\parser.cpp:628:0
#30 0x032aec06 clang::ParseAST(class clang::Sema &,bool,bool)
c:\src\llvm\tools\clang\lib\parse\parseast.cpp:147:0
#31 0x02aec5dd clang::ASTFrontendAction::ExecuteAction(void)
c:\src\llvm\tools\clang\lib\frontend\frontendaction.cpp:558:0
#32 0x02aec45b clang::FrontendAction::Execute(void)
c:\src\llvm\tools\clang\lib\frontend\frontendaction.cpp:463:0
#33 0x02abd7d6 clang::CompilerInstance::ExecuteAction(class
clang::FrontendAction &)
c:\src\llvm\tools\clang\lib\frontend\compilerinstance.cpp:931:0
#34 0x02b652ab clang::ExecuteCompilerInvocation(class
clang::CompilerInstance *)
c:\src\llvm\tools\clang\lib\frontendtool\executecompilerinvocation.cpp:249:0
#35 0x012eca3b cc1_main(class llvm::ArrayRef<char const *>,char const
*,void *) c:\src\llvm\tools\clang\tools\driver\cc1_main.cpp:221:0
#36 0x012e720a ExecuteCC1Tool
c:\src\llvm\tools\clang\tools\driver\driver.cpp:299:0
#37 0x012e9b6d main c:\src\llvm\tools\clang\tools\driver\driver.cpp:380:0
#38 0x03ffce5a _scrt_common_main_seh
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:253:0
#39 0x745138f4 (C:\Windows\SYSTEM32\KERNEL32.DLL+0x138f4)
#40 0x77705de3 (C:\Windows\SYSTEM32\ntdll.dll+0x65de3)
#41 0x77705dae (C:\Windows\SYSTEM32\ntdll.dll+0x65dae)


On Mon, Dec 12, 2016 at 4:20 PM, Richard Smith via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> On 12 December 2016 at 16:16, Mike Aizatsky <aizatsky at google.com> wrote:
>
>> 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.
>>
>
> Given that the code added here is not (yet) reachable, I'd be really
> surprised if this change is responsible. Can you get a proper backtrace
> from one of these crashes?
>
> 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\b
>> uild\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/l
>> lvm/projects/compiler-rt/lib/sanitizer_common/tests/sanitize
>> r_stacktrace_test.cc"
>> Assertion failed: (PtrWord & ~PointerBitMask) == 0 && "Pointer is not
>> sufficiently aligned", file C:\b\slave\sanitizer-windows\l
>> lvm\include\llvm/ADT/PointerIntPair.h, line 160
>>
>> Wrote crash dump file "C:\Users\buildbot\AppData\Loc
>> al\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()->getAsArrayTypeUnsa
>>> fe());
>>>    }
>>>
>>> +  /// \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/ASTDum
>>> per.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/ExprCl
>>> assification.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/ExprCo
>>> nstant.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->get
>>> Type()->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/Itaniu
>>> mMangle.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/StmtPr
>>> inter.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/StmtPr
>>> ofile.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/CG
>>> ExprAgg.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().getTypeSizeIn
>>> Chars(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/CG
>>> ExprScalar.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/Co
>>> deGenFunction.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/SemaE
>>> xceptionSpec.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/SemaI
>>> nit.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_InitListBadDe
>>> stinationType);
>>>      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())->getElementTy
>>> pe();
>>> +      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/TreeT
>>> ransform.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<MaterializeTemporaryE
>>> xpr>(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/Serializat
>>> ion/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/Serializat
>>> ion/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/StaticAnal
>>> yzer/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
>>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20161213/3e35ebb3/attachment-0001.html>


More information about the cfe-commits mailing list