1 //===- StmtOpenMP.h - Classes for OpenMP directives and clauses --*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// \file 10 /// \brief This file defines OpenMP AST classes for executable directives and 11 /// clauses. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_CLANG_AST_STMTOPENMP_H 16 #define LLVM_CLANG_AST_STMTOPENMP_H 17 18 #include "clang/Basic/OpenMPKinds.h" 19 #include "clang/Basic/SourceLocation.h" 20 #include "clang/AST/Expr.h" 21 #include "clang/AST/Stmt.h" 22 23 namespace clang { 24 25 //===----------------------------------------------------------------------===// 26 // AST classes for clauses. 27 //===----------------------------------------------------------------------===// 28 29 /// \brief This is a basic class for representing single OpenMP clause. 30 /// 31 class OMPClause { 32 /// \brief Starting location of the clause (the clause keyword). 33 SourceLocation StartLoc; 34 /// \brief Ending location of the clause. 35 SourceLocation EndLoc; 36 /// \brief Kind of the clause. 37 OpenMPClauseKind Kind; 38 protected: 39 OMPClause(OpenMPClauseKind K, SourceLocation StartLoc, SourceLocation EndLoc) 40 : StartLoc(StartLoc), EndLoc(EndLoc), Kind(K) {} 41 42 public: 43 44 /// \brief Returns the starting location of the clause. 45 SourceLocation getLocStart() const { return StartLoc; } 46 /// \brief Returns the ending location of the clause. 47 SourceLocation getLocEnd() const { return EndLoc; } 48 49 /// \brief Sets the starting location of the clause. 50 void setLocStart(SourceLocation Loc) { StartLoc = Loc; } 51 /// \brief Sets the ending location of the clause. 52 void setLocEnd(SourceLocation Loc) { EndLoc = Loc; } 53 54 /// \brief Returns kind of OpenMP clause (private, shared, reduction, etc.). 55 OpenMPClauseKind getClauseKind() const { return Kind; } 56 57 bool isImplicit() const { return StartLoc.isInvalid();} 58 59 StmtRange children(); 60 ConstStmtRange children() const { 61 return const_cast<OMPClause *>(this)->children(); 62 } 63 static bool classof(const OMPClause *T) { 64 return true; 65 } 66 }; 67 68 /// \brief This represents clauses with the list of variables like 'private', 69 /// 'firstprivate', 'copyin', 'shared', or 'reduction' clauses in the 70 /// '#pragma omp ...' directives. 71 template <class T> 72 class OMPVarList { 73 friend class OMPClauseReader; 74 /// \brief Location of '('. 75 SourceLocation LParenLoc; 76 /// \brief Number of variables in the list. 77 unsigned NumVars; 78 protected: 79 /// \brief Fetches list of variables associated with this clause. 80 llvm::MutableArrayRef<Expr *> getVarRefs() { 81 return llvm::MutableArrayRef<Expr *>( 82 reinterpret_cast<Expr **>(static_cast<T *>(this) + 1), 83 NumVars); 84 } 85 86 /// \brief Sets the list of variables for this clause. 87 void setVarRefs(ArrayRef<Expr *> VL) { 88 assert(VL.size() == NumVars && 89 "Number of variables is not the same as the preallocated buffer"); 90 std::copy(VL.begin(), VL.end(), 91 reinterpret_cast<Expr **>(static_cast<T *>(this) + 1)); 92 } 93 94 /// \brief Build clause with number of variables \a N. 95 /// 96 /// \param N Number of the variables in the clause. 97 /// 98 OMPVarList(SourceLocation LParenLoc, unsigned N) 99 : LParenLoc(LParenLoc), NumVars(N) { } 100 public: 101 typedef llvm::MutableArrayRef<Expr *>::iterator varlist_iterator; 102 typedef ArrayRef<const Expr *>::iterator varlist_const_iterator; 103 104 unsigned varlist_size() const { return NumVars; } 105 bool varlist_empty() const { return NumVars == 0; } 106 varlist_iterator varlist_begin() { return getVarRefs().begin(); } 107 varlist_iterator varlist_end() { return getVarRefs().end(); } 108 varlist_const_iterator varlist_begin() const { return getVarRefs().begin(); } 109 varlist_const_iterator varlist_end() const { return getVarRefs().end(); } 110 111 /// \brief Sets the location of '('. 112 void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } 113 /// \brief Returns the location of '('. 114 SourceLocation getLParenLoc() const { return LParenLoc; } 115 116 /// \brief Fetches list of all variables in the clause. 117 ArrayRef<const Expr *> getVarRefs() const { 118 return ArrayRef<const Expr *>( 119 reinterpret_cast<const Expr *const *>(static_cast<const T *>(this) + 1), 120 NumVars); 121 } 122 }; 123 124 /// \brief This represents 'default' clause in the '#pragma omp ...' directive. 125 /// 126 /// \code 127 /// #pragma omp parallel default(shared) 128 /// \endcode 129 /// In this example directive '#pragma omp parallel' has simple 'default' 130 /// clause with kind 'shared'. 131 /// 132 class OMPDefaultClause : public OMPClause { 133 friend class OMPClauseReader; 134 /// \brief Location of '('. 135 SourceLocation LParenLoc; 136 /// \brief A kind of the 'default' clause. 137 OpenMPDefaultClauseKind Kind; 138 /// \brief Start location of the kind in source code. 139 SourceLocation KindKwLoc; 140 141 /// \brief Set kind of the clauses. 142 /// 143 /// \param K Argument of clause. 144 /// 145 void setDefaultKind(OpenMPDefaultClauseKind K) { Kind = K; } 146 147 /// \brief Set argument location. 148 /// 149 /// \param KLoc Argument location. 150 /// 151 void setDefaultKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; } 152 public: 153 /// \brief Build 'default' clause with argument \a A ('none' or 'shared'). 154 /// 155 /// \param A Argument of the clause ('none' or 'shared'). 156 /// \param ALoc Starting location of the argument. 157 /// \param StartLoc Starting location of the clause. 158 /// \param LParenLoc Location of '('. 159 /// \param EndLoc Ending location of the clause. 160 /// 161 OMPDefaultClause(OpenMPDefaultClauseKind A, SourceLocation ALoc, 162 SourceLocation StartLoc, SourceLocation LParenLoc, 163 SourceLocation EndLoc) 164 : OMPClause(OMPC_default, StartLoc, EndLoc), LParenLoc(LParenLoc), 165 Kind(A), KindKwLoc(ALoc) { } 166 167 /// \brief Build an empty clause. 168 /// 169 OMPDefaultClause() 170 : OMPClause(OMPC_default, SourceLocation(), SourceLocation()), 171 LParenLoc(SourceLocation()), Kind(OMPC_DEFAULT_unknown), 172 KindKwLoc(SourceLocation()) { } 173 174 /// \brief Sets the location of '('. 175 void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } 176 /// \brief Returns the location of '('. 177 SourceLocation getLParenLoc() const { return LParenLoc; } 178 179 /// \brief Returns kind of the clause. 180 OpenMPDefaultClauseKind getDefaultKind() const { return Kind; } 181 182 /// \brief Returns location of clause kind. 183 SourceLocation getDefaultKindKwLoc() const { return KindKwLoc; } 184 185 static bool classof(const OMPClause *T) { 186 return T->getClauseKind() == OMPC_default; 187 } 188 189 StmtRange children() { 190 return StmtRange(); 191 } 192 }; 193 194 /// \brief This represents clause 'private' in the '#pragma omp ...' directives. 195 /// 196 /// \code 197 /// #pragma omp parallel private(a,b) 198 /// \endcode 199 /// In this example directive '#pragma omp parallel' has clause 'private' 200 /// with the variables 'a' and 'b'. 201 /// 202 class OMPPrivateClause : public OMPClause, public OMPVarList<OMPPrivateClause> { 203 /// \brief Build clause with number of variables \a N. 204 /// 205 /// \param StartLoc Starting location of the clause. 206 /// \param LParenLoc Location of '('. 207 /// \param EndLoc Ending location of the clause. 208 /// \param N Number of the variables in the clause. 209 /// 210 OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, 211 SourceLocation EndLoc, unsigned N) 212 : OMPClause(OMPC_private, StartLoc, EndLoc), 213 OMPVarList<OMPPrivateClause>(LParenLoc, N) { } 214 215 /// \brief Build an empty clause. 216 /// 217 /// \param N Number of variables. 218 /// 219 explicit OMPPrivateClause(unsigned N) 220 : OMPClause(OMPC_private, SourceLocation(), SourceLocation()), 221 OMPVarList<OMPPrivateClause>(SourceLocation(), N) { } 222 public: 223 /// \brief Creates clause with a list of variables \a VL. 224 /// 225 /// \param C AST context. 226 /// \param StartLoc Starting location of the clause. 227 /// \param LParenLoc Location of '('. 228 /// \param EndLoc Ending location of the clause. 229 /// \param VL List of references to the variables. 230 /// 231 static OMPPrivateClause *Create(ASTContext &C, SourceLocation StartLoc, 232 SourceLocation LParenLoc, 233 SourceLocation EndLoc, 234 ArrayRef<Expr *> VL); 235 /// \brief Creates an empty clause with the place for \a N variables. 236 /// 237 /// \param C AST context. 238 /// \param N The number of variables. 239 /// 240 static OMPPrivateClause *CreateEmpty(ASTContext &C, unsigned N); 241 242 StmtRange children() { 243 return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()), 244 reinterpret_cast<Stmt **>(varlist_end())); 245 } 246 247 static bool classof(const OMPClause *T) { 248 return T->getClauseKind() == OMPC_private; 249 } 250 }; 251 252 //===----------------------------------------------------------------------===// 253 // AST classes for directives. 254 //===----------------------------------------------------------------------===// 255 256 /// \brief This is a basic class for representing single OpenMP executable 257 /// directive. 258 /// 259 class OMPExecutableDirective : public Stmt { 260 friend class ASTStmtReader; 261 /// \brief Kind of the directive. 262 OpenMPDirectiveKind Kind; 263 /// \brief Starting location of the directive (directive keyword). 264 SourceLocation StartLoc; 265 /// \brief Ending location of the directive. 266 SourceLocation EndLoc; 267 /// \brief Pointer to the list of clauses. 268 llvm::MutableArrayRef<OMPClause *> Clauses; 269 /// \brief Associated statement (if any) and expressions. 270 llvm::MutableArrayRef<Stmt *> StmtAndExpressions; 271 protected: 272 /// \brief Build instance of directive of class \a K. 273 /// 274 /// \param SC Statement class. 275 /// \param K Kind of OpenMP directive. 276 /// \param StartLoc Starting location of the directive (directive keyword). 277 /// \param EndLoc Ending location of the directive. 278 /// 279 template <typename T> 280 OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K, 281 SourceLocation StartLoc, SourceLocation EndLoc, 282 unsigned NumClauses, unsigned NumberOfExpressions) 283 : Stmt(SC), Kind(K), StartLoc(StartLoc), EndLoc(EndLoc), 284 Clauses(reinterpret_cast<OMPClause **>(static_cast<T *>(this) + 1), 285 NumClauses), 286 StmtAndExpressions(reinterpret_cast<Stmt **>(Clauses.end()), 287 NumberOfExpressions) { } 288 289 /// \brief Sets the list of variables for this clause. 290 /// 291 /// \param Clauses The list of clauses for the directive. 292 /// 293 void setClauses(ArrayRef<OMPClause *> Clauses); 294 295 /// \brief Set the associated statement for the directive. 296 /// 297 /// /param S Associated statement. 298 /// 299 void setAssociatedStmt(Stmt *S) { 300 StmtAndExpressions[0] = S; 301 } 302 303 public: 304 /// \brief Returns starting location of directive kind. 305 SourceLocation getLocStart() const { return StartLoc; } 306 /// \brief Returns ending location of directive. 307 SourceLocation getLocEnd() const { return EndLoc; } 308 309 /// \brief Set starting location of directive kind. 310 /// 311 /// \param Loc New starting location of directive. 312 /// 313 void setLocStart(SourceLocation Loc) { StartLoc = Loc; } 314 /// \brief Set ending location of directive. 315 /// 316 /// \param Loc New ending location of directive. 317 /// 318 void setLocEnd(SourceLocation Loc) { EndLoc = Loc; } 319 320 /// \brief Get number of clauses. 321 unsigned getNumClauses() const { return Clauses.size(); } 322 323 /// \brief Returns specified clause. 324 /// 325 /// \param i Number of clause. 326 /// 327 OMPClause *getClause(unsigned i) const { 328 assert(i < Clauses.size() && "index out of bound!"); 329 return Clauses[i]; 330 } 331 332 /// \brief Returns statement associated with the directive. 333 Stmt *getAssociatedStmt() const { 334 return StmtAndExpressions[0]; 335 } 336 337 OpenMPDirectiveKind getDirectiveKind() const { return Kind; } 338 339 static bool classof(const Stmt *S) { 340 return S->getStmtClass() >= firstOMPExecutableDirectiveConstant && 341 S->getStmtClass() <= lastOMPExecutableDirectiveConstant; 342 } 343 344 child_range children() { 345 return child_range(StmtAndExpressions.begin(), StmtAndExpressions.end()); 346 } 347 348 ArrayRef<OMPClause *> clauses() { return Clauses; } 349 350 ArrayRef<OMPClause *> clauses() const { return Clauses; } 351 }; 352 353 /// \brief This represents '#pragma omp parallel' directive. 354 /// 355 /// \code 356 /// #pragma omp parallel private(a,b) reduction(+: c,d) 357 /// \endcode 358 /// In this example directive '#pragma omp parallel' has clauses 'private' 359 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and 360 /// variables 'c' and 'd'. 361 /// 362 class OMPParallelDirective : public OMPExecutableDirective { 363 /// \brief Build directive with the given start and end location. 364 /// 365 /// \param StartLoc Starting location of the directive (directive keyword). 366 /// \param EndLoc Ending Location of the directive. 367 /// 368 OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc, 369 unsigned N) 370 : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel, 371 StartLoc, EndLoc, N, 1) { } 372 373 /// \brief Build an empty directive. 374 /// 375 /// \param N Number of clauses. 376 /// 377 explicit OMPParallelDirective(unsigned N) 378 : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel, 379 SourceLocation(), SourceLocation(), N, 1) { } 380 public: 381 /// \brief Creates directive with a list of \a Clauses. 382 /// 383 /// \param C AST context. 384 /// \param StartLoc Starting location of the directive kind. 385 /// \param EndLoc Ending Location of the directive. 386 /// \param Clauses List of clauses. 387 /// \param AssociatedStmt Statement associated with the directive. 388 /// 389 static OMPParallelDirective *Create(ASTContext &C, SourceLocation StartLoc, 390 SourceLocation EndLoc, 391 ArrayRef<OMPClause *> Clauses, 392 Stmt *AssociatedStmt); 393 394 /// \brief Creates an empty directive with the place for \a N clauses. 395 /// 396 /// \param C AST context. 397 /// \param N The number of clauses. 398 /// 399 static OMPParallelDirective *CreateEmpty(ASTContext &C, unsigned N, 400 EmptyShell); 401 402 static bool classof(const Stmt *T) { 403 return T->getStmtClass() == OMPParallelDirectiveClass; 404 } 405 }; 406 407 } // end namespace clang 408 409 #endif 410