|
17 | 17 | #include "clang/AST/Expr.h"
|
18 | 18 |
|
19 | 19 | namespace clang {
|
20 |
| -/// OpenMP 4.0 [2.4, Array Sections]. |
| 20 | +/// OpenMP 5.0 [2.1.5, Array Sections]. |
21 | 21 | /// To specify an array section in an OpenMP construct, array subscript
|
22 | 22 | /// expressions are extended with the following syntax:
|
23 | 23 | /// \code
|
| 24 | +/// [ lower-bound : length : stride ] |
| 25 | +/// [ lower-bound : length : ] |
24 | 26 | /// [ lower-bound : length ]
|
| 27 | +/// [ lower-bound : : stride ] |
| 28 | +/// [ lower-bound : : ] |
25 | 29 | /// [ lower-bound : ]
|
| 30 | +/// [ : length : stride ] |
| 31 | +/// [ : length : ] |
26 | 32 | /// [ : length ]
|
| 33 | +/// [ : : stride ] |
| 34 | +/// [ : : ] |
27 | 35 | /// [ : ]
|
28 | 36 | /// \endcode
|
29 | 37 | /// The array section must be a subset of the original array.
|
30 | 38 | /// Array sections are allowed on multidimensional arrays. Base language array
|
31 | 39 | /// subscript expressions can be used to specify length-one dimensions of
|
32 | 40 | /// multidimensional array sections.
|
33 |
| -/// The lower-bound and length are integral type expressions. When evaluated |
| 41 | +/// Each of the lower-bound, length, and stride expressions if specified must be |
| 42 | +/// an integral type expressions of the base language. When evaluated |
34 | 43 | /// they represent a set of integer values as follows:
|
35 | 44 | /// \code
|
36 |
| -/// { lower-bound, lower-bound + 1, lower-bound + 2,... , lower-bound + length - |
37 |
| -/// 1 } |
| 45 | +/// { lower-bound, lower-bound + stride, lower-bound + 2 * stride,... , |
| 46 | +/// lower-bound + ((length - 1) * stride) } |
38 | 47 | /// \endcode
|
39 | 48 | /// The lower-bound and length must evaluate to non-negative integers.
|
| 49 | +/// The stride must evaluate to a positive integer. |
40 | 50 | /// When the size of the array dimension is not known, the length must be
|
41 | 51 | /// specified explicitly.
|
42 |
| -/// When the length is absent, it defaults to the size of the array dimension |
43 |
| -/// minus the lower-bound. |
44 |
| -/// When the lower-bound is absent it defaults to 0. |
| 52 | +/// When the stride is absent it defaults to 1. |
| 53 | +/// When the length is absent it defaults to ⌈(size − lower-bound)/stride⌉, |
| 54 | +/// where size is the size of the array dimension. When the lower-bound is |
| 55 | +/// absent it defaults to 0. |
45 | 56 | class OMPArraySectionExpr : public Expr {
|
46 |
| - enum { BASE, LOWER_BOUND, LENGTH, END_EXPR }; |
| 57 | + enum { BASE, LOWER_BOUND, LENGTH, STRIDE, END_EXPR }; |
47 | 58 | Stmt *SubExprs[END_EXPR];
|
48 |
| - SourceLocation ColonLoc; |
| 59 | + SourceLocation ColonLocFirst; |
| 60 | + SourceLocation ColonLocSecond; |
49 | 61 | SourceLocation RBracketLoc;
|
50 | 62 |
|
51 | 63 | public:
|
52 |
| - OMPArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, QualType Type, |
53 |
| - ExprValueKind VK, ExprObjectKind OK, |
54 |
| - SourceLocation ColonLoc, SourceLocation RBracketLoc) |
55 |
| - : Expr(OMPArraySectionExprClass, Type, VK, OK), ColonLoc(ColonLoc), |
| 64 | + OMPArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, Expr *Stride, |
| 65 | + QualType Type, ExprValueKind VK, ExprObjectKind OK, |
| 66 | + SourceLocation ColonLocFirst, |
| 67 | + SourceLocation ColonLocSecond, SourceLocation RBracketLoc) |
| 68 | + : Expr(OMPArraySectionExprClass, Type, VK, OK), |
| 69 | + ColonLocFirst(ColonLocFirst), ColonLocSecond(ColonLocSecond), |
56 | 70 | RBracketLoc(RBracketLoc) {
|
57 | 71 | SubExprs[BASE] = Base;
|
58 | 72 | SubExprs[LOWER_BOUND] = LowerBound;
|
59 | 73 | SubExprs[LENGTH] = Length;
|
| 74 | + SubExprs[STRIDE] = Stride; |
60 | 75 | setDependence(computeDependence(this));
|
61 | 76 | }
|
62 | 77 |
|
@@ -89,13 +104,22 @@ class OMPArraySectionExpr : public Expr {
|
89 | 104 | /// Set length of the array section.
|
90 | 105 | void setLength(Expr *E) { SubExprs[LENGTH] = E; }
|
91 | 106 |
|
| 107 | + /// Get stride of array section. |
| 108 | + Expr *getStride() { return cast_or_null<Expr>(SubExprs[STRIDE]); } |
| 109 | + const Expr *getStride() const { return cast_or_null<Expr>(SubExprs[STRIDE]); } |
| 110 | + /// Set length of the array section. |
| 111 | + void setStride(Expr *E) { SubExprs[STRIDE] = E; } |
| 112 | + |
92 | 113 | SourceLocation getBeginLoc() const LLVM_READONLY {
|
93 | 114 | return getBase()->getBeginLoc();
|
94 | 115 | }
|
95 | 116 | SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; }
|
96 | 117 |
|
97 |
| - SourceLocation getColonLoc() const { return ColonLoc; } |
98 |
| - void setColonLoc(SourceLocation L) { ColonLoc = L; } |
| 118 | + SourceLocation getColonLocFirst() const { return ColonLocFirst; } |
| 119 | + void setColonLocFirst(SourceLocation L) { ColonLocFirst = L; } |
| 120 | + |
| 121 | + SourceLocation getColonLocSecond() const { return ColonLocSecond; } |
| 122 | + void setColonLocSecond(SourceLocation L) { ColonLocSecond = L; } |
99 | 123 |
|
100 | 124 | SourceLocation getRBracketLoc() const { return RBracketLoc; }
|
101 | 125 | void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
|
|
0 commit comments