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