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::RoundUpToAlignment(sizeof(T), 74 llvm::alignOf<OMPClause *>())) {} 75 76 /// \brief Sets the list of variables for this clause. 77 /// 78 /// \param Clauses The list of clauses for the directive. 79 /// 80 void setClauses(ArrayRef<OMPClause *> Clauses); 81 82 /// \brief Set the associated statement for the directive. 83 /// 84 /// /param S Associated statement. 85 /// 86 void setAssociatedStmt(Stmt *S) { 87 assert(hasAssociatedStmt() && "no associated statement."); 88 *child_begin() = S; 89 } 90 91 public: 92 /// \brief Iterates over a filtered subrange of clauses applied to a 93 /// directive. 94 /// 95 /// This iterator visits only clauses of type SpecificClause. 96 template <typename SpecificClause> 97 class specific_clause_iterator 98 : public llvm::iterator_adaptor_base< 99 specific_clause_iterator<SpecificClause>, 100 ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag, 101 const SpecificClause *, ptrdiff_t, const SpecificClause *, 102 const SpecificClause *> { 103 ArrayRef<OMPClause *>::const_iterator End; 104 105 void SkipToNextClause() { 106 while (this->I != End && !isa<SpecificClause>(*this->I)) 107 ++this->I; 108 } 109 110 public: 111 explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses) 112 : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()), 113 End(Clauses.end()) { 114 SkipToNextClause(); 115 } 116 117 const SpecificClause *operator*() const { 118 return cast<SpecificClause>(*this->I); 119 } 120 const SpecificClause *operator->() const { return **this; } 121 122 specific_clause_iterator &operator++() { 123 ++this->I; 124 SkipToNextClause(); 125 return *this; 126 } 127 }; 128 129 template <typename SpecificClause> 130 static llvm::iterator_range<specific_clause_iterator<SpecificClause>> 131 getClausesOfKind(ArrayRef<OMPClause *> Clauses) { 132 return {specific_clause_iterator<SpecificClause>(Clauses), 133 specific_clause_iterator<SpecificClause>( 134 llvm::makeArrayRef(Clauses.end(), 0))}; 135 } 136 137 template <typename SpecificClause> 138 llvm::iterator_range<specific_clause_iterator<SpecificClause>> 139 getClausesOfKind() const { 140 return getClausesOfKind<SpecificClause>(clauses()); 141 } 142 143 /// Gets a single clause of the specified kind associated with the 144 /// current directive iff there is only one clause of this kind (and assertion 145 /// is fired if there is more than one clause is associated with the 146 /// directive). Returns nullptr if no clause of this kind is associated with 147 /// the directive. 148 template <typename SpecificClause> 149 const SpecificClause *getSingleClause() const { 150 auto Clauses = getClausesOfKind<SpecificClause>(); 151 152 if (Clauses.begin() != Clauses.end()) { 153 assert(std::next(Clauses.begin()) == Clauses.end() && 154 "There are at least 2 clauses of the specified kind"); 155 return *Clauses.begin(); 156 } 157 return nullptr; 158 } 159 160 /// Returns true if the current directive has one or more clauses of a 161 /// specific kind. 162 template <typename SpecificClause> 163 bool hasClausesOfKind() const { 164 auto Clauses = getClausesOfKind<SpecificClause>(); 165 return Clauses.begin() != Clauses.end(); 166 } 167 168 /// \brief Returns starting location of directive kind. 169 SourceLocation getLocStart() const { return StartLoc; } 170 /// \brief Returns ending location of directive. 171 SourceLocation getLocEnd() const { return EndLoc; } 172 173 /// \brief Set starting location of directive kind. 174 /// 175 /// \param Loc New starting location of directive. 176 /// 177 void setLocStart(SourceLocation Loc) { StartLoc = Loc; } 178 /// \brief Set ending location of directive. 179 /// 180 /// \param Loc New ending location of directive. 181 /// 182 void setLocEnd(SourceLocation Loc) { EndLoc = Loc; } 183 184 /// \brief Get number of clauses. 185 unsigned getNumClauses() const { return NumClauses; } 186 187 /// \brief Returns specified clause. 188 /// 189 /// \param i Number of clause. 190 /// 191 OMPClause *getClause(unsigned i) const { return clauses()[i]; } 192 193 /// \brief Returns true if directive has associated statement. 194 bool hasAssociatedStmt() const { return NumChildren > 0; } 195 196 /// \brief Returns statement associated with the directive. 197 Stmt *getAssociatedStmt() const { 198 assert(hasAssociatedStmt() && "no associated statement."); 199 return const_cast<Stmt *>(*child_begin()); 200 } 201 202 OpenMPDirectiveKind getDirectiveKind() const { return Kind; } 203 204 static bool classof(const Stmt *S) { 205 return S->getStmtClass() >= firstOMPExecutableDirectiveConstant && 206 S->getStmtClass() <= lastOMPExecutableDirectiveConstant; 207 } 208 209 child_range children() { 210 if (!hasAssociatedStmt()) 211 return child_range(child_iterator(), child_iterator()); 212 Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end()); 213 return child_range(ChildStorage, ChildStorage + NumChildren); 214 } 215 216 ArrayRef<OMPClause *> clauses() { return getClauses(); } 217 218 ArrayRef<OMPClause *> clauses() const { 219 return const_cast<OMPExecutableDirective *>(this)->getClauses(); 220 } 221 }; 222 223 /// \brief This represents '#pragma omp parallel' directive. 224 /// 225 /// \code 226 /// #pragma omp parallel private(a,b) reduction(+: c,d) 227 /// \endcode 228 /// In this example directive '#pragma omp parallel' has clauses 'private' 229 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and 230 /// variables 'c' and 'd'. 231 /// 232 class OMPParallelDirective : public OMPExecutableDirective { 233 friend class ASTStmtReader; 234 /// \brief true if the construct has inner cancel directive. 235 bool HasCancel; 236 237 /// \brief Build directive with the given start and end location. 238 /// 239 /// \param StartLoc Starting location of the directive (directive keyword). 240 /// \param EndLoc Ending Location of the directive. 241 /// 242 OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc, 243 unsigned NumClauses) 244 : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel, 245 StartLoc, EndLoc, NumClauses, 1), 246 HasCancel(false) {} 247 248 /// \brief Build an empty directive. 249 /// 250 /// \param NumClauses Number of clauses. 251 /// 252 explicit OMPParallelDirective(unsigned NumClauses) 253 : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel, 254 SourceLocation(), SourceLocation(), NumClauses, 255 1), 256 HasCancel(false) {} 257 258 /// \brief Set cancel state. 259 void setHasCancel(bool Has) { HasCancel = Has; } 260 261 public: 262 /// \brief Creates directive with a list of \a Clauses. 263 /// 264 /// \param C AST context. 265 /// \param StartLoc Starting location of the directive kind. 266 /// \param EndLoc Ending Location of the directive. 267 /// \param Clauses List of clauses. 268 /// \param AssociatedStmt Statement associated with the directive. 269 /// \param HasCancel true if this directive has inner cancel directive. 270 /// 271 static OMPParallelDirective * 272 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 273 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel); 274 275 /// \brief Creates an empty directive with the place for \a N clauses. 276 /// 277 /// \param C AST context. 278 /// \param NumClauses Number of clauses. 279 /// 280 static OMPParallelDirective *CreateEmpty(const ASTContext &C, 281 unsigned NumClauses, EmptyShell); 282 283 /// \brief Return true if current directive has inner cancel directive. 284 bool hasCancel() const { return HasCancel; } 285 286 static bool classof(const Stmt *T) { 287 return T->getStmtClass() == OMPParallelDirectiveClass; 288 } 289 }; 290 291 /// \brief This is a common base class for loop directives ('omp simd', 'omp 292 /// for', 'omp for simd' etc.). It is responsible for the loop code generation. 293 /// 294 class OMPLoopDirective : public OMPExecutableDirective { 295 friend class ASTStmtReader; 296 /// \brief Number of collapsed loops as specified by 'collapse' clause. 297 unsigned CollapsedNum; 298 299 /// \brief Offsets to the stored exprs. 300 /// This enumeration contains offsets to all the pointers to children 301 /// expressions stored in OMPLoopDirective. 302 /// The first 9 children are nesessary for all the loop directives, and 303 /// the next 7 are specific to the worksharing ones. 304 /// After the fixed children, three arrays of length CollapsedNum are 305 /// allocated: loop counters, their updates and final values. 306 /// 307 enum { 308 AssociatedStmtOffset = 0, 309 IterationVariableOffset = 1, 310 LastIterationOffset = 2, 311 CalcLastIterationOffset = 3, 312 PreConditionOffset = 4, 313 CondOffset = 5, 314 InitOffset = 6, 315 IncOffset = 7, 316 // The '...End' enumerators do not correspond to child expressions - they 317 // specify the offset to the end (and start of the following counters/ 318 // updates/finals arrays). 319 DefaultEnd = 8, 320 // The following 7 exprs are used by worksharing loops only. 321 IsLastIterVariableOffset = 8, 322 LowerBoundVariableOffset = 9, 323 UpperBoundVariableOffset = 10, 324 StrideVariableOffset = 11, 325 EnsureUpperBoundOffset = 12, 326 NextLowerBoundOffset = 13, 327 NextUpperBoundOffset = 14, 328 // Offset to the end (and start of the following counters/updates/finals 329 // arrays) for worksharing loop directives. 330 WorksharingEnd = 15, 331 }; 332 333 /// \brief Get the counters storage. 334 MutableArrayRef<Expr *> getCounters() { 335 Expr **Storage = reinterpret_cast<Expr **>( 336 &(*(std::next(child_begin(), getArraysOffset(getDirectiveKind()))))); 337 return MutableArrayRef<Expr *>(Storage, CollapsedNum); 338 } 339 340 /// \brief Get the private counters storage. 341 MutableArrayRef<Expr *> getPrivateCounters() { 342 Expr **Storage = reinterpret_cast<Expr **>(&*std::next( 343 child_begin(), getArraysOffset(getDirectiveKind()) + CollapsedNum)); 344 return MutableArrayRef<Expr *>(Storage, CollapsedNum); 345 } 346 347 /// \brief Get the updates storage. 348 MutableArrayRef<Expr *> getInits() { 349 Expr **Storage = reinterpret_cast<Expr **>( 350 &*std::next(child_begin(), 351 getArraysOffset(getDirectiveKind()) + 2 * CollapsedNum)); 352 return MutableArrayRef<Expr *>(Storage, CollapsedNum); 353 } 354 355 /// \brief Get the updates storage. 356 MutableArrayRef<Expr *> getUpdates() { 357 Expr **Storage = reinterpret_cast<Expr **>( 358 &*std::next(child_begin(), 359 getArraysOffset(getDirectiveKind()) + 3 * CollapsedNum)); 360 return MutableArrayRef<Expr *>(Storage, CollapsedNum); 361 } 362 363 /// \brief Get the final counter updates storage. 364 MutableArrayRef<Expr *> getFinals() { 365 Expr **Storage = reinterpret_cast<Expr **>( 366 &*std::next(child_begin(), 367 getArraysOffset(getDirectiveKind()) + 4 * CollapsedNum)); 368 return MutableArrayRef<Expr *>(Storage, CollapsedNum); 369 } 370 371 protected: 372 /// \brief Build instance of loop directive of class \a Kind. 373 /// 374 /// \param SC Statement class. 375 /// \param Kind Kind of OpenMP directive. 376 /// \param StartLoc Starting location of the directive (directive keyword). 377 /// \param EndLoc Ending location of the directive. 378 /// \param CollapsedNum Number of collapsed loops from 'collapse' clause. 379 /// \param NumClauses Number of clauses. 380 /// \param NumSpecialChildren Number of additional directive-specific stmts. 381 /// 382 template <typename T> 383 OMPLoopDirective(const T *That, StmtClass SC, OpenMPDirectiveKind Kind, 384 SourceLocation StartLoc, SourceLocation EndLoc, 385 unsigned CollapsedNum, unsigned NumClauses, 386 unsigned NumSpecialChildren = 0) 387 : OMPExecutableDirective(That, SC, Kind, StartLoc, EndLoc, NumClauses, 388 numLoopChildren(CollapsedNum, Kind) + 389 NumSpecialChildren), 390 CollapsedNum(CollapsedNum) {} 391 392 /// \brief Offset to the start of children expression arrays. 393 static unsigned getArraysOffset(OpenMPDirectiveKind Kind) { 394 return (isOpenMPWorksharingDirective(Kind) || 395 isOpenMPTaskLoopDirective(Kind) || 396 isOpenMPDistributeDirective(Kind)) 397 ? WorksharingEnd 398 : DefaultEnd; 399 } 400 401 /// \brief Children number. 402 static unsigned numLoopChildren(unsigned CollapsedNum, 403 OpenMPDirectiveKind Kind) { 404 return getArraysOffset(Kind) + 5 * CollapsedNum; // Counters, 405 // PrivateCounters, Inits, 406 // Updates and Finals 407 } 408 409 void setIterationVariable(Expr *IV) { 410 *std::next(child_begin(), IterationVariableOffset) = IV; 411 } 412 void setLastIteration(Expr *LI) { 413 *std::next(child_begin(), LastIterationOffset) = LI; 414 } 415 void setCalcLastIteration(Expr *CLI) { 416 *std::next(child_begin(), CalcLastIterationOffset) = CLI; 417 } 418 void setPreCond(Expr *PC) { 419 *std::next(child_begin(), PreConditionOffset) = PC; 420 } 421 void setCond(Expr *Cond) { 422 *std::next(child_begin(), CondOffset) = Cond; 423 } 424 void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; } 425 void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; } 426 void setIsLastIterVariable(Expr *IL) { 427 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 428 isOpenMPTaskLoopDirective(getDirectiveKind()) || 429 isOpenMPDistributeDirective(getDirectiveKind())) && 430 "expected worksharing loop directive"); 431 *std::next(child_begin(), IsLastIterVariableOffset) = IL; 432 } 433 void setLowerBoundVariable(Expr *LB) { 434 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 435 isOpenMPTaskLoopDirective(getDirectiveKind()) || 436 isOpenMPDistributeDirective(getDirectiveKind())) && 437 "expected worksharing loop directive"); 438 *std::next(child_begin(), LowerBoundVariableOffset) = LB; 439 } 440 void setUpperBoundVariable(Expr *UB) { 441 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 442 isOpenMPTaskLoopDirective(getDirectiveKind()) || 443 isOpenMPDistributeDirective(getDirectiveKind())) && 444 "expected worksharing loop directive"); 445 *std::next(child_begin(), UpperBoundVariableOffset) = UB; 446 } 447 void setStrideVariable(Expr *ST) { 448 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 449 isOpenMPTaskLoopDirective(getDirectiveKind()) || 450 isOpenMPDistributeDirective(getDirectiveKind())) && 451 "expected worksharing loop directive"); 452 *std::next(child_begin(), StrideVariableOffset) = ST; 453 } 454 void setEnsureUpperBound(Expr *EUB) { 455 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 456 isOpenMPTaskLoopDirective(getDirectiveKind()) || 457 isOpenMPDistributeDirective(getDirectiveKind())) && 458 "expected worksharing loop directive"); 459 *std::next(child_begin(), EnsureUpperBoundOffset) = EUB; 460 } 461 void setNextLowerBound(Expr *NLB) { 462 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 463 isOpenMPTaskLoopDirective(getDirectiveKind()) || 464 isOpenMPDistributeDirective(getDirectiveKind())) && 465 "expected worksharing loop directive"); 466 *std::next(child_begin(), NextLowerBoundOffset) = NLB; 467 } 468 void setNextUpperBound(Expr *NUB) { 469 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 470 isOpenMPTaskLoopDirective(getDirectiveKind()) || 471 isOpenMPDistributeDirective(getDirectiveKind())) && 472 "expected worksharing loop directive"); 473 *std::next(child_begin(), NextUpperBoundOffset) = NUB; 474 } 475 void setCounters(ArrayRef<Expr *> A); 476 void setPrivateCounters(ArrayRef<Expr *> A); 477 void setInits(ArrayRef<Expr *> A); 478 void setUpdates(ArrayRef<Expr *> A); 479 void setFinals(ArrayRef<Expr *> A); 480 481 public: 482 /// \brief The expressions built for the OpenMP loop CodeGen for the 483 /// whole collapsed loop nest. 484 struct HelperExprs { 485 /// \brief Loop iteration variable. 486 Expr *IterationVarRef; 487 /// \brief Loop last iteration number. 488 Expr *LastIteration; 489 /// \brief Loop number of iterations. 490 Expr *NumIterations; 491 /// \brief Calculation of last iteration. 492 Expr *CalcLastIteration; 493 /// \brief Loop pre-condition. 494 Expr *PreCond; 495 /// \brief Loop condition. 496 Expr *Cond; 497 /// \brief Loop iteration variable init. 498 Expr *Init; 499 /// \brief Loop increment. 500 Expr *Inc; 501 /// \brief IsLastIteration - local flag variable passed to runtime. 502 Expr *IL; 503 /// \brief LowerBound - local variable passed to runtime. 504 Expr *LB; 505 /// \brief UpperBound - local variable passed to runtime. 506 Expr *UB; 507 /// \brief Stride - local variable passed to runtime. 508 Expr *ST; 509 /// \brief EnsureUpperBound -- expression LB = min(LB, NumIterations). 510 Expr *EUB; 511 /// \brief Update of LowerBound for statically sheduled 'omp for' loops. 512 Expr *NLB; 513 /// \brief Update of UpperBound for statically sheduled 'omp for' loops. 514 Expr *NUB; 515 /// \brief Counters Loop counters. 516 SmallVector<Expr *, 4> Counters; 517 /// \brief PrivateCounters Loop counters. 518 SmallVector<Expr *, 4> PrivateCounters; 519 /// \brief Expressions for loop counters inits for CodeGen. 520 SmallVector<Expr *, 4> Inits; 521 /// \brief Expressions for loop counters update for CodeGen. 522 SmallVector<Expr *, 4> Updates; 523 /// \brief Final loop counter values for GodeGen. 524 SmallVector<Expr *, 4> Finals; 525 526 /// \brief Check if all the expressions are built (does not check the 527 /// worksharing ones). 528 bool builtAll() { 529 return IterationVarRef != nullptr && LastIteration != nullptr && 530 NumIterations != nullptr && PreCond != nullptr && 531 Cond != nullptr && Init != nullptr && Inc != nullptr; 532 } 533 534 /// \brief Initialize all the fields to null. 535 /// \param Size Number of elements in the counters/finals/updates arrays. 536 void clear(unsigned Size) { 537 IterationVarRef = nullptr; 538 LastIteration = nullptr; 539 CalcLastIteration = nullptr; 540 PreCond = nullptr; 541 Cond = nullptr; 542 Init = nullptr; 543 Inc = nullptr; 544 IL = nullptr; 545 LB = nullptr; 546 UB = nullptr; 547 ST = nullptr; 548 EUB = nullptr; 549 NLB = nullptr; 550 NUB = nullptr; 551 Counters.resize(Size); 552 PrivateCounters.resize(Size); 553 Inits.resize(Size); 554 Updates.resize(Size); 555 Finals.resize(Size); 556 for (unsigned i = 0; i < Size; ++i) { 557 Counters[i] = nullptr; 558 PrivateCounters[i] = nullptr; 559 Inits[i] = nullptr; 560 Updates[i] = nullptr; 561 Finals[i] = nullptr; 562 } 563 } 564 }; 565 566 /// \brief Get number of collapsed loops. 567 unsigned getCollapsedNumber() const { return CollapsedNum; } 568 569 Expr *getIterationVariable() const { 570 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 571 *std::next(child_begin(), IterationVariableOffset))); 572 } 573 Expr *getLastIteration() const { 574 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 575 *std::next(child_begin(), LastIterationOffset))); 576 } 577 Expr *getCalcLastIteration() const { 578 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 579 *std::next(child_begin(), CalcLastIterationOffset))); 580 } 581 Expr *getPreCond() const { 582 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 583 *std::next(child_begin(), PreConditionOffset))); 584 } 585 Expr *getCond() const { 586 return const_cast<Expr *>( 587 reinterpret_cast<const Expr *>(*std::next(child_begin(), CondOffset))); 588 } 589 Expr *getInit() const { 590 return const_cast<Expr *>( 591 reinterpret_cast<const Expr *>(*std::next(child_begin(), InitOffset))); 592 } 593 Expr *getInc() const { 594 return const_cast<Expr *>( 595 reinterpret_cast<const Expr *>(*std::next(child_begin(), IncOffset))); 596 } 597 Expr *getIsLastIterVariable() const { 598 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 599 isOpenMPTaskLoopDirective(getDirectiveKind())) && 600 "expected worksharing loop directive"); 601 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 602 *std::next(child_begin(), IsLastIterVariableOffset))); 603 } 604 Expr *getLowerBoundVariable() const { 605 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 606 isOpenMPTaskLoopDirective(getDirectiveKind())) && 607 "expected worksharing loop directive"); 608 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 609 *std::next(child_begin(), LowerBoundVariableOffset))); 610 } 611 Expr *getUpperBoundVariable() const { 612 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 613 isOpenMPTaskLoopDirective(getDirectiveKind())) && 614 "expected worksharing loop directive"); 615 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 616 *std::next(child_begin(), UpperBoundVariableOffset))); 617 } 618 Expr *getStrideVariable() const { 619 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 620 isOpenMPTaskLoopDirective(getDirectiveKind())) && 621 "expected worksharing loop directive"); 622 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 623 *std::next(child_begin(), StrideVariableOffset))); 624 } 625 Expr *getEnsureUpperBound() const { 626 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 627 isOpenMPTaskLoopDirective(getDirectiveKind())) && 628 "expected worksharing loop directive"); 629 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 630 *std::next(child_begin(), EnsureUpperBoundOffset))); 631 } 632 Expr *getNextLowerBound() const { 633 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 634 isOpenMPTaskLoopDirective(getDirectiveKind())) && 635 "expected worksharing loop directive"); 636 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 637 *std::next(child_begin(), NextLowerBoundOffset))); 638 } 639 Expr *getNextUpperBound() const { 640 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 641 isOpenMPTaskLoopDirective(getDirectiveKind())) && 642 "expected worksharing loop directive"); 643 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 644 *std::next(child_begin(), NextUpperBoundOffset))); 645 } 646 const Stmt *getBody() const { 647 // This relies on the loop form is already checked by Sema. 648 Stmt *Body = getAssociatedStmt()->IgnoreContainers(true); 649 Body = cast<ForStmt>(Body)->getBody(); 650 for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) { 651 Body = Body->IgnoreContainers(); 652 Body = cast<ForStmt>(Body)->getBody(); 653 } 654 return Body; 655 } 656 657 ArrayRef<Expr *> counters() { return getCounters(); } 658 659 ArrayRef<Expr *> counters() const { 660 return const_cast<OMPLoopDirective *>(this)->getCounters(); 661 } 662 663 ArrayRef<Expr *> private_counters() { return getPrivateCounters(); } 664 665 ArrayRef<Expr *> private_counters() const { 666 return const_cast<OMPLoopDirective *>(this)->getPrivateCounters(); 667 } 668 669 ArrayRef<Expr *> inits() { return getInits(); } 670 671 ArrayRef<Expr *> inits() const { 672 return const_cast<OMPLoopDirective *>(this)->getInits(); 673 } 674 675 ArrayRef<Expr *> updates() { return getUpdates(); } 676 677 ArrayRef<Expr *> updates() const { 678 return const_cast<OMPLoopDirective *>(this)->getUpdates(); 679 } 680 681 ArrayRef<Expr *> finals() { return getFinals(); } 682 683 ArrayRef<Expr *> finals() const { 684 return const_cast<OMPLoopDirective *>(this)->getFinals(); 685 } 686 687 static bool classof(const Stmt *T) { 688 return T->getStmtClass() == OMPSimdDirectiveClass || 689 T->getStmtClass() == OMPForDirectiveClass || 690 T->getStmtClass() == OMPForSimdDirectiveClass || 691 T->getStmtClass() == OMPParallelForDirectiveClass || 692 T->getStmtClass() == OMPParallelForSimdDirectiveClass || 693 T->getStmtClass() == OMPTaskLoopDirectiveClass || 694 T->getStmtClass() == OMPTaskLoopSimdDirectiveClass || 695 T->getStmtClass() == OMPDistributeDirectiveClass; 696 } 697 }; 698 699 /// \brief This represents '#pragma omp simd' directive. 700 /// 701 /// \code 702 /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d) 703 /// \endcode 704 /// In this example directive '#pragma omp simd' has clauses 'private' 705 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and 706 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'. 707 /// 708 class OMPSimdDirective : public OMPLoopDirective { 709 friend class ASTStmtReader; 710 /// \brief Build directive with the given start and end location. 711 /// 712 /// \param StartLoc Starting location of the directive kind. 713 /// \param EndLoc Ending location of the directive. 714 /// \param CollapsedNum Number of collapsed nested loops. 715 /// \param NumClauses Number of clauses. 716 /// 717 OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 718 unsigned CollapsedNum, unsigned NumClauses) 719 : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc, 720 EndLoc, CollapsedNum, NumClauses) {} 721 722 /// \brief Build an empty directive. 723 /// 724 /// \param CollapsedNum Number of collapsed nested loops. 725 /// \param NumClauses Number of clauses. 726 /// 727 explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses) 728 : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd, 729 SourceLocation(), SourceLocation(), CollapsedNum, 730 NumClauses) {} 731 732 public: 733 /// \brief Creates directive with a list of \a Clauses. 734 /// 735 /// \param C AST context. 736 /// \param StartLoc Starting location of the directive kind. 737 /// \param EndLoc Ending Location of the directive. 738 /// \param CollapsedNum Number of collapsed loops. 739 /// \param Clauses List of clauses. 740 /// \param AssociatedStmt Statement, associated with the directive. 741 /// \param Exprs Helper expressions for CodeGen. 742 /// 743 static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc, 744 SourceLocation EndLoc, unsigned CollapsedNum, 745 ArrayRef<OMPClause *> Clauses, 746 Stmt *AssociatedStmt, 747 const HelperExprs &Exprs); 748 749 /// \brief Creates an empty directive with the place 750 /// for \a NumClauses clauses. 751 /// 752 /// \param C AST context. 753 /// \param CollapsedNum Number of collapsed nested loops. 754 /// \param NumClauses Number of clauses. 755 /// 756 static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 757 unsigned CollapsedNum, EmptyShell); 758 759 static bool classof(const Stmt *T) { 760 return T->getStmtClass() == OMPSimdDirectiveClass; 761 } 762 }; 763 764 /// \brief This represents '#pragma omp for' directive. 765 /// 766 /// \code 767 /// #pragma omp for private(a,b) reduction(+:c,d) 768 /// \endcode 769 /// In this example directive '#pragma omp for' has clauses 'private' with the 770 /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c' 771 /// and 'd'. 772 /// 773 class OMPForDirective : public OMPLoopDirective { 774 friend class ASTStmtReader; 775 776 /// \brief true if current directive has inner cancel directive. 777 bool HasCancel; 778 779 /// \brief Build directive with the given start and end location. 780 /// 781 /// \param StartLoc Starting location of the directive kind. 782 /// \param EndLoc Ending location of the directive. 783 /// \param CollapsedNum Number of collapsed nested loops. 784 /// \param NumClauses Number of clauses. 785 /// 786 OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc, 787 unsigned CollapsedNum, unsigned NumClauses) 788 : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, EndLoc, 789 CollapsedNum, NumClauses), 790 HasCancel(false) {} 791 792 /// \brief Build an empty directive. 793 /// 794 /// \param CollapsedNum Number of collapsed nested loops. 795 /// \param NumClauses Number of clauses. 796 /// 797 explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses) 798 : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, SourceLocation(), 799 SourceLocation(), CollapsedNum, NumClauses), 800 HasCancel(false) {} 801 802 /// \brief Set cancel state. 803 void setHasCancel(bool Has) { HasCancel = Has; } 804 805 public: 806 /// \brief Creates directive with a list of \a Clauses. 807 /// 808 /// \param C AST context. 809 /// \param StartLoc Starting location of the directive kind. 810 /// \param EndLoc Ending Location of the directive. 811 /// \param CollapsedNum Number of collapsed loops. 812 /// \param Clauses List of clauses. 813 /// \param AssociatedStmt Statement, associated with the directive. 814 /// \param Exprs Helper expressions for CodeGen. 815 /// \param HasCancel true if current directive has inner cancel directive. 816 /// 817 static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc, 818 SourceLocation EndLoc, unsigned CollapsedNum, 819 ArrayRef<OMPClause *> Clauses, 820 Stmt *AssociatedStmt, const HelperExprs &Exprs, 821 bool HasCancel); 822 823 /// \brief Creates an empty directive with the place 824 /// for \a NumClauses clauses. 825 /// 826 /// \param C AST context. 827 /// \param CollapsedNum Number of collapsed nested loops. 828 /// \param NumClauses Number of clauses. 829 /// 830 static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 831 unsigned CollapsedNum, EmptyShell); 832 833 /// \brief Return true if current directive has inner cancel directive. 834 bool hasCancel() const { return HasCancel; } 835 836 static bool classof(const Stmt *T) { 837 return T->getStmtClass() == OMPForDirectiveClass; 838 } 839 }; 840 841 /// \brief This represents '#pragma omp for simd' directive. 842 /// 843 /// \code 844 /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d) 845 /// \endcode 846 /// In this example directive '#pragma omp for simd' has clauses 'private' 847 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and 848 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'. 849 /// 850 class OMPForSimdDirective : public OMPLoopDirective { 851 friend class ASTStmtReader; 852 /// \brief Build directive with the given start and end location. 853 /// 854 /// \param StartLoc Starting location of the directive kind. 855 /// \param EndLoc Ending location of the directive. 856 /// \param CollapsedNum Number of collapsed nested loops. 857 /// \param NumClauses Number of clauses. 858 /// 859 OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 860 unsigned CollapsedNum, unsigned NumClauses) 861 : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd, 862 StartLoc, EndLoc, CollapsedNum, NumClauses) {} 863 864 /// \brief Build an empty directive. 865 /// 866 /// \param CollapsedNum Number of collapsed nested loops. 867 /// \param NumClauses Number of clauses. 868 /// 869 explicit OMPForSimdDirective(unsigned CollapsedNum, unsigned NumClauses) 870 : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd, 871 SourceLocation(), SourceLocation(), CollapsedNum, 872 NumClauses) {} 873 874 public: 875 /// \brief Creates directive with a list of \a Clauses. 876 /// 877 /// \param C AST context. 878 /// \param StartLoc Starting location of the directive kind. 879 /// \param EndLoc Ending Location of the directive. 880 /// \param CollapsedNum Number of collapsed loops. 881 /// \param Clauses List of clauses. 882 /// \param AssociatedStmt Statement, associated with the directive. 883 /// \param Exprs Helper expressions for CodeGen. 884 /// 885 static OMPForSimdDirective * 886 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 887 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 888 Stmt *AssociatedStmt, const HelperExprs &Exprs); 889 890 /// \brief Creates an empty directive with the place 891 /// for \a NumClauses clauses. 892 /// 893 /// \param C AST context. 894 /// \param CollapsedNum Number of collapsed nested loops. 895 /// \param NumClauses Number of clauses. 896 /// 897 static OMPForSimdDirective *CreateEmpty(const ASTContext &C, 898 unsigned NumClauses, 899 unsigned CollapsedNum, EmptyShell); 900 901 static bool classof(const Stmt *T) { 902 return T->getStmtClass() == OMPForSimdDirectiveClass; 903 } 904 }; 905 906 /// \brief This represents '#pragma omp sections' directive. 907 /// 908 /// \code 909 /// #pragma omp sections private(a,b) reduction(+:c,d) 910 /// \endcode 911 /// In this example directive '#pragma omp sections' has clauses 'private' with 912 /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables 913 /// 'c' and 'd'. 914 /// 915 class OMPSectionsDirective : public OMPExecutableDirective { 916 friend class ASTStmtReader; 917 918 /// \brief true if current directive has inner cancel directive. 919 bool HasCancel; 920 921 /// \brief Build directive with the given start and end location. 922 /// 923 /// \param StartLoc Starting location of the directive kind. 924 /// \param EndLoc Ending location of the directive. 925 /// \param NumClauses Number of clauses. 926 /// 927 OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc, 928 unsigned NumClauses) 929 : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections, 930 StartLoc, EndLoc, NumClauses, 1), 931 HasCancel(false) {} 932 933 /// \brief Build an empty directive. 934 /// 935 /// \param NumClauses Number of clauses. 936 /// 937 explicit OMPSectionsDirective(unsigned NumClauses) 938 : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections, 939 SourceLocation(), SourceLocation(), NumClauses, 940 1), 941 HasCancel(false) {} 942 943 /// \brief Set cancel state. 944 void setHasCancel(bool Has) { HasCancel = Has; } 945 946 public: 947 /// \brief Creates directive with a list of \a Clauses. 948 /// 949 /// \param C AST context. 950 /// \param StartLoc Starting location of the directive kind. 951 /// \param EndLoc Ending Location of the directive. 952 /// \param Clauses List of clauses. 953 /// \param AssociatedStmt Statement, associated with the directive. 954 /// \param HasCancel true if current directive has inner directive. 955 /// 956 static OMPSectionsDirective * 957 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 958 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel); 959 960 /// \brief Creates an empty directive with the place for \a NumClauses 961 /// clauses. 962 /// 963 /// \param C AST context. 964 /// \param NumClauses Number of clauses. 965 /// 966 static OMPSectionsDirective *CreateEmpty(const ASTContext &C, 967 unsigned NumClauses, EmptyShell); 968 969 /// \brief Return true if current directive has inner cancel directive. 970 bool hasCancel() const { return HasCancel; } 971 972 static bool classof(const Stmt *T) { 973 return T->getStmtClass() == OMPSectionsDirectiveClass; 974 } 975 }; 976 977 /// \brief This represents '#pragma omp section' directive. 978 /// 979 /// \code 980 /// #pragma omp section 981 /// \endcode 982 /// 983 class OMPSectionDirective : public OMPExecutableDirective { 984 friend class ASTStmtReader; 985 986 /// \brief true if current directive has inner cancel directive. 987 bool HasCancel; 988 989 /// \brief Build directive with the given start and end location. 990 /// 991 /// \param StartLoc Starting location of the directive kind. 992 /// \param EndLoc Ending location of the directive. 993 /// 994 OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc) 995 : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section, 996 StartLoc, EndLoc, 0, 1), 997 HasCancel(false) {} 998 999 /// \brief Build an empty directive. 1000 /// 1001 explicit OMPSectionDirective() 1002 : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section, 1003 SourceLocation(), SourceLocation(), 0, 1), 1004 HasCancel(false) {} 1005 1006 public: 1007 /// \brief Creates directive. 1008 /// 1009 /// \param C AST context. 1010 /// \param StartLoc Starting location of the directive kind. 1011 /// \param EndLoc Ending Location of the directive. 1012 /// \param AssociatedStmt Statement, associated with the directive. 1013 /// \param HasCancel true if current directive has inner directive. 1014 /// 1015 static OMPSectionDirective *Create(const ASTContext &C, 1016 SourceLocation StartLoc, 1017 SourceLocation EndLoc, 1018 Stmt *AssociatedStmt, bool HasCancel); 1019 1020 /// \brief Creates an empty directive. 1021 /// 1022 /// \param C AST context. 1023 /// 1024 static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell); 1025 1026 /// \brief Set cancel state. 1027 void setHasCancel(bool Has) { HasCancel = Has; } 1028 1029 /// \brief Return true if current directive has inner cancel directive. 1030 bool hasCancel() const { return HasCancel; } 1031 1032 static bool classof(const Stmt *T) { 1033 return T->getStmtClass() == OMPSectionDirectiveClass; 1034 } 1035 }; 1036 1037 /// \brief This represents '#pragma omp single' directive. 1038 /// 1039 /// \code 1040 /// #pragma omp single private(a,b) copyprivate(c,d) 1041 /// \endcode 1042 /// In this example directive '#pragma omp single' has clauses 'private' with 1043 /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'. 1044 /// 1045 class OMPSingleDirective : public OMPExecutableDirective { 1046 friend class ASTStmtReader; 1047 /// \brief Build directive with the given start and end location. 1048 /// 1049 /// \param StartLoc Starting location of the directive kind. 1050 /// \param EndLoc Ending location of the directive. 1051 /// \param NumClauses Number of clauses. 1052 /// 1053 OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1054 unsigned NumClauses) 1055 : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single, 1056 StartLoc, EndLoc, NumClauses, 1) {} 1057 1058 /// \brief Build an empty directive. 1059 /// 1060 /// \param NumClauses Number of clauses. 1061 /// 1062 explicit OMPSingleDirective(unsigned NumClauses) 1063 : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single, 1064 SourceLocation(), SourceLocation(), NumClauses, 1065 1) {} 1066 1067 public: 1068 /// \brief Creates directive with a list of \a Clauses. 1069 /// 1070 /// \param C AST context. 1071 /// \param StartLoc Starting location of the directive kind. 1072 /// \param EndLoc Ending Location of the directive. 1073 /// \param Clauses List of clauses. 1074 /// \param AssociatedStmt Statement, associated with the directive. 1075 /// 1076 static OMPSingleDirective * 1077 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1078 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 1079 1080 /// \brief Creates an empty directive with the place for \a NumClauses 1081 /// clauses. 1082 /// 1083 /// \param C AST context. 1084 /// \param NumClauses Number of clauses. 1085 /// 1086 static OMPSingleDirective *CreateEmpty(const ASTContext &C, 1087 unsigned NumClauses, EmptyShell); 1088 1089 static bool classof(const Stmt *T) { 1090 return T->getStmtClass() == OMPSingleDirectiveClass; 1091 } 1092 }; 1093 1094 /// \brief This represents '#pragma omp master' directive. 1095 /// 1096 /// \code 1097 /// #pragma omp master 1098 /// \endcode 1099 /// 1100 class OMPMasterDirective : public OMPExecutableDirective { 1101 friend class ASTStmtReader; 1102 /// \brief Build directive with the given start and end location. 1103 /// 1104 /// \param StartLoc Starting location of the directive kind. 1105 /// \param EndLoc Ending location of the directive. 1106 /// 1107 OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1108 : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master, 1109 StartLoc, EndLoc, 0, 1) {} 1110 1111 /// \brief Build an empty directive. 1112 /// 1113 explicit OMPMasterDirective() 1114 : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master, 1115 SourceLocation(), SourceLocation(), 0, 1) {} 1116 1117 public: 1118 /// \brief Creates directive. 1119 /// 1120 /// \param C AST context. 1121 /// \param StartLoc Starting location of the directive kind. 1122 /// \param EndLoc Ending Location of the directive. 1123 /// \param AssociatedStmt Statement, associated with the directive. 1124 /// 1125 static OMPMasterDirective *Create(const ASTContext &C, 1126 SourceLocation StartLoc, 1127 SourceLocation EndLoc, 1128 Stmt *AssociatedStmt); 1129 1130 /// \brief Creates an empty directive. 1131 /// 1132 /// \param C AST context. 1133 /// 1134 static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell); 1135 1136 static bool classof(const Stmt *T) { 1137 return T->getStmtClass() == OMPMasterDirectiveClass; 1138 } 1139 }; 1140 1141 /// \brief This represents '#pragma omp critical' directive. 1142 /// 1143 /// \code 1144 /// #pragma omp critical 1145 /// \endcode 1146 /// 1147 class OMPCriticalDirective : public OMPExecutableDirective { 1148 friend class ASTStmtReader; 1149 /// \brief Name of the directive. 1150 DeclarationNameInfo DirName; 1151 /// \brief Build directive with the given start and end location. 1152 /// 1153 /// \param Name Name of the directive. 1154 /// \param StartLoc Starting location of the directive kind. 1155 /// \param EndLoc Ending location of the directive. 1156 /// \param NumClauses Number of clauses. 1157 /// 1158 OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc, 1159 SourceLocation EndLoc, unsigned NumClauses) 1160 : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical, 1161 StartLoc, EndLoc, NumClauses, 1), 1162 DirName(Name) {} 1163 1164 /// \brief Build an empty directive. 1165 /// 1166 /// \param NumClauses Number of clauses. 1167 /// 1168 explicit OMPCriticalDirective(unsigned NumClauses) 1169 : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical, 1170 SourceLocation(), SourceLocation(), NumClauses, 1171 1), 1172 DirName() {} 1173 1174 /// \brief Set name of the directive. 1175 /// 1176 /// \param Name Name of the directive. 1177 /// 1178 void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; } 1179 1180 public: 1181 /// \brief Creates directive. 1182 /// 1183 /// \param C AST context. 1184 /// \param Name Name of the directive. 1185 /// \param StartLoc Starting location of the directive kind. 1186 /// \param EndLoc Ending Location of the directive. 1187 /// \param Clauses List of clauses. 1188 /// \param AssociatedStmt Statement, associated with the directive. 1189 /// 1190 static OMPCriticalDirective * 1191 Create(const ASTContext &C, const DeclarationNameInfo &Name, 1192 SourceLocation StartLoc, SourceLocation EndLoc, 1193 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 1194 1195 /// \brief Creates an empty directive. 1196 /// 1197 /// \param C AST context. 1198 /// \param NumClauses Number of clauses. 1199 /// 1200 static OMPCriticalDirective *CreateEmpty(const ASTContext &C, 1201 unsigned NumClauses, EmptyShell); 1202 1203 /// \brief Return name of the directive. 1204 /// 1205 DeclarationNameInfo getDirectiveName() const { return DirName; } 1206 1207 static bool classof(const Stmt *T) { 1208 return T->getStmtClass() == OMPCriticalDirectiveClass; 1209 } 1210 }; 1211 1212 /// \brief This represents '#pragma omp parallel for' directive. 1213 /// 1214 /// \code 1215 /// #pragma omp parallel for private(a,b) reduction(+:c,d) 1216 /// \endcode 1217 /// In this example directive '#pragma omp parallel for' has clauses 'private' 1218 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and 1219 /// variables 'c' and 'd'. 1220 /// 1221 class OMPParallelForDirective : public OMPLoopDirective { 1222 friend class ASTStmtReader; 1223 1224 /// \brief true if current region has inner cancel directive. 1225 bool HasCancel; 1226 1227 /// \brief Build directive with the given start and end location. 1228 /// 1229 /// \param StartLoc Starting location of the directive kind. 1230 /// \param EndLoc Ending location of the directive. 1231 /// \param CollapsedNum Number of collapsed nested loops. 1232 /// \param NumClauses Number of clauses. 1233 /// 1234 OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1235 unsigned CollapsedNum, unsigned NumClauses) 1236 : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for, 1237 StartLoc, EndLoc, CollapsedNum, NumClauses), 1238 HasCancel(false) {} 1239 1240 /// \brief Build an empty directive. 1241 /// 1242 /// \param CollapsedNum Number of collapsed nested loops. 1243 /// \param NumClauses Number of clauses. 1244 /// 1245 explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses) 1246 : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for, 1247 SourceLocation(), SourceLocation(), CollapsedNum, 1248 NumClauses), 1249 HasCancel(false) {} 1250 1251 /// \brief Set cancel state. 1252 void setHasCancel(bool Has) { HasCancel = Has; } 1253 1254 public: 1255 /// \brief Creates directive with a list of \a Clauses. 1256 /// 1257 /// \param C AST context. 1258 /// \param StartLoc Starting location of the directive kind. 1259 /// \param EndLoc Ending Location of the directive. 1260 /// \param CollapsedNum Number of collapsed loops. 1261 /// \param Clauses List of clauses. 1262 /// \param AssociatedStmt Statement, associated with the directive. 1263 /// \param Exprs Helper expressions for CodeGen. 1264 /// \param HasCancel true if current directive has inner cancel directive. 1265 /// 1266 static OMPParallelForDirective * 1267 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1268 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 1269 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 1270 1271 /// \brief Creates an empty directive with the place 1272 /// for \a NumClauses clauses. 1273 /// 1274 /// \param C AST context. 1275 /// \param CollapsedNum Number of collapsed nested loops. 1276 /// \param NumClauses Number of clauses. 1277 /// 1278 static OMPParallelForDirective *CreateEmpty(const ASTContext &C, 1279 unsigned NumClauses, 1280 unsigned CollapsedNum, 1281 EmptyShell); 1282 1283 /// \brief Return true if current directive has inner cancel directive. 1284 bool hasCancel() const { return HasCancel; } 1285 1286 static bool classof(const Stmt *T) { 1287 return T->getStmtClass() == OMPParallelForDirectiveClass; 1288 } 1289 }; 1290 1291 /// \brief This represents '#pragma omp parallel for simd' directive. 1292 /// 1293 /// \code 1294 /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d) 1295 /// \endcode 1296 /// In this example directive '#pragma omp parallel for simd' has clauses 1297 /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j' 1298 /// and linear step 's', 'reduction' with operator '+' and variables 'c' and 1299 /// 'd'. 1300 /// 1301 class OMPParallelForSimdDirective : public OMPLoopDirective { 1302 friend class ASTStmtReader; 1303 /// \brief Build directive with the given start and end location. 1304 /// 1305 /// \param StartLoc Starting location of the directive kind. 1306 /// \param EndLoc Ending location of the directive. 1307 /// \param CollapsedNum Number of collapsed nested loops. 1308 /// \param NumClauses Number of clauses. 1309 /// 1310 OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1311 unsigned CollapsedNum, unsigned NumClauses) 1312 : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass, 1313 OMPD_parallel_for_simd, StartLoc, EndLoc, CollapsedNum, 1314 NumClauses) {} 1315 1316 /// \brief Build an empty directive. 1317 /// 1318 /// \param CollapsedNum Number of collapsed nested loops. 1319 /// \param NumClauses Number of clauses. 1320 /// 1321 explicit OMPParallelForSimdDirective(unsigned CollapsedNum, 1322 unsigned NumClauses) 1323 : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass, 1324 OMPD_parallel_for_simd, SourceLocation(), 1325 SourceLocation(), CollapsedNum, NumClauses) {} 1326 1327 public: 1328 /// \brief Creates directive with a list of \a Clauses. 1329 /// 1330 /// \param C AST context. 1331 /// \param StartLoc Starting location of the directive kind. 1332 /// \param EndLoc Ending Location of the directive. 1333 /// \param CollapsedNum Number of collapsed loops. 1334 /// \param Clauses List of clauses. 1335 /// \param AssociatedStmt Statement, associated with the directive. 1336 /// \param Exprs Helper expressions for CodeGen. 1337 /// 1338 static OMPParallelForSimdDirective * 1339 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1340 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 1341 Stmt *AssociatedStmt, const HelperExprs &Exprs); 1342 1343 /// \brief Creates an empty directive with the place 1344 /// for \a NumClauses clauses. 1345 /// 1346 /// \param C AST context. 1347 /// \param CollapsedNum Number of collapsed nested loops. 1348 /// \param NumClauses Number of clauses. 1349 /// 1350 static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C, 1351 unsigned NumClauses, 1352 unsigned CollapsedNum, 1353 EmptyShell); 1354 1355 static bool classof(const Stmt *T) { 1356 return T->getStmtClass() == OMPParallelForSimdDirectiveClass; 1357 } 1358 }; 1359 1360 /// \brief This represents '#pragma omp parallel sections' directive. 1361 /// 1362 /// \code 1363 /// #pragma omp parallel sections private(a,b) reduction(+:c,d) 1364 /// \endcode 1365 /// In this example directive '#pragma omp parallel sections' has clauses 1366 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+' 1367 /// and variables 'c' and 'd'. 1368 /// 1369 class OMPParallelSectionsDirective : public OMPExecutableDirective { 1370 friend class ASTStmtReader; 1371 1372 /// \brief true if current directive has inner cancel directive. 1373 bool HasCancel; 1374 1375 /// \brief Build directive with the given start and end location. 1376 /// 1377 /// \param StartLoc Starting location of the directive kind. 1378 /// \param EndLoc Ending location of the directive. 1379 /// \param NumClauses Number of clauses. 1380 /// 1381 OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1382 unsigned NumClauses) 1383 : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass, 1384 OMPD_parallel_sections, StartLoc, EndLoc, 1385 NumClauses, 1), 1386 HasCancel(false) {} 1387 1388 /// \brief Build an empty directive. 1389 /// 1390 /// \param NumClauses Number of clauses. 1391 /// 1392 explicit OMPParallelSectionsDirective(unsigned NumClauses) 1393 : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass, 1394 OMPD_parallel_sections, SourceLocation(), 1395 SourceLocation(), NumClauses, 1), 1396 HasCancel(false) {} 1397 1398 /// \brief Set cancel state. 1399 void setHasCancel(bool Has) { HasCancel = Has; } 1400 1401 public: 1402 /// \brief Creates directive with a list of \a Clauses. 1403 /// 1404 /// \param C AST context. 1405 /// \param StartLoc Starting location of the directive kind. 1406 /// \param EndLoc Ending Location of the directive. 1407 /// \param Clauses List of clauses. 1408 /// \param AssociatedStmt Statement, associated with the directive. 1409 /// \param HasCancel true if current directive has inner cancel directive. 1410 /// 1411 static OMPParallelSectionsDirective * 1412 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1413 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel); 1414 1415 /// \brief Creates an empty directive with the place for \a NumClauses 1416 /// clauses. 1417 /// 1418 /// \param C AST context. 1419 /// \param NumClauses Number of clauses. 1420 /// 1421 static OMPParallelSectionsDirective * 1422 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 1423 1424 /// \brief Return true if current directive has inner cancel directive. 1425 bool hasCancel() const { return HasCancel; } 1426 1427 static bool classof(const Stmt *T) { 1428 return T->getStmtClass() == OMPParallelSectionsDirectiveClass; 1429 } 1430 }; 1431 1432 /// \brief This represents '#pragma omp task' directive. 1433 /// 1434 /// \code 1435 /// #pragma omp task private(a,b) final(d) 1436 /// \endcode 1437 /// In this example directive '#pragma omp task' has clauses 'private' with the 1438 /// variables 'a' and 'b' and 'final' with condition 'd'. 1439 /// 1440 class OMPTaskDirective : public OMPExecutableDirective { 1441 friend class ASTStmtReader; 1442 /// \brief true if this directive has inner cancel directive. 1443 bool HasCancel; 1444 1445 /// \brief Build directive with the given start and end location. 1446 /// 1447 /// \param StartLoc Starting location of the directive kind. 1448 /// \param EndLoc Ending location of the directive. 1449 /// \param NumClauses Number of clauses. 1450 /// 1451 OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1452 unsigned NumClauses) 1453 : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc, 1454 EndLoc, NumClauses, 1), 1455 HasCancel(false) {} 1456 1457 /// \brief Build an empty directive. 1458 /// 1459 /// \param NumClauses Number of clauses. 1460 /// 1461 explicit OMPTaskDirective(unsigned NumClauses) 1462 : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, 1463 SourceLocation(), SourceLocation(), NumClauses, 1464 1), 1465 HasCancel(false) {} 1466 1467 /// \brief Set cancel state. 1468 void setHasCancel(bool Has) { HasCancel = Has; } 1469 1470 public: 1471 /// \brief Creates directive with a list of \a Clauses. 1472 /// 1473 /// \param C AST context. 1474 /// \param StartLoc Starting location of the directive kind. 1475 /// \param EndLoc Ending Location of the directive. 1476 /// \param Clauses List of clauses. 1477 /// \param AssociatedStmt Statement, associated with the directive. 1478 /// \param HasCancel true, if current directive has inner cancel directive. 1479 /// 1480 static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc, 1481 SourceLocation EndLoc, 1482 ArrayRef<OMPClause *> Clauses, 1483 Stmt *AssociatedStmt, bool HasCancel); 1484 1485 /// \brief Creates an empty directive with the place for \a NumClauses 1486 /// clauses. 1487 /// 1488 /// \param C AST context. 1489 /// \param NumClauses Number of clauses. 1490 /// 1491 static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 1492 EmptyShell); 1493 1494 /// \brief Return true if current directive has inner cancel directive. 1495 bool hasCancel() const { return HasCancel; } 1496 1497 static bool classof(const Stmt *T) { 1498 return T->getStmtClass() == OMPTaskDirectiveClass; 1499 } 1500 }; 1501 1502 /// \brief This represents '#pragma omp taskyield' directive. 1503 /// 1504 /// \code 1505 /// #pragma omp taskyield 1506 /// \endcode 1507 /// 1508 class OMPTaskyieldDirective : public OMPExecutableDirective { 1509 friend class ASTStmtReader; 1510 /// \brief Build directive with the given start and end location. 1511 /// 1512 /// \param StartLoc Starting location of the directive kind. 1513 /// \param EndLoc Ending location of the directive. 1514 /// 1515 OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1516 : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield, 1517 StartLoc, EndLoc, 0, 0) {} 1518 1519 /// \brief Build an empty directive. 1520 /// 1521 explicit OMPTaskyieldDirective() 1522 : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield, 1523 SourceLocation(), SourceLocation(), 0, 0) {} 1524 1525 public: 1526 /// \brief Creates directive. 1527 /// 1528 /// \param C AST context. 1529 /// \param StartLoc Starting location of the directive kind. 1530 /// \param EndLoc Ending Location of the directive. 1531 /// 1532 static OMPTaskyieldDirective * 1533 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); 1534 1535 /// \brief Creates an empty directive. 1536 /// 1537 /// \param C AST context. 1538 /// 1539 static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell); 1540 1541 static bool classof(const Stmt *T) { 1542 return T->getStmtClass() == OMPTaskyieldDirectiveClass; 1543 } 1544 }; 1545 1546 /// \brief This represents '#pragma omp barrier' directive. 1547 /// 1548 /// \code 1549 /// #pragma omp barrier 1550 /// \endcode 1551 /// 1552 class OMPBarrierDirective : public OMPExecutableDirective { 1553 friend class ASTStmtReader; 1554 /// \brief Build directive with the given start and end location. 1555 /// 1556 /// \param StartLoc Starting location of the directive kind. 1557 /// \param EndLoc Ending location of the directive. 1558 /// 1559 OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1560 : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier, 1561 StartLoc, EndLoc, 0, 0) {} 1562 1563 /// \brief Build an empty directive. 1564 /// 1565 explicit OMPBarrierDirective() 1566 : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier, 1567 SourceLocation(), SourceLocation(), 0, 0) {} 1568 1569 public: 1570 /// \brief Creates directive. 1571 /// 1572 /// \param C AST context. 1573 /// \param StartLoc Starting location of the directive kind. 1574 /// \param EndLoc Ending Location of the directive. 1575 /// 1576 static OMPBarrierDirective * 1577 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); 1578 1579 /// \brief Creates an empty directive. 1580 /// 1581 /// \param C AST context. 1582 /// 1583 static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell); 1584 1585 static bool classof(const Stmt *T) { 1586 return T->getStmtClass() == OMPBarrierDirectiveClass; 1587 } 1588 }; 1589 1590 /// \brief This represents '#pragma omp taskwait' directive. 1591 /// 1592 /// \code 1593 /// #pragma omp taskwait 1594 /// \endcode 1595 /// 1596 class OMPTaskwaitDirective : public OMPExecutableDirective { 1597 friend class ASTStmtReader; 1598 /// \brief Build directive with the given start and end location. 1599 /// 1600 /// \param StartLoc Starting location of the directive kind. 1601 /// \param EndLoc Ending location of the directive. 1602 /// 1603 OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1604 : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait, 1605 StartLoc, EndLoc, 0, 0) {} 1606 1607 /// \brief Build an empty directive. 1608 /// 1609 explicit OMPTaskwaitDirective() 1610 : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait, 1611 SourceLocation(), SourceLocation(), 0, 0) {} 1612 1613 public: 1614 /// \brief Creates directive. 1615 /// 1616 /// \param C AST context. 1617 /// \param StartLoc Starting location of the directive kind. 1618 /// \param EndLoc Ending Location of the directive. 1619 /// 1620 static OMPTaskwaitDirective * 1621 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); 1622 1623 /// \brief Creates an empty directive. 1624 /// 1625 /// \param C AST context. 1626 /// 1627 static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell); 1628 1629 static bool classof(const Stmt *T) { 1630 return T->getStmtClass() == OMPTaskwaitDirectiveClass; 1631 } 1632 }; 1633 1634 /// \brief This represents '#pragma omp taskgroup' directive. 1635 /// 1636 /// \code 1637 /// #pragma omp taskgroup 1638 /// \endcode 1639 /// 1640 class OMPTaskgroupDirective : public OMPExecutableDirective { 1641 friend class ASTStmtReader; 1642 /// \brief Build directive with the given start and end location. 1643 /// 1644 /// \param StartLoc Starting location of the directive kind. 1645 /// \param EndLoc Ending location of the directive. 1646 /// 1647 OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1648 : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup, 1649 StartLoc, EndLoc, 0, 1) {} 1650 1651 /// \brief Build an empty directive. 1652 /// 1653 explicit OMPTaskgroupDirective() 1654 : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup, 1655 SourceLocation(), SourceLocation(), 0, 1) {} 1656 1657 public: 1658 /// \brief Creates directive. 1659 /// 1660 /// \param C AST context. 1661 /// \param StartLoc Starting location of the directive kind. 1662 /// \param EndLoc Ending Location of the directive. 1663 /// \param AssociatedStmt Statement, associated with the directive. 1664 /// 1665 static OMPTaskgroupDirective *Create(const ASTContext &C, 1666 SourceLocation StartLoc, 1667 SourceLocation EndLoc, 1668 Stmt *AssociatedStmt); 1669 1670 /// \brief Creates an empty directive. 1671 /// 1672 /// \param C AST context. 1673 /// 1674 static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C, EmptyShell); 1675 1676 static bool classof(const Stmt *T) { 1677 return T->getStmtClass() == OMPTaskgroupDirectiveClass; 1678 } 1679 }; 1680 1681 /// \brief This represents '#pragma omp flush' directive. 1682 /// 1683 /// \code 1684 /// #pragma omp flush(a,b) 1685 /// \endcode 1686 /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a' 1687 /// and 'b'. 1688 /// 'omp flush' directive does not have clauses but have an optional list of 1689 /// variables to flush. This list of variables is stored within some fake clause 1690 /// FlushClause. 1691 class OMPFlushDirective : public OMPExecutableDirective { 1692 friend class ASTStmtReader; 1693 /// \brief Build directive with the given start and end location. 1694 /// 1695 /// \param StartLoc Starting location of the directive kind. 1696 /// \param EndLoc Ending location of the directive. 1697 /// \param NumClauses Number of clauses. 1698 /// 1699 OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1700 unsigned NumClauses) 1701 : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush, 1702 StartLoc, EndLoc, NumClauses, 0) {} 1703 1704 /// \brief Build an empty directive. 1705 /// 1706 /// \param NumClauses Number of clauses. 1707 /// 1708 explicit OMPFlushDirective(unsigned NumClauses) 1709 : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush, 1710 SourceLocation(), SourceLocation(), NumClauses, 1711 0) {} 1712 1713 public: 1714 /// \brief Creates directive with a list of \a Clauses. 1715 /// 1716 /// \param C AST context. 1717 /// \param StartLoc Starting location of the directive kind. 1718 /// \param EndLoc Ending Location of the directive. 1719 /// \param Clauses List of clauses (only single OMPFlushClause clause is 1720 /// allowed). 1721 /// 1722 static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc, 1723 SourceLocation EndLoc, 1724 ArrayRef<OMPClause *> Clauses); 1725 1726 /// \brief Creates an empty directive with the place for \a NumClauses 1727 /// clauses. 1728 /// 1729 /// \param C AST context. 1730 /// \param NumClauses Number of clauses. 1731 /// 1732 static OMPFlushDirective *CreateEmpty(const ASTContext &C, 1733 unsigned NumClauses, EmptyShell); 1734 1735 static bool classof(const Stmt *T) { 1736 return T->getStmtClass() == OMPFlushDirectiveClass; 1737 } 1738 }; 1739 1740 /// \brief This represents '#pragma omp ordered' directive. 1741 /// 1742 /// \code 1743 /// #pragma omp ordered 1744 /// \endcode 1745 /// 1746 class OMPOrderedDirective : public OMPExecutableDirective { 1747 friend class ASTStmtReader; 1748 /// \brief Build directive with the given start and end location. 1749 /// 1750 /// \param StartLoc Starting location of the directive kind. 1751 /// \param EndLoc Ending location of the directive. 1752 /// \param NumClauses Number of clauses. 1753 /// 1754 OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1755 unsigned NumClauses) 1756 : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered, 1757 StartLoc, EndLoc, NumClauses, 1) {} 1758 1759 /// \brief Build an empty directive. 1760 /// 1761 /// \param NumClauses Number of clauses. 1762 /// 1763 explicit OMPOrderedDirective(unsigned NumClauses) 1764 : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered, 1765 SourceLocation(), SourceLocation(), NumClauses, 1766 1) {} 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 /// \param Clauses List of clauses. 1775 /// \param AssociatedStmt Statement, associated with the directive. 1776 /// 1777 static OMPOrderedDirective * 1778 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1779 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 1780 1781 /// \brief Creates an empty directive. 1782 /// 1783 /// \param C AST context. 1784 /// \param NumClauses Number of clauses. 1785 /// 1786 static OMPOrderedDirective *CreateEmpty(const ASTContext &C, 1787 unsigned NumClauses, EmptyShell); 1788 1789 static bool classof(const Stmt *T) { 1790 return T->getStmtClass() == OMPOrderedDirectiveClass; 1791 } 1792 }; 1793 1794 /// \brief This represents '#pragma omp atomic' directive. 1795 /// 1796 /// \code 1797 /// #pragma omp atomic capture 1798 /// \endcode 1799 /// In this example directive '#pragma omp atomic' has clause 'capture'. 1800 /// 1801 class OMPAtomicDirective : public OMPExecutableDirective { 1802 friend class ASTStmtReader; 1803 /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may 1804 /// have atomic expressions of forms 1805 /// \code 1806 /// x = x binop expr; 1807 /// x = expr binop x; 1808 /// \endcode 1809 /// This field is true for the first form of the expression and false for the 1810 /// second. Required for correct codegen of non-associative operations (like 1811 /// << or >>). 1812 bool IsXLHSInRHSPart; 1813 /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may 1814 /// have atomic expressions of forms 1815 /// \code 1816 /// v = x; <update x>; 1817 /// <update x>; v = x; 1818 /// \endcode 1819 /// This field is true for the first(postfix) form of the expression and false 1820 /// otherwise. 1821 bool IsPostfixUpdate; 1822 1823 /// \brief Build directive with the given start and end location. 1824 /// 1825 /// \param StartLoc Starting location of the directive kind. 1826 /// \param EndLoc Ending location of the directive. 1827 /// \param NumClauses Number of clauses. 1828 /// 1829 OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1830 unsigned NumClauses) 1831 : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic, 1832 StartLoc, EndLoc, NumClauses, 5), 1833 IsXLHSInRHSPart(false), IsPostfixUpdate(false) {} 1834 1835 /// \brief Build an empty directive. 1836 /// 1837 /// \param NumClauses Number of clauses. 1838 /// 1839 explicit OMPAtomicDirective(unsigned NumClauses) 1840 : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic, 1841 SourceLocation(), SourceLocation(), NumClauses, 1842 5), 1843 IsXLHSInRHSPart(false), IsPostfixUpdate(false) {} 1844 1845 /// \brief Set 'x' part of the associated expression/statement. 1846 void setX(Expr *X) { *std::next(child_begin()) = X; } 1847 /// \brief Set helper expression of the form 1848 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 1849 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 1850 void setUpdateExpr(Expr *UE) { *std::next(child_begin(), 2) = UE; } 1851 /// \brief Set 'v' part of the associated expression/statement. 1852 void setV(Expr *V) { *std::next(child_begin(), 3) = V; } 1853 /// \brief Set 'expr' part of the associated expression/statement. 1854 void setExpr(Expr *E) { *std::next(child_begin(), 4) = E; } 1855 1856 public: 1857 /// \brief Creates directive with a list of \a Clauses and 'x', 'v' and 'expr' 1858 /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for 1859 /// detailed description of 'x', 'v' and 'expr'). 1860 /// 1861 /// \param C AST context. 1862 /// \param StartLoc Starting location of the directive kind. 1863 /// \param EndLoc Ending Location of the directive. 1864 /// \param Clauses List of clauses. 1865 /// \param AssociatedStmt Statement, associated with the directive. 1866 /// \param X 'x' part of the associated expression/statement. 1867 /// \param V 'v' part of the associated expression/statement. 1868 /// \param E 'expr' part of the associated expression/statement. 1869 /// \param UE Helper expression of the form 1870 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 1871 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 1872 /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the 1873 /// second. 1874 /// \param IsPostfixUpdate true if original value of 'x' must be stored in 1875 /// 'v', not an updated one. 1876 static OMPAtomicDirective * 1877 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1878 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V, 1879 Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate); 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 OMPAtomicDirective *CreateEmpty(const ASTContext &C, 1888 unsigned NumClauses, EmptyShell); 1889 1890 /// \brief Get 'x' part of the associated expression/statement. 1891 Expr *getX() { return cast_or_null<Expr>(*std::next(child_begin())); } 1892 const Expr *getX() const { 1893 return cast_or_null<Expr>(*std::next(child_begin())); 1894 } 1895 /// \brief Get helper expression of the form 1896 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 1897 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 1898 Expr *getUpdateExpr() { 1899 return cast_or_null<Expr>(*std::next(child_begin(), 2)); 1900 } 1901 const Expr *getUpdateExpr() const { 1902 return cast_or_null<Expr>(*std::next(child_begin(), 2)); 1903 } 1904 /// \brief Return true if helper update expression has form 1905 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form 1906 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 1907 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 1908 /// \brief Return true if 'v' expression must be updated to original value of 1909 /// 'x', false if 'v' must be updated to the new value of 'x'. 1910 bool isPostfixUpdate() const { return IsPostfixUpdate; } 1911 /// \brief Get 'v' part of the associated expression/statement. 1912 Expr *getV() { return cast_or_null<Expr>(*std::next(child_begin(), 3)); } 1913 const Expr *getV() const { 1914 return cast_or_null<Expr>(*std::next(child_begin(), 3)); 1915 } 1916 /// \brief Get 'expr' part of the associated expression/statement. 1917 Expr *getExpr() { return cast_or_null<Expr>(*std::next(child_begin(), 4)); } 1918 const Expr *getExpr() const { 1919 return cast_or_null<Expr>(*std::next(child_begin(), 4)); 1920 } 1921 1922 static bool classof(const Stmt *T) { 1923 return T->getStmtClass() == OMPAtomicDirectiveClass; 1924 } 1925 }; 1926 1927 /// \brief This represents '#pragma omp target' directive. 1928 /// 1929 /// \code 1930 /// #pragma omp target if(a) 1931 /// \endcode 1932 /// In this example directive '#pragma omp target' has clause 'if' with 1933 /// condition 'a'. 1934 /// 1935 class OMPTargetDirective : public OMPExecutableDirective { 1936 friend class ASTStmtReader; 1937 /// \brief Build directive with the given start and end location. 1938 /// 1939 /// \param StartLoc Starting location of the directive kind. 1940 /// \param EndLoc Ending location of the directive. 1941 /// \param NumClauses Number of clauses. 1942 /// 1943 OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1944 unsigned NumClauses) 1945 : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target, 1946 StartLoc, EndLoc, NumClauses, 1) {} 1947 1948 /// \brief Build an empty directive. 1949 /// 1950 /// \param NumClauses Number of clauses. 1951 /// 1952 explicit OMPTargetDirective(unsigned NumClauses) 1953 : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target, 1954 SourceLocation(), SourceLocation(), NumClauses, 1955 1) {} 1956 1957 public: 1958 /// \brief Creates directive with a list of \a Clauses. 1959 /// 1960 /// \param C AST context. 1961 /// \param StartLoc Starting location of the directive kind. 1962 /// \param EndLoc Ending Location of the directive. 1963 /// \param Clauses List of clauses. 1964 /// \param AssociatedStmt Statement, associated with the directive. 1965 /// 1966 static OMPTargetDirective * 1967 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1968 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 1969 1970 /// \brief Creates an empty directive with the place for \a NumClauses 1971 /// clauses. 1972 /// 1973 /// \param C AST context. 1974 /// \param NumClauses Number of clauses. 1975 /// 1976 static OMPTargetDirective *CreateEmpty(const ASTContext &C, 1977 unsigned NumClauses, EmptyShell); 1978 1979 static bool classof(const Stmt *T) { 1980 return T->getStmtClass() == OMPTargetDirectiveClass; 1981 } 1982 }; 1983 1984 /// \brief This represents '#pragma omp target data' directive. 1985 /// 1986 /// \code 1987 /// #pragma omp target data device(0) if(a) map(b[:]) 1988 /// \endcode 1989 /// In this example directive '#pragma omp target data' has clauses 'device' 1990 /// with the value '0', 'if' with condition 'a' and 'map' with array 1991 /// section 'b[:]'. 1992 /// 1993 class OMPTargetDataDirective : public OMPExecutableDirective { 1994 friend class ASTStmtReader; 1995 /// \brief Build directive with the given start and end location. 1996 /// 1997 /// \param StartLoc Starting location of the directive kind. 1998 /// \param EndLoc Ending Location of the directive. 1999 /// \param NumClauses The number of clauses. 2000 /// 2001 OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2002 unsigned NumClauses) 2003 : OMPExecutableDirective(this, OMPTargetDataDirectiveClass, 2004 OMPD_target_data, StartLoc, EndLoc, NumClauses, 2005 1) {} 2006 2007 /// \brief Build an empty directive. 2008 /// 2009 /// \param NumClauses Number of clauses. 2010 /// 2011 explicit OMPTargetDataDirective(unsigned NumClauses) 2012 : OMPExecutableDirective(this, OMPTargetDataDirectiveClass, 2013 OMPD_target_data, SourceLocation(), 2014 SourceLocation(), NumClauses, 1) {} 2015 2016 public: 2017 /// \brief Creates directive with a list of \a Clauses. 2018 /// 2019 /// \param C AST context. 2020 /// \param StartLoc Starting location of the directive kind. 2021 /// \param EndLoc Ending Location of the directive. 2022 /// \param Clauses List of clauses. 2023 /// \param AssociatedStmt Statement, associated with the directive. 2024 /// 2025 static OMPTargetDataDirective * 2026 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2027 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 2028 2029 /// \brief Creates an empty directive with the place for \a N clauses. 2030 /// 2031 /// \param C AST context. 2032 /// \param N The number of clauses. 2033 /// 2034 static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N, 2035 EmptyShell); 2036 2037 static bool classof(const Stmt *T) { 2038 return T->getStmtClass() == OMPTargetDataDirectiveClass; 2039 } 2040 }; 2041 2042 /// \brief This represents '#pragma omp teams' directive. 2043 /// 2044 /// \code 2045 /// #pragma omp teams if(a) 2046 /// \endcode 2047 /// In this example directive '#pragma omp teams' has clause 'if' with 2048 /// condition 'a'. 2049 /// 2050 class OMPTeamsDirective : public OMPExecutableDirective { 2051 friend class ASTStmtReader; 2052 /// \brief Build directive with the given start and end location. 2053 /// 2054 /// \param StartLoc Starting location of the directive kind. 2055 /// \param EndLoc Ending location of the directive. 2056 /// \param NumClauses Number of clauses. 2057 /// 2058 OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2059 unsigned NumClauses) 2060 : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams, 2061 StartLoc, EndLoc, NumClauses, 1) {} 2062 2063 /// \brief Build an empty directive. 2064 /// 2065 /// \param NumClauses Number of clauses. 2066 /// 2067 explicit OMPTeamsDirective(unsigned NumClauses) 2068 : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams, 2069 SourceLocation(), SourceLocation(), NumClauses, 2070 1) {} 2071 2072 public: 2073 /// \brief Creates directive with a list of \a Clauses. 2074 /// 2075 /// \param C AST context. 2076 /// \param StartLoc Starting location of the directive kind. 2077 /// \param EndLoc Ending Location of the directive. 2078 /// \param Clauses List of clauses. 2079 /// \param AssociatedStmt Statement, associated with the directive. 2080 /// 2081 static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc, 2082 SourceLocation EndLoc, 2083 ArrayRef<OMPClause *> Clauses, 2084 Stmt *AssociatedStmt); 2085 2086 /// \brief Creates an empty directive with the place for \a NumClauses 2087 /// clauses. 2088 /// 2089 /// \param C AST context. 2090 /// \param NumClauses Number of clauses. 2091 /// 2092 static OMPTeamsDirective *CreateEmpty(const ASTContext &C, 2093 unsigned NumClauses, EmptyShell); 2094 2095 static bool classof(const Stmt *T) { 2096 return T->getStmtClass() == OMPTeamsDirectiveClass; 2097 } 2098 }; 2099 2100 /// \brief This represents '#pragma omp cancellation point' directive. 2101 /// 2102 /// \code 2103 /// #pragma omp cancellation point for 2104 /// \endcode 2105 /// 2106 /// In this example a cancellation point is created for innermost 'for' region. 2107 class OMPCancellationPointDirective : public OMPExecutableDirective { 2108 friend class ASTStmtReader; 2109 OpenMPDirectiveKind CancelRegion; 2110 /// \brief Build directive with the given start and end location. 2111 /// 2112 /// \param StartLoc Starting location of the directive kind. 2113 /// \param EndLoc Ending location of the directive. 2114 /// 2115 OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2116 : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass, 2117 OMPD_cancellation_point, StartLoc, EndLoc, 0, 0), 2118 CancelRegion(OMPD_unknown) {} 2119 2120 /// \brief Build an empty directive. 2121 /// 2122 explicit OMPCancellationPointDirective() 2123 : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass, 2124 OMPD_cancellation_point, SourceLocation(), 2125 SourceLocation(), 0, 0), 2126 CancelRegion(OMPD_unknown) {} 2127 2128 /// \brief Set cancel region for current cancellation point. 2129 /// \param CR Cancellation region. 2130 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; } 2131 2132 public: 2133 /// \brief Creates directive. 2134 /// 2135 /// \param C AST context. 2136 /// \param StartLoc Starting location of the directive kind. 2137 /// \param EndLoc Ending Location of the directive. 2138 /// 2139 static OMPCancellationPointDirective * 2140 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2141 OpenMPDirectiveKind CancelRegion); 2142 2143 /// \brief Creates an empty directive. 2144 /// 2145 /// \param C AST context. 2146 /// 2147 static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C, 2148 EmptyShell); 2149 2150 /// \brief Get cancellation region for the current cancellation point. 2151 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } 2152 2153 static bool classof(const Stmt *T) { 2154 return T->getStmtClass() == OMPCancellationPointDirectiveClass; 2155 } 2156 }; 2157 2158 /// \brief This represents '#pragma omp cancel' directive. 2159 /// 2160 /// \code 2161 /// #pragma omp cancel for 2162 /// \endcode 2163 /// 2164 /// In this example a cancel is created for innermost 'for' region. 2165 class OMPCancelDirective : public OMPExecutableDirective { 2166 friend class ASTStmtReader; 2167 OpenMPDirectiveKind CancelRegion; 2168 /// \brief Build directive with the given start and end location. 2169 /// 2170 /// \param StartLoc Starting location of the directive kind. 2171 /// \param EndLoc Ending location of the directive. 2172 /// \param NumClauses Number of clauses. 2173 /// 2174 OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2175 unsigned NumClauses) 2176 : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel, 2177 StartLoc, EndLoc, NumClauses, 0), 2178 CancelRegion(OMPD_unknown) {} 2179 2180 /// \brief Build an empty directive. 2181 /// 2182 /// \param NumClauses Number of clauses. 2183 explicit OMPCancelDirective(unsigned NumClauses) 2184 : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel, 2185 SourceLocation(), SourceLocation(), NumClauses, 2186 0), 2187 CancelRegion(OMPD_unknown) {} 2188 2189 /// \brief Set cancel region for current cancellation point. 2190 /// \param CR Cancellation region. 2191 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; } 2192 2193 public: 2194 /// \brief Creates directive. 2195 /// 2196 /// \param C AST context. 2197 /// \param StartLoc Starting location of the directive kind. 2198 /// \param EndLoc Ending Location of the directive. 2199 /// \param Clauses List of clauses. 2200 /// 2201 static OMPCancelDirective * 2202 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2203 ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion); 2204 2205 /// \brief Creates an empty directive. 2206 /// 2207 /// \param C AST context. 2208 /// \param NumClauses Number of clauses. 2209 /// 2210 static OMPCancelDirective *CreateEmpty(const ASTContext &C, 2211 unsigned NumClauses, EmptyShell); 2212 2213 /// \brief Get cancellation region for the current cancellation point. 2214 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } 2215 2216 static bool classof(const Stmt *T) { 2217 return T->getStmtClass() == OMPCancelDirectiveClass; 2218 } 2219 }; 2220 2221 /// \brief This represents '#pragma omp taskloop' directive. 2222 /// 2223 /// \code 2224 /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num) 2225 /// \endcode 2226 /// In this example directive '#pragma omp taskloop' has clauses 'private' 2227 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and 2228 /// 'num_tasks' with expression 'num'. 2229 /// 2230 class OMPTaskLoopDirective : public OMPLoopDirective { 2231 friend class ASTStmtReader; 2232 /// \brief Build directive with the given start and end location. 2233 /// 2234 /// \param StartLoc Starting location of the directive kind. 2235 /// \param EndLoc Ending location of the directive. 2236 /// \param CollapsedNum Number of collapsed nested loops. 2237 /// \param NumClauses Number of clauses. 2238 /// 2239 OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2240 unsigned CollapsedNum, unsigned NumClauses) 2241 : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop, 2242 StartLoc, EndLoc, CollapsedNum, NumClauses) {} 2243 2244 /// \brief Build an empty directive. 2245 /// 2246 /// \param CollapsedNum Number of collapsed nested loops. 2247 /// \param NumClauses Number of clauses. 2248 /// 2249 explicit OMPTaskLoopDirective(unsigned CollapsedNum, unsigned NumClauses) 2250 : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop, 2251 SourceLocation(), SourceLocation(), CollapsedNum, 2252 NumClauses) {} 2253 2254 public: 2255 /// \brief Creates directive with a list of \a Clauses. 2256 /// 2257 /// \param C AST context. 2258 /// \param StartLoc Starting location of the directive kind. 2259 /// \param EndLoc Ending Location of the directive. 2260 /// \param CollapsedNum Number of collapsed loops. 2261 /// \param Clauses List of clauses. 2262 /// \param AssociatedStmt Statement, associated with the directive. 2263 /// \param Exprs Helper expressions for CodeGen. 2264 /// 2265 static OMPTaskLoopDirective * 2266 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2267 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 2268 Stmt *AssociatedStmt, const HelperExprs &Exprs); 2269 2270 /// \brief Creates an empty directive with the place 2271 /// for \a NumClauses clauses. 2272 /// 2273 /// \param C AST context. 2274 /// \param CollapsedNum Number of collapsed nested loops. 2275 /// \param NumClauses Number of clauses. 2276 /// 2277 static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C, 2278 unsigned NumClauses, 2279 unsigned CollapsedNum, EmptyShell); 2280 2281 static bool classof(const Stmt *T) { 2282 return T->getStmtClass() == OMPTaskLoopDirectiveClass; 2283 } 2284 }; 2285 2286 /// \brief This represents '#pragma omp taskloop simd' directive. 2287 /// 2288 /// \code 2289 /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num) 2290 /// \endcode 2291 /// In this example directive '#pragma omp taskloop simd' has clauses 'private' 2292 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and 2293 /// 'num_tasks' with expression 'num'. 2294 /// 2295 class OMPTaskLoopSimdDirective : public OMPLoopDirective { 2296 friend class ASTStmtReader; 2297 /// \brief Build directive with the given start and end location. 2298 /// 2299 /// \param StartLoc Starting location of the directive kind. 2300 /// \param EndLoc Ending location of the directive. 2301 /// \param CollapsedNum Number of collapsed nested loops. 2302 /// \param NumClauses Number of clauses. 2303 /// 2304 OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2305 unsigned CollapsedNum, unsigned NumClauses) 2306 : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass, 2307 OMPD_taskloop_simd, StartLoc, EndLoc, CollapsedNum, 2308 NumClauses) {} 2309 2310 /// \brief Build an empty directive. 2311 /// 2312 /// \param CollapsedNum Number of collapsed nested loops. 2313 /// \param NumClauses Number of clauses. 2314 /// 2315 explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum, unsigned NumClauses) 2316 : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass, 2317 OMPD_taskloop_simd, SourceLocation(), SourceLocation(), 2318 CollapsedNum, NumClauses) {} 2319 2320 public: 2321 /// \brief Creates directive with a list of \a Clauses. 2322 /// 2323 /// \param C AST context. 2324 /// \param StartLoc Starting location of the directive kind. 2325 /// \param EndLoc Ending Location of the directive. 2326 /// \param CollapsedNum Number of collapsed loops. 2327 /// \param Clauses List of clauses. 2328 /// \param AssociatedStmt Statement, associated with the directive. 2329 /// \param Exprs Helper expressions for CodeGen. 2330 /// 2331 static OMPTaskLoopSimdDirective * 2332 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2333 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 2334 Stmt *AssociatedStmt, const HelperExprs &Exprs); 2335 2336 /// \brief Creates an empty directive with the place 2337 /// for \a NumClauses clauses. 2338 /// 2339 /// \param C AST context. 2340 /// \param CollapsedNum Number of collapsed nested loops. 2341 /// \param NumClauses Number of clauses. 2342 /// 2343 static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, 2344 unsigned NumClauses, 2345 unsigned CollapsedNum, 2346 EmptyShell); 2347 2348 static bool classof(const Stmt *T) { 2349 return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass; 2350 } 2351 }; 2352 2353 /// \brief This represents '#pragma omp distribute' directive. 2354 /// 2355 /// \code 2356 /// #pragma omp distribute private(a,b) 2357 /// \endcode 2358 /// In this example directive '#pragma omp distribute' has clauses 'private' 2359 /// with the variables 'a' and 'b' 2360 /// 2361 class OMPDistributeDirective : public OMPLoopDirective { 2362 friend class ASTStmtReader; 2363 2364 /// \brief Build directive with the given start and end location. 2365 /// 2366 /// \param StartLoc Starting location of the directive kind. 2367 /// \param EndLoc Ending location of the directive. 2368 /// \param CollapsedNum Number of collapsed nested loops. 2369 /// \param NumClauses Number of clauses. 2370 /// 2371 OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2372 unsigned CollapsedNum, unsigned NumClauses) 2373 : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute, 2374 StartLoc, EndLoc, CollapsedNum, NumClauses) 2375 {} 2376 2377 /// \brief Build an empty directive. 2378 /// 2379 /// \param CollapsedNum Number of collapsed nested loops. 2380 /// \param NumClauses Number of clauses. 2381 /// 2382 explicit OMPDistributeDirective(unsigned CollapsedNum, unsigned NumClauses) 2383 : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute, 2384 SourceLocation(), SourceLocation(), CollapsedNum, 2385 NumClauses) 2386 {} 2387 2388 public: 2389 /// \brief Creates directive with a list of \a Clauses. 2390 /// 2391 /// \param C AST context. 2392 /// \param StartLoc Starting location of the directive kind. 2393 /// \param EndLoc Ending Location of the directive. 2394 /// \param CollapsedNum Number of collapsed loops. 2395 /// \param Clauses List of clauses. 2396 /// \param AssociatedStmt Statement, associated with the directive. 2397 /// \param Exprs Helper expressions for CodeGen. 2398 /// 2399 static OMPDistributeDirective * 2400 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2401 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 2402 Stmt *AssociatedStmt, const HelperExprs &Exprs); 2403 2404 /// \brief Creates an empty directive with the place 2405 /// for \a NumClauses clauses. 2406 /// 2407 /// \param C AST context. 2408 /// \param CollapsedNum Number of collapsed nested loops. 2409 /// \param NumClauses Number of clauses. 2410 /// 2411 static OMPDistributeDirective *CreateEmpty(const ASTContext &C, 2412 unsigned NumClauses, 2413 unsigned CollapsedNum, EmptyShell); 2414 2415 static bool classof(const Stmt *T) { 2416 return T->getStmtClass() == OMPDistributeDirectiveClass; 2417 } 2418 }; 2419 2420 } // end namespace clang 2421 2422 #endif 2423