@@ -205,6 +205,169 @@ class OMPArrayShapingExpr final
205205 return const_child_range (Begin, Begin + NumDims + 1 );
206206 }
207207};
208+
209+ // / OpenMP 5.0 [2.1.6 Iterators]
210+ // / Iterators are identifiers that expand to multiple values in the clause on
211+ // / which they appear.
212+ // / The syntax of the iterator modifier is as follows:
213+ // / \code
214+ // / iterator(iterators-definition)
215+ // / \endcode
216+ // / where iterators-definition is one of the following:
217+ // / \code
218+ // / iterator-specifier [, iterators-definition ]
219+ // / \endcode
220+ // / where iterator-specifier is one of the following:
221+ // / \code
222+ // / [ iterator-type ] identifier = range-specification
223+ // / \endcode
224+ // / where identifier is a base language identifier.
225+ // / iterator-type is a type name.
226+ // / range-specification is of the form begin:end[:step], where begin and end are
227+ // / expressions for which their types can be converted to iterator-type and step
228+ // / is an integral expression.
229+ // / In an iterator-specifier, if the iterator-type is not specified then the
230+ // / type of that iterator is of int type.
231+ // / The iterator-type must be an integral or pointer type.
232+ // / The iterator-type must not be const qualified.
233+ class OMPIteratorExpr final
234+ : public Expr,
235+ private llvm::TrailingObjects<OMPIteratorExpr, Decl *, Expr *,
236+ SourceLocation> {
237+ public:
238+ // / Iterator range representation begin:end[:step].
239+ struct IteratorRange {
240+ Expr *Begin = nullptr ;
241+ Expr *End = nullptr ;
242+ Expr *Step = nullptr ;
243+ };
244+ // / Iterator definition representation.
245+ struct IteratorDefinition {
246+ Decl *IteratorDecl = nullptr ;
247+ IteratorRange Range;
248+ SourceLocation AssignmentLoc;
249+ SourceLocation ColonLoc, SecondColonLoc;
250+ };
251+
252+ private:
253+ friend TrailingObjects;
254+ friend class ASTStmtReader ;
255+ friend class ASTStmtWriter ;
256+
257+ // / Offset in the list of expressions for subelements of the ranges.
258+ enum class RangeExprOffset {
259+ Begin = 0 ,
260+ End = 1 ,
261+ Step = 2 ,
262+ Total = 3 ,
263+ };
264+ // / Offset in the list of locations for subelements of colon symbols
265+ // / locations.
266+ enum class RangeLocOffset {
267+ AssignLoc = 0 ,
268+ FirstColonLoc = 1 ,
269+ SecondColonLoc = 2 ,
270+ Total = 3 ,
271+ };
272+ // / Location of 'iterator' keyword.
273+ SourceLocation IteratorKwLoc;
274+ // / Location of '('.
275+ SourceLocation LPLoc;
276+ // / Location of ')'.
277+ SourceLocation RPLoc;
278+ // / Number of iterator definitions.
279+ unsigned NumIterators = 0 ;
280+
281+ OMPIteratorExpr (QualType ExprTy, SourceLocation IteratorKwLoc,
282+ SourceLocation L, SourceLocation R,
283+ ArrayRef<OMPIteratorExpr::IteratorDefinition> Data);
284+
285+ // / Construct an empty expression.
286+ explicit OMPIteratorExpr (EmptyShell Shell, unsigned NumIterators)
287+ : Expr(OMPIteratorExprClass, Shell), NumIterators(NumIterators) {}
288+
289+ // / Sets basic declaration for the specified iterator definition.
290+ void setIteratorDeclaration (unsigned I, Decl *D);
291+
292+ // / Sets the location of the assignment symbol for the specified iterator
293+ // / definition.
294+ void setAssignmentLoc (unsigned I, SourceLocation Loc);
295+
296+ // / Sets begin, end and optional step expressions for specified iterator
297+ // / definition.
298+ void setIteratorRange (unsigned I, Expr *Begin, SourceLocation ColonLoc,
299+ Expr *End, SourceLocation SecondColonLoc, Expr *Step);
300+
301+ unsigned numTrailingObjects (OverloadToken<Decl *>) const {
302+ return NumIterators;
303+ }
304+
305+ unsigned numTrailingObjects (OverloadToken<Expr *>) const {
306+ return NumIterators * static_cast <int >(RangeExprOffset::Total);
307+ }
308+
309+ public:
310+ static OMPIteratorExpr *Create (const ASTContext &Context, QualType T,
311+ SourceLocation IteratorKwLoc, SourceLocation L,
312+ SourceLocation R,
313+ ArrayRef<IteratorDefinition> Data);
314+
315+ static OMPIteratorExpr *CreateEmpty (const ASTContext &Context,
316+ unsigned NumIterators);
317+
318+ SourceLocation getLParenLoc () const { return LPLoc; }
319+ void setLParenLoc (SourceLocation L) { LPLoc = L; }
320+
321+ SourceLocation getRParenLoc () const { return RPLoc; }
322+ void setRParenLoc (SourceLocation L) { RPLoc = L; }
323+
324+ SourceLocation getIteratorKwLoc () const { return IteratorKwLoc; }
325+ void setIteratorKwLoc (SourceLocation L) { IteratorKwLoc = L; }
326+ SourceLocation getBeginLoc () const LLVM_READONLY { return IteratorKwLoc; }
327+ SourceLocation getEndLoc () const LLVM_READONLY { return RPLoc; }
328+
329+ // / Gets the iterator declaration for the given iterator.
330+ Decl *getIteratorDecl (unsigned I);
331+ const Decl *getIteratorDecl (unsigned I) const {
332+ return const_cast <OMPIteratorExpr *>(this )->getIteratorDecl (I);
333+ }
334+
335+ // / Gets the iterator range for the given iterator.
336+ IteratorRange getIteratorRange (unsigned I);
337+ const IteratorRange getIteratorRange (unsigned I) const {
338+ return const_cast <OMPIteratorExpr *>(this )->getIteratorRange (I);
339+ }
340+
341+ // / Gets the location of '=' for the given iterator definition.
342+ SourceLocation getAssignLoc (unsigned I) const ;
343+ // / Gets the location of the first ':' in the range for the given iterator
344+ // / definition.
345+ SourceLocation getColonLoc (unsigned I) const ;
346+ // / Gets the location of the second ':' (if any) in the range for the given
347+ // / iteratori definition.
348+ SourceLocation getSecondColonLoc (unsigned I) const ;
349+
350+ // / Returns number of iterator definitions.
351+ unsigned numOfIterators () const { return NumIterators; }
352+
353+ static bool classof (const Stmt *T) {
354+ return T->getStmtClass () == OMPIteratorExprClass;
355+ }
356+
357+ // Iterators
358+ child_range children () {
359+ Stmt **Begin = reinterpret_cast <Stmt **>(getTrailingObjects<Expr *>());
360+ return child_range (
361+ Begin, Begin + NumIterators * static_cast <int >(RangeExprOffset::Total));
362+ }
363+ const_child_range children () const {
364+ Stmt *const *Begin =
365+ reinterpret_cast <Stmt *const *>(getTrailingObjects<Expr *>());
366+ return const_child_range (
367+ Begin, Begin + NumIterators * static_cast <int >(RangeExprOffset::Total));
368+ }
369+ };
370+
208371} // end namespace clang
209372
210373#endif
0 commit comments