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