xref: /freebsd/contrib/llvm-project/clang/include/clang/AST/ExprOpenMP.h (revision b64c5a0ace59af62eff52bfe110a521dc73c937b)
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 
19 namespace 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.
22 class 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 
59 public:
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.
111 struct 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.
148 class OMPIteratorExpr final
149     : public Expr,
150       private llvm::TrailingObjects<OMPIteratorExpr, Decl *, Expr *,
151                                     SourceLocation, OMPIteratorHelperData> {
152 public:
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 
167 private:
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 
232 public:
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