1//===--- ExprOpenMP.h - Classes for representing expressions ----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the Expr interface and subclasses.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_AST_EXPROPENMP_H
14#define LLVM_CLANG_AST_EXPROPENMP_H
15
16#include "clang/AST/ComputeDependence.h"
17#include "clang/AST/Expr.h"
18
19namespace clang {
20/// An explicit cast in C or a C-style cast in C++, which uses the syntax
21/// ([s1][s2]...[sn])expr. For example: @c ([3][3])f.
22class OMPArrayShapingExpr final
23 : public Expr,
24 private llvm::TrailingObjects<OMPArrayShapingExpr, Expr *, SourceRange> {
25 friend TrailingObjects;
26 friend class ASTStmtReader;
27 friend class ASTStmtWriter;
28 /// Base node.
29 SourceLocation LPLoc; /// The location of the left paren
30 SourceLocation RPLoc; /// The location of the right paren
31 unsigned NumDims = 0; /// Number of dimensions in the shaping expression.
32
33 /// Construct full expression.
34 OMPArrayShapingExpr(QualType ExprTy, Expr *Op, SourceLocation L,
35 SourceLocation R, ArrayRef<Expr *> Dims);
36
37 /// Construct an empty expression.
38 explicit OMPArrayShapingExpr(EmptyShell Shell, unsigned NumDims)
39 : Expr(OMPArrayShapingExprClass, Shell), NumDims(NumDims) {}
40
41 /// Sets the dimensions for the array shaping.
42 void setDimensions(ArrayRef<Expr *> Dims);
43
44 /// Sets the base expression for array shaping operation.
45 void setBase(Expr *Op) { getTrailingObjects<Expr *>()[NumDims] = Op; }
46
47 /// Sets source ranges for the brackets in the array shaping operation.
48 void setBracketsRanges(ArrayRef<SourceRange> BR);
49
50 unsigned numTrailingObjects(OverloadToken<Expr *>) const {
51 // Add an extra one for the base expression.
52 return NumDims + 1;
53 }
54
55 unsigned numTrailingObjects(OverloadToken<SourceRange>) const {
56 return NumDims;
57 }
58
59public:
60 static OMPArrayShapingExpr *Create(const ASTContext &Context, QualType T,
61 Expr *Op, SourceLocation L,
62 SourceLocation R, ArrayRef<Expr *> Dims,
63 ArrayRef<SourceRange> BracketRanges);
64
65 static OMPArrayShapingExpr *CreateEmpty(const ASTContext &Context,
66 unsigned NumDims);
67
68 SourceLocation getLParenLoc() const { return LPLoc; }
69 void setLParenLoc(SourceLocation L) { LPLoc = L; }
70
71 SourceLocation getRParenLoc() const { return RPLoc; }
72 void setRParenLoc(SourceLocation L) { RPLoc = L; }
73
74 SourceLocation getBeginLoc() const LLVM_READONLY { return LPLoc; }
75 SourceLocation getEndLoc() const LLVM_READONLY {
76 return getBase()->getEndLoc();
77 }
78
79 /// Fetches the dimensions for array shaping expression.
80 ArrayRef<Expr *> getDimensions() const {
81 return llvm::ArrayRef(getTrailingObjects<Expr *>(), NumDims);
82 }
83
84 /// Fetches source ranges for the brackets os the array shaping expression.
85 ArrayRef<SourceRange> getBracketsRanges() const {
86 return llvm::ArrayRef(getTrailingObjects<SourceRange>(), NumDims);
87 }
88
89 /// Fetches base expression of array shaping expression.
90 Expr *getBase() { return getTrailingObjects<Expr *>()[NumDims]; }
91 const Expr *getBase() const { return getTrailingObjects<Expr *>()[NumDims]; }
92
93 static bool classof(const Stmt *T) {
94 return T->getStmtClass() == OMPArrayShapingExprClass;
95 }
96
97 // Iterators
98 child_range children() {
99 Stmt **Begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
100 return child_range(Begin, Begin + NumDims + 1);
101 }
102 const_child_range children() const {
103 Stmt *const *Begin =
104 reinterpret_cast<Stmt *const *>(getTrailingObjects<Expr *>());
105 return const_child_range(Begin, Begin + NumDims + 1);
106 }
107};
108
109/// Helper expressions and declaration for OMPIteratorExpr class for each
110/// iteration space.
111struct OMPIteratorHelperData {
112 /// Internal normalized counter.
113 VarDecl *CounterVD = nullptr;
114 /// Normalized upper bound. Normalized loop iterates from 0 to Upper with
115 /// step 1.
116 Expr *Upper = nullptr;
117 /// Update expression for the originally specified iteration variable,
118 /// calculated as VD = Begin + CounterVD * Step;
119 Expr *Update = nullptr;
120 /// Updater for the internal counter: ++CounterVD;
121 Expr *CounterUpdate = nullptr;
122};
123
124/// OpenMP 5.0 [2.1.6 Iterators]
125/// Iterators are identifiers that expand to multiple values in the clause on
126/// which they appear.
127/// The syntax of the iterator modifier is as follows:
128/// \code
129/// iterator(iterators-definition)
130/// \endcode
131/// where iterators-definition is one of the following:
132/// \code
133/// iterator-specifier [, iterators-definition ]
134/// \endcode
135/// where iterator-specifier is one of the following:
136/// \code
137/// [ iterator-type ] identifier = range-specification
138/// \endcode
139/// where identifier is a base language identifier.
140/// iterator-type is a type name.
141/// range-specification is of the form begin:end[:step], where begin and end are
142/// expressions for which their types can be converted to iterator-type and step
143/// is an integral expression.
144/// In an iterator-specifier, if the iterator-type is not specified then the
145/// type of that iterator is of int type.
146/// The iterator-type must be an integral or pointer type.
147/// The iterator-type must not be const qualified.
148class OMPIteratorExpr final
149 : public Expr,
150 private llvm::TrailingObjects<OMPIteratorExpr, Decl *, Expr *,
151 SourceLocation, OMPIteratorHelperData> {
152public:
153 /// Iterator range representation begin:end[:step].
154 struct IteratorRange {
155 Expr *Begin = nullptr;
156 Expr *End = nullptr;
157 Expr *Step = nullptr;
158 };
159 /// Iterator definition representation.
160 struct IteratorDefinition {
161 Decl *IteratorDecl = nullptr;
162 IteratorRange Range;
163 SourceLocation AssignmentLoc;
164 SourceLocation ColonLoc, SecondColonLoc;
165 };
166
167private:
168 friend TrailingObjects;
169 friend class ASTStmtReader;
170 friend class ASTStmtWriter;
171
172 /// Offset in the list of expressions for subelements of the ranges.
173 enum class RangeExprOffset {
174 Begin = 0,
175 End = 1,
176 Step = 2,
177 Total = 3,
178 };
179 /// Offset in the list of locations for subelements of colon symbols
180 /// locations.
181 enum class RangeLocOffset {
182 AssignLoc = 0,
183 FirstColonLoc = 1,
184 SecondColonLoc = 2,
185 Total = 3,
186 };
187 /// Location of 'iterator' keyword.
188 SourceLocation IteratorKwLoc;
189 /// Location of '('.
190 SourceLocation LPLoc;
191 /// Location of ')'.
192 SourceLocation RPLoc;
193 /// Number of iterator definitions.
194 unsigned NumIterators = 0;
195
196 OMPIteratorExpr(QualType ExprTy, SourceLocation IteratorKwLoc,
197 SourceLocation L, SourceLocation R,
198 ArrayRef<IteratorDefinition> Data,
199 ArrayRef<OMPIteratorHelperData> Helpers);
200
201 /// Construct an empty expression.
202 explicit OMPIteratorExpr(EmptyShell Shell, unsigned NumIterators)
203 : Expr(OMPIteratorExprClass, Shell), NumIterators(NumIterators) {}
204
205 /// Sets basic declaration for the specified iterator definition.
206 void setIteratorDeclaration(unsigned I, Decl *D);
207
208 /// Sets the location of the assignment symbol for the specified iterator
209 /// definition.
210 void setAssignmentLoc(unsigned I, SourceLocation Loc);
211
212 /// Sets begin, end and optional step expressions for specified iterator
213 /// definition.
214 void setIteratorRange(unsigned I, Expr *Begin, SourceLocation ColonLoc,
215 Expr *End, SourceLocation SecondColonLoc, Expr *Step);
216
217 /// Sets helpers for the specified iteration space.
218 void setHelper(unsigned I, const OMPIteratorHelperData &D);
219
220 unsigned numTrailingObjects(OverloadToken<Decl *>) const {
221 return NumIterators;
222 }
223
224 unsigned numTrailingObjects(OverloadToken<Expr *>) const {
225 return NumIterators * static_cast<int>(RangeExprOffset::Total);
226 }
227
228 unsigned numTrailingObjects(OverloadToken<SourceLocation>) const {
229 return NumIterators * static_cast<int>(RangeLocOffset::Total);
230 }
231
232public:
233 static OMPIteratorExpr *Create(const ASTContext &Context, QualType T,
234 SourceLocation IteratorKwLoc, SourceLocation L,
235 SourceLocation R,
236 ArrayRef<IteratorDefinition> Data,
237 ArrayRef<OMPIteratorHelperData> Helpers);
238
239 static OMPIteratorExpr *CreateEmpty(const ASTContext &Context,
240 unsigned NumIterators);
241
242 SourceLocation getLParenLoc() const { return LPLoc; }
243 void setLParenLoc(SourceLocation L) { LPLoc = L; }
244
245 SourceLocation getRParenLoc() const { return RPLoc; }
246 void setRParenLoc(SourceLocation L) { RPLoc = L; }
247
248 SourceLocation getIteratorKwLoc() const { return IteratorKwLoc; }
249 void setIteratorKwLoc(SourceLocation L) { IteratorKwLoc = L; }
250 SourceLocation getBeginLoc() const LLVM_READONLY { return IteratorKwLoc; }
251 SourceLocation getEndLoc() const LLVM_READONLY { return RPLoc; }
252
253 /// Gets the iterator declaration for the given iterator.
254 Decl *getIteratorDecl(unsigned I);
255 const Decl *getIteratorDecl(unsigned I) const {
256 return const_cast<OMPIteratorExpr *>(this)->getIteratorDecl(I);
257 }
258
259 /// Gets the iterator range for the given iterator.
260 IteratorRange getIteratorRange(unsigned I);
261 const IteratorRange getIteratorRange(unsigned I) const {
262 return const_cast<OMPIteratorExpr *>(this)->getIteratorRange(I);
263 }
264
265 /// Gets the location of '=' for the given iterator definition.
266 SourceLocation getAssignLoc(unsigned I) const;
267 /// Gets the location of the first ':' in the range for the given iterator
268 /// definition.
269 SourceLocation getColonLoc(unsigned I) const;
270 /// Gets the location of the second ':' (if any) in the range for the given
271 /// iteratori definition.
272 SourceLocation getSecondColonLoc(unsigned I) const;
273
274 /// Returns number of iterator definitions.
275 unsigned numOfIterators() const { return NumIterators; }
276
277 /// Fetches helper data for the specified iteration space.
278 OMPIteratorHelperData &getHelper(unsigned I);
279 const OMPIteratorHelperData &getHelper(unsigned I) const;
280
281 static bool classof(const Stmt *T) {
282 return T->getStmtClass() == OMPIteratorExprClass;
283 }
284
285 // Iterators
286 child_range children() {
287 Stmt **Begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
288 return child_range(
289 Begin, Begin + NumIterators * static_cast<int>(RangeExprOffset::Total));
290 }
291 const_child_range children() const {
292 Stmt *const *Begin =
293 reinterpret_cast<Stmt *const *>(getTrailingObjects<Expr *>());
294 return const_child_range(
295 Begin, Begin + NumIterators * static_cast<int>(RangeExprOffset::Total));
296 }
297};
298
299} // end namespace clang
300
301#endif
302