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