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