StmtOpenMP.h revision d195bc38fd424b0c928e3c354038a8ca6e2ccac3
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 23namespace clang { 24 25//===----------------------------------------------------------------------===// 26// AST classes for clauses. 27//===----------------------------------------------------------------------===// 28 29/// \brief This is a basic class for representing single OpenMP clause. 30/// 31class 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; 38protected: 39 OMPClause(OpenMPClauseKind K, SourceLocation StartLoc, SourceLocation EndLoc) 40 : StartLoc(StartLoc), EndLoc(EndLoc), Kind(K) {} 41 42public: 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. 71template <class T> 72class OMPVarList { 73 friend class OMPClauseReader; 74 /// \brief Location of '('. 75 SourceLocation LParenLoc; 76 /// \brief Number of variables in the list. 77 unsigned NumVars; 78protected: 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) { } 100public: 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/// 132class 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; } 152public: 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/// 202class 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) { } 222public: 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(const 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(const 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/// \brief This represents clause 'firstprivate' in the '#pragma omp ...' 253/// directives. 254/// 255/// \code 256/// #pragma omp parallel firstprivate(a,b) 257/// \endcode 258/// In this example directive '#pragma omp parallel' has clause 'firstprivate' 259/// with the variables 'a' and 'b'. 260/// 261class OMPFirstprivateClause : public OMPClause, 262 public OMPVarList<OMPFirstprivateClause> { 263 /// \brief Build clause with number of variables \a N. 264 /// 265 /// \param StartLoc Starting location of the clause. 266 /// \param LParenLoc Location of '('. 267 /// \param EndLoc Ending location of the clause. 268 /// \param N Number of the variables in the clause. 269 /// 270 OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, 271 SourceLocation EndLoc, unsigned N) 272 : OMPClause(OMPC_firstprivate, StartLoc, EndLoc), 273 OMPVarList<OMPFirstprivateClause>(LParenLoc, N) { } 274 275 /// \brief Build an empty clause. 276 /// 277 /// \param N Number of variables. 278 /// 279 explicit OMPFirstprivateClause(unsigned N) 280 : OMPClause(OMPC_firstprivate, SourceLocation(), SourceLocation()), 281 OMPVarList<OMPFirstprivateClause>(SourceLocation(), N) { } 282public: 283 /// \brief Creates clause with a list of variables \a VL. 284 /// 285 /// \param C AST context. 286 /// \param StartLoc Starting location of the clause. 287 /// \param LParenLoc Location of '('. 288 /// \param EndLoc Ending location of the clause. 289 /// \param VL List of references to the variables. 290 /// 291 static OMPFirstprivateClause *Create(const ASTContext &C, 292 SourceLocation StartLoc, 293 SourceLocation LParenLoc, 294 SourceLocation EndLoc, 295 ArrayRef<Expr *> VL); 296 /// \brief Creates an empty clause with the place for \a N variables. 297 /// 298 /// \param C AST context. 299 /// \param N The number of variables. 300 /// 301 static OMPFirstprivateClause *CreateEmpty(const ASTContext &C, unsigned N); 302 303 StmtRange children() { 304 return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()), 305 reinterpret_cast<Stmt **>(varlist_end())); 306 } 307 308 static bool classof(const OMPClause *T) { 309 return T->getClauseKind() == OMPC_firstprivate; 310 } 311}; 312 313/// \brief This represents clause 'shared' in the '#pragma omp ...' directives. 314/// 315/// \code 316/// #pragma omp parallel shared(a,b) 317/// \endcode 318/// In this example directive '#pragma omp parallel' has clause 'shared' 319/// with the variables 'a' and 'b'. 320/// 321class OMPSharedClause : public OMPClause, public OMPVarList<OMPSharedClause> { 322 /// \brief Build clause with number of variables \a N. 323 /// 324 /// \param StartLoc Starting location of the clause. 325 /// \param LParenLoc Location of '('. 326 /// \param EndLoc Ending location of the clause. 327 /// \param N Number of the variables in the clause. 328 /// 329 OMPSharedClause(SourceLocation StartLoc, SourceLocation LParenLoc, 330 SourceLocation EndLoc, unsigned N) 331 : OMPClause(OMPC_shared, StartLoc, EndLoc), 332 OMPVarList<OMPSharedClause>(LParenLoc, N) { } 333 334 /// \brief Build an empty clause. 335 /// 336 /// \param N Number of variables. 337 /// 338 explicit OMPSharedClause(unsigned N) 339 : OMPClause(OMPC_shared, SourceLocation(), SourceLocation()), 340 OMPVarList<OMPSharedClause>(SourceLocation(), N) { } 341public: 342 /// \brief Creates clause with a list of variables \a VL. 343 /// 344 /// \param C AST context. 345 /// \param StartLoc Starting location of the clause. 346 /// \param LParenLoc Location of '('. 347 /// \param EndLoc Ending location of the clause. 348 /// \param VL List of references to the variables. 349 /// 350 static OMPSharedClause *Create(const ASTContext &C, SourceLocation StartLoc, 351 SourceLocation LParenLoc, 352 SourceLocation EndLoc, ArrayRef<Expr *> VL); 353 /// \brief Creates an empty clause with \a N variables. 354 /// 355 /// \param C AST context. 356 /// \param N The number of variables. 357 /// 358 static OMPSharedClause *CreateEmpty(const ASTContext &C, unsigned N); 359 360 StmtRange children() { 361 return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()), 362 reinterpret_cast<Stmt **>(varlist_end())); 363 } 364 365 static bool classof(const OMPClause *T) { 366 return T->getClauseKind() == OMPC_shared; 367 } 368}; 369 370//===----------------------------------------------------------------------===// 371// AST classes for directives. 372//===----------------------------------------------------------------------===// 373 374/// \brief This is a basic class for representing single OpenMP executable 375/// directive. 376/// 377class OMPExecutableDirective : public Stmt { 378 friend class ASTStmtReader; 379 /// \brief Kind of the directive. 380 OpenMPDirectiveKind Kind; 381 /// \brief Starting location of the directive (directive keyword). 382 SourceLocation StartLoc; 383 /// \brief Ending location of the directive. 384 SourceLocation EndLoc; 385 /// \brief Pointer to the list of clauses. 386 llvm::MutableArrayRef<OMPClause *> Clauses; 387 /// \brief Associated statement (if any) and expressions. 388 llvm::MutableArrayRef<Stmt *> StmtAndExpressions; 389protected: 390 /// \brief Build instance of directive of class \a K. 391 /// 392 /// \param SC Statement class. 393 /// \param K Kind of OpenMP directive. 394 /// \param StartLoc Starting location of the directive (directive keyword). 395 /// \param EndLoc Ending location of the directive. 396 /// 397 template <typename T> 398 OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K, 399 SourceLocation StartLoc, SourceLocation EndLoc, 400 unsigned NumClauses, unsigned NumberOfExpressions) 401 : Stmt(SC), Kind(K), StartLoc(StartLoc), EndLoc(EndLoc), 402 Clauses(reinterpret_cast<OMPClause **>(static_cast<T *>(this) + 1), 403 NumClauses), 404 StmtAndExpressions(reinterpret_cast<Stmt **>(Clauses.end()), 405 NumberOfExpressions) { } 406 407 /// \brief Sets the list of variables for this clause. 408 /// 409 /// \param Clauses The list of clauses for the directive. 410 /// 411 void setClauses(ArrayRef<OMPClause *> Clauses); 412 413 /// \brief Set the associated statement for the directive. 414 /// 415 /// /param S Associated statement. 416 /// 417 void setAssociatedStmt(Stmt *S) { 418 StmtAndExpressions[0] = S; 419 } 420 421public: 422 /// \brief Returns starting location of directive kind. 423 SourceLocation getLocStart() const { return StartLoc; } 424 /// \brief Returns ending location of directive. 425 SourceLocation getLocEnd() const { return EndLoc; } 426 427 /// \brief Set starting location of directive kind. 428 /// 429 /// \param Loc New starting location of directive. 430 /// 431 void setLocStart(SourceLocation Loc) { StartLoc = Loc; } 432 /// \brief Set ending location of directive. 433 /// 434 /// \param Loc New ending location of directive. 435 /// 436 void setLocEnd(SourceLocation Loc) { EndLoc = Loc; } 437 438 /// \brief Get number of clauses. 439 unsigned getNumClauses() const { return Clauses.size(); } 440 441 /// \brief Returns specified clause. 442 /// 443 /// \param i Number of clause. 444 /// 445 OMPClause *getClause(unsigned i) const { 446 assert(i < Clauses.size() && "index out of bound!"); 447 return Clauses[i]; 448 } 449 450 /// \brief Returns statement associated with the directive. 451 Stmt *getAssociatedStmt() const { 452 return StmtAndExpressions[0]; 453 } 454 455 OpenMPDirectiveKind getDirectiveKind() const { return Kind; } 456 457 static bool classof(const Stmt *S) { 458 return S->getStmtClass() >= firstOMPExecutableDirectiveConstant && 459 S->getStmtClass() <= lastOMPExecutableDirectiveConstant; 460 } 461 462 child_range children() { 463 return child_range(StmtAndExpressions.begin(), StmtAndExpressions.end()); 464 } 465 466 ArrayRef<OMPClause *> clauses() { return Clauses; } 467 468 ArrayRef<OMPClause *> clauses() const { return Clauses; } 469}; 470 471/// \brief This represents '#pragma omp parallel' directive. 472/// 473/// \code 474/// #pragma omp parallel private(a,b) reduction(+: c,d) 475/// \endcode 476/// In this example directive '#pragma omp parallel' has clauses 'private' 477/// with the variables 'a' and 'b' and 'reduction' with operator '+' and 478/// variables 'c' and 'd'. 479/// 480class OMPParallelDirective : public OMPExecutableDirective { 481 /// \brief Build directive with the given start and end location. 482 /// 483 /// \param StartLoc Starting location of the directive (directive keyword). 484 /// \param EndLoc Ending Location of the directive. 485 /// 486 OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc, 487 unsigned N) 488 : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel, 489 StartLoc, EndLoc, N, 1) { } 490 491 /// \brief Build an empty directive. 492 /// 493 /// \param N Number of clauses. 494 /// 495 explicit OMPParallelDirective(unsigned N) 496 : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel, 497 SourceLocation(), SourceLocation(), N, 1) { } 498public: 499 /// \brief Creates directive with a list of \a Clauses. 500 /// 501 /// \param C AST context. 502 /// \param StartLoc Starting location of the directive kind. 503 /// \param EndLoc Ending Location of the directive. 504 /// \param Clauses List of clauses. 505 /// \param AssociatedStmt Statement associated with the directive. 506 /// 507 static OMPParallelDirective *Create(const ASTContext &C, 508 SourceLocation StartLoc, 509 SourceLocation EndLoc, 510 ArrayRef<OMPClause *> Clauses, 511 Stmt *AssociatedStmt); 512 513 /// \brief Creates an empty directive with the place for \a N clauses. 514 /// 515 /// \param C AST context. 516 /// \param N The number of clauses. 517 /// 518 static OMPParallelDirective *CreateEmpty(const ASTContext &C, unsigned N, 519 EmptyShell); 520 521 static bool classof(const Stmt *T) { 522 return T->getStmtClass() == OMPParallelDirectiveClass; 523 } 524}; 525 526} // end namespace clang 527 528#endif 529