1 //===- StmtOpenMP.h - Classes for OpenMP directives ------------*- 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/AST/Expr.h" 19 #include "clang/AST/OpenMPClause.h" 20 #include "clang/AST/Stmt.h" 21 #include "clang/Basic/OpenMPKinds.h" 22 #include "clang/Basic/SourceLocation.h" 23 24 namespace clang { 25 26 //===----------------------------------------------------------------------===// 27 // AST classes for directives. 28 //===----------------------------------------------------------------------===// 29 30 /// \brief This is a basic class for representing single OpenMP executable 31 /// directive. 32 /// 33 class OMPExecutableDirective : public Stmt { 34 friend class ASTStmtReader; 35 /// \brief Kind of the directive. 36 OpenMPDirectiveKind Kind; 37 /// \brief Starting location of the directive (directive keyword). 38 SourceLocation StartLoc; 39 /// \brief Ending location of the directive. 40 SourceLocation EndLoc; 41 /// \brief Numbers of clauses. 42 const unsigned NumClauses; 43 /// \brief Number of child expressions/stmts. 44 const unsigned NumChildren; 45 /// \brief Offset from this to the start of clauses. 46 /// There are NumClauses pointers to clauses, they are followed by 47 /// NumChildren pointers to child stmts/exprs (if the directive type 48 /// requires an associated stmt, then it has to be the first of them). 49 const unsigned ClausesOffset; 50 51 /// \brief Get the clauses storage. 52 MutableArrayRef<OMPClause *> getClauses() { 53 OMPClause **ClauseStorage = reinterpret_cast<OMPClause **>( 54 reinterpret_cast<char *>(this) + ClausesOffset); 55 return MutableArrayRef<OMPClause *>(ClauseStorage, NumClauses); 56 } 57 58 protected: 59 /// \brief Build instance of directive of class \a K. 60 /// 61 /// \param SC Statement class. 62 /// \param K Kind of OpenMP directive. 63 /// \param StartLoc Starting location of the directive (directive keyword). 64 /// \param EndLoc Ending location of the directive. 65 /// 66 template <typename T> 67 OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K, 68 SourceLocation StartLoc, SourceLocation EndLoc, 69 unsigned NumClauses, unsigned NumChildren) 70 : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)), 71 EndLoc(std::move(EndLoc)), NumClauses(NumClauses), 72 NumChildren(NumChildren), 73 ClausesOffset(llvm::alignTo(sizeof(T), alignof(OMPClause *))) {} 74 75 /// \brief Sets the list of variables for this clause. 76 /// 77 /// \param Clauses The list of clauses for the directive. 78 /// 79 void setClauses(ArrayRef<OMPClause *> Clauses); 80 81 /// \brief Set the associated statement for the directive. 82 /// 83 /// /param S Associated statement. 84 /// 85 void setAssociatedStmt(Stmt *S) { 86 assert(hasAssociatedStmt() && "no associated statement."); 87 *child_begin() = S; 88 } 89 90 public: 91 /// \brief Iterates over a filtered subrange of clauses applied to a 92 /// directive. 93 /// 94 /// This iterator visits only clauses of type SpecificClause. 95 template <typename SpecificClause> 96 class specific_clause_iterator 97 : public llvm::iterator_adaptor_base< 98 specific_clause_iterator<SpecificClause>, 99 ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag, 100 const SpecificClause *, ptrdiff_t, const SpecificClause *, 101 const SpecificClause *> { 102 ArrayRef<OMPClause *>::const_iterator End; 103 104 void SkipToNextClause() { 105 while (this->I != End && !isa<SpecificClause>(*this->I)) 106 ++this->I; 107 } 108 109 public: 110 explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses) 111 : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()), 112 End(Clauses.end()) { 113 SkipToNextClause(); 114 } 115 116 const SpecificClause *operator*() const { 117 return cast<SpecificClause>(*this->I); 118 } 119 const SpecificClause *operator->() const { return **this; } 120 121 specific_clause_iterator &operator++() { 122 ++this->I; 123 SkipToNextClause(); 124 return *this; 125 } 126 }; 127 128 template <typename SpecificClause> 129 static llvm::iterator_range<specific_clause_iterator<SpecificClause>> 130 getClausesOfKind(ArrayRef<OMPClause *> Clauses) { 131 return {specific_clause_iterator<SpecificClause>(Clauses), 132 specific_clause_iterator<SpecificClause>( 133 llvm::makeArrayRef(Clauses.end(), 0))}; 134 } 135 136 template <typename SpecificClause> 137 llvm::iterator_range<specific_clause_iterator<SpecificClause>> 138 getClausesOfKind() const { 139 return getClausesOfKind<SpecificClause>(clauses()); 140 } 141 142 /// Gets a single clause of the specified kind associated with the 143 /// current directive iff there is only one clause of this kind (and assertion 144 /// is fired if there is more than one clause is associated with the 145 /// directive). Returns nullptr if no clause of this kind is associated with 146 /// the directive. 147 template <typename SpecificClause> 148 const SpecificClause *getSingleClause() const { 149 auto Clauses = getClausesOfKind<SpecificClause>(); 150 151 if (Clauses.begin() != Clauses.end()) { 152 assert(std::next(Clauses.begin()) == Clauses.end() && 153 "There are at least 2 clauses of the specified kind"); 154 return *Clauses.begin(); 155 } 156 return nullptr; 157 } 158 159 /// Returns true if the current directive has one or more clauses of a 160 /// specific kind. 161 template <typename SpecificClause> 162 bool hasClausesOfKind() const { 163 auto Clauses = getClausesOfKind<SpecificClause>(); 164 return Clauses.begin() != Clauses.end(); 165 } 166 167 /// \brief Returns starting location of directive kind. 168 SourceLocation getLocStart() const { return StartLoc; } 169 /// \brief Returns ending location of directive. 170 SourceLocation getLocEnd() const { return EndLoc; } 171 172 /// \brief Set starting location of directive kind. 173 /// 174 /// \param Loc New starting location of directive. 175 /// 176 void setLocStart(SourceLocation Loc) { StartLoc = Loc; } 177 /// \brief Set ending location of directive. 178 /// 179 /// \param Loc New ending location of directive. 180 /// 181 void setLocEnd(SourceLocation Loc) { EndLoc = Loc; } 182 183 /// \brief Get number of clauses. 184 unsigned getNumClauses() const { return NumClauses; } 185 186 /// \brief Returns specified clause. 187 /// 188 /// \param i Number of clause. 189 /// 190 OMPClause *getClause(unsigned i) const { return clauses()[i]; } 191 192 /// \brief Returns true if directive has associated statement. 193 bool hasAssociatedStmt() const { return NumChildren > 0; } 194 195 /// \brief Returns statement associated with the directive. 196 Stmt *getAssociatedStmt() const { 197 assert(hasAssociatedStmt() && "no associated statement."); 198 return const_cast<Stmt *>(*child_begin()); 199 } 200 201 /// \brief Returns the captured statement associated with the 202 /// component region within the (combined) directive. 203 // 204 // \param RegionKind Component region kind. 205 CapturedStmt *getCapturedStmt(OpenMPDirectiveKind RegionKind) const { 206 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 207 getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind()); 208 assert(std::any_of( 209 CaptureRegions.begin(), CaptureRegions.end(), 210 [=](const OpenMPDirectiveKind K) { return K == RegionKind; }) && 211 "RegionKind not found in OpenMP CaptureRegions."); 212 auto *CS = cast<CapturedStmt>(getAssociatedStmt()); 213 for (auto ThisCaptureRegion : CaptureRegions) { 214 if (ThisCaptureRegion == RegionKind) 215 return CS; 216 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 217 } 218 llvm_unreachable("Incorrect RegionKind specified for directive."); 219 } 220 221 OpenMPDirectiveKind getDirectiveKind() const { return Kind; } 222 223 static bool classof(const Stmt *S) { 224 return S->getStmtClass() >= firstOMPExecutableDirectiveConstant && 225 S->getStmtClass() <= lastOMPExecutableDirectiveConstant; 226 } 227 228 child_range children() { 229 if (!hasAssociatedStmt()) 230 return child_range(child_iterator(), child_iterator()); 231 Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end()); 232 return child_range(ChildStorage, ChildStorage + NumChildren); 233 } 234 235 ArrayRef<OMPClause *> clauses() { return getClauses(); } 236 237 ArrayRef<OMPClause *> clauses() const { 238 return const_cast<OMPExecutableDirective *>(this)->getClauses(); 239 } 240 }; 241 242 /// \brief This represents '#pragma omp parallel' directive. 243 /// 244 /// \code 245 /// #pragma omp parallel private(a,b) reduction(+: c,d) 246 /// \endcode 247 /// In this example directive '#pragma omp parallel' has clauses 'private' 248 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and 249 /// variables 'c' and 'd'. 250 /// 251 class OMPParallelDirective : public OMPExecutableDirective { 252 friend class ASTStmtReader; 253 /// \brief true if the construct has inner cancel directive. 254 bool HasCancel; 255 256 /// \brief Build directive with the given start and end location. 257 /// 258 /// \param StartLoc Starting location of the directive (directive keyword). 259 /// \param EndLoc Ending Location of the directive. 260 /// 261 OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc, 262 unsigned NumClauses) 263 : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel, 264 StartLoc, EndLoc, NumClauses, 1), 265 HasCancel(false) {} 266 267 /// \brief Build an empty directive. 268 /// 269 /// \param NumClauses Number of clauses. 270 /// 271 explicit OMPParallelDirective(unsigned NumClauses) 272 : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel, 273 SourceLocation(), SourceLocation(), NumClauses, 274 1), 275 HasCancel(false) {} 276 277 /// \brief Set cancel state. 278 void setHasCancel(bool Has) { HasCancel = Has; } 279 280 public: 281 /// \brief Creates directive with a list of \a Clauses. 282 /// 283 /// \param C AST context. 284 /// \param StartLoc Starting location of the directive kind. 285 /// \param EndLoc Ending Location of the directive. 286 /// \param Clauses List of clauses. 287 /// \param AssociatedStmt Statement associated with the directive. 288 /// \param HasCancel true if this directive has inner cancel directive. 289 /// 290 static OMPParallelDirective * 291 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 292 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel); 293 294 /// \brief Creates an empty directive with the place for \a N clauses. 295 /// 296 /// \param C AST context. 297 /// \param NumClauses Number of clauses. 298 /// 299 static OMPParallelDirective *CreateEmpty(const ASTContext &C, 300 unsigned NumClauses, EmptyShell); 301 302 /// \brief Return true if current directive has inner cancel directive. 303 bool hasCancel() const { return HasCancel; } 304 305 static bool classof(const Stmt *T) { 306 return T->getStmtClass() == OMPParallelDirectiveClass; 307 } 308 }; 309 310 /// \brief This is a common base class for loop directives ('omp simd', 'omp 311 /// for', 'omp for simd' etc.). It is responsible for the loop code generation. 312 /// 313 class OMPLoopDirective : public OMPExecutableDirective { 314 friend class ASTStmtReader; 315 /// \brief Number of collapsed loops as specified by 'collapse' clause. 316 unsigned CollapsedNum; 317 318 /// \brief Offsets to the stored exprs. 319 /// This enumeration contains offsets to all the pointers to children 320 /// expressions stored in OMPLoopDirective. 321 /// The first 9 children are nesessary for all the loop directives, and 322 /// the next 10 are specific to the worksharing ones. 323 /// After the fixed children, three arrays of length CollapsedNum are 324 /// allocated: loop counters, their updates and final values. 325 /// PrevLowerBound and PrevUpperBound are used to communicate blocking 326 /// information in composite constructs which require loop blocking 327 /// DistInc is used to generate the increment expression for the distribute 328 /// loop when combined with a further nested loop 329 /// PrevEnsureUpperBound is used as the EnsureUpperBound expression for the 330 /// for loop when combined with a previous distribute loop in the same pragma 331 /// (e.g. 'distribute parallel for') 332 /// 333 enum { 334 AssociatedStmtOffset = 0, 335 IterationVariableOffset = 1, 336 LastIterationOffset = 2, 337 CalcLastIterationOffset = 3, 338 PreConditionOffset = 4, 339 CondOffset = 5, 340 InitOffset = 6, 341 IncOffset = 7, 342 PreInitsOffset = 8, 343 // The '...End' enumerators do not correspond to child expressions - they 344 // specify the offset to the end (and start of the following counters/ 345 // updates/finals arrays). 346 DefaultEnd = 9, 347 // The following 12 exprs are used by worksharing and distribute loops only. 348 IsLastIterVariableOffset = 9, 349 LowerBoundVariableOffset = 10, 350 UpperBoundVariableOffset = 11, 351 StrideVariableOffset = 12, 352 EnsureUpperBoundOffset = 13, 353 NextLowerBoundOffset = 14, 354 NextUpperBoundOffset = 15, 355 NumIterationsOffset = 16, 356 PrevLowerBoundVariableOffset = 17, 357 PrevUpperBoundVariableOffset = 18, 358 DistIncOffset = 19, 359 PrevEnsureUpperBoundOffset = 20, 360 // Offset to the end (and start of the following counters/updates/finals 361 // arrays) for worksharing loop directives. 362 WorksharingEnd = 21, 363 }; 364 365 /// \brief Get the counters storage. 366 MutableArrayRef<Expr *> getCounters() { 367 Expr **Storage = reinterpret_cast<Expr **>( 368 &(*(std::next(child_begin(), getArraysOffset(getDirectiveKind()))))); 369 return MutableArrayRef<Expr *>(Storage, CollapsedNum); 370 } 371 372 /// \brief Get the private counters storage. 373 MutableArrayRef<Expr *> getPrivateCounters() { 374 Expr **Storage = reinterpret_cast<Expr **>(&*std::next( 375 child_begin(), getArraysOffset(getDirectiveKind()) + CollapsedNum)); 376 return MutableArrayRef<Expr *>(Storage, CollapsedNum); 377 } 378 379 /// \brief Get the updates storage. 380 MutableArrayRef<Expr *> getInits() { 381 Expr **Storage = reinterpret_cast<Expr **>( 382 &*std::next(child_begin(), 383 getArraysOffset(getDirectiveKind()) + 2 * CollapsedNum)); 384 return MutableArrayRef<Expr *>(Storage, CollapsedNum); 385 } 386 387 /// \brief Get the updates storage. 388 MutableArrayRef<Expr *> getUpdates() { 389 Expr **Storage = reinterpret_cast<Expr **>( 390 &*std::next(child_begin(), 391 getArraysOffset(getDirectiveKind()) + 3 * CollapsedNum)); 392 return MutableArrayRef<Expr *>(Storage, CollapsedNum); 393 } 394 395 /// \brief Get the final counter updates storage. 396 MutableArrayRef<Expr *> getFinals() { 397 Expr **Storage = reinterpret_cast<Expr **>( 398 &*std::next(child_begin(), 399 getArraysOffset(getDirectiveKind()) + 4 * CollapsedNum)); 400 return MutableArrayRef<Expr *>(Storage, CollapsedNum); 401 } 402 403 protected: 404 /// \brief Build instance of loop directive of class \a Kind. 405 /// 406 /// \param SC Statement class. 407 /// \param Kind Kind of OpenMP directive. 408 /// \param StartLoc Starting location of the directive (directive keyword). 409 /// \param EndLoc Ending location of the directive. 410 /// \param CollapsedNum Number of collapsed loops from 'collapse' clause. 411 /// \param NumClauses Number of clauses. 412 /// \param NumSpecialChildren Number of additional directive-specific stmts. 413 /// 414 template <typename T> 415 OMPLoopDirective(const T *That, StmtClass SC, OpenMPDirectiveKind Kind, 416 SourceLocation StartLoc, SourceLocation EndLoc, 417 unsigned CollapsedNum, unsigned NumClauses, 418 unsigned NumSpecialChildren = 0) 419 : OMPExecutableDirective(That, SC, Kind, StartLoc, EndLoc, NumClauses, 420 numLoopChildren(CollapsedNum, Kind) + 421 NumSpecialChildren), 422 CollapsedNum(CollapsedNum) {} 423 424 /// \brief Offset to the start of children expression arrays. 425 static unsigned getArraysOffset(OpenMPDirectiveKind Kind) { 426 return (isOpenMPWorksharingDirective(Kind) || 427 isOpenMPTaskLoopDirective(Kind) || 428 isOpenMPDistributeDirective(Kind)) 429 ? WorksharingEnd 430 : DefaultEnd; 431 } 432 433 /// \brief Children number. 434 static unsigned numLoopChildren(unsigned CollapsedNum, 435 OpenMPDirectiveKind Kind) { 436 return getArraysOffset(Kind) + 5 * CollapsedNum; // Counters, 437 // PrivateCounters, Inits, 438 // Updates and Finals 439 } 440 441 void setIterationVariable(Expr *IV) { 442 *std::next(child_begin(), IterationVariableOffset) = IV; 443 } 444 void setLastIteration(Expr *LI) { 445 *std::next(child_begin(), LastIterationOffset) = LI; 446 } 447 void setCalcLastIteration(Expr *CLI) { 448 *std::next(child_begin(), CalcLastIterationOffset) = CLI; 449 } 450 void setPreCond(Expr *PC) { 451 *std::next(child_begin(), PreConditionOffset) = PC; 452 } 453 void setCond(Expr *Cond) { 454 *std::next(child_begin(), CondOffset) = Cond; 455 } 456 void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; } 457 void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; } 458 void setPreInits(Stmt *PreInits) { 459 *std::next(child_begin(), PreInitsOffset) = PreInits; 460 } 461 void setIsLastIterVariable(Expr *IL) { 462 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 463 isOpenMPTaskLoopDirective(getDirectiveKind()) || 464 isOpenMPDistributeDirective(getDirectiveKind())) && 465 "expected worksharing loop directive"); 466 *std::next(child_begin(), IsLastIterVariableOffset) = IL; 467 } 468 void setLowerBoundVariable(Expr *LB) { 469 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 470 isOpenMPTaskLoopDirective(getDirectiveKind()) || 471 isOpenMPDistributeDirective(getDirectiveKind())) && 472 "expected worksharing loop directive"); 473 *std::next(child_begin(), LowerBoundVariableOffset) = LB; 474 } 475 void setUpperBoundVariable(Expr *UB) { 476 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 477 isOpenMPTaskLoopDirective(getDirectiveKind()) || 478 isOpenMPDistributeDirective(getDirectiveKind())) && 479 "expected worksharing loop directive"); 480 *std::next(child_begin(), UpperBoundVariableOffset) = UB; 481 } 482 void setStrideVariable(Expr *ST) { 483 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 484 isOpenMPTaskLoopDirective(getDirectiveKind()) || 485 isOpenMPDistributeDirective(getDirectiveKind())) && 486 "expected worksharing loop directive"); 487 *std::next(child_begin(), StrideVariableOffset) = ST; 488 } 489 void setEnsureUpperBound(Expr *EUB) { 490 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 491 isOpenMPTaskLoopDirective(getDirectiveKind()) || 492 isOpenMPDistributeDirective(getDirectiveKind())) && 493 "expected worksharing loop directive"); 494 *std::next(child_begin(), EnsureUpperBoundOffset) = EUB; 495 } 496 void setNextLowerBound(Expr *NLB) { 497 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 498 isOpenMPTaskLoopDirective(getDirectiveKind()) || 499 isOpenMPDistributeDirective(getDirectiveKind())) && 500 "expected worksharing loop directive"); 501 *std::next(child_begin(), NextLowerBoundOffset) = NLB; 502 } 503 void setNextUpperBound(Expr *NUB) { 504 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 505 isOpenMPTaskLoopDirective(getDirectiveKind()) || 506 isOpenMPDistributeDirective(getDirectiveKind())) && 507 "expected worksharing loop directive"); 508 *std::next(child_begin(), NextUpperBoundOffset) = NUB; 509 } 510 void setNumIterations(Expr *NI) { 511 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 512 isOpenMPTaskLoopDirective(getDirectiveKind()) || 513 isOpenMPDistributeDirective(getDirectiveKind())) && 514 "expected worksharing loop directive"); 515 *std::next(child_begin(), NumIterationsOffset) = NI; 516 } 517 void setPrevLowerBoundVariable(Expr *PrevLB) { 518 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 519 isOpenMPTaskLoopDirective(getDirectiveKind()) || 520 isOpenMPDistributeDirective(getDirectiveKind())) && 521 "expected worksharing loop directive"); 522 *std::next(child_begin(), PrevLowerBoundVariableOffset) = PrevLB; 523 } 524 void setPrevUpperBoundVariable(Expr *PrevUB) { 525 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 526 isOpenMPTaskLoopDirective(getDirectiveKind()) || 527 isOpenMPDistributeDirective(getDirectiveKind())) && 528 "expected worksharing loop directive"); 529 *std::next(child_begin(), PrevUpperBoundVariableOffset) = PrevUB; 530 } 531 void setDistInc(Expr *DistInc) { 532 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 533 isOpenMPTaskLoopDirective(getDirectiveKind()) || 534 isOpenMPDistributeDirective(getDirectiveKind())) && 535 "expected worksharing loop directive"); 536 *std::next(child_begin(), DistIncOffset) = DistInc; 537 } 538 void setPrevEnsureUpperBound(Expr *PrevEUB) { 539 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 540 isOpenMPTaskLoopDirective(getDirectiveKind()) || 541 isOpenMPDistributeDirective(getDirectiveKind())) && 542 "expected worksharing loop directive"); 543 *std::next(child_begin(), PrevEnsureUpperBoundOffset) = PrevEUB; 544 } 545 void setCounters(ArrayRef<Expr *> A); 546 void setPrivateCounters(ArrayRef<Expr *> A); 547 void setInits(ArrayRef<Expr *> A); 548 void setUpdates(ArrayRef<Expr *> A); 549 void setFinals(ArrayRef<Expr *> A); 550 551 public: 552 /// \brief The expressions built for the OpenMP loop CodeGen for the 553 /// whole collapsed loop nest. 554 struct HelperExprs { 555 /// \brief Loop iteration variable. 556 Expr *IterationVarRef; 557 /// \brief Loop last iteration number. 558 Expr *LastIteration; 559 /// \brief Loop number of iterations. 560 Expr *NumIterations; 561 /// \brief Calculation of last iteration. 562 Expr *CalcLastIteration; 563 /// \brief Loop pre-condition. 564 Expr *PreCond; 565 /// \brief Loop condition. 566 Expr *Cond; 567 /// \brief Loop iteration variable init. 568 Expr *Init; 569 /// \brief Loop increment. 570 Expr *Inc; 571 /// \brief IsLastIteration - local flag variable passed to runtime. 572 Expr *IL; 573 /// \brief LowerBound - local variable passed to runtime. 574 Expr *LB; 575 /// \brief UpperBound - local variable passed to runtime. 576 Expr *UB; 577 /// \brief Stride - local variable passed to runtime. 578 Expr *ST; 579 /// \brief EnsureUpperBound -- expression UB = min(UB, NumIterations). 580 Expr *EUB; 581 /// \brief Update of LowerBound for statically sheduled 'omp for' loops. 582 Expr *NLB; 583 /// \brief Update of UpperBound for statically sheduled 'omp for' loops. 584 Expr *NUB; 585 /// \brief PreviousLowerBound - local variable passed to runtime in the 586 /// enclosing schedule or null if that does not apply. 587 Expr *PrevLB; 588 /// \brief PreviousUpperBound - local variable passed to runtime in the 589 /// enclosing schedule or null if that does not apply. 590 Expr *PrevUB; 591 /// \brief DistInc - increment expression for distribute loop when found 592 /// combined with a further loop level (e.g. in 'distribute parallel for') 593 /// expression IV = IV + ST 594 Expr *DistInc; 595 /// \brief PrevEUB - expression similar to EUB but to be used when loop 596 /// scheduling uses PrevLB and PrevUB (e.g. in 'distribute parallel for' 597 /// when ensuring that the UB is either the calculated UB by the runtime or 598 /// the end of the assigned distribute chunk) 599 /// expression UB = min (UB, PrevUB) 600 Expr *PrevEUB; 601 /// \brief Counters Loop counters. 602 SmallVector<Expr *, 4> Counters; 603 /// \brief PrivateCounters Loop counters. 604 SmallVector<Expr *, 4> PrivateCounters; 605 /// \brief Expressions for loop counters inits for CodeGen. 606 SmallVector<Expr *, 4> Inits; 607 /// \brief Expressions for loop counters update for CodeGen. 608 SmallVector<Expr *, 4> Updates; 609 /// \brief Final loop counter values for GodeGen. 610 SmallVector<Expr *, 4> Finals; 611 /// Init statement for all captured expressions. 612 Stmt *PreInits; 613 614 /// \brief Check if all the expressions are built (does not check the 615 /// worksharing ones). 616 bool builtAll() { 617 return IterationVarRef != nullptr && LastIteration != nullptr && 618 NumIterations != nullptr && PreCond != nullptr && 619 Cond != nullptr && Init != nullptr && Inc != nullptr; 620 } 621 622 /// \brief Initialize all the fields to null. 623 /// \param Size Number of elements in the counters/finals/updates arrays. 624 void clear(unsigned Size) { 625 IterationVarRef = nullptr; 626 LastIteration = nullptr; 627 CalcLastIteration = nullptr; 628 PreCond = nullptr; 629 Cond = nullptr; 630 Init = nullptr; 631 Inc = nullptr; 632 IL = nullptr; 633 LB = nullptr; 634 UB = nullptr; 635 ST = nullptr; 636 EUB = nullptr; 637 NLB = nullptr; 638 NUB = nullptr; 639 NumIterations = nullptr; 640 PrevLB = nullptr; 641 PrevUB = nullptr; 642 DistInc = nullptr; 643 PrevEUB = nullptr; 644 Counters.resize(Size); 645 PrivateCounters.resize(Size); 646 Inits.resize(Size); 647 Updates.resize(Size); 648 Finals.resize(Size); 649 for (unsigned i = 0; i < Size; ++i) { 650 Counters[i] = nullptr; 651 PrivateCounters[i] = nullptr; 652 Inits[i] = nullptr; 653 Updates[i] = nullptr; 654 Finals[i] = nullptr; 655 } 656 PreInits = nullptr; 657 } 658 }; 659 660 /// \brief Get number of collapsed loops. 661 unsigned getCollapsedNumber() const { return CollapsedNum; } 662 663 Expr *getIterationVariable() const { 664 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 665 *std::next(child_begin(), IterationVariableOffset))); 666 } 667 Expr *getLastIteration() const { 668 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 669 *std::next(child_begin(), LastIterationOffset))); 670 } 671 Expr *getCalcLastIteration() const { 672 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 673 *std::next(child_begin(), CalcLastIterationOffset))); 674 } 675 Expr *getPreCond() const { 676 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 677 *std::next(child_begin(), PreConditionOffset))); 678 } 679 Expr *getCond() const { 680 return const_cast<Expr *>( 681 reinterpret_cast<const Expr *>(*std::next(child_begin(), CondOffset))); 682 } 683 Expr *getInit() const { 684 return const_cast<Expr *>( 685 reinterpret_cast<const Expr *>(*std::next(child_begin(), InitOffset))); 686 } 687 Expr *getInc() const { 688 return const_cast<Expr *>( 689 reinterpret_cast<const Expr *>(*std::next(child_begin(), IncOffset))); 690 } 691 const Stmt *getPreInits() const { 692 return *std::next(child_begin(), PreInitsOffset); 693 } 694 Stmt *getPreInits() { return *std::next(child_begin(), PreInitsOffset); } 695 Expr *getIsLastIterVariable() const { 696 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 697 isOpenMPTaskLoopDirective(getDirectiveKind()) || 698 isOpenMPDistributeDirective(getDirectiveKind())) && 699 "expected worksharing loop directive"); 700 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 701 *std::next(child_begin(), IsLastIterVariableOffset))); 702 } 703 Expr *getLowerBoundVariable() const { 704 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 705 isOpenMPTaskLoopDirective(getDirectiveKind()) || 706 isOpenMPDistributeDirective(getDirectiveKind())) && 707 "expected worksharing loop directive"); 708 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 709 *std::next(child_begin(), LowerBoundVariableOffset))); 710 } 711 Expr *getUpperBoundVariable() const { 712 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 713 isOpenMPTaskLoopDirective(getDirectiveKind()) || 714 isOpenMPDistributeDirective(getDirectiveKind())) && 715 "expected worksharing loop directive"); 716 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 717 *std::next(child_begin(), UpperBoundVariableOffset))); 718 } 719 Expr *getStrideVariable() const { 720 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 721 isOpenMPTaskLoopDirective(getDirectiveKind()) || 722 isOpenMPDistributeDirective(getDirectiveKind())) && 723 "expected worksharing loop directive"); 724 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 725 *std::next(child_begin(), StrideVariableOffset))); 726 } 727 Expr *getEnsureUpperBound() const { 728 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 729 isOpenMPTaskLoopDirective(getDirectiveKind()) || 730 isOpenMPDistributeDirective(getDirectiveKind())) && 731 "expected worksharing loop directive"); 732 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 733 *std::next(child_begin(), EnsureUpperBoundOffset))); 734 } 735 Expr *getNextLowerBound() const { 736 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 737 isOpenMPTaskLoopDirective(getDirectiveKind()) || 738 isOpenMPDistributeDirective(getDirectiveKind())) && 739 "expected worksharing loop directive"); 740 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 741 *std::next(child_begin(), NextLowerBoundOffset))); 742 } 743 Expr *getNextUpperBound() const { 744 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 745 isOpenMPTaskLoopDirective(getDirectiveKind()) || 746 isOpenMPDistributeDirective(getDirectiveKind())) && 747 "expected worksharing loop directive"); 748 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 749 *std::next(child_begin(), NextUpperBoundOffset))); 750 } 751 Expr *getNumIterations() const { 752 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 753 isOpenMPTaskLoopDirective(getDirectiveKind()) || 754 isOpenMPDistributeDirective(getDirectiveKind())) && 755 "expected worksharing loop directive"); 756 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 757 *std::next(child_begin(), NumIterationsOffset))); 758 } 759 Expr *getPrevLowerBoundVariable() const { 760 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 761 isOpenMPTaskLoopDirective(getDirectiveKind()) || 762 isOpenMPDistributeDirective(getDirectiveKind())) && 763 "expected worksharing loop directive"); 764 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 765 *std::next(child_begin(), PrevLowerBoundVariableOffset))); 766 } 767 Expr *getPrevUpperBoundVariable() const { 768 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 769 isOpenMPTaskLoopDirective(getDirectiveKind()) || 770 isOpenMPDistributeDirective(getDirectiveKind())) && 771 "expected worksharing loop directive"); 772 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 773 *std::next(child_begin(), PrevUpperBoundVariableOffset))); 774 } 775 Expr *getDistInc() const { 776 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 777 isOpenMPTaskLoopDirective(getDirectiveKind()) || 778 isOpenMPDistributeDirective(getDirectiveKind())) && 779 "expected worksharing loop directive"); 780 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 781 *std::next(child_begin(), DistIncOffset))); 782 } 783 Expr *getPrevEnsureUpperBound() const { 784 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 785 isOpenMPTaskLoopDirective(getDirectiveKind()) || 786 isOpenMPDistributeDirective(getDirectiveKind())) && 787 "expected worksharing loop directive"); 788 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 789 *std::next(child_begin(), PrevEnsureUpperBoundOffset))); 790 } 791 const Stmt *getBody() const { 792 // This relies on the loop form is already checked by Sema. 793 Stmt *Body = getAssociatedStmt()->IgnoreContainers(true); 794 Body = cast<ForStmt>(Body)->getBody(); 795 for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) { 796 Body = Body->IgnoreContainers(); 797 Body = cast<ForStmt>(Body)->getBody(); 798 } 799 return Body; 800 } 801 802 ArrayRef<Expr *> counters() { return getCounters(); } 803 804 ArrayRef<Expr *> counters() const { 805 return const_cast<OMPLoopDirective *>(this)->getCounters(); 806 } 807 808 ArrayRef<Expr *> private_counters() { return getPrivateCounters(); } 809 810 ArrayRef<Expr *> private_counters() const { 811 return const_cast<OMPLoopDirective *>(this)->getPrivateCounters(); 812 } 813 814 ArrayRef<Expr *> inits() { return getInits(); } 815 816 ArrayRef<Expr *> inits() const { 817 return const_cast<OMPLoopDirective *>(this)->getInits(); 818 } 819 820 ArrayRef<Expr *> updates() { return getUpdates(); } 821 822 ArrayRef<Expr *> updates() const { 823 return const_cast<OMPLoopDirective *>(this)->getUpdates(); 824 } 825 826 ArrayRef<Expr *> finals() { return getFinals(); } 827 828 ArrayRef<Expr *> finals() const { 829 return const_cast<OMPLoopDirective *>(this)->getFinals(); 830 } 831 832 static bool classof(const Stmt *T) { 833 return T->getStmtClass() == OMPSimdDirectiveClass || 834 T->getStmtClass() == OMPForDirectiveClass || 835 T->getStmtClass() == OMPForSimdDirectiveClass || 836 T->getStmtClass() == OMPParallelForDirectiveClass || 837 T->getStmtClass() == OMPParallelForSimdDirectiveClass || 838 T->getStmtClass() == OMPTaskLoopDirectiveClass || 839 T->getStmtClass() == OMPTaskLoopSimdDirectiveClass || 840 T->getStmtClass() == OMPDistributeDirectiveClass || 841 T->getStmtClass() == OMPTargetParallelForDirectiveClass || 842 T->getStmtClass() == OMPDistributeParallelForDirectiveClass || 843 T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass || 844 T->getStmtClass() == OMPDistributeSimdDirectiveClass || 845 T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass || 846 T->getStmtClass() == OMPTargetSimdDirectiveClass || 847 T->getStmtClass() == OMPTeamsDistributeDirectiveClass || 848 T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass || 849 T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass || 850 T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass; 851 } 852 }; 853 854 /// \brief This represents '#pragma omp simd' directive. 855 /// 856 /// \code 857 /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d) 858 /// \endcode 859 /// In this example directive '#pragma omp simd' has clauses 'private' 860 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and 861 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'. 862 /// 863 class OMPSimdDirective : public OMPLoopDirective { 864 friend class ASTStmtReader; 865 /// \brief Build directive with the given start and end location. 866 /// 867 /// \param StartLoc Starting location of the directive kind. 868 /// \param EndLoc Ending location of the directive. 869 /// \param CollapsedNum Number of collapsed nested loops. 870 /// \param NumClauses Number of clauses. 871 /// 872 OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 873 unsigned CollapsedNum, unsigned NumClauses) 874 : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc, 875 EndLoc, CollapsedNum, NumClauses) {} 876 877 /// \brief Build an empty directive. 878 /// 879 /// \param CollapsedNum Number of collapsed nested loops. 880 /// \param NumClauses Number of clauses. 881 /// 882 explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses) 883 : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd, 884 SourceLocation(), SourceLocation(), CollapsedNum, 885 NumClauses) {} 886 887 public: 888 /// \brief Creates directive with a list of \a Clauses. 889 /// 890 /// \param C AST context. 891 /// \param StartLoc Starting location of the directive kind. 892 /// \param EndLoc Ending Location of the directive. 893 /// \param CollapsedNum Number of collapsed loops. 894 /// \param Clauses List of clauses. 895 /// \param AssociatedStmt Statement, associated with the directive. 896 /// \param Exprs Helper expressions for CodeGen. 897 /// 898 static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc, 899 SourceLocation EndLoc, unsigned CollapsedNum, 900 ArrayRef<OMPClause *> Clauses, 901 Stmt *AssociatedStmt, 902 const HelperExprs &Exprs); 903 904 /// \brief Creates an empty directive with the place 905 /// for \a NumClauses clauses. 906 /// 907 /// \param C AST context. 908 /// \param CollapsedNum Number of collapsed nested loops. 909 /// \param NumClauses Number of clauses. 910 /// 911 static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 912 unsigned CollapsedNum, EmptyShell); 913 914 static bool classof(const Stmt *T) { 915 return T->getStmtClass() == OMPSimdDirectiveClass; 916 } 917 }; 918 919 /// \brief This represents '#pragma omp for' directive. 920 /// 921 /// \code 922 /// #pragma omp for private(a,b) reduction(+:c,d) 923 /// \endcode 924 /// In this example directive '#pragma omp for' has clauses 'private' with the 925 /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c' 926 /// and 'd'. 927 /// 928 class OMPForDirective : public OMPLoopDirective { 929 friend class ASTStmtReader; 930 931 /// \brief true if current directive has inner cancel directive. 932 bool HasCancel; 933 934 /// \brief Build directive with the given start and end location. 935 /// 936 /// \param StartLoc Starting location of the directive kind. 937 /// \param EndLoc Ending location of the directive. 938 /// \param CollapsedNum Number of collapsed nested loops. 939 /// \param NumClauses Number of clauses. 940 /// 941 OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc, 942 unsigned CollapsedNum, unsigned NumClauses) 943 : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, EndLoc, 944 CollapsedNum, NumClauses), 945 HasCancel(false) {} 946 947 /// \brief Build an empty directive. 948 /// 949 /// \param CollapsedNum Number of collapsed nested loops. 950 /// \param NumClauses Number of clauses. 951 /// 952 explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses) 953 : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, SourceLocation(), 954 SourceLocation(), CollapsedNum, NumClauses), 955 HasCancel(false) {} 956 957 /// \brief Set cancel state. 958 void setHasCancel(bool Has) { HasCancel = Has; } 959 960 public: 961 /// \brief Creates directive with a list of \a Clauses. 962 /// 963 /// \param C AST context. 964 /// \param StartLoc Starting location of the directive kind. 965 /// \param EndLoc Ending Location of the directive. 966 /// \param CollapsedNum Number of collapsed loops. 967 /// \param Clauses List of clauses. 968 /// \param AssociatedStmt Statement, associated with the directive. 969 /// \param Exprs Helper expressions for CodeGen. 970 /// \param HasCancel true if current directive has inner cancel directive. 971 /// 972 static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc, 973 SourceLocation EndLoc, unsigned CollapsedNum, 974 ArrayRef<OMPClause *> Clauses, 975 Stmt *AssociatedStmt, const HelperExprs &Exprs, 976 bool HasCancel); 977 978 /// \brief Creates an empty directive with the place 979 /// for \a NumClauses clauses. 980 /// 981 /// \param C AST context. 982 /// \param CollapsedNum Number of collapsed nested loops. 983 /// \param NumClauses Number of clauses. 984 /// 985 static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 986 unsigned CollapsedNum, EmptyShell); 987 988 /// \brief Return true if current directive has inner cancel directive. 989 bool hasCancel() const { return HasCancel; } 990 991 static bool classof(const Stmt *T) { 992 return T->getStmtClass() == OMPForDirectiveClass; 993 } 994 }; 995 996 /// \brief This represents '#pragma omp for simd' directive. 997 /// 998 /// \code 999 /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d) 1000 /// \endcode 1001 /// In this example directive '#pragma omp for simd' has clauses 'private' 1002 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and 1003 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'. 1004 /// 1005 class OMPForSimdDirective : public OMPLoopDirective { 1006 friend class ASTStmtReader; 1007 /// \brief Build directive with the given start and end location. 1008 /// 1009 /// \param StartLoc Starting location of the directive kind. 1010 /// \param EndLoc Ending location of the directive. 1011 /// \param CollapsedNum Number of collapsed nested loops. 1012 /// \param NumClauses Number of clauses. 1013 /// 1014 OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1015 unsigned CollapsedNum, unsigned NumClauses) 1016 : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd, 1017 StartLoc, EndLoc, CollapsedNum, NumClauses) {} 1018 1019 /// \brief Build an empty directive. 1020 /// 1021 /// \param CollapsedNum Number of collapsed nested loops. 1022 /// \param NumClauses Number of clauses. 1023 /// 1024 explicit OMPForSimdDirective(unsigned CollapsedNum, unsigned NumClauses) 1025 : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd, 1026 SourceLocation(), SourceLocation(), CollapsedNum, 1027 NumClauses) {} 1028 1029 public: 1030 /// \brief Creates directive with a list of \a Clauses. 1031 /// 1032 /// \param C AST context. 1033 /// \param StartLoc Starting location of the directive kind. 1034 /// \param EndLoc Ending Location of the directive. 1035 /// \param CollapsedNum Number of collapsed loops. 1036 /// \param Clauses List of clauses. 1037 /// \param AssociatedStmt Statement, associated with the directive. 1038 /// \param Exprs Helper expressions for CodeGen. 1039 /// 1040 static OMPForSimdDirective * 1041 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1042 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 1043 Stmt *AssociatedStmt, const HelperExprs &Exprs); 1044 1045 /// \brief Creates an empty directive with the place 1046 /// for \a NumClauses clauses. 1047 /// 1048 /// \param C AST context. 1049 /// \param CollapsedNum Number of collapsed nested loops. 1050 /// \param NumClauses Number of clauses. 1051 /// 1052 static OMPForSimdDirective *CreateEmpty(const ASTContext &C, 1053 unsigned NumClauses, 1054 unsigned CollapsedNum, EmptyShell); 1055 1056 static bool classof(const Stmt *T) { 1057 return T->getStmtClass() == OMPForSimdDirectiveClass; 1058 } 1059 }; 1060 1061 /// \brief This represents '#pragma omp sections' directive. 1062 /// 1063 /// \code 1064 /// #pragma omp sections private(a,b) reduction(+:c,d) 1065 /// \endcode 1066 /// In this example directive '#pragma omp sections' has clauses 'private' with 1067 /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables 1068 /// 'c' and 'd'. 1069 /// 1070 class OMPSectionsDirective : public OMPExecutableDirective { 1071 friend class ASTStmtReader; 1072 1073 /// \brief true if current directive has inner cancel directive. 1074 bool HasCancel; 1075 1076 /// \brief Build directive with the given start and end location. 1077 /// 1078 /// \param StartLoc Starting location of the directive kind. 1079 /// \param EndLoc Ending location of the directive. 1080 /// \param NumClauses Number of clauses. 1081 /// 1082 OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1083 unsigned NumClauses) 1084 : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections, 1085 StartLoc, EndLoc, NumClauses, 1), 1086 HasCancel(false) {} 1087 1088 /// \brief Build an empty directive. 1089 /// 1090 /// \param NumClauses Number of clauses. 1091 /// 1092 explicit OMPSectionsDirective(unsigned NumClauses) 1093 : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections, 1094 SourceLocation(), SourceLocation(), NumClauses, 1095 1), 1096 HasCancel(false) {} 1097 1098 /// \brief Set cancel state. 1099 void setHasCancel(bool Has) { HasCancel = Has; } 1100 1101 public: 1102 /// \brief Creates directive with a list of \a Clauses. 1103 /// 1104 /// \param C AST context. 1105 /// \param StartLoc Starting location of the directive kind. 1106 /// \param EndLoc Ending Location of the directive. 1107 /// \param Clauses List of clauses. 1108 /// \param AssociatedStmt Statement, associated with the directive. 1109 /// \param HasCancel true if current directive has inner directive. 1110 /// 1111 static OMPSectionsDirective * 1112 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1113 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel); 1114 1115 /// \brief Creates an empty directive with the place for \a NumClauses 1116 /// clauses. 1117 /// 1118 /// \param C AST context. 1119 /// \param NumClauses Number of clauses. 1120 /// 1121 static OMPSectionsDirective *CreateEmpty(const ASTContext &C, 1122 unsigned NumClauses, EmptyShell); 1123 1124 /// \brief Return true if current directive has inner cancel directive. 1125 bool hasCancel() const { return HasCancel; } 1126 1127 static bool classof(const Stmt *T) { 1128 return T->getStmtClass() == OMPSectionsDirectiveClass; 1129 } 1130 }; 1131 1132 /// \brief This represents '#pragma omp section' directive. 1133 /// 1134 /// \code 1135 /// #pragma omp section 1136 /// \endcode 1137 /// 1138 class OMPSectionDirective : public OMPExecutableDirective { 1139 friend class ASTStmtReader; 1140 1141 /// \brief true if current directive has inner cancel directive. 1142 bool HasCancel; 1143 1144 /// \brief Build directive with the given start and end location. 1145 /// 1146 /// \param StartLoc Starting location of the directive kind. 1147 /// \param EndLoc Ending location of the directive. 1148 /// 1149 OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1150 : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section, 1151 StartLoc, EndLoc, 0, 1), 1152 HasCancel(false) {} 1153 1154 /// \brief Build an empty directive. 1155 /// 1156 explicit OMPSectionDirective() 1157 : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section, 1158 SourceLocation(), SourceLocation(), 0, 1), 1159 HasCancel(false) {} 1160 1161 public: 1162 /// \brief Creates directive. 1163 /// 1164 /// \param C AST context. 1165 /// \param StartLoc Starting location of the directive kind. 1166 /// \param EndLoc Ending Location of the directive. 1167 /// \param AssociatedStmt Statement, associated with the directive. 1168 /// \param HasCancel true if current directive has inner directive. 1169 /// 1170 static OMPSectionDirective *Create(const ASTContext &C, 1171 SourceLocation StartLoc, 1172 SourceLocation EndLoc, 1173 Stmt *AssociatedStmt, bool HasCancel); 1174 1175 /// \brief Creates an empty directive. 1176 /// 1177 /// \param C AST context. 1178 /// 1179 static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell); 1180 1181 /// \brief Set cancel state. 1182 void setHasCancel(bool Has) { HasCancel = Has; } 1183 1184 /// \brief Return true if current directive has inner cancel directive. 1185 bool hasCancel() const { return HasCancel; } 1186 1187 static bool classof(const Stmt *T) { 1188 return T->getStmtClass() == OMPSectionDirectiveClass; 1189 } 1190 }; 1191 1192 /// \brief This represents '#pragma omp single' directive. 1193 /// 1194 /// \code 1195 /// #pragma omp single private(a,b) copyprivate(c,d) 1196 /// \endcode 1197 /// In this example directive '#pragma omp single' has clauses 'private' with 1198 /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'. 1199 /// 1200 class OMPSingleDirective : public OMPExecutableDirective { 1201 friend class ASTStmtReader; 1202 /// \brief Build directive with the given start and end location. 1203 /// 1204 /// \param StartLoc Starting location of the directive kind. 1205 /// \param EndLoc Ending location of the directive. 1206 /// \param NumClauses Number of clauses. 1207 /// 1208 OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1209 unsigned NumClauses) 1210 : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single, 1211 StartLoc, EndLoc, NumClauses, 1) {} 1212 1213 /// \brief Build an empty directive. 1214 /// 1215 /// \param NumClauses Number of clauses. 1216 /// 1217 explicit OMPSingleDirective(unsigned NumClauses) 1218 : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single, 1219 SourceLocation(), SourceLocation(), NumClauses, 1220 1) {} 1221 1222 public: 1223 /// \brief Creates directive with a list of \a Clauses. 1224 /// 1225 /// \param C AST context. 1226 /// \param StartLoc Starting location of the directive kind. 1227 /// \param EndLoc Ending Location of the directive. 1228 /// \param Clauses List of clauses. 1229 /// \param AssociatedStmt Statement, associated with the directive. 1230 /// 1231 static OMPSingleDirective * 1232 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1233 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 1234 1235 /// \brief Creates an empty directive with the place for \a NumClauses 1236 /// clauses. 1237 /// 1238 /// \param C AST context. 1239 /// \param NumClauses Number of clauses. 1240 /// 1241 static OMPSingleDirective *CreateEmpty(const ASTContext &C, 1242 unsigned NumClauses, EmptyShell); 1243 1244 static bool classof(const Stmt *T) { 1245 return T->getStmtClass() == OMPSingleDirectiveClass; 1246 } 1247 }; 1248 1249 /// \brief This represents '#pragma omp master' directive. 1250 /// 1251 /// \code 1252 /// #pragma omp master 1253 /// \endcode 1254 /// 1255 class OMPMasterDirective : public OMPExecutableDirective { 1256 friend class ASTStmtReader; 1257 /// \brief Build directive with the given start and end location. 1258 /// 1259 /// \param StartLoc Starting location of the directive kind. 1260 /// \param EndLoc Ending location of the directive. 1261 /// 1262 OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1263 : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master, 1264 StartLoc, EndLoc, 0, 1) {} 1265 1266 /// \brief Build an empty directive. 1267 /// 1268 explicit OMPMasterDirective() 1269 : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master, 1270 SourceLocation(), SourceLocation(), 0, 1) {} 1271 1272 public: 1273 /// \brief Creates directive. 1274 /// 1275 /// \param C AST context. 1276 /// \param StartLoc Starting location of the directive kind. 1277 /// \param EndLoc Ending Location of the directive. 1278 /// \param AssociatedStmt Statement, associated with the directive. 1279 /// 1280 static OMPMasterDirective *Create(const ASTContext &C, 1281 SourceLocation StartLoc, 1282 SourceLocation EndLoc, 1283 Stmt *AssociatedStmt); 1284 1285 /// \brief Creates an empty directive. 1286 /// 1287 /// \param C AST context. 1288 /// 1289 static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell); 1290 1291 static bool classof(const Stmt *T) { 1292 return T->getStmtClass() == OMPMasterDirectiveClass; 1293 } 1294 }; 1295 1296 /// \brief This represents '#pragma omp critical' directive. 1297 /// 1298 /// \code 1299 /// #pragma omp critical 1300 /// \endcode 1301 /// 1302 class OMPCriticalDirective : public OMPExecutableDirective { 1303 friend class ASTStmtReader; 1304 /// \brief Name of the directive. 1305 DeclarationNameInfo DirName; 1306 /// \brief Build directive with the given start and end location. 1307 /// 1308 /// \param Name Name of the directive. 1309 /// \param StartLoc Starting location of the directive kind. 1310 /// \param EndLoc Ending location of the directive. 1311 /// \param NumClauses Number of clauses. 1312 /// 1313 OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc, 1314 SourceLocation EndLoc, unsigned NumClauses) 1315 : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical, 1316 StartLoc, EndLoc, NumClauses, 1), 1317 DirName(Name) {} 1318 1319 /// \brief Build an empty directive. 1320 /// 1321 /// \param NumClauses Number of clauses. 1322 /// 1323 explicit OMPCriticalDirective(unsigned NumClauses) 1324 : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical, 1325 SourceLocation(), SourceLocation(), NumClauses, 1326 1), 1327 DirName() {} 1328 1329 /// \brief Set name of the directive. 1330 /// 1331 /// \param Name Name of the directive. 1332 /// 1333 void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; } 1334 1335 public: 1336 /// \brief Creates directive. 1337 /// 1338 /// \param C AST context. 1339 /// \param Name Name of the directive. 1340 /// \param StartLoc Starting location of the directive kind. 1341 /// \param EndLoc Ending Location of the directive. 1342 /// \param Clauses List of clauses. 1343 /// \param AssociatedStmt Statement, associated with the directive. 1344 /// 1345 static OMPCriticalDirective * 1346 Create(const ASTContext &C, const DeclarationNameInfo &Name, 1347 SourceLocation StartLoc, SourceLocation EndLoc, 1348 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 1349 1350 /// \brief Creates an empty directive. 1351 /// 1352 /// \param C AST context. 1353 /// \param NumClauses Number of clauses. 1354 /// 1355 static OMPCriticalDirective *CreateEmpty(const ASTContext &C, 1356 unsigned NumClauses, EmptyShell); 1357 1358 /// \brief Return name of the directive. 1359 /// 1360 DeclarationNameInfo getDirectiveName() const { return DirName; } 1361 1362 static bool classof(const Stmt *T) { 1363 return T->getStmtClass() == OMPCriticalDirectiveClass; 1364 } 1365 }; 1366 1367 /// \brief This represents '#pragma omp parallel for' directive. 1368 /// 1369 /// \code 1370 /// #pragma omp parallel for private(a,b) reduction(+:c,d) 1371 /// \endcode 1372 /// In this example directive '#pragma omp parallel for' has clauses 'private' 1373 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and 1374 /// variables 'c' and 'd'. 1375 /// 1376 class OMPParallelForDirective : public OMPLoopDirective { 1377 friend class ASTStmtReader; 1378 1379 /// \brief true if current region has inner cancel directive. 1380 bool HasCancel; 1381 1382 /// \brief Build directive with the given start and end location. 1383 /// 1384 /// \param StartLoc Starting location of the directive kind. 1385 /// \param EndLoc Ending location of the directive. 1386 /// \param CollapsedNum Number of collapsed nested loops. 1387 /// \param NumClauses Number of clauses. 1388 /// 1389 OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1390 unsigned CollapsedNum, unsigned NumClauses) 1391 : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for, 1392 StartLoc, EndLoc, CollapsedNum, NumClauses), 1393 HasCancel(false) {} 1394 1395 /// \brief Build an empty directive. 1396 /// 1397 /// \param CollapsedNum Number of collapsed nested loops. 1398 /// \param NumClauses Number of clauses. 1399 /// 1400 explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses) 1401 : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for, 1402 SourceLocation(), SourceLocation(), CollapsedNum, 1403 NumClauses), 1404 HasCancel(false) {} 1405 1406 /// \brief Set cancel state. 1407 void setHasCancel(bool Has) { HasCancel = Has; } 1408 1409 public: 1410 /// \brief Creates directive with a list of \a Clauses. 1411 /// 1412 /// \param C AST context. 1413 /// \param StartLoc Starting location of the directive kind. 1414 /// \param EndLoc Ending Location of the directive. 1415 /// \param CollapsedNum Number of collapsed loops. 1416 /// \param Clauses List of clauses. 1417 /// \param AssociatedStmt Statement, associated with the directive. 1418 /// \param Exprs Helper expressions for CodeGen. 1419 /// \param HasCancel true if current directive has inner cancel directive. 1420 /// 1421 static OMPParallelForDirective * 1422 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1423 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 1424 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 1425 1426 /// \brief Creates an empty directive with the place 1427 /// for \a NumClauses clauses. 1428 /// 1429 /// \param C AST context. 1430 /// \param CollapsedNum Number of collapsed nested loops. 1431 /// \param NumClauses Number of clauses. 1432 /// 1433 static OMPParallelForDirective *CreateEmpty(const ASTContext &C, 1434 unsigned NumClauses, 1435 unsigned CollapsedNum, 1436 EmptyShell); 1437 1438 /// \brief Return true if current directive has inner cancel directive. 1439 bool hasCancel() const { return HasCancel; } 1440 1441 static bool classof(const Stmt *T) { 1442 return T->getStmtClass() == OMPParallelForDirectiveClass; 1443 } 1444 }; 1445 1446 /// \brief This represents '#pragma omp parallel for simd' directive. 1447 /// 1448 /// \code 1449 /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d) 1450 /// \endcode 1451 /// In this example directive '#pragma omp parallel for simd' has clauses 1452 /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j' 1453 /// and linear step 's', 'reduction' with operator '+' and variables 'c' and 1454 /// 'd'. 1455 /// 1456 class OMPParallelForSimdDirective : public OMPLoopDirective { 1457 friend class ASTStmtReader; 1458 /// \brief Build directive with the given start and end location. 1459 /// 1460 /// \param StartLoc Starting location of the directive kind. 1461 /// \param EndLoc Ending location of the directive. 1462 /// \param CollapsedNum Number of collapsed nested loops. 1463 /// \param NumClauses Number of clauses. 1464 /// 1465 OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1466 unsigned CollapsedNum, unsigned NumClauses) 1467 : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass, 1468 OMPD_parallel_for_simd, StartLoc, EndLoc, CollapsedNum, 1469 NumClauses) {} 1470 1471 /// \brief Build an empty directive. 1472 /// 1473 /// \param CollapsedNum Number of collapsed nested loops. 1474 /// \param NumClauses Number of clauses. 1475 /// 1476 explicit OMPParallelForSimdDirective(unsigned CollapsedNum, 1477 unsigned NumClauses) 1478 : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass, 1479 OMPD_parallel_for_simd, SourceLocation(), 1480 SourceLocation(), CollapsedNum, NumClauses) {} 1481 1482 public: 1483 /// \brief Creates directive with a list of \a Clauses. 1484 /// 1485 /// \param C AST context. 1486 /// \param StartLoc Starting location of the directive kind. 1487 /// \param EndLoc Ending Location of the directive. 1488 /// \param CollapsedNum Number of collapsed loops. 1489 /// \param Clauses List of clauses. 1490 /// \param AssociatedStmt Statement, associated with the directive. 1491 /// \param Exprs Helper expressions for CodeGen. 1492 /// 1493 static OMPParallelForSimdDirective * 1494 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1495 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 1496 Stmt *AssociatedStmt, const HelperExprs &Exprs); 1497 1498 /// \brief Creates an empty directive with the place 1499 /// for \a NumClauses clauses. 1500 /// 1501 /// \param C AST context. 1502 /// \param CollapsedNum Number of collapsed nested loops. 1503 /// \param NumClauses Number of clauses. 1504 /// 1505 static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C, 1506 unsigned NumClauses, 1507 unsigned CollapsedNum, 1508 EmptyShell); 1509 1510 static bool classof(const Stmt *T) { 1511 return T->getStmtClass() == OMPParallelForSimdDirectiveClass; 1512 } 1513 }; 1514 1515 /// \brief This represents '#pragma omp parallel sections' directive. 1516 /// 1517 /// \code 1518 /// #pragma omp parallel sections private(a,b) reduction(+:c,d) 1519 /// \endcode 1520 /// In this example directive '#pragma omp parallel sections' has clauses 1521 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+' 1522 /// and variables 'c' and 'd'. 1523 /// 1524 class OMPParallelSectionsDirective : public OMPExecutableDirective { 1525 friend class ASTStmtReader; 1526 1527 /// \brief true if current directive has inner cancel directive. 1528 bool HasCancel; 1529 1530 /// \brief Build directive with the given start and end location. 1531 /// 1532 /// \param StartLoc Starting location of the directive kind. 1533 /// \param EndLoc Ending location of the directive. 1534 /// \param NumClauses Number of clauses. 1535 /// 1536 OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1537 unsigned NumClauses) 1538 : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass, 1539 OMPD_parallel_sections, StartLoc, EndLoc, 1540 NumClauses, 1), 1541 HasCancel(false) {} 1542 1543 /// \brief Build an empty directive. 1544 /// 1545 /// \param NumClauses Number of clauses. 1546 /// 1547 explicit OMPParallelSectionsDirective(unsigned NumClauses) 1548 : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass, 1549 OMPD_parallel_sections, SourceLocation(), 1550 SourceLocation(), NumClauses, 1), 1551 HasCancel(false) {} 1552 1553 /// \brief Set cancel state. 1554 void setHasCancel(bool Has) { HasCancel = Has; } 1555 1556 public: 1557 /// \brief Creates directive with a list of \a Clauses. 1558 /// 1559 /// \param C AST context. 1560 /// \param StartLoc Starting location of the directive kind. 1561 /// \param EndLoc Ending Location of the directive. 1562 /// \param Clauses List of clauses. 1563 /// \param AssociatedStmt Statement, associated with the directive. 1564 /// \param HasCancel true if current directive has inner cancel directive. 1565 /// 1566 static OMPParallelSectionsDirective * 1567 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1568 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel); 1569 1570 /// \brief Creates an empty directive with the place for \a NumClauses 1571 /// clauses. 1572 /// 1573 /// \param C AST context. 1574 /// \param NumClauses Number of clauses. 1575 /// 1576 static OMPParallelSectionsDirective * 1577 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 1578 1579 /// \brief Return true if current directive has inner cancel directive. 1580 bool hasCancel() const { return HasCancel; } 1581 1582 static bool classof(const Stmt *T) { 1583 return T->getStmtClass() == OMPParallelSectionsDirectiveClass; 1584 } 1585 }; 1586 1587 /// \brief This represents '#pragma omp task' directive. 1588 /// 1589 /// \code 1590 /// #pragma omp task private(a,b) final(d) 1591 /// \endcode 1592 /// In this example directive '#pragma omp task' has clauses 'private' with the 1593 /// variables 'a' and 'b' and 'final' with condition 'd'. 1594 /// 1595 class OMPTaskDirective : public OMPExecutableDirective { 1596 friend class ASTStmtReader; 1597 /// \brief true if this directive has inner cancel directive. 1598 bool HasCancel; 1599 1600 /// \brief Build directive with the given start and end location. 1601 /// 1602 /// \param StartLoc Starting location of the directive kind. 1603 /// \param EndLoc Ending location of the directive. 1604 /// \param NumClauses Number of clauses. 1605 /// 1606 OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1607 unsigned NumClauses) 1608 : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc, 1609 EndLoc, NumClauses, 1), 1610 HasCancel(false) {} 1611 1612 /// \brief Build an empty directive. 1613 /// 1614 /// \param NumClauses Number of clauses. 1615 /// 1616 explicit OMPTaskDirective(unsigned NumClauses) 1617 : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, 1618 SourceLocation(), SourceLocation(), NumClauses, 1619 1), 1620 HasCancel(false) {} 1621 1622 /// \brief Set cancel state. 1623 void setHasCancel(bool Has) { HasCancel = Has; } 1624 1625 public: 1626 /// \brief Creates directive with a list of \a Clauses. 1627 /// 1628 /// \param C AST context. 1629 /// \param StartLoc Starting location of the directive kind. 1630 /// \param EndLoc Ending Location of the directive. 1631 /// \param Clauses List of clauses. 1632 /// \param AssociatedStmt Statement, associated with the directive. 1633 /// \param HasCancel true, if current directive has inner cancel directive. 1634 /// 1635 static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc, 1636 SourceLocation EndLoc, 1637 ArrayRef<OMPClause *> Clauses, 1638 Stmt *AssociatedStmt, bool HasCancel); 1639 1640 /// \brief Creates an empty directive with the place for \a NumClauses 1641 /// clauses. 1642 /// 1643 /// \param C AST context. 1644 /// \param NumClauses Number of clauses. 1645 /// 1646 static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 1647 EmptyShell); 1648 1649 /// \brief Return true if current directive has inner cancel directive. 1650 bool hasCancel() const { return HasCancel; } 1651 1652 static bool classof(const Stmt *T) { 1653 return T->getStmtClass() == OMPTaskDirectiveClass; 1654 } 1655 }; 1656 1657 /// \brief This represents '#pragma omp taskyield' directive. 1658 /// 1659 /// \code 1660 /// #pragma omp taskyield 1661 /// \endcode 1662 /// 1663 class OMPTaskyieldDirective : public OMPExecutableDirective { 1664 friend class ASTStmtReader; 1665 /// \brief Build directive with the given start and end location. 1666 /// 1667 /// \param StartLoc Starting location of the directive kind. 1668 /// \param EndLoc Ending location of the directive. 1669 /// 1670 OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1671 : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield, 1672 StartLoc, EndLoc, 0, 0) {} 1673 1674 /// \brief Build an empty directive. 1675 /// 1676 explicit OMPTaskyieldDirective() 1677 : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield, 1678 SourceLocation(), SourceLocation(), 0, 0) {} 1679 1680 public: 1681 /// \brief Creates directive. 1682 /// 1683 /// \param C AST context. 1684 /// \param StartLoc Starting location of the directive kind. 1685 /// \param EndLoc Ending Location of the directive. 1686 /// 1687 static OMPTaskyieldDirective * 1688 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); 1689 1690 /// \brief Creates an empty directive. 1691 /// 1692 /// \param C AST context. 1693 /// 1694 static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell); 1695 1696 static bool classof(const Stmt *T) { 1697 return T->getStmtClass() == OMPTaskyieldDirectiveClass; 1698 } 1699 }; 1700 1701 /// \brief This represents '#pragma omp barrier' directive. 1702 /// 1703 /// \code 1704 /// #pragma omp barrier 1705 /// \endcode 1706 /// 1707 class OMPBarrierDirective : public OMPExecutableDirective { 1708 friend class ASTStmtReader; 1709 /// \brief Build directive with the given start and end location. 1710 /// 1711 /// \param StartLoc Starting location of the directive kind. 1712 /// \param EndLoc Ending location of the directive. 1713 /// 1714 OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1715 : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier, 1716 StartLoc, EndLoc, 0, 0) {} 1717 1718 /// \brief Build an empty directive. 1719 /// 1720 explicit OMPBarrierDirective() 1721 : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier, 1722 SourceLocation(), SourceLocation(), 0, 0) {} 1723 1724 public: 1725 /// \brief Creates directive. 1726 /// 1727 /// \param C AST context. 1728 /// \param StartLoc Starting location of the directive kind. 1729 /// \param EndLoc Ending Location of the directive. 1730 /// 1731 static OMPBarrierDirective * 1732 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); 1733 1734 /// \brief Creates an empty directive. 1735 /// 1736 /// \param C AST context. 1737 /// 1738 static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell); 1739 1740 static bool classof(const Stmt *T) { 1741 return T->getStmtClass() == OMPBarrierDirectiveClass; 1742 } 1743 }; 1744 1745 /// \brief This represents '#pragma omp taskwait' directive. 1746 /// 1747 /// \code 1748 /// #pragma omp taskwait 1749 /// \endcode 1750 /// 1751 class OMPTaskwaitDirective : public OMPExecutableDirective { 1752 friend class ASTStmtReader; 1753 /// \brief Build directive with the given start and end location. 1754 /// 1755 /// \param StartLoc Starting location of the directive kind. 1756 /// \param EndLoc Ending location of the directive. 1757 /// 1758 OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1759 : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait, 1760 StartLoc, EndLoc, 0, 0) {} 1761 1762 /// \brief Build an empty directive. 1763 /// 1764 explicit OMPTaskwaitDirective() 1765 : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait, 1766 SourceLocation(), SourceLocation(), 0, 0) {} 1767 1768 public: 1769 /// \brief Creates directive. 1770 /// 1771 /// \param C AST context. 1772 /// \param StartLoc Starting location of the directive kind. 1773 /// \param EndLoc Ending Location of the directive. 1774 /// 1775 static OMPTaskwaitDirective * 1776 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); 1777 1778 /// \brief Creates an empty directive. 1779 /// 1780 /// \param C AST context. 1781 /// 1782 static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell); 1783 1784 static bool classof(const Stmt *T) { 1785 return T->getStmtClass() == OMPTaskwaitDirectiveClass; 1786 } 1787 }; 1788 1789 /// \brief This represents '#pragma omp taskgroup' directive. 1790 /// 1791 /// \code 1792 /// #pragma omp taskgroup 1793 /// \endcode 1794 /// 1795 class OMPTaskgroupDirective : public OMPExecutableDirective { 1796 friend class ASTStmtReader; 1797 /// \brief Build directive with the given start and end location. 1798 /// 1799 /// \param StartLoc Starting location of the directive kind. 1800 /// \param EndLoc Ending location of the directive. 1801 /// 1802 OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1803 : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup, 1804 StartLoc, EndLoc, 0, 1) {} 1805 1806 /// \brief Build an empty directive. 1807 /// 1808 explicit OMPTaskgroupDirective() 1809 : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup, 1810 SourceLocation(), SourceLocation(), 0, 1) {} 1811 1812 public: 1813 /// \brief Creates directive. 1814 /// 1815 /// \param C AST context. 1816 /// \param StartLoc Starting location of the directive kind. 1817 /// \param EndLoc Ending Location of the directive. 1818 /// \param AssociatedStmt Statement, associated with the directive. 1819 /// 1820 static OMPTaskgroupDirective *Create(const ASTContext &C, 1821 SourceLocation StartLoc, 1822 SourceLocation EndLoc, 1823 Stmt *AssociatedStmt); 1824 1825 /// \brief Creates an empty directive. 1826 /// 1827 /// \param C AST context. 1828 /// 1829 static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C, EmptyShell); 1830 1831 static bool classof(const Stmt *T) { 1832 return T->getStmtClass() == OMPTaskgroupDirectiveClass; 1833 } 1834 }; 1835 1836 /// \brief This represents '#pragma omp flush' directive. 1837 /// 1838 /// \code 1839 /// #pragma omp flush(a,b) 1840 /// \endcode 1841 /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a' 1842 /// and 'b'. 1843 /// 'omp flush' directive does not have clauses but have an optional list of 1844 /// variables to flush. This list of variables is stored within some fake clause 1845 /// FlushClause. 1846 class OMPFlushDirective : public OMPExecutableDirective { 1847 friend class ASTStmtReader; 1848 /// \brief Build directive with the given start and end location. 1849 /// 1850 /// \param StartLoc Starting location of the directive kind. 1851 /// \param EndLoc Ending location of the directive. 1852 /// \param NumClauses Number of clauses. 1853 /// 1854 OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1855 unsigned NumClauses) 1856 : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush, 1857 StartLoc, EndLoc, NumClauses, 0) {} 1858 1859 /// \brief Build an empty directive. 1860 /// 1861 /// \param NumClauses Number of clauses. 1862 /// 1863 explicit OMPFlushDirective(unsigned NumClauses) 1864 : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush, 1865 SourceLocation(), SourceLocation(), NumClauses, 1866 0) {} 1867 1868 public: 1869 /// \brief Creates directive with a list of \a Clauses. 1870 /// 1871 /// \param C AST context. 1872 /// \param StartLoc Starting location of the directive kind. 1873 /// \param EndLoc Ending Location of the directive. 1874 /// \param Clauses List of clauses (only single OMPFlushClause clause is 1875 /// allowed). 1876 /// 1877 static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc, 1878 SourceLocation EndLoc, 1879 ArrayRef<OMPClause *> Clauses); 1880 1881 /// \brief Creates an empty directive with the place for \a NumClauses 1882 /// clauses. 1883 /// 1884 /// \param C AST context. 1885 /// \param NumClauses Number of clauses. 1886 /// 1887 static OMPFlushDirective *CreateEmpty(const ASTContext &C, 1888 unsigned NumClauses, EmptyShell); 1889 1890 static bool classof(const Stmt *T) { 1891 return T->getStmtClass() == OMPFlushDirectiveClass; 1892 } 1893 }; 1894 1895 /// \brief This represents '#pragma omp ordered' directive. 1896 /// 1897 /// \code 1898 /// #pragma omp ordered 1899 /// \endcode 1900 /// 1901 class OMPOrderedDirective : public OMPExecutableDirective { 1902 friend class ASTStmtReader; 1903 /// \brief Build directive with the given start and end location. 1904 /// 1905 /// \param StartLoc Starting location of the directive kind. 1906 /// \param EndLoc Ending location of the directive. 1907 /// \param NumClauses Number of clauses. 1908 /// 1909 OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1910 unsigned NumClauses) 1911 : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered, 1912 StartLoc, EndLoc, NumClauses, 1) {} 1913 1914 /// \brief Build an empty directive. 1915 /// 1916 /// \param NumClauses Number of clauses. 1917 /// 1918 explicit OMPOrderedDirective(unsigned NumClauses) 1919 : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered, 1920 SourceLocation(), SourceLocation(), NumClauses, 1921 1) {} 1922 1923 public: 1924 /// \brief Creates directive. 1925 /// 1926 /// \param C AST context. 1927 /// \param StartLoc Starting location of the directive kind. 1928 /// \param EndLoc Ending Location of the directive. 1929 /// \param Clauses List of clauses. 1930 /// \param AssociatedStmt Statement, associated with the directive. 1931 /// 1932 static OMPOrderedDirective * 1933 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1934 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 1935 1936 /// \brief Creates an empty directive. 1937 /// 1938 /// \param C AST context. 1939 /// \param NumClauses Number of clauses. 1940 /// 1941 static OMPOrderedDirective *CreateEmpty(const ASTContext &C, 1942 unsigned NumClauses, EmptyShell); 1943 1944 static bool classof(const Stmt *T) { 1945 return T->getStmtClass() == OMPOrderedDirectiveClass; 1946 } 1947 }; 1948 1949 /// \brief This represents '#pragma omp atomic' directive. 1950 /// 1951 /// \code 1952 /// #pragma omp atomic capture 1953 /// \endcode 1954 /// In this example directive '#pragma omp atomic' has clause 'capture'. 1955 /// 1956 class OMPAtomicDirective : public OMPExecutableDirective { 1957 friend class ASTStmtReader; 1958 /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may 1959 /// have atomic expressions of forms 1960 /// \code 1961 /// x = x binop expr; 1962 /// x = expr binop x; 1963 /// \endcode 1964 /// This field is true for the first form of the expression and false for the 1965 /// second. Required for correct codegen of non-associative operations (like 1966 /// << or >>). 1967 bool IsXLHSInRHSPart; 1968 /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may 1969 /// have atomic expressions of forms 1970 /// \code 1971 /// v = x; <update x>; 1972 /// <update x>; v = x; 1973 /// \endcode 1974 /// This field is true for the first(postfix) form of the expression and false 1975 /// otherwise. 1976 bool IsPostfixUpdate; 1977 1978 /// \brief Build directive with the given start and end location. 1979 /// 1980 /// \param StartLoc Starting location of the directive kind. 1981 /// \param EndLoc Ending location of the directive. 1982 /// \param NumClauses Number of clauses. 1983 /// 1984 OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1985 unsigned NumClauses) 1986 : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic, 1987 StartLoc, EndLoc, NumClauses, 5), 1988 IsXLHSInRHSPart(false), IsPostfixUpdate(false) {} 1989 1990 /// \brief Build an empty directive. 1991 /// 1992 /// \param NumClauses Number of clauses. 1993 /// 1994 explicit OMPAtomicDirective(unsigned NumClauses) 1995 : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic, 1996 SourceLocation(), SourceLocation(), NumClauses, 1997 5), 1998 IsXLHSInRHSPart(false), IsPostfixUpdate(false) {} 1999 2000 /// \brief Set 'x' part of the associated expression/statement. 2001 void setX(Expr *X) { *std::next(child_begin()) = X; } 2002 /// \brief Set helper expression of the form 2003 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 2004 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 2005 void setUpdateExpr(Expr *UE) { *std::next(child_begin(), 2) = UE; } 2006 /// \brief Set 'v' part of the associated expression/statement. 2007 void setV(Expr *V) { *std::next(child_begin(), 3) = V; } 2008 /// \brief Set 'expr' part of the associated expression/statement. 2009 void setExpr(Expr *E) { *std::next(child_begin(), 4) = E; } 2010 2011 public: 2012 /// \brief Creates directive with a list of \a Clauses and 'x', 'v' and 'expr' 2013 /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for 2014 /// detailed description of 'x', 'v' and 'expr'). 2015 /// 2016 /// \param C AST context. 2017 /// \param StartLoc Starting location of the directive kind. 2018 /// \param EndLoc Ending Location of the directive. 2019 /// \param Clauses List of clauses. 2020 /// \param AssociatedStmt Statement, associated with the directive. 2021 /// \param X 'x' part of the associated expression/statement. 2022 /// \param V 'v' part of the associated expression/statement. 2023 /// \param E 'expr' part of the associated expression/statement. 2024 /// \param UE Helper expression of the form 2025 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 2026 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 2027 /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the 2028 /// second. 2029 /// \param IsPostfixUpdate true if original value of 'x' must be stored in 2030 /// 'v', not an updated one. 2031 static OMPAtomicDirective * 2032 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2033 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V, 2034 Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate); 2035 2036 /// \brief Creates an empty directive with the place for \a NumClauses 2037 /// clauses. 2038 /// 2039 /// \param C AST context. 2040 /// \param NumClauses Number of clauses. 2041 /// 2042 static OMPAtomicDirective *CreateEmpty(const ASTContext &C, 2043 unsigned NumClauses, EmptyShell); 2044 2045 /// \brief Get 'x' part of the associated expression/statement. 2046 Expr *getX() { return cast_or_null<Expr>(*std::next(child_begin())); } 2047 const Expr *getX() const { 2048 return cast_or_null<Expr>(*std::next(child_begin())); 2049 } 2050 /// \brief Get helper expression of the form 2051 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 2052 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 2053 Expr *getUpdateExpr() { 2054 return cast_or_null<Expr>(*std::next(child_begin(), 2)); 2055 } 2056 const Expr *getUpdateExpr() const { 2057 return cast_or_null<Expr>(*std::next(child_begin(), 2)); 2058 } 2059 /// \brief Return true if helper update expression has form 2060 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form 2061 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 2062 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 2063 /// \brief Return true if 'v' expression must be updated to original value of 2064 /// 'x', false if 'v' must be updated to the new value of 'x'. 2065 bool isPostfixUpdate() const { return IsPostfixUpdate; } 2066 /// \brief Get 'v' part of the associated expression/statement. 2067 Expr *getV() { return cast_or_null<Expr>(*std::next(child_begin(), 3)); } 2068 const Expr *getV() const { 2069 return cast_or_null<Expr>(*std::next(child_begin(), 3)); 2070 } 2071 /// \brief Get 'expr' part of the associated expression/statement. 2072 Expr *getExpr() { return cast_or_null<Expr>(*std::next(child_begin(), 4)); } 2073 const Expr *getExpr() const { 2074 return cast_or_null<Expr>(*std::next(child_begin(), 4)); 2075 } 2076 2077 static bool classof(const Stmt *T) { 2078 return T->getStmtClass() == OMPAtomicDirectiveClass; 2079 } 2080 }; 2081 2082 /// \brief This represents '#pragma omp target' directive. 2083 /// 2084 /// \code 2085 /// #pragma omp target if(a) 2086 /// \endcode 2087 /// In this example directive '#pragma omp target' has clause 'if' with 2088 /// condition 'a'. 2089 /// 2090 class OMPTargetDirective : public OMPExecutableDirective { 2091 friend class ASTStmtReader; 2092 /// \brief Build directive with the given start and end location. 2093 /// 2094 /// \param StartLoc Starting location of the directive kind. 2095 /// \param EndLoc Ending location of the directive. 2096 /// \param NumClauses Number of clauses. 2097 /// 2098 OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2099 unsigned NumClauses) 2100 : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target, 2101 StartLoc, EndLoc, NumClauses, 1) {} 2102 2103 /// \brief Build an empty directive. 2104 /// 2105 /// \param NumClauses Number of clauses. 2106 /// 2107 explicit OMPTargetDirective(unsigned NumClauses) 2108 : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target, 2109 SourceLocation(), SourceLocation(), NumClauses, 2110 1) {} 2111 2112 public: 2113 /// \brief Creates directive with a list of \a Clauses. 2114 /// 2115 /// \param C AST context. 2116 /// \param StartLoc Starting location of the directive kind. 2117 /// \param EndLoc Ending Location of the directive. 2118 /// \param Clauses List of clauses. 2119 /// \param AssociatedStmt Statement, associated with the directive. 2120 /// 2121 static OMPTargetDirective * 2122 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2123 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 2124 2125 /// \brief Creates an empty directive with the place for \a NumClauses 2126 /// clauses. 2127 /// 2128 /// \param C AST context. 2129 /// \param NumClauses Number of clauses. 2130 /// 2131 static OMPTargetDirective *CreateEmpty(const ASTContext &C, 2132 unsigned NumClauses, EmptyShell); 2133 2134 static bool classof(const Stmt *T) { 2135 return T->getStmtClass() == OMPTargetDirectiveClass; 2136 } 2137 }; 2138 2139 /// \brief This represents '#pragma omp target data' directive. 2140 /// 2141 /// \code 2142 /// #pragma omp target data device(0) if(a) map(b[:]) 2143 /// \endcode 2144 /// In this example directive '#pragma omp target data' has clauses 'device' 2145 /// with the value '0', 'if' with condition 'a' and 'map' with array 2146 /// section 'b[:]'. 2147 /// 2148 class OMPTargetDataDirective : public OMPExecutableDirective { 2149 friend class ASTStmtReader; 2150 /// \brief Build directive with the given start and end location. 2151 /// 2152 /// \param StartLoc Starting location of the directive kind. 2153 /// \param EndLoc Ending Location of the directive. 2154 /// \param NumClauses The number of clauses. 2155 /// 2156 OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2157 unsigned NumClauses) 2158 : OMPExecutableDirective(this, OMPTargetDataDirectiveClass, 2159 OMPD_target_data, StartLoc, EndLoc, NumClauses, 2160 1) {} 2161 2162 /// \brief Build an empty directive. 2163 /// 2164 /// \param NumClauses Number of clauses. 2165 /// 2166 explicit OMPTargetDataDirective(unsigned NumClauses) 2167 : OMPExecutableDirective(this, OMPTargetDataDirectiveClass, 2168 OMPD_target_data, SourceLocation(), 2169 SourceLocation(), NumClauses, 1) {} 2170 2171 public: 2172 /// \brief Creates directive with a list of \a Clauses. 2173 /// 2174 /// \param C AST context. 2175 /// \param StartLoc Starting location of the directive kind. 2176 /// \param EndLoc Ending Location of the directive. 2177 /// \param Clauses List of clauses. 2178 /// \param AssociatedStmt Statement, associated with the directive. 2179 /// 2180 static OMPTargetDataDirective * 2181 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2182 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 2183 2184 /// \brief Creates an empty directive with the place for \a N clauses. 2185 /// 2186 /// \param C AST context. 2187 /// \param N The number of clauses. 2188 /// 2189 static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N, 2190 EmptyShell); 2191 2192 static bool classof(const Stmt *T) { 2193 return T->getStmtClass() == OMPTargetDataDirectiveClass; 2194 } 2195 }; 2196 2197 /// \brief This represents '#pragma omp target enter data' directive. 2198 /// 2199 /// \code 2200 /// #pragma omp target enter data device(0) if(a) map(b[:]) 2201 /// \endcode 2202 /// In this example directive '#pragma omp target enter data' has clauses 2203 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array 2204 /// section 'b[:]'. 2205 /// 2206 class OMPTargetEnterDataDirective : public OMPExecutableDirective { 2207 friend class ASTStmtReader; 2208 /// \brief Build directive with the given start and end location. 2209 /// 2210 /// \param StartLoc Starting location of the directive kind. 2211 /// \param EndLoc Ending Location of the directive. 2212 /// \param NumClauses The number of clauses. 2213 /// 2214 OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2215 unsigned NumClauses) 2216 : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass, 2217 OMPD_target_enter_data, StartLoc, EndLoc, 2218 NumClauses, /*NumChildren=*/0) {} 2219 2220 /// \brief Build an empty directive. 2221 /// 2222 /// \param NumClauses Number of clauses. 2223 /// 2224 explicit OMPTargetEnterDataDirective(unsigned NumClauses) 2225 : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass, 2226 OMPD_target_enter_data, SourceLocation(), 2227 SourceLocation(), NumClauses, 2228 /*NumChildren=*/0) {} 2229 2230 public: 2231 /// \brief Creates directive with a list of \a Clauses. 2232 /// 2233 /// \param C AST context. 2234 /// \param StartLoc Starting location of the directive kind. 2235 /// \param EndLoc Ending Location of the directive. 2236 /// \param Clauses List of clauses. 2237 /// 2238 static OMPTargetEnterDataDirective *Create(const ASTContext &C, 2239 SourceLocation StartLoc, 2240 SourceLocation EndLoc, 2241 ArrayRef<OMPClause *> Clauses); 2242 2243 /// \brief Creates an empty directive with the place for \a N clauses. 2244 /// 2245 /// \param C AST context. 2246 /// \param N The number of clauses. 2247 /// 2248 static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C, 2249 unsigned N, EmptyShell); 2250 2251 static bool classof(const Stmt *T) { 2252 return T->getStmtClass() == OMPTargetEnterDataDirectiveClass; 2253 } 2254 }; 2255 2256 /// \brief This represents '#pragma omp target exit data' directive. 2257 /// 2258 /// \code 2259 /// #pragma omp target exit data device(0) if(a) map(b[:]) 2260 /// \endcode 2261 /// In this example directive '#pragma omp target exit data' has clauses 2262 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array 2263 /// section 'b[:]'. 2264 /// 2265 class OMPTargetExitDataDirective : public OMPExecutableDirective { 2266 friend class ASTStmtReader; 2267 /// \brief Build directive with the given start and end location. 2268 /// 2269 /// \param StartLoc Starting location of the directive kind. 2270 /// \param EndLoc Ending Location of the directive. 2271 /// \param NumClauses The number of clauses. 2272 /// 2273 OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2274 unsigned NumClauses) 2275 : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass, 2276 OMPD_target_exit_data, StartLoc, EndLoc, 2277 NumClauses, /*NumChildren=*/0) {} 2278 2279 /// \brief Build an empty directive. 2280 /// 2281 /// \param NumClauses Number of clauses. 2282 /// 2283 explicit OMPTargetExitDataDirective(unsigned NumClauses) 2284 : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass, 2285 OMPD_target_exit_data, SourceLocation(), 2286 SourceLocation(), NumClauses, 2287 /*NumChildren=*/0) {} 2288 2289 public: 2290 /// \brief Creates directive with a list of \a Clauses. 2291 /// 2292 /// \param C AST context. 2293 /// \param StartLoc Starting location of the directive kind. 2294 /// \param EndLoc Ending Location of the directive. 2295 /// \param Clauses List of clauses. 2296 /// 2297 static OMPTargetExitDataDirective *Create(const ASTContext &C, 2298 SourceLocation StartLoc, 2299 SourceLocation EndLoc, 2300 ArrayRef<OMPClause *> Clauses); 2301 2302 /// \brief Creates an empty directive with the place for \a N clauses. 2303 /// 2304 /// \param C AST context. 2305 /// \param N The number of clauses. 2306 /// 2307 static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C, 2308 unsigned N, EmptyShell); 2309 2310 static bool classof(const Stmt *T) { 2311 return T->getStmtClass() == OMPTargetExitDataDirectiveClass; 2312 } 2313 }; 2314 2315 /// \brief This represents '#pragma omp target parallel' directive. 2316 /// 2317 /// \code 2318 /// #pragma omp target parallel if(a) 2319 /// \endcode 2320 /// In this example directive '#pragma omp target parallel' has clause 'if' with 2321 /// condition 'a'. 2322 /// 2323 class OMPTargetParallelDirective : public OMPExecutableDirective { 2324 friend class ASTStmtReader; 2325 /// \brief Build directive with the given start and end location. 2326 /// 2327 /// \param StartLoc Starting location of the directive kind. 2328 /// \param EndLoc Ending location of the directive. 2329 /// \param NumClauses Number of clauses. 2330 /// 2331 OMPTargetParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2332 unsigned NumClauses) 2333 : OMPExecutableDirective(this, OMPTargetParallelDirectiveClass, 2334 OMPD_target_parallel, StartLoc, EndLoc, 2335 NumClauses, /*NumChildren=*/1) {} 2336 2337 /// \brief Build an empty directive. 2338 /// 2339 /// \param NumClauses Number of clauses. 2340 /// 2341 explicit OMPTargetParallelDirective(unsigned NumClauses) 2342 : OMPExecutableDirective(this, OMPTargetParallelDirectiveClass, 2343 OMPD_target_parallel, SourceLocation(), 2344 SourceLocation(), NumClauses, 2345 /*NumChildren=*/1) {} 2346 2347 public: 2348 /// \brief Creates directive with a list of \a Clauses. 2349 /// 2350 /// \param C AST context. 2351 /// \param StartLoc Starting location of the directive kind. 2352 /// \param EndLoc Ending Location of the directive. 2353 /// \param Clauses List of clauses. 2354 /// \param AssociatedStmt Statement, associated with the directive. 2355 /// 2356 static OMPTargetParallelDirective * 2357 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2358 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 2359 2360 /// \brief Creates an empty directive with the place for \a NumClauses 2361 /// clauses. 2362 /// 2363 /// \param C AST context. 2364 /// \param NumClauses Number of clauses. 2365 /// 2366 static OMPTargetParallelDirective * 2367 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 2368 2369 static bool classof(const Stmt *T) { 2370 return T->getStmtClass() == OMPTargetParallelDirectiveClass; 2371 } 2372 }; 2373 2374 /// \brief This represents '#pragma omp target parallel for' directive. 2375 /// 2376 /// \code 2377 /// #pragma omp target parallel for private(a,b) reduction(+:c,d) 2378 /// \endcode 2379 /// In this example directive '#pragma omp target parallel for' has clauses 2380 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+' 2381 /// and variables 'c' and 'd'. 2382 /// 2383 class OMPTargetParallelForDirective : public OMPLoopDirective { 2384 friend class ASTStmtReader; 2385 2386 /// \brief true if current region has inner cancel directive. 2387 bool HasCancel; 2388 2389 /// \brief Build directive with the given start and end location. 2390 /// 2391 /// \param StartLoc Starting location of the directive kind. 2392 /// \param EndLoc Ending location of the directive. 2393 /// \param CollapsedNum Number of collapsed nested loops. 2394 /// \param NumClauses Number of clauses. 2395 /// 2396 OMPTargetParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2397 unsigned CollapsedNum, unsigned NumClauses) 2398 : OMPLoopDirective(this, OMPTargetParallelForDirectiveClass, 2399 OMPD_target_parallel_for, StartLoc, EndLoc, 2400 CollapsedNum, NumClauses), 2401 HasCancel(false) {} 2402 2403 /// \brief Build an empty directive. 2404 /// 2405 /// \param CollapsedNum Number of collapsed nested loops. 2406 /// \param NumClauses Number of clauses. 2407 /// 2408 explicit OMPTargetParallelForDirective(unsigned CollapsedNum, 2409 unsigned NumClauses) 2410 : OMPLoopDirective(this, OMPTargetParallelForDirectiveClass, 2411 OMPD_target_parallel_for, SourceLocation(), 2412 SourceLocation(), CollapsedNum, NumClauses), 2413 HasCancel(false) {} 2414 2415 /// \brief Set cancel state. 2416 void setHasCancel(bool Has) { HasCancel = Has; } 2417 2418 public: 2419 /// \brief Creates directive with a list of \a Clauses. 2420 /// 2421 /// \param C AST context. 2422 /// \param StartLoc Starting location of the directive kind. 2423 /// \param EndLoc Ending Location of the directive. 2424 /// \param CollapsedNum Number of collapsed loops. 2425 /// \param Clauses List of clauses. 2426 /// \param AssociatedStmt Statement, associated with the directive. 2427 /// \param Exprs Helper expressions for CodeGen. 2428 /// \param HasCancel true if current directive has inner cancel directive. 2429 /// 2430 static OMPTargetParallelForDirective * 2431 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2432 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 2433 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 2434 2435 /// \brief Creates an empty directive with the place 2436 /// for \a NumClauses clauses. 2437 /// 2438 /// \param C AST context. 2439 /// \param CollapsedNum Number of collapsed nested loops. 2440 /// \param NumClauses Number of clauses. 2441 /// 2442 static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C, 2443 unsigned NumClauses, 2444 unsigned CollapsedNum, 2445 EmptyShell); 2446 2447 /// \brief Return true if current directive has inner cancel directive. 2448 bool hasCancel() const { return HasCancel; } 2449 2450 static bool classof(const Stmt *T) { 2451 return T->getStmtClass() == OMPTargetParallelForDirectiveClass; 2452 } 2453 }; 2454 2455 /// \brief This represents '#pragma omp teams' directive. 2456 /// 2457 /// \code 2458 /// #pragma omp teams if(a) 2459 /// \endcode 2460 /// In this example directive '#pragma omp teams' has clause 'if' with 2461 /// condition 'a'. 2462 /// 2463 class OMPTeamsDirective : public OMPExecutableDirective { 2464 friend class ASTStmtReader; 2465 /// \brief Build directive with the given start and end location. 2466 /// 2467 /// \param StartLoc Starting location of the directive kind. 2468 /// \param EndLoc Ending location of the directive. 2469 /// \param NumClauses Number of clauses. 2470 /// 2471 OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2472 unsigned NumClauses) 2473 : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams, 2474 StartLoc, EndLoc, NumClauses, 1) {} 2475 2476 /// \brief Build an empty directive. 2477 /// 2478 /// \param NumClauses Number of clauses. 2479 /// 2480 explicit OMPTeamsDirective(unsigned NumClauses) 2481 : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams, 2482 SourceLocation(), SourceLocation(), NumClauses, 2483 1) {} 2484 2485 public: 2486 /// \brief Creates directive with a list of \a Clauses. 2487 /// 2488 /// \param C AST context. 2489 /// \param StartLoc Starting location of the directive kind. 2490 /// \param EndLoc Ending Location of the directive. 2491 /// \param Clauses List of clauses. 2492 /// \param AssociatedStmt Statement, associated with the directive. 2493 /// 2494 static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc, 2495 SourceLocation EndLoc, 2496 ArrayRef<OMPClause *> Clauses, 2497 Stmt *AssociatedStmt); 2498 2499 /// \brief Creates an empty directive with the place for \a NumClauses 2500 /// clauses. 2501 /// 2502 /// \param C AST context. 2503 /// \param NumClauses Number of clauses. 2504 /// 2505 static OMPTeamsDirective *CreateEmpty(const ASTContext &C, 2506 unsigned NumClauses, EmptyShell); 2507 2508 static bool classof(const Stmt *T) { 2509 return T->getStmtClass() == OMPTeamsDirectiveClass; 2510 } 2511 }; 2512 2513 /// \brief This represents '#pragma omp cancellation point' directive. 2514 /// 2515 /// \code 2516 /// #pragma omp cancellation point for 2517 /// \endcode 2518 /// 2519 /// In this example a cancellation point is created for innermost 'for' region. 2520 class OMPCancellationPointDirective : public OMPExecutableDirective { 2521 friend class ASTStmtReader; 2522 OpenMPDirectiveKind CancelRegion; 2523 /// \brief Build directive with the given start and end location. 2524 /// 2525 /// \param StartLoc Starting location of the directive kind. 2526 /// \param EndLoc Ending location of the directive. 2527 /// 2528 OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2529 : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass, 2530 OMPD_cancellation_point, StartLoc, EndLoc, 0, 0), 2531 CancelRegion(OMPD_unknown) {} 2532 2533 /// \brief Build an empty directive. 2534 /// 2535 explicit OMPCancellationPointDirective() 2536 : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass, 2537 OMPD_cancellation_point, SourceLocation(), 2538 SourceLocation(), 0, 0), 2539 CancelRegion(OMPD_unknown) {} 2540 2541 /// \brief Set cancel region for current cancellation point. 2542 /// \param CR Cancellation region. 2543 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; } 2544 2545 public: 2546 /// \brief Creates directive. 2547 /// 2548 /// \param C AST context. 2549 /// \param StartLoc Starting location of the directive kind. 2550 /// \param EndLoc Ending Location of the directive. 2551 /// 2552 static OMPCancellationPointDirective * 2553 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2554 OpenMPDirectiveKind CancelRegion); 2555 2556 /// \brief Creates an empty directive. 2557 /// 2558 /// \param C AST context. 2559 /// 2560 static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C, 2561 EmptyShell); 2562 2563 /// \brief Get cancellation region for the current cancellation point. 2564 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } 2565 2566 static bool classof(const Stmt *T) { 2567 return T->getStmtClass() == OMPCancellationPointDirectiveClass; 2568 } 2569 }; 2570 2571 /// \brief This represents '#pragma omp cancel' directive. 2572 /// 2573 /// \code 2574 /// #pragma omp cancel for 2575 /// \endcode 2576 /// 2577 /// In this example a cancel is created for innermost 'for' region. 2578 class OMPCancelDirective : public OMPExecutableDirective { 2579 friend class ASTStmtReader; 2580 OpenMPDirectiveKind CancelRegion; 2581 /// \brief Build directive with the given start and end location. 2582 /// 2583 /// \param StartLoc Starting location of the directive kind. 2584 /// \param EndLoc Ending location of the directive. 2585 /// \param NumClauses Number of clauses. 2586 /// 2587 OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2588 unsigned NumClauses) 2589 : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel, 2590 StartLoc, EndLoc, NumClauses, 0), 2591 CancelRegion(OMPD_unknown) {} 2592 2593 /// \brief Build an empty directive. 2594 /// 2595 /// \param NumClauses Number of clauses. 2596 explicit OMPCancelDirective(unsigned NumClauses) 2597 : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel, 2598 SourceLocation(), SourceLocation(), NumClauses, 2599 0), 2600 CancelRegion(OMPD_unknown) {} 2601 2602 /// \brief Set cancel region for current cancellation point. 2603 /// \param CR Cancellation region. 2604 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; } 2605 2606 public: 2607 /// \brief Creates directive. 2608 /// 2609 /// \param C AST context. 2610 /// \param StartLoc Starting location of the directive kind. 2611 /// \param EndLoc Ending Location of the directive. 2612 /// \param Clauses List of clauses. 2613 /// 2614 static OMPCancelDirective * 2615 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2616 ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion); 2617 2618 /// \brief Creates an empty directive. 2619 /// 2620 /// \param C AST context. 2621 /// \param NumClauses Number of clauses. 2622 /// 2623 static OMPCancelDirective *CreateEmpty(const ASTContext &C, 2624 unsigned NumClauses, EmptyShell); 2625 2626 /// \brief Get cancellation region for the current cancellation point. 2627 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } 2628 2629 static bool classof(const Stmt *T) { 2630 return T->getStmtClass() == OMPCancelDirectiveClass; 2631 } 2632 }; 2633 2634 /// \brief This represents '#pragma omp taskloop' directive. 2635 /// 2636 /// \code 2637 /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num) 2638 /// \endcode 2639 /// In this example directive '#pragma omp taskloop' has clauses 'private' 2640 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and 2641 /// 'num_tasks' with expression 'num'. 2642 /// 2643 class OMPTaskLoopDirective : public OMPLoopDirective { 2644 friend class ASTStmtReader; 2645 /// \brief Build directive with the given start and end location. 2646 /// 2647 /// \param StartLoc Starting location of the directive kind. 2648 /// \param EndLoc Ending location of the directive. 2649 /// \param CollapsedNum Number of collapsed nested loops. 2650 /// \param NumClauses Number of clauses. 2651 /// 2652 OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2653 unsigned CollapsedNum, unsigned NumClauses) 2654 : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop, 2655 StartLoc, EndLoc, CollapsedNum, NumClauses) {} 2656 2657 /// \brief Build an empty directive. 2658 /// 2659 /// \param CollapsedNum Number of collapsed nested loops. 2660 /// \param NumClauses Number of clauses. 2661 /// 2662 explicit OMPTaskLoopDirective(unsigned CollapsedNum, unsigned NumClauses) 2663 : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop, 2664 SourceLocation(), SourceLocation(), CollapsedNum, 2665 NumClauses) {} 2666 2667 public: 2668 /// \brief Creates directive with a list of \a Clauses. 2669 /// 2670 /// \param C AST context. 2671 /// \param StartLoc Starting location of the directive kind. 2672 /// \param EndLoc Ending Location of the directive. 2673 /// \param CollapsedNum Number of collapsed loops. 2674 /// \param Clauses List of clauses. 2675 /// \param AssociatedStmt Statement, associated with the directive. 2676 /// \param Exprs Helper expressions for CodeGen. 2677 /// 2678 static OMPTaskLoopDirective * 2679 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2680 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 2681 Stmt *AssociatedStmt, const HelperExprs &Exprs); 2682 2683 /// \brief Creates an empty directive with the place 2684 /// for \a NumClauses clauses. 2685 /// 2686 /// \param C AST context. 2687 /// \param CollapsedNum Number of collapsed nested loops. 2688 /// \param NumClauses Number of clauses. 2689 /// 2690 static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C, 2691 unsigned NumClauses, 2692 unsigned CollapsedNum, EmptyShell); 2693 2694 static bool classof(const Stmt *T) { 2695 return T->getStmtClass() == OMPTaskLoopDirectiveClass; 2696 } 2697 }; 2698 2699 /// \brief This represents '#pragma omp taskloop simd' directive. 2700 /// 2701 /// \code 2702 /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num) 2703 /// \endcode 2704 /// In this example directive '#pragma omp taskloop simd' has clauses 'private' 2705 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and 2706 /// 'num_tasks' with expression 'num'. 2707 /// 2708 class OMPTaskLoopSimdDirective : public OMPLoopDirective { 2709 friend class ASTStmtReader; 2710 /// \brief Build directive with the given start and end location. 2711 /// 2712 /// \param StartLoc Starting location of the directive kind. 2713 /// \param EndLoc Ending location of the directive. 2714 /// \param CollapsedNum Number of collapsed nested loops. 2715 /// \param NumClauses Number of clauses. 2716 /// 2717 OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2718 unsigned CollapsedNum, unsigned NumClauses) 2719 : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass, 2720 OMPD_taskloop_simd, StartLoc, EndLoc, CollapsedNum, 2721 NumClauses) {} 2722 2723 /// \brief Build an empty directive. 2724 /// 2725 /// \param CollapsedNum Number of collapsed nested loops. 2726 /// \param NumClauses Number of clauses. 2727 /// 2728 explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum, unsigned NumClauses) 2729 : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass, 2730 OMPD_taskloop_simd, SourceLocation(), SourceLocation(), 2731 CollapsedNum, NumClauses) {} 2732 2733 public: 2734 /// \brief Creates directive with a list of \a Clauses. 2735 /// 2736 /// \param C AST context. 2737 /// \param StartLoc Starting location of the directive kind. 2738 /// \param EndLoc Ending Location of the directive. 2739 /// \param CollapsedNum Number of collapsed loops. 2740 /// \param Clauses List of clauses. 2741 /// \param AssociatedStmt Statement, associated with the directive. 2742 /// \param Exprs Helper expressions for CodeGen. 2743 /// 2744 static OMPTaskLoopSimdDirective * 2745 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2746 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 2747 Stmt *AssociatedStmt, const HelperExprs &Exprs); 2748 2749 /// \brief Creates an empty directive with the place 2750 /// for \a NumClauses clauses. 2751 /// 2752 /// \param C AST context. 2753 /// \param CollapsedNum Number of collapsed nested loops. 2754 /// \param NumClauses Number of clauses. 2755 /// 2756 static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, 2757 unsigned NumClauses, 2758 unsigned CollapsedNum, 2759 EmptyShell); 2760 2761 static bool classof(const Stmt *T) { 2762 return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass; 2763 } 2764 }; 2765 2766 /// \brief This represents '#pragma omp distribute' directive. 2767 /// 2768 /// \code 2769 /// #pragma omp distribute private(a,b) 2770 /// \endcode 2771 /// In this example directive '#pragma omp distribute' has clauses 'private' 2772 /// with the variables 'a' and 'b' 2773 /// 2774 class OMPDistributeDirective : public OMPLoopDirective { 2775 friend class ASTStmtReader; 2776 2777 /// \brief Build directive with the given start and end location. 2778 /// 2779 /// \param StartLoc Starting location of the directive kind. 2780 /// \param EndLoc Ending location of the directive. 2781 /// \param CollapsedNum Number of collapsed nested loops. 2782 /// \param NumClauses Number of clauses. 2783 /// 2784 OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2785 unsigned CollapsedNum, unsigned NumClauses) 2786 : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute, 2787 StartLoc, EndLoc, CollapsedNum, NumClauses) 2788 {} 2789 2790 /// \brief Build an empty directive. 2791 /// 2792 /// \param CollapsedNum Number of collapsed nested loops. 2793 /// \param NumClauses Number of clauses. 2794 /// 2795 explicit OMPDistributeDirective(unsigned CollapsedNum, unsigned NumClauses) 2796 : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute, 2797 SourceLocation(), SourceLocation(), CollapsedNum, 2798 NumClauses) 2799 {} 2800 2801 public: 2802 /// \brief Creates directive with a list of \a Clauses. 2803 /// 2804 /// \param C AST context. 2805 /// \param StartLoc Starting location of the directive kind. 2806 /// \param EndLoc Ending Location of the directive. 2807 /// \param CollapsedNum Number of collapsed loops. 2808 /// \param Clauses List of clauses. 2809 /// \param AssociatedStmt Statement, associated with the directive. 2810 /// \param Exprs Helper expressions for CodeGen. 2811 /// 2812 static OMPDistributeDirective * 2813 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2814 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 2815 Stmt *AssociatedStmt, const HelperExprs &Exprs); 2816 2817 /// \brief Creates an empty directive with the place 2818 /// for \a NumClauses clauses. 2819 /// 2820 /// \param C AST context. 2821 /// \param CollapsedNum Number of collapsed nested loops. 2822 /// \param NumClauses Number of clauses. 2823 /// 2824 static OMPDistributeDirective *CreateEmpty(const ASTContext &C, 2825 unsigned NumClauses, 2826 unsigned CollapsedNum, EmptyShell); 2827 2828 static bool classof(const Stmt *T) { 2829 return T->getStmtClass() == OMPDistributeDirectiveClass; 2830 } 2831 }; 2832 2833 /// \brief This represents '#pragma omp target update' directive. 2834 /// 2835 /// \code 2836 /// #pragma omp target update to(a) from(b) device(1) 2837 /// \endcode 2838 /// In this example directive '#pragma omp target update' has clause 'to' with 2839 /// argument 'a', clause 'from' with argument 'b' and clause 'device' with 2840 /// argument '1'. 2841 /// 2842 class OMPTargetUpdateDirective : public OMPExecutableDirective { 2843 friend class ASTStmtReader; 2844 /// \brief Build directive with the given start and end location. 2845 /// 2846 /// \param StartLoc Starting location of the directive kind. 2847 /// \param EndLoc Ending Location of the directive. 2848 /// \param NumClauses The number of clauses. 2849 /// 2850 OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2851 unsigned NumClauses) 2852 : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass, 2853 OMPD_target_update, StartLoc, EndLoc, NumClauses, 2854 0) {} 2855 2856 /// \brief Build an empty directive. 2857 /// 2858 /// \param NumClauses Number of clauses. 2859 /// 2860 explicit OMPTargetUpdateDirective(unsigned NumClauses) 2861 : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass, 2862 OMPD_target_update, SourceLocation(), 2863 SourceLocation(), NumClauses, 0) {} 2864 2865 public: 2866 /// \brief Creates directive with a list of \a Clauses. 2867 /// 2868 /// \param C AST context. 2869 /// \param StartLoc Starting location of the directive kind. 2870 /// \param EndLoc Ending Location of the directive. 2871 /// \param Clauses List of clauses. 2872 /// 2873 static OMPTargetUpdateDirective *Create(const ASTContext &C, 2874 SourceLocation StartLoc, 2875 SourceLocation EndLoc, 2876 ArrayRef<OMPClause *> Clauses); 2877 2878 /// \brief Creates an empty directive with the place for \a NumClauses 2879 /// clauses. 2880 /// 2881 /// \param C AST context. 2882 /// \param NumClauses The number of clauses. 2883 /// 2884 static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C, 2885 unsigned NumClauses, EmptyShell); 2886 2887 static bool classof(const Stmt *T) { 2888 return T->getStmtClass() == OMPTargetUpdateDirectiveClass; 2889 } 2890 }; 2891 2892 /// \brief This represents '#pragma omp distribute parallel for' composite 2893 /// directive. 2894 /// 2895 /// \code 2896 /// #pragma omp distribute parallel for private(a,b) 2897 /// \endcode 2898 /// In this example directive '#pragma omp distribute parallel for' has clause 2899 /// 'private' with the variables 'a' and 'b' 2900 /// 2901 class OMPDistributeParallelForDirective : public OMPLoopDirective { 2902 friend class ASTStmtReader; 2903 2904 /// \brief Build directive with the given start and end location. 2905 /// 2906 /// \param StartLoc Starting location of the directive kind. 2907 /// \param EndLoc Ending location of the directive. 2908 /// \param CollapsedNum Number of collapsed nested loops. 2909 /// \param NumClauses Number of clauses. 2910 /// 2911 OMPDistributeParallelForDirective(SourceLocation StartLoc, 2912 SourceLocation EndLoc, 2913 unsigned CollapsedNum, unsigned NumClauses) 2914 : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass, 2915 OMPD_distribute_parallel_for, StartLoc, EndLoc, 2916 CollapsedNum, NumClauses) {} 2917 2918 /// \brief Build an empty directive. 2919 /// 2920 /// \param CollapsedNum Number of collapsed nested loops. 2921 /// \param NumClauses Number of clauses. 2922 /// 2923 explicit OMPDistributeParallelForDirective(unsigned CollapsedNum, 2924 unsigned NumClauses) 2925 : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass, 2926 OMPD_distribute_parallel_for, SourceLocation(), 2927 SourceLocation(), CollapsedNum, NumClauses) {} 2928 2929 public: 2930 /// \brief Creates directive with a list of \a Clauses. 2931 /// 2932 /// \param C AST context. 2933 /// \param StartLoc Starting location of the directive kind. 2934 /// \param EndLoc Ending Location of the directive. 2935 /// \param CollapsedNum Number of collapsed loops. 2936 /// \param Clauses List of clauses. 2937 /// \param AssociatedStmt Statement, associated with the directive. 2938 /// \param Exprs Helper expressions for CodeGen. 2939 /// 2940 static OMPDistributeParallelForDirective * 2941 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2942 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 2943 Stmt *AssociatedStmt, const HelperExprs &Exprs); 2944 2945 /// \brief Creates an empty directive with the place 2946 /// for \a NumClauses clauses. 2947 /// 2948 /// \param C AST context. 2949 /// \param CollapsedNum Number of collapsed nested loops. 2950 /// \param NumClauses Number of clauses. 2951 /// 2952 static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C, 2953 unsigned NumClauses, 2954 unsigned CollapsedNum, 2955 EmptyShell); 2956 2957 static bool classof(const Stmt *T) { 2958 return T->getStmtClass() == OMPDistributeParallelForDirectiveClass; 2959 } 2960 }; 2961 2962 /// This represents '#pragma omp distribute parallel for simd' composite 2963 /// directive. 2964 /// 2965 /// \code 2966 /// #pragma omp distribute parallel for simd private(x) 2967 /// \endcode 2968 /// In this example directive '#pragma omp distribute parallel for simd' has 2969 /// clause 'private' with the variables 'x' 2970 /// 2971 class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective { 2972 friend class ASTStmtReader; 2973 2974 /// Build directive with the given start and end location. 2975 /// 2976 /// \param StartLoc Starting location of the directive kind. 2977 /// \param EndLoc Ending location of the directive. 2978 /// \param CollapsedNum Number of collapsed nested loops. 2979 /// \param NumClauses Number of clauses. 2980 /// 2981 OMPDistributeParallelForSimdDirective(SourceLocation StartLoc, 2982 SourceLocation EndLoc, 2983 unsigned CollapsedNum, 2984 unsigned NumClauses) 2985 : OMPLoopDirective(this, OMPDistributeParallelForSimdDirectiveClass, 2986 OMPD_distribute_parallel_for_simd, StartLoc, 2987 EndLoc, CollapsedNum, NumClauses) {} 2988 2989 /// Build an empty directive. 2990 /// 2991 /// \param CollapsedNum Number of collapsed nested loops. 2992 /// \param NumClauses Number of clauses. 2993 /// 2994 explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum, 2995 unsigned NumClauses) 2996 : OMPLoopDirective(this, OMPDistributeParallelForSimdDirectiveClass, 2997 OMPD_distribute_parallel_for_simd, 2998 SourceLocation(), SourceLocation(), CollapsedNum, 2999 NumClauses) {} 3000 3001 public: 3002 /// Creates directive with a list of \a Clauses. 3003 /// 3004 /// \param C AST context. 3005 /// \param StartLoc Starting location of the directive kind. 3006 /// \param EndLoc Ending Location of the directive. 3007 /// \param CollapsedNum Number of collapsed loops. 3008 /// \param Clauses List of clauses. 3009 /// \param AssociatedStmt Statement, associated with the directive. 3010 /// \param Exprs Helper expressions for CodeGen. 3011 /// 3012 static OMPDistributeParallelForSimdDirective *Create( 3013 const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3014 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3015 Stmt *AssociatedStmt, const HelperExprs &Exprs); 3016 3017 /// Creates an empty directive with the place for \a NumClauses clauses. 3018 /// 3019 /// \param C AST context. 3020 /// \param CollapsedNum Number of collapsed nested loops. 3021 /// \param NumClauses Number of clauses. 3022 /// 3023 static OMPDistributeParallelForSimdDirective *CreateEmpty( 3024 const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 3025 EmptyShell); 3026 3027 static bool classof(const Stmt *T) { 3028 return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass; 3029 } 3030 }; 3031 3032 /// This represents '#pragma omp distribute simd' composite directive. 3033 /// 3034 /// \code 3035 /// #pragma omp distribute simd private(x) 3036 /// \endcode 3037 /// In this example directive '#pragma omp distribute simd' has clause 3038 /// 'private' with the variables 'x' 3039 /// 3040 class OMPDistributeSimdDirective final : public OMPLoopDirective { 3041 friend class ASTStmtReader; 3042 3043 /// Build directive with the given start and end location. 3044 /// 3045 /// \param StartLoc Starting location of the directive kind. 3046 /// \param EndLoc Ending location of the directive. 3047 /// \param CollapsedNum Number of collapsed nested loops. 3048 /// \param NumClauses Number of clauses. 3049 /// 3050 OMPDistributeSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3051 unsigned CollapsedNum, unsigned NumClauses) 3052 : OMPLoopDirective(this, OMPDistributeSimdDirectiveClass, 3053 OMPD_distribute_simd, StartLoc, EndLoc, CollapsedNum, 3054 NumClauses) {} 3055 3056 /// Build an empty directive. 3057 /// 3058 /// \param CollapsedNum Number of collapsed nested loops. 3059 /// \param NumClauses Number of clauses. 3060 /// 3061 explicit OMPDistributeSimdDirective(unsigned CollapsedNum, 3062 unsigned NumClauses) 3063 : OMPLoopDirective(this, OMPDistributeSimdDirectiveClass, 3064 OMPD_distribute_simd, SourceLocation(), 3065 SourceLocation(), CollapsedNum, NumClauses) {} 3066 3067 public: 3068 /// Creates directive with a list of \a Clauses. 3069 /// 3070 /// \param C AST context. 3071 /// \param StartLoc Starting location of the directive kind. 3072 /// \param EndLoc Ending Location of the directive. 3073 /// \param CollapsedNum Number of collapsed loops. 3074 /// \param Clauses List of clauses. 3075 /// \param AssociatedStmt Statement, associated with the directive. 3076 /// \param Exprs Helper expressions for CodeGen. 3077 /// 3078 static OMPDistributeSimdDirective * 3079 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3080 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3081 Stmt *AssociatedStmt, const HelperExprs &Exprs); 3082 3083 /// Creates an empty directive with the place for \a NumClauses clauses. 3084 /// 3085 /// \param C AST context. 3086 /// \param CollapsedNum Number of collapsed nested loops. 3087 /// \param NumClauses Number of clauses. 3088 /// 3089 static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C, 3090 unsigned NumClauses, 3091 unsigned CollapsedNum, 3092 EmptyShell); 3093 3094 static bool classof(const Stmt *T) { 3095 return T->getStmtClass() == OMPDistributeSimdDirectiveClass; 3096 } 3097 }; 3098 3099 /// This represents '#pragma omp target parallel for simd' directive. 3100 /// 3101 /// \code 3102 /// #pragma omp target parallel for simd private(a) map(b) safelen(c) 3103 /// \endcode 3104 /// In this example directive '#pragma omp target parallel for simd' has clauses 3105 /// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen' 3106 /// with the variable 'c'. 3107 /// 3108 class OMPTargetParallelForSimdDirective final : public OMPLoopDirective { 3109 friend class ASTStmtReader; 3110 3111 /// Build directive with the given start and end location. 3112 /// 3113 /// \param StartLoc Starting location of the directive kind. 3114 /// \param EndLoc Ending location of the directive. 3115 /// \param CollapsedNum Number of collapsed nested loops. 3116 /// \param NumClauses Number of clauses. 3117 /// 3118 OMPTargetParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3119 unsigned CollapsedNum, unsigned NumClauses) 3120 : OMPLoopDirective(this, OMPTargetParallelForSimdDirectiveClass, 3121 OMPD_target_parallel_for_simd, StartLoc, EndLoc, 3122 CollapsedNum, NumClauses) {} 3123 3124 /// Build an empty directive. 3125 /// 3126 /// \param CollapsedNum Number of collapsed nested loops. 3127 /// \param NumClauses Number of clauses. 3128 /// 3129 explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum, 3130 unsigned NumClauses) 3131 : OMPLoopDirective(this, OMPTargetParallelForSimdDirectiveClass, 3132 OMPD_target_parallel_for_simd, SourceLocation(), 3133 SourceLocation(), CollapsedNum, NumClauses) {} 3134 3135 public: 3136 /// Creates directive with a list of \a Clauses. 3137 /// 3138 /// \param C AST context. 3139 /// \param StartLoc Starting location of the directive kind. 3140 /// \param EndLoc Ending Location of the directive. 3141 /// \param CollapsedNum Number of collapsed loops. 3142 /// \param Clauses List of clauses. 3143 /// \param AssociatedStmt Statement, associated with the directive. 3144 /// \param Exprs Helper expressions for CodeGen. 3145 /// 3146 static OMPTargetParallelForSimdDirective * 3147 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3148 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3149 Stmt *AssociatedStmt, const HelperExprs &Exprs); 3150 3151 /// Creates an empty directive with the place for \a NumClauses clauses. 3152 /// 3153 /// \param C AST context. 3154 /// \param CollapsedNum Number of collapsed nested loops. 3155 /// \param NumClauses Number of clauses. 3156 /// 3157 static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C, 3158 unsigned NumClauses, 3159 unsigned CollapsedNum, 3160 EmptyShell); 3161 3162 static bool classof(const Stmt *T) { 3163 return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass; 3164 } 3165 }; 3166 3167 /// This represents '#pragma omp target simd' directive. 3168 /// 3169 /// \code 3170 /// #pragma omp target simd private(a) map(b) safelen(c) 3171 /// \endcode 3172 /// In this example directive '#pragma omp target simd' has clauses 'private' 3173 /// with the variable 'a', 'map' with the variable 'b' and 'safelen' with 3174 /// the variable 'c'. 3175 /// 3176 class OMPTargetSimdDirective final : public OMPLoopDirective { 3177 friend class ASTStmtReader; 3178 3179 /// Build directive with the given start and end location. 3180 /// 3181 /// \param StartLoc Starting location of the directive kind. 3182 /// \param EndLoc Ending location of the directive. 3183 /// \param CollapsedNum Number of collapsed nested loops. 3184 /// \param NumClauses Number of clauses. 3185 /// 3186 OMPTargetSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3187 unsigned CollapsedNum, unsigned NumClauses) 3188 : OMPLoopDirective(this, OMPTargetSimdDirectiveClass, 3189 OMPD_target_simd, StartLoc, EndLoc, CollapsedNum, 3190 NumClauses) {} 3191 3192 /// Build an empty directive. 3193 /// 3194 /// \param CollapsedNum Number of collapsed nested loops. 3195 /// \param NumClauses Number of clauses. 3196 /// 3197 explicit OMPTargetSimdDirective(unsigned CollapsedNum, unsigned NumClauses) 3198 : OMPLoopDirective(this, OMPTargetSimdDirectiveClass, OMPD_target_simd, 3199 SourceLocation(),SourceLocation(), CollapsedNum, 3200 NumClauses) {} 3201 3202 public: 3203 /// Creates directive with a list of \a Clauses. 3204 /// 3205 /// \param C AST context. 3206 /// \param StartLoc Starting location of the directive kind. 3207 /// \param EndLoc Ending Location of the directive. 3208 /// \param CollapsedNum Number of collapsed loops. 3209 /// \param Clauses List of clauses. 3210 /// \param AssociatedStmt Statement, associated with the directive. 3211 /// \param Exprs Helper expressions for CodeGen. 3212 /// 3213 static OMPTargetSimdDirective * 3214 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3215 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3216 Stmt *AssociatedStmt, const HelperExprs &Exprs); 3217 3218 /// Creates an empty directive with the place for \a NumClauses clauses. 3219 /// 3220 /// \param C AST context. 3221 /// \param CollapsedNum Number of collapsed nested loops. 3222 /// \param NumClauses Number of clauses. 3223 /// 3224 static OMPTargetSimdDirective *CreateEmpty(const ASTContext &C, 3225 unsigned NumClauses, 3226 unsigned CollapsedNum, 3227 EmptyShell); 3228 3229 static bool classof(const Stmt *T) { 3230 return T->getStmtClass() == OMPTargetSimdDirectiveClass; 3231 } 3232 }; 3233 3234 /// This represents '#pragma omp teams distribute' directive. 3235 /// 3236 /// \code 3237 /// #pragma omp teams distribute private(a,b) 3238 /// \endcode 3239 /// In this example directive '#pragma omp teams distribute' has clauses 3240 /// 'private' with the variables 'a' and 'b' 3241 /// 3242 class OMPTeamsDistributeDirective final : public OMPLoopDirective { 3243 friend class ASTStmtReader; 3244 3245 /// Build directive with the given start and end location. 3246 /// 3247 /// \param StartLoc Starting location of the directive kind. 3248 /// \param EndLoc Ending location of the directive. 3249 /// \param CollapsedNum Number of collapsed nested loops. 3250 /// \param NumClauses Number of clauses. 3251 /// 3252 OMPTeamsDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3253 unsigned CollapsedNum, unsigned NumClauses) 3254 : OMPLoopDirective(this, OMPTeamsDistributeDirectiveClass, 3255 OMPD_teams_distribute, StartLoc, EndLoc, 3256 CollapsedNum, NumClauses) {} 3257 3258 /// Build an empty directive. 3259 /// 3260 /// \param CollapsedNum Number of collapsed nested loops. 3261 /// \param NumClauses Number of clauses. 3262 /// 3263 explicit OMPTeamsDistributeDirective(unsigned CollapsedNum, 3264 unsigned NumClauses) 3265 : OMPLoopDirective(this, OMPTeamsDistributeDirectiveClass, 3266 OMPD_teams_distribute, SourceLocation(), 3267 SourceLocation(), CollapsedNum, NumClauses) {} 3268 3269 public: 3270 /// Creates directive with a list of \a Clauses. 3271 /// 3272 /// \param C AST context. 3273 /// \param StartLoc Starting location of the directive kind. 3274 /// \param EndLoc Ending Location of the directive. 3275 /// \param CollapsedNum Number of collapsed loops. 3276 /// \param Clauses List of clauses. 3277 /// \param AssociatedStmt Statement, associated with the directive. 3278 /// \param Exprs Helper expressions for CodeGen. 3279 /// 3280 static OMPTeamsDistributeDirective * 3281 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3282 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3283 Stmt *AssociatedStmt, const HelperExprs &Exprs); 3284 3285 /// Creates an empty directive with the place for \a NumClauses clauses. 3286 /// 3287 /// \param C AST context. 3288 /// \param CollapsedNum Number of collapsed nested loops. 3289 /// \param NumClauses Number of clauses. 3290 /// 3291 static OMPTeamsDistributeDirective *CreateEmpty(const ASTContext &C, 3292 unsigned NumClauses, 3293 unsigned CollapsedNum, 3294 EmptyShell); 3295 3296 static bool classof(const Stmt *T) { 3297 return T->getStmtClass() == OMPTeamsDistributeDirectiveClass; 3298 } 3299 }; 3300 3301 /// This represents '#pragma omp teams distribute simd' 3302 /// combined directive. 3303 /// 3304 /// \code 3305 /// #pragma omp teams distribute simd private(a,b) 3306 /// \endcode 3307 /// In this example directive '#pragma omp teams distribute simd' 3308 /// has clause 'private' with the variables 'a' and 'b' 3309 /// 3310 class OMPTeamsDistributeSimdDirective final : public OMPLoopDirective { 3311 friend class ASTStmtReader; 3312 3313 /// Build directive with the given start and end location. 3314 /// 3315 /// \param StartLoc Starting location of the directive kind. 3316 /// \param EndLoc Ending location of the directive. 3317 /// \param CollapsedNum Number of collapsed nested loops. 3318 /// \param NumClauses Number of clauses. 3319 /// 3320 OMPTeamsDistributeSimdDirective(SourceLocation StartLoc, 3321 SourceLocation EndLoc, unsigned CollapsedNum, 3322 unsigned NumClauses) 3323 : OMPLoopDirective(this, OMPTeamsDistributeSimdDirectiveClass, 3324 OMPD_teams_distribute_simd, StartLoc, EndLoc, 3325 CollapsedNum, NumClauses) {} 3326 3327 /// Build an empty directive. 3328 /// 3329 /// \param CollapsedNum Number of collapsed nested loops. 3330 /// \param NumClauses Number of clauses. 3331 /// 3332 explicit OMPTeamsDistributeSimdDirective(unsigned CollapsedNum, 3333 unsigned NumClauses) 3334 : OMPLoopDirective(this, OMPTeamsDistributeSimdDirectiveClass, 3335 OMPD_teams_distribute_simd, SourceLocation(), 3336 SourceLocation(), CollapsedNum, NumClauses) {} 3337 3338 public: 3339 /// Creates directive with a list of \a Clauses. 3340 /// 3341 /// \param C AST context. 3342 /// \param StartLoc Starting location of the directive kind. 3343 /// \param EndLoc Ending Location of the directive. 3344 /// \param CollapsedNum Number of collapsed loops. 3345 /// \param Clauses List of clauses. 3346 /// \param AssociatedStmt Statement, associated with the directive. 3347 /// \param Exprs Helper expressions for CodeGen. 3348 /// 3349 static OMPTeamsDistributeSimdDirective * 3350 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3351 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3352 Stmt *AssociatedStmt, const HelperExprs &Exprs); 3353 3354 /// Creates an empty directive with the place 3355 /// for \a NumClauses clauses. 3356 /// 3357 /// \param C AST context. 3358 /// \param CollapsedNum Number of collapsed nested loops. 3359 /// \param NumClauses Number of clauses. 3360 /// 3361 static OMPTeamsDistributeSimdDirective *CreateEmpty(const ASTContext &C, 3362 unsigned NumClauses, 3363 unsigned CollapsedNum, 3364 EmptyShell); 3365 3366 static bool classof(const Stmt *T) { 3367 return T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass; 3368 } 3369 }; 3370 3371 /// This represents '#pragma omp teams distribute parallel for simd' composite 3372 /// directive. 3373 /// 3374 /// \code 3375 /// #pragma omp teams distribute parallel for simd private(x) 3376 /// \endcode 3377 /// In this example directive '#pragma omp teams distribute parallel for simd' 3378 /// has clause 'private' with the variables 'x' 3379 /// 3380 class OMPTeamsDistributeParallelForSimdDirective final 3381 : public OMPLoopDirective { 3382 friend class ASTStmtReader; 3383 3384 /// Build directive with the given start and end location. 3385 /// 3386 /// \param StartLoc Starting location of the directive kind. 3387 /// \param EndLoc Ending location of the directive. 3388 /// \param CollapsedNum Number of collapsed nested loops. 3389 /// \param NumClauses Number of clauses. 3390 /// 3391 OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc, 3392 SourceLocation EndLoc, 3393 unsigned CollapsedNum, 3394 unsigned NumClauses) 3395 : OMPLoopDirective(this, OMPTeamsDistributeParallelForSimdDirectiveClass, 3396 OMPD_teams_distribute_parallel_for_simd, StartLoc, 3397 EndLoc, CollapsedNum, NumClauses) {} 3398 3399 /// Build an empty directive. 3400 /// 3401 /// \param CollapsedNum Number of collapsed nested loops. 3402 /// \param NumClauses Number of clauses. 3403 /// 3404 explicit OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum, 3405 unsigned NumClauses) 3406 : OMPLoopDirective(this, OMPTeamsDistributeParallelForSimdDirectiveClass, 3407 OMPD_teams_distribute_parallel_for_simd, 3408 SourceLocation(), SourceLocation(), CollapsedNum, 3409 NumClauses) {} 3410 3411 public: 3412 /// Creates directive with a list of \a Clauses. 3413 /// 3414 /// \param C AST context. 3415 /// \param StartLoc Starting location of the directive kind. 3416 /// \param EndLoc Ending Location of the directive. 3417 /// \param CollapsedNum Number of collapsed loops. 3418 /// \param Clauses List of clauses. 3419 /// \param AssociatedStmt Statement, associated with the directive. 3420 /// \param Exprs Helper expressions for CodeGen. 3421 /// 3422 static OMPTeamsDistributeParallelForSimdDirective * 3423 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3424 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3425 Stmt *AssociatedStmt, const HelperExprs &Exprs); 3426 3427 /// Creates an empty directive with the place for \a NumClauses clauses. 3428 /// 3429 /// \param C AST context. 3430 /// \param CollapsedNum Number of collapsed nested loops. 3431 /// \param NumClauses Number of clauses. 3432 /// 3433 static OMPTeamsDistributeParallelForSimdDirective * 3434 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 3435 EmptyShell); 3436 3437 static bool classof(const Stmt *T) { 3438 return T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass; 3439 } 3440 }; 3441 3442 /// This represents '#pragma omp teams distribute parallel for' composite 3443 /// directive. 3444 /// 3445 /// \code 3446 /// #pragma omp teams distribute parallel for private(x) 3447 /// \endcode 3448 /// In this example directive '#pragma omp teams distribute parallel for' 3449 /// has clause 'private' with the variables 'x' 3450 /// 3451 class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective { 3452 friend class ASTStmtReader; 3453 3454 /// Build directive with the given start and end location. 3455 /// 3456 /// \param StartLoc Starting location of the directive kind. 3457 /// \param EndLoc Ending location of the directive. 3458 /// \param CollapsedNum Number of collapsed nested loops. 3459 /// \param NumClauses Number of clauses. 3460 /// 3461 OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc, 3462 SourceLocation EndLoc, 3463 unsigned CollapsedNum, 3464 unsigned NumClauses) 3465 : OMPLoopDirective(this, OMPTeamsDistributeParallelForDirectiveClass, 3466 OMPD_teams_distribute_parallel_for, StartLoc, EndLoc, 3467 CollapsedNum, NumClauses) {} 3468 3469 /// Build an empty directive. 3470 /// 3471 /// \param CollapsedNum Number of collapsed nested loops. 3472 /// \param NumClauses Number of clauses. 3473 /// 3474 explicit OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum, 3475 unsigned NumClauses) 3476 : OMPLoopDirective(this, OMPTeamsDistributeParallelForDirectiveClass, 3477 OMPD_teams_distribute_parallel_for, SourceLocation(), 3478 SourceLocation(), CollapsedNum, NumClauses) {} 3479 3480 public: 3481 /// Creates directive with a list of \a Clauses. 3482 /// 3483 /// \param C AST context. 3484 /// \param StartLoc Starting location of the directive kind. 3485 /// \param EndLoc Ending Location of the directive. 3486 /// \param CollapsedNum Number of collapsed loops. 3487 /// \param Clauses List of clauses. 3488 /// \param AssociatedStmt Statement, associated with the directive. 3489 /// \param Exprs Helper expressions for CodeGen. 3490 /// 3491 static OMPTeamsDistributeParallelForDirective * 3492 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3493 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3494 Stmt *AssociatedStmt, const HelperExprs &Exprs); 3495 3496 /// Creates an empty directive with the place for \a NumClauses clauses. 3497 /// 3498 /// \param C AST context. 3499 /// \param CollapsedNum Number of collapsed nested loops. 3500 /// \param NumClauses Number of clauses. 3501 /// 3502 static OMPTeamsDistributeParallelForDirective * 3503 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 3504 EmptyShell); 3505 3506 static bool classof(const Stmt *T) { 3507 return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass; 3508 } 3509 }; 3510 3511 /// This represents '#pragma omp target teams' directive. 3512 /// 3513 /// \code 3514 /// #pragma omp target teams if(a>0) 3515 /// \endcode 3516 /// In this example directive '#pragma omp target teams' has clause 'if' with 3517 /// condition 'a>0'. 3518 /// 3519 class OMPTargetTeamsDirective final : public OMPExecutableDirective { 3520 friend class ASTStmtReader; 3521 /// Build directive with the given start and end location. 3522 /// 3523 /// \param StartLoc Starting location of the directive kind. 3524 /// \param EndLoc Ending location of the directive. 3525 /// \param NumClauses Number of clauses. 3526 /// 3527 OMPTargetTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3528 unsigned NumClauses) 3529 : OMPExecutableDirective(this, OMPTargetTeamsDirectiveClass, 3530 OMPD_target_teams, StartLoc, EndLoc, NumClauses, 3531 1) {} 3532 3533 /// Build an empty directive. 3534 /// 3535 /// \param NumClauses Number of clauses. 3536 /// 3537 explicit OMPTargetTeamsDirective(unsigned NumClauses) 3538 : OMPExecutableDirective(this, OMPTargetTeamsDirectiveClass, 3539 OMPD_target_teams, SourceLocation(), 3540 SourceLocation(), NumClauses, 1) {} 3541 3542 public: 3543 /// Creates directive with a list of \a Clauses. 3544 /// 3545 /// \param C AST context. 3546 /// \param StartLoc Starting location of the directive kind. 3547 /// \param EndLoc Ending Location of the directive. 3548 /// \param Clauses List of clauses. 3549 /// \param AssociatedStmt Statement, associated with the directive. 3550 /// 3551 static OMPTargetTeamsDirective *Create(const ASTContext &C, 3552 SourceLocation StartLoc, 3553 SourceLocation EndLoc, 3554 ArrayRef<OMPClause *> Clauses, 3555 Stmt *AssociatedStmt); 3556 3557 /// Creates an empty directive with the place for \a NumClauses clauses. 3558 /// 3559 /// \param C AST context. 3560 /// \param NumClauses Number of clauses. 3561 /// 3562 static OMPTargetTeamsDirective *CreateEmpty(const ASTContext &C, 3563 unsigned NumClauses, EmptyShell); 3564 3565 static bool classof(const Stmt *T) { 3566 return T->getStmtClass() == OMPTargetTeamsDirectiveClass; 3567 } 3568 }; 3569 3570 /// This represents '#pragma omp target teams distribute' combined directive. 3571 /// 3572 /// \code 3573 /// #pragma omp target teams distribute private(x) 3574 /// \endcode 3575 /// In this example directive '#pragma omp target teams distribute' has clause 3576 /// 'private' with the variables 'x' 3577 /// 3578 class OMPTargetTeamsDistributeDirective final : public OMPLoopDirective { 3579 friend class ASTStmtReader; 3580 3581 /// Build directive with the given start and end location. 3582 /// 3583 /// \param StartLoc Starting location of the directive kind. 3584 /// \param EndLoc Ending location of the directive. 3585 /// \param CollapsedNum Number of collapsed nested loops. 3586 /// \param NumClauses Number of clauses. 3587 /// 3588 OMPTargetTeamsDistributeDirective(SourceLocation StartLoc, 3589 SourceLocation EndLoc, 3590 unsigned CollapsedNum, unsigned NumClauses) 3591 : OMPLoopDirective(this, OMPTargetTeamsDistributeDirectiveClass, 3592 OMPD_target_teams_distribute, StartLoc, EndLoc, 3593 CollapsedNum, NumClauses) {} 3594 3595 /// Build an empty directive. 3596 /// 3597 /// \param CollapsedNum Number of collapsed nested loops. 3598 /// \param NumClauses Number of clauses. 3599 /// 3600 explicit OMPTargetTeamsDistributeDirective(unsigned CollapsedNum, 3601 unsigned NumClauses) 3602 : OMPLoopDirective(this, OMPTargetTeamsDistributeDirectiveClass, 3603 OMPD_target_teams_distribute, SourceLocation(), 3604 SourceLocation(), CollapsedNum, NumClauses) {} 3605 3606 public: 3607 /// Creates directive with a list of \a Clauses. 3608 /// 3609 /// \param C AST context. 3610 /// \param StartLoc Starting location of the directive kind. 3611 /// \param EndLoc Ending Location of the directive. 3612 /// \param CollapsedNum Number of collapsed loops. 3613 /// \param Clauses List of clauses. 3614 /// \param AssociatedStmt Statement, associated with the directive. 3615 /// \param Exprs Helper expressions for CodeGen. 3616 /// 3617 static OMPTargetTeamsDistributeDirective * 3618 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3619 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3620 Stmt *AssociatedStmt, const HelperExprs &Exprs); 3621 3622 /// Creates an empty directive with the place for \a NumClauses clauses. 3623 /// 3624 /// \param C AST context. 3625 /// \param CollapsedNum Number of collapsed nested loops. 3626 /// \param NumClauses Number of clauses. 3627 /// 3628 static OMPTargetTeamsDistributeDirective * 3629 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 3630 EmptyShell); 3631 3632 static bool classof(const Stmt *T) { 3633 return T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass; 3634 } 3635 }; 3636 3637 /// This represents '#pragma omp target teams distribute parallel for' combined 3638 /// directive. 3639 /// 3640 /// \code 3641 /// #pragma omp target teams distribute parallel for private(x) 3642 /// \endcode 3643 /// In this example directive '#pragma omp target teams distribute parallel 3644 /// for' has clause 'private' with the variables 'x' 3645 /// 3646 class OMPTargetTeamsDistributeParallelForDirective final 3647 : public OMPLoopDirective { 3648 friend class ASTStmtReader; 3649 3650 /// Build directive with the given start and end location. 3651 /// 3652 /// \param StartLoc Starting location of the directive kind. 3653 /// \param EndLoc Ending location of the directive. 3654 /// \param CollapsedNum Number of collapsed nested loops. 3655 /// \param NumClauses Number of clauses. 3656 /// 3657 OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc, 3658 SourceLocation EndLoc, 3659 unsigned CollapsedNum, 3660 unsigned NumClauses) 3661 : OMPLoopDirective(this, 3662 OMPTargetTeamsDistributeParallelForDirectiveClass, 3663 OMPD_target_teams_distribute_parallel_for, StartLoc, 3664 EndLoc, CollapsedNum, NumClauses) {} 3665 3666 /// Build an empty directive. 3667 /// 3668 /// \param CollapsedNum Number of collapsed nested loops. 3669 /// \param NumClauses Number of clauses. 3670 /// 3671 explicit OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum, 3672 unsigned NumClauses) 3673 : OMPLoopDirective( 3674 this, OMPTargetTeamsDistributeParallelForDirectiveClass, 3675 OMPD_target_teams_distribute_parallel_for, SourceLocation(), 3676 SourceLocation(), CollapsedNum, NumClauses) {} 3677 3678 public: 3679 /// Creates directive with a list of \a Clauses. 3680 /// 3681 /// \param C AST context. 3682 /// \param StartLoc Starting location of the directive kind. 3683 /// \param EndLoc Ending Location of the directive. 3684 /// \param CollapsedNum Number of collapsed loops. 3685 /// \param Clauses List of clauses. 3686 /// \param AssociatedStmt Statement, associated with the directive. 3687 /// \param Exprs Helper expressions for CodeGen. 3688 /// 3689 static OMPTargetTeamsDistributeParallelForDirective * 3690 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3691 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3692 Stmt *AssociatedStmt, const HelperExprs &Exprs); 3693 3694 /// Creates an empty directive with the place for \a NumClauses clauses. 3695 /// 3696 /// \param C AST context. 3697 /// \param CollapsedNum Number of collapsed nested loops. 3698 /// \param NumClauses Number of clauses. 3699 /// 3700 static OMPTargetTeamsDistributeParallelForDirective * 3701 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 3702 EmptyShell); 3703 3704 static bool classof(const Stmt *T) { 3705 return T->getStmtClass() == 3706 OMPTargetTeamsDistributeParallelForDirectiveClass; 3707 } 3708 }; 3709 3710 /// This represents '#pragma omp target teams distribute parallel for simd' 3711 /// combined directive. 3712 /// 3713 /// \code 3714 /// #pragma omp target teams distribute parallel for simd private(x) 3715 /// \endcode 3716 /// In this example directive '#pragma omp target teams distribute parallel 3717 /// for simd' has clause 'private' with the variables 'x' 3718 /// 3719 class OMPTargetTeamsDistributeParallelForSimdDirective final 3720 : public OMPLoopDirective { 3721 friend class ASTStmtReader; 3722 3723 /// Build directive with the given start and end location. 3724 /// 3725 /// \param StartLoc Starting location of the directive kind. 3726 /// \param EndLoc Ending location of the directive. 3727 /// \param CollapsedNum Number of collapsed nested loops. 3728 /// \param NumClauses Number of clauses. 3729 /// 3730 OMPTargetTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc, 3731 SourceLocation EndLoc, 3732 unsigned CollapsedNum, 3733 unsigned NumClauses) 3734 : OMPLoopDirective(this, 3735 OMPTargetTeamsDistributeParallelForSimdDirectiveClass, 3736 OMPD_target_teams_distribute_parallel_for_simd, 3737 StartLoc, EndLoc, CollapsedNum, NumClauses) {} 3738 3739 /// Build an empty directive. 3740 /// 3741 /// \param CollapsedNum Number of collapsed nested loops. 3742 /// \param NumClauses Number of clauses. 3743 /// 3744 explicit OMPTargetTeamsDistributeParallelForSimdDirective( 3745 unsigned CollapsedNum, unsigned NumClauses) 3746 : OMPLoopDirective( 3747 this, OMPTargetTeamsDistributeParallelForSimdDirectiveClass, 3748 OMPD_target_teams_distribute_parallel_for_simd, SourceLocation(), 3749 SourceLocation(), CollapsedNum, NumClauses) {} 3750 3751 public: 3752 /// Creates directive with a list of \a Clauses. 3753 /// 3754 /// \param C AST context. 3755 /// \param StartLoc Starting location of the directive kind. 3756 /// \param EndLoc Ending Location of the directive. 3757 /// \param CollapsedNum Number of collapsed loops. 3758 /// \param Clauses List of clauses. 3759 /// \param AssociatedStmt Statement, associated with the directive. 3760 /// \param Exprs Helper expressions for CodeGen. 3761 /// 3762 static OMPTargetTeamsDistributeParallelForSimdDirective * 3763 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3764 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3765 Stmt *AssociatedStmt, const HelperExprs &Exprs); 3766 3767 /// Creates an empty directive with the place for \a NumClauses clauses. 3768 /// 3769 /// \param C AST context. 3770 /// \param CollapsedNum Number of collapsed nested loops. 3771 /// \param NumClauses Number of clauses. 3772 /// 3773 static OMPTargetTeamsDistributeParallelForSimdDirective * 3774 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 3775 EmptyShell); 3776 3777 static bool classof(const Stmt *T) { 3778 return T->getStmtClass() == 3779 OMPTargetTeamsDistributeParallelForSimdDirectiveClass; 3780 } 3781 }; 3782 3783 /// This represents '#pragma omp target teams distribute simd' combined 3784 /// directive. 3785 /// 3786 /// \code 3787 /// #pragma omp target teams distribute simd private(x) 3788 /// \endcode 3789 /// In this example directive '#pragma omp target teams distribute simd' 3790 /// has clause 'private' with the variables 'x' 3791 /// 3792 class OMPTargetTeamsDistributeSimdDirective final : public OMPLoopDirective { 3793 friend class ASTStmtReader; 3794 3795 /// Build directive with the given start and end location. 3796 /// 3797 /// \param StartLoc Starting location of the directive kind. 3798 /// \param EndLoc Ending location of the directive. 3799 /// \param CollapsedNum Number of collapsed nested loops. 3800 /// \param NumClauses Number of clauses. 3801 /// 3802 OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc, 3803 SourceLocation EndLoc, 3804 unsigned CollapsedNum, 3805 unsigned NumClauses) 3806 : OMPLoopDirective(this, OMPTargetTeamsDistributeSimdDirectiveClass, 3807 OMPD_target_teams_distribute_simd, StartLoc, EndLoc, 3808 CollapsedNum, NumClauses) {} 3809 3810 /// Build an empty directive. 3811 /// 3812 /// \param CollapsedNum Number of collapsed nested loops. 3813 /// \param NumClauses Number of clauses. 3814 /// 3815 explicit OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum, 3816 unsigned NumClauses) 3817 : OMPLoopDirective(this, OMPTargetTeamsDistributeSimdDirectiveClass, 3818 OMPD_target_teams_distribute_simd, SourceLocation(), 3819 SourceLocation(), CollapsedNum, NumClauses) {} 3820 3821 public: 3822 /// Creates directive with a list of \a Clauses. 3823 /// 3824 /// \param C AST context. 3825 /// \param StartLoc Starting location of the directive kind. 3826 /// \param EndLoc Ending Location of the directive. 3827 /// \param CollapsedNum Number of collapsed loops. 3828 /// \param Clauses List of clauses. 3829 /// \param AssociatedStmt Statement, associated with the directive. 3830 /// \param Exprs Helper expressions for CodeGen. 3831 /// 3832 static OMPTargetTeamsDistributeSimdDirective * 3833 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3834 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3835 Stmt *AssociatedStmt, const HelperExprs &Exprs); 3836 3837 /// Creates an empty directive with the place for \a NumClauses clauses. 3838 /// 3839 /// \param C AST context. 3840 /// \param CollapsedNum Number of collapsed nested loops. 3841 /// \param NumClauses Number of clauses. 3842 /// 3843 static OMPTargetTeamsDistributeSimdDirective * 3844 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 3845 EmptyShell); 3846 3847 static bool classof(const Stmt *T) { 3848 return T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass; 3849 } 3850 }; 3851 3852 } // end namespace clang 3853 3854 #endif 3855