Author: rsmith
Date: Sun Dec 11 20:53:20 2016
New Revision: 289413
URL: http://llvm.org/viewvc/llvm-project?rev=289413=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=289412=289413=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(SubExprs[0]);
+ }
+
+ /// Get the initializer to use for each array element.
+ Expr *getSubExpr() const { return cast(SubExprs[1]); }
+
+ llvm::APInt getArraySize() const {
+return cast(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