@@ -6610,6 +6610,275 @@ class TypoExpr : public Expr {
66106610
66116611};
66126612
6613+ // / This class represents BOTH the OpenMP Array Section and OpenACC 'subarray',
6614+ // / with a boolean differentiator.
6615+ // / OpenMP 5.0 [2.1.5, Array Sections].
6616+ // / To specify an array section in an OpenMP construct, array subscript
6617+ // / expressions are extended with the following syntax:
6618+ // / \code
6619+ // / [ lower-bound : length : stride ]
6620+ // / [ lower-bound : length : ]
6621+ // / [ lower-bound : length ]
6622+ // / [ lower-bound : : stride ]
6623+ // / [ lower-bound : : ]
6624+ // / [ lower-bound : ]
6625+ // / [ : length : stride ]
6626+ // / [ : length : ]
6627+ // / [ : length ]
6628+ // / [ : : stride ]
6629+ // / [ : : ]
6630+ // / [ : ]
6631+ // / \endcode
6632+ // / The array section must be a subset of the original array.
6633+ // / Array sections are allowed on multidimensional arrays. Base language array
6634+ // / subscript expressions can be used to specify length-one dimensions of
6635+ // / multidimensional array sections.
6636+ // / Each of the lower-bound, length, and stride expressions if specified must be
6637+ // / an integral type expressions of the base language. When evaluated
6638+ // / they represent a set of integer values as follows:
6639+ // / \code
6640+ // / { lower-bound, lower-bound + stride, lower-bound + 2 * stride,... ,
6641+ // / lower-bound + ((length - 1) * stride) }
6642+ // / \endcode
6643+ // / The lower-bound and length must evaluate to non-negative integers.
6644+ // / The stride must evaluate to a positive integer.
6645+ // / When the size of the array dimension is not known, the length must be
6646+ // / specified explicitly.
6647+ // / When the stride is absent it defaults to 1.
6648+ // / When the length is absent it defaults to ⌈(size − lower-bound)/stride⌉,
6649+ // / where size is the size of the array dimension. When the lower-bound is
6650+ // / absent it defaults to 0.
6651+ // /
6652+ // /
6653+ // / OpenACC 3.3 [2.7.1 Data Specification in Data Clauses]
6654+ // / In C and C++, a subarray is an array name followed by an extended array
6655+ // / range specification in brackets, with start and length, such as
6656+ // /
6657+ // / AA[2:n]
6658+ // /
6659+ // / If the lower bound is missing, zero is used. If the length is missing and
6660+ // / the array has known size, the size of the array is used; otherwise the
6661+ // / length is required. The subarray AA[2:n] means elements AA[2], AA[3], . . .
6662+ // / , AA[2+n-1]. In C and C++, a two dimensional array may be declared in at
6663+ // / least four ways:
6664+ // /
6665+ // / -Statically-sized array: float AA[100][200];
6666+ // / -Pointer to statically sized rows: typedef float row[200]; row* BB;
6667+ // / -Statically-sized array of pointers: float* CC[200];
6668+ // / -Pointer to pointers: float** DD;
6669+ // /
6670+ // / Each dimension may be statically sized, or a pointer to dynamically
6671+ // / allocated memory. Each of these may be included in a data clause using
6672+ // / subarray notation to specify a rectangular array:
6673+ // /
6674+ // / -AA[2:n][0:200]
6675+ // / -BB[2:n][0:m]
6676+ // / -CC[2:n][0:m]
6677+ // / -DD[2:n][0:m]
6678+ // /
6679+ // / Multidimensional rectangular subarrays in C and C++ may be specified for any
6680+ // / array with any combination of statically-sized or dynamically-allocated
6681+ // / dimensions. For statically sized dimensions, all dimensions except the first
6682+ // / must specify the whole extent to preserve the contiguous data restriction,
6683+ // / discussed below. For dynamically allocated dimensions, the implementation
6684+ // / will allocate pointers in device memory corresponding to the pointers in
6685+ // / local memory and will fill in those pointers as appropriate.
6686+ // /
6687+ // / In Fortran, a subarray is an array name followed by a comma-separated list
6688+ // / of range specifications in parentheses, with lower and upper bound
6689+ // / subscripts, such as
6690+ // /
6691+ // / arr(1:high,low:100)
6692+ // /
6693+ // / If either the lower or upper bounds are missing, the declared or allocated
6694+ // / bounds of the array, if known, are used. All dimensions except the last must
6695+ // / specify the whole extent, to preserve the contiguous data restriction,
6696+ // / discussed below.
6697+ // /
6698+ // / Restrictions
6699+ // /
6700+ // / -In Fortran, the upper bound for the last dimension of an assumed-size dummy
6701+ // / array must be specified.
6702+ // /
6703+ // / -In C and C++, the length for dynamically allocated dimensions of an array
6704+ // / must be explicitly specified.
6705+ // /
6706+ // / -In C and C++, modifying pointers in pointer arrays during the data
6707+ // / lifetime, either on the host or on the device, may result in undefined
6708+ // / behavior.
6709+ // /
6710+ // / -If a subarray appears in a data clause, the implementation may choose to
6711+ // / allocate memory for only that subarray on the accelerator.
6712+ // /
6713+ // / -In Fortran, array pointers may appear, but pointer association is not
6714+ // / preserved in device memory.
6715+ // /
6716+ // / -Any array or subarray in a data clause, including Fortran array pointers,
6717+ // / must be a contiguous section of memory, except for dynamic multidimensional
6718+ // / C arrays.
6719+ // /
6720+ // / -In C and C++, if a variable or array of composite type appears, all the
6721+ // / data members of the struct or class are allocated and copied, as
6722+ // / appropriate. If a composite member is a pointer type, the data addressed by
6723+ // / that pointer are not implicitly copied.
6724+ // /
6725+ // / -In Fortran, if a variable or array of composite type appears, all the
6726+ // / members of that derived type are allocated and copied, as appropriate. If
6727+ // / any member has the allocatable or pointer attribute, the data accessed
6728+ // / through that member are not copied.
6729+ // /
6730+ // / -If an expression is used in a subscript or subarray expression in a clause
6731+ // / on a data construct, the same value is used when copying data at the end of
6732+ // / the data region, even if the values of variables in the expression change
6733+ // / during the data region.
6734+ class ArraySectionExpr : public Expr {
6735+ friend class ASTStmtReader ;
6736+ friend class ASTStmtWriter ;
6737+
6738+ public:
6739+ enum ArraySectionType { OMPArraySection, OpenACCArraySection };
6740+
6741+ private:
6742+ enum {
6743+ BASE,
6744+ LOWER_BOUND,
6745+ LENGTH,
6746+ STRIDE,
6747+ END_EXPR,
6748+ OPENACC_END_EXPR = STRIDE
6749+ };
6750+
6751+ ArraySectionType ASType = OMPArraySection;
6752+ Stmt *SubExprs[END_EXPR] = {nullptr };
6753+ SourceLocation ColonLocFirst;
6754+ SourceLocation ColonLocSecond;
6755+ SourceLocation RBracketLoc;
6756+
6757+ public:
6758+ // Constructor for OMP array sections, which include a 'stride'.
6759+ ArraySectionExpr (Expr *Base, Expr *LowerBound, Expr *Length, Expr *Stride,
6760+ QualType Type, ExprValueKind VK, ExprObjectKind OK,
6761+ SourceLocation ColonLocFirst, SourceLocation ColonLocSecond,
6762+ SourceLocation RBracketLoc)
6763+ : Expr(ArraySectionExprClass, Type, VK, OK), ASType(OMPArraySection),
6764+ ColonLocFirst (ColonLocFirst), ColonLocSecond(ColonLocSecond),
6765+ RBracketLoc(RBracketLoc) {
6766+ setBase (Base);
6767+ setLowerBound (LowerBound);
6768+ setLength (Length);
6769+ setStride (Stride);
6770+ setDependence (computeDependence (this ));
6771+ }
6772+
6773+ // Constructor for OpenACC sub-arrays, which do not permit a 'stride'.
6774+ ArraySectionExpr (Expr *Base, Expr *LowerBound, Expr *Length, QualType Type,
6775+ ExprValueKind VK, ExprObjectKind OK, SourceLocation ColonLoc,
6776+ SourceLocation RBracketLoc)
6777+ : Expr(ArraySectionExprClass, Type, VK, OK), ASType(OpenACCArraySection),
6778+ ColonLocFirst(ColonLoc), RBracketLoc(RBracketLoc) {
6779+ setBase (Base);
6780+ setLowerBound (LowerBound);
6781+ setLength (Length);
6782+ setDependence (computeDependence (this ));
6783+ }
6784+
6785+ // / Create an empty array section expression.
6786+ explicit ArraySectionExpr (EmptyShell Shell)
6787+ : Expr(ArraySectionExprClass, Shell) {}
6788+
6789+ // / Return original type of the base expression for array section.
6790+ static QualType getBaseOriginalType (const Expr *Base);
6791+
6792+ static bool classof (const Stmt *T) {
6793+ return T->getStmtClass () == ArraySectionExprClass;
6794+ }
6795+
6796+ bool isOMPArraySection () const { return ASType == OMPArraySection; }
6797+ bool isOpenACCArraySection () const { return ASType == OpenACCArraySection; }
6798+
6799+ // / Get base of the array section.
6800+ Expr *getBase () { return cast<Expr>(SubExprs[BASE]); }
6801+ const Expr *getBase () const { return cast<Expr>(SubExprs[BASE]); }
6802+
6803+ // / Get lower bound of array section.
6804+ Expr *getLowerBound () { return cast_or_null<Expr>(SubExprs[LOWER_BOUND]); }
6805+ const Expr *getLowerBound () const {
6806+ return cast_or_null<Expr>(SubExprs[LOWER_BOUND]);
6807+ }
6808+
6809+ // / Get length of array section.
6810+ Expr *getLength () { return cast_or_null<Expr>(SubExprs[LENGTH]); }
6811+ const Expr *getLength () const { return cast_or_null<Expr>(SubExprs[LENGTH]); }
6812+
6813+ // / Get stride of array section.
6814+ Expr *getStride () {
6815+ assert (ASType != OpenACCArraySection &&
6816+ " Stride not valid in OpenACC subarrays" );
6817+ return cast_or_null<Expr>(SubExprs[STRIDE]);
6818+ }
6819+
6820+ const Expr *getStride () const {
6821+ assert (ASType != OpenACCArraySection &&
6822+ " Stride not valid in OpenACC subarrays" );
6823+ return cast_or_null<Expr>(SubExprs[STRIDE]);
6824+ }
6825+
6826+ SourceLocation getBeginLoc () const LLVM_READONLY {
6827+ return getBase ()->getBeginLoc ();
6828+ }
6829+ SourceLocation getEndLoc () const LLVM_READONLY { return RBracketLoc; }
6830+
6831+ SourceLocation getColonLocFirst () const { return ColonLocFirst; }
6832+ SourceLocation getColonLocSecond () const {
6833+ assert (ASType != OpenACCArraySection &&
6834+ " second colon for stride not valid in OpenACC subarrays" );
6835+ return ColonLocSecond;
6836+ }
6837+ SourceLocation getRBracketLoc () const { return RBracketLoc; }
6838+
6839+ SourceLocation getExprLoc () const LLVM_READONLY {
6840+ return getBase ()->getExprLoc ();
6841+ }
6842+
6843+ child_range children () {
6844+ return child_range (
6845+ &SubExprs[BASE],
6846+ &SubExprs[ASType == OMPArraySection ? END_EXPR : OPENACC_END_EXPR]);
6847+ }
6848+
6849+ const_child_range children () const {
6850+ return const_child_range (
6851+ &SubExprs[BASE],
6852+ &SubExprs[ASType == OMPArraySection ? END_EXPR : OPENACC_END_EXPR]);
6853+ }
6854+
6855+ private:
6856+ // / Set base of the array section.
6857+ void setBase (Expr *E) { SubExprs[BASE] = E; }
6858+
6859+ // / Set lower bound of the array section.
6860+ void setLowerBound (Expr *E) { SubExprs[LOWER_BOUND] = E; }
6861+
6862+ // / Set length of the array section.
6863+ void setLength (Expr *E) { SubExprs[LENGTH] = E; }
6864+
6865+ // / Set length of the array section.
6866+ void setStride (Expr *E) {
6867+ assert (ASType != OpenACCArraySection &&
6868+ " Stride not valid in OpenACC subarrays" );
6869+ SubExprs[STRIDE] = E;
6870+ }
6871+
6872+ void setColonLocFirst (SourceLocation L) { ColonLocFirst = L; }
6873+
6874+ void setColonLocSecond (SourceLocation L) {
6875+ assert (ASType != OpenACCArraySection &&
6876+ " second colon for stride not valid in OpenACC subarrays" );
6877+ ColonLocSecond = L;
6878+ }
6879+ void setRBracketLoc (SourceLocation L) { RBracketLoc = L; }
6880+ };
6881+
66136882// / Frontend produces RecoveryExprs on semantic errors that prevent creating
66146883// / other well-formed expressions. E.g. when type-checking of a binary operator
66156884// / fails, we cannot produce a BinaryOperator expression. Instead, we can choose
0 commit comments