@@ -6610,6 +6610,275 @@ class TypoExpr : public Expr {
6610
6610
6611
6611
};
6612
6612
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
+
6613
6882
// / Frontend produces RecoveryExprs on semantic errors that prevent creating
6614
6883
// / other well-formed expressions. E.g. when type-checking of a binary operator
6615
6884
// / fails, we cannot produce a BinaryOperator expression. Instead, we can choose
0 commit comments