1 //===- StmtOpenMP.h - Classes for OpenMP directives ------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file defines OpenMP AST classes for executable directives and 10 /// clauses. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_AST_STMTOPENMP_H 15 #define LLVM_CLANG_AST_STMTOPENMP_H 16 17 #include "clang/AST/ASTContext.h" 18 #include "clang/AST/Expr.h" 19 #include "clang/AST/OpenMPClause.h" 20 #include "clang/AST/Stmt.h" 21 #include "clang/AST/StmtCXX.h" 22 #include "clang/Basic/OpenMPKinds.h" 23 #include "clang/Basic/SourceLocation.h" 24 25 namespace clang { 26 27 //===----------------------------------------------------------------------===// 28 // AST classes for directives. 29 //===----------------------------------------------------------------------===// 30 31 /// Representation of an OpenMP canonical loop. 32 /// 33 /// OpenMP 1.0 C/C++, section 2.4.1 for Construct; canonical-shape 34 /// OpenMP 2.0 C/C++, section 2.4.1 for Construct; canonical-shape 35 /// OpenMP 2.5, section 2.5.1 Loop Construct; canonical form 36 /// OpenMP 3.1, section 2.5.1 Loop Construct; canonical form 37 /// OpenMP 4.0, section 2.6 Canonical Loop Form 38 /// OpenMP 4.5, section 2.6 Canonical Loop Form 39 /// OpenMP 5.0, section 2.9.1 Canonical Loop Form 40 /// OpenMP 5.1, section 2.11.1 Canonical Loop Nest Form 41 /// 42 /// An OpenMP canonical loop is a for-statement or range-based for-statement 43 /// with additional requirements that ensure that the number of iterations is 44 /// known before entering the loop and allow skipping to an arbitrary iteration. 45 /// The OMPCanonicalLoop AST node wraps a ForStmt or CXXForRangeStmt that is 46 /// known to fulfill OpenMP's canonical loop requirements because of being 47 /// associated to an OMPLoopBasedDirective. That is, the general structure is: 48 /// 49 /// OMPLoopBasedDirective 50 /// [`- CapturedStmt ] 51 /// [ `- CapturedDecl] 52 /// ` OMPCanonicalLoop 53 /// `- ForStmt/CXXForRangeStmt 54 /// `- Stmt 55 /// 56 /// One or multiple CapturedStmt/CapturedDecl pairs may be inserted by some 57 /// directives such as OMPParallelForDirective, but others do not need them 58 /// (such as OMPTileDirective). In The OMPCanonicalLoop and 59 /// ForStmt/CXXForRangeStmt pair is repeated for loop associated with the 60 /// directive. A OMPCanonicalLoop must not appear in the AST unless associated 61 /// with a OMPLoopBasedDirective. In an imperfectly nested loop nest, the 62 /// OMPCanonicalLoop may also be wrapped in a CompoundStmt: 63 /// 64 /// [...] 65 /// ` OMPCanonicalLoop 66 /// `- ForStmt/CXXForRangeStmt 67 /// `- CompoundStmt 68 /// |- Leading in-between code (if any) 69 /// |- OMPCanonicalLoop 70 /// | `- ForStmt/CXXForRangeStmt 71 /// | `- ... 72 /// `- Trailing in-between code (if any) 73 /// 74 /// The leading/trailing in-between code must not itself be a OMPCanonicalLoop 75 /// to avoid confusion which loop belongs to the nesting. 76 /// 77 /// There are three different kinds of iteration variables for different 78 /// purposes: 79 /// * Loop user variable: The user-accessible variable with different value for 80 /// each iteration. 81 /// * Loop iteration variable: The variable used to identify a loop iteration; 82 /// for range-based for-statement, this is the hidden iterator '__begin'. For 83 /// other loops, it is identical to the loop user variable. Must be a 84 /// random-access iterator, pointer or integer type. 85 /// * Logical iteration counter: Normalized loop counter starting at 0 and 86 /// incrementing by one at each iteration. Allows abstracting over the type 87 /// of the loop iteration variable and is always an unsigned integer type 88 /// appropriate to represent the range of the loop iteration variable. Its 89 /// value corresponds to the logical iteration number in the OpenMP 90 /// specification. 91 /// 92 /// This AST node provides two captured statements: 93 /// * The distance function which computes the number of iterations. 94 /// * The loop user variable function that computes the loop user variable when 95 /// given a logical iteration number. 96 /// 97 /// These captured statements provide the link between C/C++ semantics and the 98 /// logical iteration counters used by the OpenMPIRBuilder which is 99 /// language-agnostic and therefore does not know e.g. how to advance a 100 /// random-access iterator. The OpenMPIRBuilder will use this information to 101 /// apply simd, workshare-loop, distribute, taskloop and loop directives to the 102 /// loop. For compatibility with the non-OpenMPIRBuilder codegen path, an 103 /// OMPCanonicalLoop can itself also be wrapped into the CapturedStmts of an 104 /// OMPLoopDirective and skipped when searching for the associated syntactical 105 /// loop. 106 /// 107 /// Example: 108 /// <code> 109 /// std::vector<std::string> Container{1,2,3}; 110 /// for (std::string Str : Container) 111 /// Body(Str); 112 /// </code> 113 /// which is syntactic sugar for approximately: 114 /// <code> 115 /// auto &&__range = Container; 116 /// auto __begin = std::begin(__range); 117 /// auto __end = std::end(__range); 118 /// for (; __begin != __end; ++__begin) { 119 /// std::String Str = *__begin; 120 /// Body(Str); 121 /// } 122 /// </code> 123 /// In this example, the loop user variable is `Str`, the loop iteration 124 /// variable is `__begin` of type `std::vector<std::string>::iterator` and the 125 /// logical iteration number type is `size_t` (unsigned version of 126 /// `std::vector<std::string>::iterator::difference_type` aka `ptrdiff_t`). 127 /// Therefore, the distance function will be 128 /// <code> 129 /// [&](size_t &Result) { Result = __end - __begin; } 130 /// </code> 131 /// and the loop variable function is 132 /// <code> 133 /// [&,__begin](std::vector<std::string>::iterator &Result, size_t Logical) { 134 /// Result = __begin + Logical; 135 /// } 136 /// </code> 137 /// The variable `__begin`, aka the loop iteration variable, is captured by 138 /// value because it is modified in the loop body, but both functions require 139 /// the initial value. The OpenMP specification explicitly leaves unspecified 140 /// when the loop expressions are evaluated such that a capture by reference is 141 /// sufficient. 142 class OMPCanonicalLoop : public Stmt { 143 friend class ASTStmtReader; 144 friend class ASTStmtWriter; 145 146 /// Children of this AST node. 147 enum { 148 LOOP_STMT, 149 DISTANCE_FUNC, 150 LOOPVAR_FUNC, 151 LOOPVAR_REF, 152 LastSubStmt = LOOPVAR_REF 153 }; 154 155 private: 156 /// This AST node's children. 157 Stmt *SubStmts[LastSubStmt + 1] = {}; 158 OMPCanonicalLoop()159 OMPCanonicalLoop() : Stmt(StmtClass::OMPCanonicalLoopClass) {} 160 161 public: 162 /// Create a new OMPCanonicalLoop. create(const ASTContext & Ctx,Stmt * LoopStmt,CapturedStmt * DistanceFunc,CapturedStmt * LoopVarFunc,DeclRefExpr * LoopVarRef)163 static OMPCanonicalLoop *create(const ASTContext &Ctx, Stmt *LoopStmt, 164 CapturedStmt *DistanceFunc, 165 CapturedStmt *LoopVarFunc, 166 DeclRefExpr *LoopVarRef) { 167 OMPCanonicalLoop *S = new (Ctx) OMPCanonicalLoop(); 168 S->setLoopStmt(LoopStmt); 169 S->setDistanceFunc(DistanceFunc); 170 S->setLoopVarFunc(LoopVarFunc); 171 S->setLoopVarRef(LoopVarRef); 172 return S; 173 } 174 175 /// Create an empty OMPCanonicalLoop for deserialization. createEmpty(const ASTContext & Ctx)176 static OMPCanonicalLoop *createEmpty(const ASTContext &Ctx) { 177 return new (Ctx) OMPCanonicalLoop(); 178 } 179 classof(const Stmt * S)180 static bool classof(const Stmt *S) { 181 return S->getStmtClass() == StmtClass::OMPCanonicalLoopClass; 182 } 183 getBeginLoc()184 SourceLocation getBeginLoc() const { return getLoopStmt()->getBeginLoc(); } getEndLoc()185 SourceLocation getEndLoc() const { return getLoopStmt()->getEndLoc(); } 186 187 /// Return this AST node's children. 188 /// @{ children()189 child_range children() { 190 return child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1); 191 } children()192 const_child_range children() const { 193 return const_child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1); 194 } 195 /// @} 196 197 /// The wrapped syntactic loop statement (ForStmt or CXXForRangeStmt). 198 /// @{ getLoopStmt()199 Stmt *getLoopStmt() { return SubStmts[LOOP_STMT]; } getLoopStmt()200 const Stmt *getLoopStmt() const { return SubStmts[LOOP_STMT]; } setLoopStmt(Stmt * S)201 void setLoopStmt(Stmt *S) { 202 assert((isa<ForStmt>(S) || isa<CXXForRangeStmt>(S)) && 203 "Canonical loop must be a for loop (range-based or otherwise)"); 204 SubStmts[LOOP_STMT] = S; 205 } 206 /// @} 207 208 /// The function that computes the number of loop iterations. Can be evaluated 209 /// before entering the loop but after the syntactical loop's init 210 /// statement(s). 211 /// 212 /// Function signature: void(LogicalTy &Result) 213 /// Any values necessary to compute the distance are captures of the closure. 214 /// @{ getDistanceFunc()215 CapturedStmt *getDistanceFunc() { 216 return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]); 217 } getDistanceFunc()218 const CapturedStmt *getDistanceFunc() const { 219 return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]); 220 } setDistanceFunc(CapturedStmt * S)221 void setDistanceFunc(CapturedStmt *S) { 222 assert(S && "Expected non-null captured statement"); 223 SubStmts[DISTANCE_FUNC] = S; 224 } 225 /// @} 226 227 /// The function that computes the loop user variable from a logical iteration 228 /// counter. Can be evaluated as first statement in the loop. 229 /// 230 /// Function signature: void(LoopVarTy &Result, LogicalTy Number) 231 /// Any other values required to compute the loop user variable (such as start 232 /// value, step size) are captured by the closure. In particular, the initial 233 /// value of loop iteration variable is captured by value to be unaffected by 234 /// previous iterations. 235 /// @{ getLoopVarFunc()236 CapturedStmt *getLoopVarFunc() { 237 return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]); 238 } getLoopVarFunc()239 const CapturedStmt *getLoopVarFunc() const { 240 return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]); 241 } setLoopVarFunc(CapturedStmt * S)242 void setLoopVarFunc(CapturedStmt *S) { 243 assert(S && "Expected non-null captured statement"); 244 SubStmts[LOOPVAR_FUNC] = S; 245 } 246 /// @} 247 248 /// Reference to the loop user variable as accessed in the loop body. 249 /// @{ getLoopVarRef()250 DeclRefExpr *getLoopVarRef() { 251 return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]); 252 } getLoopVarRef()253 const DeclRefExpr *getLoopVarRef() const { 254 return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]); 255 } setLoopVarRef(DeclRefExpr * E)256 void setLoopVarRef(DeclRefExpr *E) { 257 assert(E && "Expected non-null loop variable"); 258 SubStmts[LOOPVAR_REF] = E; 259 } 260 /// @} 261 }; 262 263 /// This is a basic class for representing single OpenMP executable 264 /// directive. 265 /// 266 class OMPExecutableDirective : public Stmt { 267 friend class ASTStmtReader; 268 friend class ASTStmtWriter; 269 270 /// Kind of the directive. 271 OpenMPDirectiveKind Kind = llvm::omp::OMPD_unknown; 272 /// Starting location of the directive (directive keyword). 273 SourceLocation StartLoc; 274 /// Ending location of the directive. 275 SourceLocation EndLoc; 276 277 /// Get the clauses storage. getClauses()278 MutableArrayRef<OMPClause *> getClauses() { 279 if (!Data) 280 return std::nullopt; 281 return Data->getClauses(); 282 } 283 284 protected: 285 /// Data, associated with the directive. 286 OMPChildren *Data = nullptr; 287 288 /// Build instance of directive of class \a K. 289 /// 290 /// \param SC Statement class. 291 /// \param K Kind of OpenMP directive. 292 /// \param StartLoc Starting location of the directive (directive keyword). 293 /// \param EndLoc Ending location of the directive. 294 /// OMPExecutableDirective(StmtClass SC,OpenMPDirectiveKind K,SourceLocation StartLoc,SourceLocation EndLoc)295 OMPExecutableDirective(StmtClass SC, OpenMPDirectiveKind K, 296 SourceLocation StartLoc, SourceLocation EndLoc) 297 : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)), 298 EndLoc(std::move(EndLoc)) {} 299 300 template <typename T, typename... Params> createDirective(const ASTContext & C,ArrayRef<OMPClause * > Clauses,Stmt * AssociatedStmt,unsigned NumChildren,Params &&...P)301 static T *createDirective(const ASTContext &C, ArrayRef<OMPClause *> Clauses, 302 Stmt *AssociatedStmt, unsigned NumChildren, 303 Params &&... P) { 304 void *Mem = 305 C.Allocate(sizeof(T) + OMPChildren::size(Clauses.size(), AssociatedStmt, 306 NumChildren), 307 alignof(T)); 308 309 auto *Data = OMPChildren::Create(reinterpret_cast<T *>(Mem) + 1, Clauses, 310 AssociatedStmt, NumChildren); 311 auto *Inst = new (Mem) T(std::forward<Params>(P)...); 312 Inst->Data = Data; 313 return Inst; 314 } 315 316 template <typename T, typename... Params> createEmptyDirective(const ASTContext & C,unsigned NumClauses,bool HasAssociatedStmt,unsigned NumChildren,Params &&...P)317 static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses, 318 bool HasAssociatedStmt, unsigned NumChildren, 319 Params &&... P) { 320 void *Mem = 321 C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt, 322 NumChildren), 323 alignof(T)); 324 auto *Data = 325 OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses, 326 HasAssociatedStmt, NumChildren); 327 auto *Inst = new (Mem) T(std::forward<Params>(P)...); 328 Inst->Data = Data; 329 return Inst; 330 } 331 332 template <typename T> 333 static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses, 334 bool HasAssociatedStmt = false, 335 unsigned NumChildren = 0) { 336 void *Mem = 337 C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt, 338 NumChildren), 339 alignof(T)); 340 auto *Data = 341 OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses, 342 HasAssociatedStmt, NumChildren); 343 auto *Inst = new (Mem) T; 344 Inst->Data = Data; 345 return Inst; 346 } 347 348 public: 349 /// Iterates over expressions/statements used in the construct. 350 class used_clauses_child_iterator 351 : public llvm::iterator_adaptor_base< 352 used_clauses_child_iterator, ArrayRef<OMPClause *>::iterator, 353 std::forward_iterator_tag, Stmt *, ptrdiff_t, Stmt *, Stmt *> { 354 ArrayRef<OMPClause *>::iterator End; 355 OMPClause::child_iterator ChildI, ChildEnd; 356 MoveToNext()357 void MoveToNext() { 358 if (ChildI != ChildEnd) 359 return; 360 while (this->I != End) { 361 ++this->I; 362 if (this->I != End) { 363 ChildI = (*this->I)->used_children().begin(); 364 ChildEnd = (*this->I)->used_children().end(); 365 if (ChildI != ChildEnd) 366 return; 367 } 368 } 369 } 370 371 public: used_clauses_child_iterator(ArrayRef<OMPClause * > Clauses)372 explicit used_clauses_child_iterator(ArrayRef<OMPClause *> Clauses) 373 : used_clauses_child_iterator::iterator_adaptor_base(Clauses.begin()), 374 End(Clauses.end()) { 375 if (this->I != End) { 376 ChildI = (*this->I)->used_children().begin(); 377 ChildEnd = (*this->I)->used_children().end(); 378 MoveToNext(); 379 } 380 } 381 Stmt *operator*() const { return *ChildI; } 382 Stmt *operator->() const { return **this; } 383 384 used_clauses_child_iterator &operator++() { 385 ++ChildI; 386 if (ChildI != ChildEnd) 387 return *this; 388 if (this->I != End) { 389 ++this->I; 390 if (this->I != End) { 391 ChildI = (*this->I)->used_children().begin(); 392 ChildEnd = (*this->I)->used_children().end(); 393 } 394 } 395 MoveToNext(); 396 return *this; 397 } 398 }; 399 400 static llvm::iterator_range<used_clauses_child_iterator> used_clauses_children(ArrayRef<OMPClause * > Clauses)401 used_clauses_children(ArrayRef<OMPClause *> Clauses) { 402 return { 403 used_clauses_child_iterator(Clauses), 404 used_clauses_child_iterator(llvm::ArrayRef(Clauses.end(), (size_t)0))}; 405 } 406 407 /// Iterates over a filtered subrange of clauses applied to a 408 /// directive. 409 /// 410 /// This iterator visits only clauses of type SpecificClause. 411 template <typename SpecificClause> 412 class specific_clause_iterator 413 : public llvm::iterator_adaptor_base< 414 specific_clause_iterator<SpecificClause>, 415 ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag, 416 const SpecificClause *, ptrdiff_t, const SpecificClause *, 417 const SpecificClause *> { 418 ArrayRef<OMPClause *>::const_iterator End; 419 SkipToNextClause()420 void SkipToNextClause() { 421 while (this->I != End && !isa<SpecificClause>(*this->I)) 422 ++this->I; 423 } 424 425 public: specific_clause_iterator(ArrayRef<OMPClause * > Clauses)426 explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses) 427 : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()), 428 End(Clauses.end()) { 429 SkipToNextClause(); 430 } 431 432 const SpecificClause *operator*() const { 433 return cast<SpecificClause>(*this->I); 434 } 435 const SpecificClause *operator->() const { return **this; } 436 437 specific_clause_iterator &operator++() { 438 ++this->I; 439 SkipToNextClause(); 440 return *this; 441 } 442 }; 443 444 template <typename SpecificClause> 445 static llvm::iterator_range<specific_clause_iterator<SpecificClause>> getClausesOfKind(ArrayRef<OMPClause * > Clauses)446 getClausesOfKind(ArrayRef<OMPClause *> Clauses) { 447 return {specific_clause_iterator<SpecificClause>(Clauses), 448 specific_clause_iterator<SpecificClause>( 449 llvm::ArrayRef(Clauses.end(), (size_t)0))}; 450 } 451 452 template <typename SpecificClause> 453 llvm::iterator_range<specific_clause_iterator<SpecificClause>> getClausesOfKind()454 getClausesOfKind() const { 455 return getClausesOfKind<SpecificClause>(clauses()); 456 } 457 458 /// Gets a single clause of the specified kind associated with the 459 /// current directive iff there is only one clause of this kind (and assertion 460 /// is fired if there is more than one clause is associated with the 461 /// directive). Returns nullptr if no clause of this kind is associated with 462 /// the directive. 463 template <typename SpecificClause> getSingleClause(ArrayRef<OMPClause * > Clauses)464 static const SpecificClause *getSingleClause(ArrayRef<OMPClause *> Clauses) { 465 auto ClausesOfKind = getClausesOfKind<SpecificClause>(Clauses); 466 467 if (ClausesOfKind.begin() != ClausesOfKind.end()) { 468 assert(std::next(ClausesOfKind.begin()) == ClausesOfKind.end() && 469 "There are at least 2 clauses of the specified kind"); 470 return *ClausesOfKind.begin(); 471 } 472 return nullptr; 473 } 474 475 template <typename SpecificClause> getSingleClause()476 const SpecificClause *getSingleClause() const { 477 return getSingleClause<SpecificClause>(clauses()); 478 } 479 480 /// Returns true if the current directive has one or more clauses of a 481 /// specific kind. 482 template <typename SpecificClause> hasClausesOfKind()483 bool hasClausesOfKind() const { 484 auto Clauses = getClausesOfKind<SpecificClause>(); 485 return Clauses.begin() != Clauses.end(); 486 } 487 488 /// Returns starting location of directive kind. getBeginLoc()489 SourceLocation getBeginLoc() const { return StartLoc; } 490 /// Returns ending location of directive. getEndLoc()491 SourceLocation getEndLoc() const { return EndLoc; } 492 493 /// Set starting location of directive kind. 494 /// 495 /// \param Loc New starting location of directive. 496 /// setLocStart(SourceLocation Loc)497 void setLocStart(SourceLocation Loc) { StartLoc = Loc; } 498 /// Set ending location of directive. 499 /// 500 /// \param Loc New ending location of directive. 501 /// setLocEnd(SourceLocation Loc)502 void setLocEnd(SourceLocation Loc) { EndLoc = Loc; } 503 504 /// Get number of clauses. getNumClauses()505 unsigned getNumClauses() const { 506 if (!Data) 507 return 0; 508 return Data->getNumClauses(); 509 } 510 511 /// Returns specified clause. 512 /// 513 /// \param I Number of clause. 514 /// getClause(unsigned I)515 OMPClause *getClause(unsigned I) const { return clauses()[I]; } 516 517 /// Returns true if directive has associated statement. hasAssociatedStmt()518 bool hasAssociatedStmt() const { return Data && Data->hasAssociatedStmt(); } 519 520 /// Returns statement associated with the directive. getAssociatedStmt()521 const Stmt *getAssociatedStmt() const { 522 return const_cast<OMPExecutableDirective *>(this)->getAssociatedStmt(); 523 } getAssociatedStmt()524 Stmt *getAssociatedStmt() { 525 assert(hasAssociatedStmt() && 526 "Expected directive with the associated statement."); 527 return Data->getAssociatedStmt(); 528 } 529 530 /// Returns the captured statement associated with the 531 /// component region within the (combined) directive. 532 /// 533 /// \param RegionKind Component region kind. getCapturedStmt(OpenMPDirectiveKind RegionKind)534 const CapturedStmt *getCapturedStmt(OpenMPDirectiveKind RegionKind) const { 535 assert(hasAssociatedStmt() && 536 "Expected directive with the associated statement."); 537 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 538 getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind()); 539 return Data->getCapturedStmt(RegionKind, CaptureRegions); 540 } 541 542 /// Get innermost captured statement for the construct. getInnermostCapturedStmt()543 CapturedStmt *getInnermostCapturedStmt() { 544 assert(hasAssociatedStmt() && 545 "Expected directive with the associated statement."); 546 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 547 getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind()); 548 return Data->getInnermostCapturedStmt(CaptureRegions); 549 } 550 getInnermostCapturedStmt()551 const CapturedStmt *getInnermostCapturedStmt() const { 552 return const_cast<OMPExecutableDirective *>(this) 553 ->getInnermostCapturedStmt(); 554 } 555 getDirectiveKind()556 OpenMPDirectiveKind getDirectiveKind() const { return Kind; } 557 classof(const Stmt * S)558 static bool classof(const Stmt *S) { 559 return S->getStmtClass() >= firstOMPExecutableDirectiveConstant && 560 S->getStmtClass() <= lastOMPExecutableDirectiveConstant; 561 } 562 children()563 child_range children() { 564 if (!Data) 565 return child_range(child_iterator(), child_iterator()); 566 return Data->getAssociatedStmtAsRange(); 567 } 568 children()569 const_child_range children() const { 570 return const_cast<OMPExecutableDirective *>(this)->children(); 571 } 572 clauses()573 ArrayRef<OMPClause *> clauses() const { 574 if (!Data) 575 return std::nullopt; 576 return Data->getClauses(); 577 } 578 579 /// Returns whether or not this is a Standalone directive. 580 /// 581 /// Stand-alone directives are executable directives 582 /// that have no associated user code. 583 bool isStandaloneDirective() const; 584 585 /// Returns the AST node representing OpenMP structured-block of this 586 /// OpenMP executable directive, 587 /// Prerequisite: Executable Directive must not be Standalone directive. getStructuredBlock()588 const Stmt *getStructuredBlock() const { 589 return const_cast<OMPExecutableDirective *>(this)->getStructuredBlock(); 590 } 591 Stmt *getStructuredBlock(); 592 getRawStmt()593 const Stmt *getRawStmt() const { 594 return const_cast<OMPExecutableDirective *>(this)->getRawStmt(); 595 } getRawStmt()596 Stmt *getRawStmt() { 597 assert(hasAssociatedStmt() && 598 "Expected directive with the associated statement."); 599 return Data->getRawStmt(); 600 } 601 }; 602 603 /// This represents '#pragma omp parallel' directive. 604 /// 605 /// \code 606 /// #pragma omp parallel private(a,b) reduction(+: c,d) 607 /// \endcode 608 /// In this example directive '#pragma omp parallel' has clauses 'private' 609 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and 610 /// variables 'c' and 'd'. 611 /// 612 class OMPParallelDirective : public OMPExecutableDirective { 613 friend class ASTStmtReader; 614 friend class OMPExecutableDirective; 615 /// true if the construct has inner cancel directive. 616 bool HasCancel = false; 617 618 /// Build directive with the given start and end location. 619 /// 620 /// \param StartLoc Starting location of the directive (directive keyword). 621 /// \param EndLoc Ending Location of the directive. 622 /// OMPParallelDirective(SourceLocation StartLoc,SourceLocation EndLoc)623 OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc) 624 : OMPExecutableDirective(OMPParallelDirectiveClass, 625 llvm::omp::OMPD_parallel, StartLoc, EndLoc) {} 626 627 /// Build an empty directive. 628 /// OMPParallelDirective()629 explicit OMPParallelDirective() 630 : OMPExecutableDirective(OMPParallelDirectiveClass, 631 llvm::omp::OMPD_parallel, SourceLocation(), 632 SourceLocation()) {} 633 634 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)635 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 636 637 /// Set cancel state. setHasCancel(bool Has)638 void setHasCancel(bool Has) { HasCancel = Has; } 639 640 public: 641 /// Creates directive with a list of \a Clauses. 642 /// 643 /// \param C AST context. 644 /// \param StartLoc Starting location of the directive kind. 645 /// \param EndLoc Ending Location of the directive. 646 /// \param Clauses List of clauses. 647 /// \param AssociatedStmt Statement associated with the directive. 648 /// \param TaskRedRef Task reduction special reference expression to handle 649 /// taskgroup descriptor. 650 /// \param HasCancel true if this directive has inner cancel directive. 651 /// 652 static OMPParallelDirective * 653 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 654 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, 655 bool HasCancel); 656 657 /// Creates an empty directive with the place for \a N clauses. 658 /// 659 /// \param C AST context. 660 /// \param NumClauses Number of clauses. 661 /// 662 static OMPParallelDirective *CreateEmpty(const ASTContext &C, 663 unsigned NumClauses, EmptyShell); 664 665 /// Returns special task reduction reference expression. getTaskReductionRefExpr()666 Expr *getTaskReductionRefExpr() { 667 return cast_or_null<Expr>(Data->getChildren()[0]); 668 } getTaskReductionRefExpr()669 const Expr *getTaskReductionRefExpr() const { 670 return const_cast<OMPParallelDirective *>(this)->getTaskReductionRefExpr(); 671 } 672 673 /// Return true if current directive has inner cancel directive. hasCancel()674 bool hasCancel() const { return HasCancel; } 675 classof(const Stmt * T)676 static bool classof(const Stmt *T) { 677 return T->getStmtClass() == OMPParallelDirectiveClass; 678 } 679 }; 680 681 /// The base class for all loop-based directives, including loop transformation 682 /// directives. 683 class OMPLoopBasedDirective : public OMPExecutableDirective { 684 friend class ASTStmtReader; 685 686 protected: 687 /// Number of collapsed loops as specified by 'collapse' clause. 688 unsigned NumAssociatedLoops = 0; 689 690 /// Build instance of loop directive of class \a Kind. 691 /// 692 /// \param SC Statement class. 693 /// \param Kind Kind of OpenMP directive. 694 /// \param StartLoc Starting location of the directive (directive keyword). 695 /// \param EndLoc Ending location of the directive. 696 /// \param NumAssociatedLoops Number of loops associated with the construct. 697 /// OMPLoopBasedDirective(StmtClass SC,OpenMPDirectiveKind Kind,SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumAssociatedLoops)698 OMPLoopBasedDirective(StmtClass SC, OpenMPDirectiveKind Kind, 699 SourceLocation StartLoc, SourceLocation EndLoc, 700 unsigned NumAssociatedLoops) 701 : OMPExecutableDirective(SC, Kind, StartLoc, EndLoc), 702 NumAssociatedLoops(NumAssociatedLoops) {} 703 704 public: 705 /// The expressions built to support OpenMP loops in combined/composite 706 /// pragmas (e.g. pragma omp distribute parallel for) 707 struct DistCombinedHelperExprs { 708 /// DistributeLowerBound - used when composing 'omp distribute' with 709 /// 'omp for' in a same construct. 710 Expr *LB; 711 /// DistributeUpperBound - used when composing 'omp distribute' with 712 /// 'omp for' in a same construct. 713 Expr *UB; 714 /// DistributeEnsureUpperBound - used when composing 'omp distribute' 715 /// with 'omp for' in a same construct, EUB depends on DistUB 716 Expr *EUB; 717 /// Distribute loop iteration variable init used when composing 'omp 718 /// distribute' 719 /// with 'omp for' in a same construct 720 Expr *Init; 721 /// Distribute Loop condition used when composing 'omp distribute' 722 /// with 'omp for' in a same construct 723 Expr *Cond; 724 /// Update of LowerBound for statically scheduled omp loops for 725 /// outer loop in combined constructs (e.g. 'distribute parallel for') 726 Expr *NLB; 727 /// Update of UpperBound for statically scheduled omp loops for 728 /// outer loop in combined constructs (e.g. 'distribute parallel for') 729 Expr *NUB; 730 /// Distribute Loop condition used when composing 'omp distribute' 731 /// with 'omp for' in a same construct when schedule is chunked. 732 Expr *DistCond; 733 /// 'omp parallel for' loop condition used when composed with 734 /// 'omp distribute' in the same construct and when schedule is 735 /// chunked and the chunk size is 1. 736 Expr *ParForInDistCond; 737 }; 738 739 /// The expressions built for the OpenMP loop CodeGen for the 740 /// whole collapsed loop nest. 741 struct HelperExprs { 742 /// Loop iteration variable. 743 Expr *IterationVarRef; 744 /// Loop last iteration number. 745 Expr *LastIteration; 746 /// Loop number of iterations. 747 Expr *NumIterations; 748 /// Calculation of last iteration. 749 Expr *CalcLastIteration; 750 /// Loop pre-condition. 751 Expr *PreCond; 752 /// Loop condition. 753 Expr *Cond; 754 /// Loop iteration variable init. 755 Expr *Init; 756 /// Loop increment. 757 Expr *Inc; 758 /// IsLastIteration - local flag variable passed to runtime. 759 Expr *IL; 760 /// LowerBound - local variable passed to runtime. 761 Expr *LB; 762 /// UpperBound - local variable passed to runtime. 763 Expr *UB; 764 /// Stride - local variable passed to runtime. 765 Expr *ST; 766 /// EnsureUpperBound -- expression UB = min(UB, NumIterations). 767 Expr *EUB; 768 /// Update of LowerBound for statically scheduled 'omp for' loops. 769 Expr *NLB; 770 /// Update of UpperBound for statically scheduled 'omp for' loops. 771 Expr *NUB; 772 /// PreviousLowerBound - local variable passed to runtime in the 773 /// enclosing schedule or null if that does not apply. 774 Expr *PrevLB; 775 /// PreviousUpperBound - local variable passed to runtime in the 776 /// enclosing schedule or null if that does not apply. 777 Expr *PrevUB; 778 /// DistInc - increment expression for distribute loop when found 779 /// combined with a further loop level (e.g. in 'distribute parallel for') 780 /// expression IV = IV + ST 781 Expr *DistInc; 782 /// PrevEUB - expression similar to EUB but to be used when loop 783 /// scheduling uses PrevLB and PrevUB (e.g. in 'distribute parallel for' 784 /// when ensuring that the UB is either the calculated UB by the runtime or 785 /// the end of the assigned distribute chunk) 786 /// expression UB = min (UB, PrevUB) 787 Expr *PrevEUB; 788 /// Counters Loop counters. 789 SmallVector<Expr *, 4> Counters; 790 /// PrivateCounters Loop counters. 791 SmallVector<Expr *, 4> PrivateCounters; 792 /// Expressions for loop counters inits for CodeGen. 793 SmallVector<Expr *, 4> Inits; 794 /// Expressions for loop counters update for CodeGen. 795 SmallVector<Expr *, 4> Updates; 796 /// Final loop counter values for GodeGen. 797 SmallVector<Expr *, 4> Finals; 798 /// List of counters required for the generation of the non-rectangular 799 /// loops. 800 SmallVector<Expr *, 4> DependentCounters; 801 /// List of initializers required for the generation of the non-rectangular 802 /// loops. 803 SmallVector<Expr *, 4> DependentInits; 804 /// List of final conditions required for the generation of the 805 /// non-rectangular loops. 806 SmallVector<Expr *, 4> FinalsConditions; 807 /// Init statement for all captured expressions. 808 Stmt *PreInits; 809 810 /// Expressions used when combining OpenMP loop pragmas 811 DistCombinedHelperExprs DistCombinedFields; 812 813 /// Check if all the expressions are built (does not check the 814 /// worksharing ones). builtAllHelperExprs815 bool builtAll() { 816 return IterationVarRef != nullptr && LastIteration != nullptr && 817 NumIterations != nullptr && PreCond != nullptr && 818 Cond != nullptr && Init != nullptr && Inc != nullptr; 819 } 820 821 /// Initialize all the fields to null. 822 /// \param Size Number of elements in the 823 /// counters/finals/updates/dependent_counters/dependent_inits/finals_conditions 824 /// arrays. clearHelperExprs825 void clear(unsigned Size) { 826 IterationVarRef = nullptr; 827 LastIteration = nullptr; 828 CalcLastIteration = nullptr; 829 PreCond = nullptr; 830 Cond = nullptr; 831 Init = nullptr; 832 Inc = nullptr; 833 IL = nullptr; 834 LB = nullptr; 835 UB = nullptr; 836 ST = nullptr; 837 EUB = nullptr; 838 NLB = nullptr; 839 NUB = nullptr; 840 NumIterations = nullptr; 841 PrevLB = nullptr; 842 PrevUB = nullptr; 843 DistInc = nullptr; 844 PrevEUB = nullptr; 845 Counters.resize(Size); 846 PrivateCounters.resize(Size); 847 Inits.resize(Size); 848 Updates.resize(Size); 849 Finals.resize(Size); 850 DependentCounters.resize(Size); 851 DependentInits.resize(Size); 852 FinalsConditions.resize(Size); 853 for (unsigned I = 0; I < Size; ++I) { 854 Counters[I] = nullptr; 855 PrivateCounters[I] = nullptr; 856 Inits[I] = nullptr; 857 Updates[I] = nullptr; 858 Finals[I] = nullptr; 859 DependentCounters[I] = nullptr; 860 DependentInits[I] = nullptr; 861 FinalsConditions[I] = nullptr; 862 } 863 PreInits = nullptr; 864 DistCombinedFields.LB = nullptr; 865 DistCombinedFields.UB = nullptr; 866 DistCombinedFields.EUB = nullptr; 867 DistCombinedFields.Init = nullptr; 868 DistCombinedFields.Cond = nullptr; 869 DistCombinedFields.NLB = nullptr; 870 DistCombinedFields.NUB = nullptr; 871 DistCombinedFields.DistCond = nullptr; 872 DistCombinedFields.ParForInDistCond = nullptr; 873 } 874 }; 875 876 /// Get number of collapsed loops. getLoopsNumber()877 unsigned getLoopsNumber() const { return NumAssociatedLoops; } 878 879 /// Try to find the next loop sub-statement in the specified statement \p 880 /// CurStmt. 881 /// \param TryImperfectlyNestedLoops true, if we need to try to look for the 882 /// imperfectly nested loop. 883 static Stmt *tryToFindNextInnerLoop(Stmt *CurStmt, 884 bool TryImperfectlyNestedLoops); tryToFindNextInnerLoop(const Stmt * CurStmt,bool TryImperfectlyNestedLoops)885 static const Stmt *tryToFindNextInnerLoop(const Stmt *CurStmt, 886 bool TryImperfectlyNestedLoops) { 887 return tryToFindNextInnerLoop(const_cast<Stmt *>(CurStmt), 888 TryImperfectlyNestedLoops); 889 } 890 891 /// Calls the specified callback function for all the loops in \p CurStmt, 892 /// from the outermost to the innermost. 893 static bool 894 doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops, 895 unsigned NumLoops, 896 llvm::function_ref<bool(unsigned, Stmt *)> Callback, 897 llvm::function_ref<void(OMPLoopTransformationDirective *)> 898 OnTransformationCallback); 899 static bool doForAllLoops(const Stmt * CurStmt,bool TryImperfectlyNestedLoops,unsigned NumLoops,llvm::function_ref<bool (unsigned,const Stmt *)> Callback,llvm::function_ref<void (const OMPLoopTransformationDirective *)> OnTransformationCallback)900 doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops, 901 unsigned NumLoops, 902 llvm::function_ref<bool(unsigned, const Stmt *)> Callback, 903 llvm::function_ref<void(const OMPLoopTransformationDirective *)> 904 OnTransformationCallback) { 905 auto &&NewCallback = [Callback](unsigned Cnt, Stmt *CurStmt) { 906 return Callback(Cnt, CurStmt); 907 }; 908 auto &&NewTransformCb = 909 [OnTransformationCallback](OMPLoopTransformationDirective *A) { 910 OnTransformationCallback(A); 911 }; 912 return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops, 913 NumLoops, NewCallback, NewTransformCb); 914 } 915 916 /// Calls the specified callback function for all the loops in \p CurStmt, 917 /// from the outermost to the innermost. 918 static bool doForAllLoops(Stmt * CurStmt,bool TryImperfectlyNestedLoops,unsigned NumLoops,llvm::function_ref<bool (unsigned,Stmt *)> Callback)919 doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops, 920 unsigned NumLoops, 921 llvm::function_ref<bool(unsigned, Stmt *)> Callback) { 922 auto &&TransformCb = [](OMPLoopTransformationDirective *) {}; 923 return doForAllLoops(CurStmt, TryImperfectlyNestedLoops, NumLoops, Callback, 924 TransformCb); 925 } 926 static bool doForAllLoops(const Stmt * CurStmt,bool TryImperfectlyNestedLoops,unsigned NumLoops,llvm::function_ref<bool (unsigned,const Stmt *)> Callback)927 doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops, 928 unsigned NumLoops, 929 llvm::function_ref<bool(unsigned, const Stmt *)> Callback) { 930 auto &&NewCallback = [Callback](unsigned Cnt, const Stmt *CurStmt) { 931 return Callback(Cnt, CurStmt); 932 }; 933 return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops, 934 NumLoops, NewCallback); 935 } 936 937 /// Calls the specified callback function for all the loop bodies in \p 938 /// CurStmt, from the outermost loop to the innermost. 939 static void doForAllLoopsBodies( 940 Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops, 941 llvm::function_ref<void(unsigned, Stmt *, Stmt *)> Callback); doForAllLoopsBodies(const Stmt * CurStmt,bool TryImperfectlyNestedLoops,unsigned NumLoops,llvm::function_ref<void (unsigned,const Stmt *,const Stmt *)> Callback)942 static void doForAllLoopsBodies( 943 const Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops, 944 llvm::function_ref<void(unsigned, const Stmt *, const Stmt *)> Callback) { 945 auto &&NewCallback = [Callback](unsigned Cnt, Stmt *Loop, Stmt *Body) { 946 Callback(Cnt, Loop, Body); 947 }; 948 doForAllLoopsBodies(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops, 949 NumLoops, NewCallback); 950 } 951 classof(const Stmt * T)952 static bool classof(const Stmt *T) { 953 if (auto *D = dyn_cast<OMPExecutableDirective>(T)) 954 return isOpenMPLoopDirective(D->getDirectiveKind()); 955 return false; 956 } 957 }; 958 959 /// The base class for all loop transformation directives. 960 class OMPLoopTransformationDirective : public OMPLoopBasedDirective { 961 friend class ASTStmtReader; 962 963 /// Number of loops generated by this loop transformation. 964 unsigned NumGeneratedLoops = 0; 965 966 protected: OMPLoopTransformationDirective(StmtClass SC,OpenMPDirectiveKind Kind,SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumAssociatedLoops)967 explicit OMPLoopTransformationDirective(StmtClass SC, 968 OpenMPDirectiveKind Kind, 969 SourceLocation StartLoc, 970 SourceLocation EndLoc, 971 unsigned NumAssociatedLoops) 972 : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, NumAssociatedLoops) {} 973 974 /// Set the number of loops generated by this loop transformation. setNumGeneratedLoops(unsigned Num)975 void setNumGeneratedLoops(unsigned Num) { NumGeneratedLoops = Num; } 976 977 public: 978 /// Return the number of associated (consumed) loops. getNumAssociatedLoops()979 unsigned getNumAssociatedLoops() const { return getLoopsNumber(); } 980 981 /// Return the number of loops generated by this loop transformation. getNumGeneratedLoops()982 unsigned getNumGeneratedLoops() { return NumGeneratedLoops; } 983 984 /// Get the de-sugared statements after the loop transformation. 985 /// 986 /// Might be nullptr if either the directive generates no loops and is handled 987 /// directly in CodeGen, or resolving a template-dependence context is 988 /// required. 989 Stmt *getTransformedStmt() const; 990 991 /// Return preinits statement. 992 Stmt *getPreInits() const; 993 classof(const Stmt * T)994 static bool classof(const Stmt *T) { 995 return T->getStmtClass() == OMPTileDirectiveClass || 996 T->getStmtClass() == OMPUnrollDirectiveClass; 997 } 998 }; 999 1000 /// This is a common base class for loop directives ('omp simd', 'omp 1001 /// for', 'omp for simd' etc.). It is responsible for the loop code generation. 1002 /// 1003 class OMPLoopDirective : public OMPLoopBasedDirective { 1004 friend class ASTStmtReader; 1005 1006 /// Offsets to the stored exprs. 1007 /// This enumeration contains offsets to all the pointers to children 1008 /// expressions stored in OMPLoopDirective. 1009 /// The first 9 children are necessary for all the loop directives, 1010 /// the next 8 are specific to the worksharing ones, and the next 11 are 1011 /// used for combined constructs containing two pragmas associated to loops. 1012 /// After the fixed children, three arrays of length NumAssociatedLoops are 1013 /// allocated: loop counters, their updates and final values. 1014 /// PrevLowerBound and PrevUpperBound are used to communicate blocking 1015 /// information in composite constructs which require loop blocking 1016 /// DistInc is used to generate the increment expression for the distribute 1017 /// loop when combined with a further nested loop 1018 /// PrevEnsureUpperBound is used as the EnsureUpperBound expression for the 1019 /// for loop when combined with a previous distribute loop in the same pragma 1020 /// (e.g. 'distribute parallel for') 1021 /// 1022 enum { 1023 IterationVariableOffset = 0, 1024 LastIterationOffset = 1, 1025 CalcLastIterationOffset = 2, 1026 PreConditionOffset = 3, 1027 CondOffset = 4, 1028 InitOffset = 5, 1029 IncOffset = 6, 1030 PreInitsOffset = 7, 1031 // The '...End' enumerators do not correspond to child expressions - they 1032 // specify the offset to the end (and start of the following counters/ 1033 // updates/finals/dependent_counters/dependent_inits/finals_conditions 1034 // arrays). 1035 DefaultEnd = 8, 1036 // The following 8 exprs are used by worksharing and distribute loops only. 1037 IsLastIterVariableOffset = 8, 1038 LowerBoundVariableOffset = 9, 1039 UpperBoundVariableOffset = 10, 1040 StrideVariableOffset = 11, 1041 EnsureUpperBoundOffset = 12, 1042 NextLowerBoundOffset = 13, 1043 NextUpperBoundOffset = 14, 1044 NumIterationsOffset = 15, 1045 // Offset to the end for worksharing loop directives. 1046 WorksharingEnd = 16, 1047 PrevLowerBoundVariableOffset = 16, 1048 PrevUpperBoundVariableOffset = 17, 1049 DistIncOffset = 18, 1050 PrevEnsureUpperBoundOffset = 19, 1051 CombinedLowerBoundVariableOffset = 20, 1052 CombinedUpperBoundVariableOffset = 21, 1053 CombinedEnsureUpperBoundOffset = 22, 1054 CombinedInitOffset = 23, 1055 CombinedConditionOffset = 24, 1056 CombinedNextLowerBoundOffset = 25, 1057 CombinedNextUpperBoundOffset = 26, 1058 CombinedDistConditionOffset = 27, 1059 CombinedParForInDistConditionOffset = 28, 1060 // Offset to the end (and start of the following 1061 // counters/updates/finals/dependent_counters/dependent_inits/finals_conditions 1062 // arrays) for combined distribute loop directives. 1063 CombinedDistributeEnd = 29, 1064 }; 1065 1066 /// Get the counters storage. getCounters()1067 MutableArrayRef<Expr *> getCounters() { 1068 auto **Storage = reinterpret_cast<Expr **>( 1069 &Data->getChildren()[getArraysOffset(getDirectiveKind())]); 1070 return llvm::MutableArrayRef(Storage, getLoopsNumber()); 1071 } 1072 1073 /// Get the private counters storage. getPrivateCounters()1074 MutableArrayRef<Expr *> getPrivateCounters() { 1075 auto **Storage = reinterpret_cast<Expr **>( 1076 &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1077 getLoopsNumber()]); 1078 return llvm::MutableArrayRef(Storage, getLoopsNumber()); 1079 } 1080 1081 /// Get the updates storage. getInits()1082 MutableArrayRef<Expr *> getInits() { 1083 auto **Storage = reinterpret_cast<Expr **>( 1084 &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1085 2 * getLoopsNumber()]); 1086 return llvm::MutableArrayRef(Storage, getLoopsNumber()); 1087 } 1088 1089 /// Get the updates storage. getUpdates()1090 MutableArrayRef<Expr *> getUpdates() { 1091 auto **Storage = reinterpret_cast<Expr **>( 1092 &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1093 3 * getLoopsNumber()]); 1094 return llvm::MutableArrayRef(Storage, getLoopsNumber()); 1095 } 1096 1097 /// Get the final counter updates storage. getFinals()1098 MutableArrayRef<Expr *> getFinals() { 1099 auto **Storage = reinterpret_cast<Expr **>( 1100 &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1101 4 * getLoopsNumber()]); 1102 return llvm::MutableArrayRef(Storage, getLoopsNumber()); 1103 } 1104 1105 /// Get the dependent counters storage. getDependentCounters()1106 MutableArrayRef<Expr *> getDependentCounters() { 1107 auto **Storage = reinterpret_cast<Expr **>( 1108 &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1109 5 * getLoopsNumber()]); 1110 return llvm::MutableArrayRef(Storage, getLoopsNumber()); 1111 } 1112 1113 /// Get the dependent inits storage. getDependentInits()1114 MutableArrayRef<Expr *> getDependentInits() { 1115 auto **Storage = reinterpret_cast<Expr **>( 1116 &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1117 6 * getLoopsNumber()]); 1118 return llvm::MutableArrayRef(Storage, getLoopsNumber()); 1119 } 1120 1121 /// Get the finals conditions storage. getFinalsConditions()1122 MutableArrayRef<Expr *> getFinalsConditions() { 1123 auto **Storage = reinterpret_cast<Expr **>( 1124 &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1125 7 * getLoopsNumber()]); 1126 return llvm::MutableArrayRef(Storage, getLoopsNumber()); 1127 } 1128 1129 protected: 1130 /// Build instance of loop directive of class \a Kind. 1131 /// 1132 /// \param SC Statement class. 1133 /// \param Kind Kind of OpenMP directive. 1134 /// \param StartLoc Starting location of the directive (directive keyword). 1135 /// \param EndLoc Ending location of the directive. 1136 /// \param CollapsedNum Number of collapsed loops from 'collapse' clause. 1137 /// OMPLoopDirective(StmtClass SC,OpenMPDirectiveKind Kind,SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)1138 OMPLoopDirective(StmtClass SC, OpenMPDirectiveKind Kind, 1139 SourceLocation StartLoc, SourceLocation EndLoc, 1140 unsigned CollapsedNum) 1141 : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, CollapsedNum) {} 1142 1143 /// Offset to the start of children expression arrays. getArraysOffset(OpenMPDirectiveKind Kind)1144 static unsigned getArraysOffset(OpenMPDirectiveKind Kind) { 1145 if (isOpenMPLoopBoundSharingDirective(Kind)) 1146 return CombinedDistributeEnd; 1147 if (isOpenMPWorksharingDirective(Kind) || isOpenMPTaskLoopDirective(Kind) || 1148 isOpenMPGenericLoopDirective(Kind) || isOpenMPDistributeDirective(Kind)) 1149 return WorksharingEnd; 1150 return DefaultEnd; 1151 } 1152 1153 /// Children number. numLoopChildren(unsigned CollapsedNum,OpenMPDirectiveKind Kind)1154 static unsigned numLoopChildren(unsigned CollapsedNum, 1155 OpenMPDirectiveKind Kind) { 1156 return getArraysOffset(Kind) + 1157 8 * CollapsedNum; // Counters, PrivateCounters, Inits, 1158 // Updates, Finals, DependentCounters, 1159 // DependentInits, FinalsConditions. 1160 } 1161 setIterationVariable(Expr * IV)1162 void setIterationVariable(Expr *IV) { 1163 Data->getChildren()[IterationVariableOffset] = IV; 1164 } setLastIteration(Expr * LI)1165 void setLastIteration(Expr *LI) { 1166 Data->getChildren()[LastIterationOffset] = LI; 1167 } setCalcLastIteration(Expr * CLI)1168 void setCalcLastIteration(Expr *CLI) { 1169 Data->getChildren()[CalcLastIterationOffset] = CLI; 1170 } setPreCond(Expr * PC)1171 void setPreCond(Expr *PC) { Data->getChildren()[PreConditionOffset] = PC; } setCond(Expr * Cond)1172 void setCond(Expr *Cond) { Data->getChildren()[CondOffset] = Cond; } setInit(Expr * Init)1173 void setInit(Expr *Init) { Data->getChildren()[InitOffset] = Init; } setInc(Expr * Inc)1174 void setInc(Expr *Inc) { Data->getChildren()[IncOffset] = Inc; } setPreInits(Stmt * PreInits)1175 void setPreInits(Stmt *PreInits) { 1176 Data->getChildren()[PreInitsOffset] = PreInits; 1177 } setIsLastIterVariable(Expr * IL)1178 void setIsLastIterVariable(Expr *IL) { 1179 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1180 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1181 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1182 isOpenMPDistributeDirective(getDirectiveKind())) && 1183 "expected worksharing loop directive"); 1184 Data->getChildren()[IsLastIterVariableOffset] = IL; 1185 } setLowerBoundVariable(Expr * LB)1186 void setLowerBoundVariable(Expr *LB) { 1187 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1188 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1189 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1190 isOpenMPDistributeDirective(getDirectiveKind())) && 1191 "expected worksharing loop directive"); 1192 Data->getChildren()[LowerBoundVariableOffset] = LB; 1193 } setUpperBoundVariable(Expr * UB)1194 void setUpperBoundVariable(Expr *UB) { 1195 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1196 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1197 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1198 isOpenMPDistributeDirective(getDirectiveKind())) && 1199 "expected worksharing loop directive"); 1200 Data->getChildren()[UpperBoundVariableOffset] = UB; 1201 } setStrideVariable(Expr * ST)1202 void setStrideVariable(Expr *ST) { 1203 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1204 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1205 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1206 isOpenMPDistributeDirective(getDirectiveKind())) && 1207 "expected worksharing loop directive"); 1208 Data->getChildren()[StrideVariableOffset] = ST; 1209 } setEnsureUpperBound(Expr * EUB)1210 void setEnsureUpperBound(Expr *EUB) { 1211 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1212 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1213 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1214 isOpenMPDistributeDirective(getDirectiveKind())) && 1215 "expected worksharing loop directive"); 1216 Data->getChildren()[EnsureUpperBoundOffset] = EUB; 1217 } setNextLowerBound(Expr * NLB)1218 void setNextLowerBound(Expr *NLB) { 1219 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1220 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1221 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1222 isOpenMPDistributeDirective(getDirectiveKind())) && 1223 "expected worksharing loop directive"); 1224 Data->getChildren()[NextLowerBoundOffset] = NLB; 1225 } setNextUpperBound(Expr * NUB)1226 void setNextUpperBound(Expr *NUB) { 1227 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1228 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1229 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1230 isOpenMPDistributeDirective(getDirectiveKind())) && 1231 "expected worksharing loop directive"); 1232 Data->getChildren()[NextUpperBoundOffset] = NUB; 1233 } setNumIterations(Expr * NI)1234 void setNumIterations(Expr *NI) { 1235 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1236 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1237 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1238 isOpenMPDistributeDirective(getDirectiveKind())) && 1239 "expected worksharing loop directive"); 1240 Data->getChildren()[NumIterationsOffset] = NI; 1241 } setPrevLowerBoundVariable(Expr * PrevLB)1242 void setPrevLowerBoundVariable(Expr *PrevLB) { 1243 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1244 "expected loop bound sharing directive"); 1245 Data->getChildren()[PrevLowerBoundVariableOffset] = PrevLB; 1246 } setPrevUpperBoundVariable(Expr * PrevUB)1247 void setPrevUpperBoundVariable(Expr *PrevUB) { 1248 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1249 "expected loop bound sharing directive"); 1250 Data->getChildren()[PrevUpperBoundVariableOffset] = PrevUB; 1251 } setDistInc(Expr * DistInc)1252 void setDistInc(Expr *DistInc) { 1253 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1254 "expected loop bound sharing directive"); 1255 Data->getChildren()[DistIncOffset] = DistInc; 1256 } setPrevEnsureUpperBound(Expr * PrevEUB)1257 void setPrevEnsureUpperBound(Expr *PrevEUB) { 1258 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1259 "expected loop bound sharing directive"); 1260 Data->getChildren()[PrevEnsureUpperBoundOffset] = PrevEUB; 1261 } setCombinedLowerBoundVariable(Expr * CombLB)1262 void setCombinedLowerBoundVariable(Expr *CombLB) { 1263 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1264 "expected loop bound sharing directive"); 1265 Data->getChildren()[CombinedLowerBoundVariableOffset] = CombLB; 1266 } setCombinedUpperBoundVariable(Expr * CombUB)1267 void setCombinedUpperBoundVariable(Expr *CombUB) { 1268 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1269 "expected loop bound sharing directive"); 1270 Data->getChildren()[CombinedUpperBoundVariableOffset] = CombUB; 1271 } setCombinedEnsureUpperBound(Expr * CombEUB)1272 void setCombinedEnsureUpperBound(Expr *CombEUB) { 1273 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1274 "expected loop bound sharing directive"); 1275 Data->getChildren()[CombinedEnsureUpperBoundOffset] = CombEUB; 1276 } setCombinedInit(Expr * CombInit)1277 void setCombinedInit(Expr *CombInit) { 1278 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1279 "expected loop bound sharing directive"); 1280 Data->getChildren()[CombinedInitOffset] = CombInit; 1281 } setCombinedCond(Expr * CombCond)1282 void setCombinedCond(Expr *CombCond) { 1283 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1284 "expected loop bound sharing directive"); 1285 Data->getChildren()[CombinedConditionOffset] = CombCond; 1286 } setCombinedNextLowerBound(Expr * CombNLB)1287 void setCombinedNextLowerBound(Expr *CombNLB) { 1288 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1289 "expected loop bound sharing directive"); 1290 Data->getChildren()[CombinedNextLowerBoundOffset] = CombNLB; 1291 } setCombinedNextUpperBound(Expr * CombNUB)1292 void setCombinedNextUpperBound(Expr *CombNUB) { 1293 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1294 "expected loop bound sharing directive"); 1295 Data->getChildren()[CombinedNextUpperBoundOffset] = CombNUB; 1296 } setCombinedDistCond(Expr * CombDistCond)1297 void setCombinedDistCond(Expr *CombDistCond) { 1298 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1299 "expected loop bound distribute sharing directive"); 1300 Data->getChildren()[CombinedDistConditionOffset] = CombDistCond; 1301 } setCombinedParForInDistCond(Expr * CombParForInDistCond)1302 void setCombinedParForInDistCond(Expr *CombParForInDistCond) { 1303 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1304 "expected loop bound distribute sharing directive"); 1305 Data->getChildren()[CombinedParForInDistConditionOffset] = 1306 CombParForInDistCond; 1307 } 1308 void setCounters(ArrayRef<Expr *> A); 1309 void setPrivateCounters(ArrayRef<Expr *> A); 1310 void setInits(ArrayRef<Expr *> A); 1311 void setUpdates(ArrayRef<Expr *> A); 1312 void setFinals(ArrayRef<Expr *> A); 1313 void setDependentCounters(ArrayRef<Expr *> A); 1314 void setDependentInits(ArrayRef<Expr *> A); 1315 void setFinalsConditions(ArrayRef<Expr *> A); 1316 1317 public: getIterationVariable()1318 Expr *getIterationVariable() const { 1319 return cast<Expr>(Data->getChildren()[IterationVariableOffset]); 1320 } getLastIteration()1321 Expr *getLastIteration() const { 1322 return cast<Expr>(Data->getChildren()[LastIterationOffset]); 1323 } getCalcLastIteration()1324 Expr *getCalcLastIteration() const { 1325 return cast<Expr>(Data->getChildren()[CalcLastIterationOffset]); 1326 } getPreCond()1327 Expr *getPreCond() const { 1328 return cast<Expr>(Data->getChildren()[PreConditionOffset]); 1329 } getCond()1330 Expr *getCond() const { return cast<Expr>(Data->getChildren()[CondOffset]); } getInit()1331 Expr *getInit() const { return cast<Expr>(Data->getChildren()[InitOffset]); } getInc()1332 Expr *getInc() const { return cast<Expr>(Data->getChildren()[IncOffset]); } getPreInits()1333 const Stmt *getPreInits() const { 1334 return Data->getChildren()[PreInitsOffset]; 1335 } getPreInits()1336 Stmt *getPreInits() { return Data->getChildren()[PreInitsOffset]; } getIsLastIterVariable()1337 Expr *getIsLastIterVariable() const { 1338 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1339 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1340 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1341 isOpenMPDistributeDirective(getDirectiveKind())) && 1342 "expected worksharing loop directive"); 1343 return cast<Expr>(Data->getChildren()[IsLastIterVariableOffset]); 1344 } getLowerBoundVariable()1345 Expr *getLowerBoundVariable() const { 1346 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1347 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1348 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1349 isOpenMPDistributeDirective(getDirectiveKind())) && 1350 "expected worksharing loop directive"); 1351 return cast<Expr>(Data->getChildren()[LowerBoundVariableOffset]); 1352 } getUpperBoundVariable()1353 Expr *getUpperBoundVariable() const { 1354 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1355 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1356 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1357 isOpenMPDistributeDirective(getDirectiveKind())) && 1358 "expected worksharing loop directive"); 1359 return cast<Expr>(Data->getChildren()[UpperBoundVariableOffset]); 1360 } getStrideVariable()1361 Expr *getStrideVariable() const { 1362 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1363 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1364 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1365 isOpenMPDistributeDirective(getDirectiveKind())) && 1366 "expected worksharing loop directive"); 1367 return cast<Expr>(Data->getChildren()[StrideVariableOffset]); 1368 } getEnsureUpperBound()1369 Expr *getEnsureUpperBound() const { 1370 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1371 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1372 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1373 isOpenMPDistributeDirective(getDirectiveKind())) && 1374 "expected worksharing loop directive"); 1375 return cast<Expr>(Data->getChildren()[EnsureUpperBoundOffset]); 1376 } getNextLowerBound()1377 Expr *getNextLowerBound() const { 1378 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1379 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1380 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1381 isOpenMPDistributeDirective(getDirectiveKind())) && 1382 "expected worksharing loop directive"); 1383 return cast<Expr>(Data->getChildren()[NextLowerBoundOffset]); 1384 } getNextUpperBound()1385 Expr *getNextUpperBound() const { 1386 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1387 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1388 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1389 isOpenMPDistributeDirective(getDirectiveKind())) && 1390 "expected worksharing loop directive"); 1391 return cast<Expr>(Data->getChildren()[NextUpperBoundOffset]); 1392 } getNumIterations()1393 Expr *getNumIterations() const { 1394 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1395 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1396 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1397 isOpenMPDistributeDirective(getDirectiveKind())) && 1398 "expected worksharing loop directive"); 1399 return cast<Expr>(Data->getChildren()[NumIterationsOffset]); 1400 } getPrevLowerBoundVariable()1401 Expr *getPrevLowerBoundVariable() const { 1402 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1403 "expected loop bound sharing directive"); 1404 return cast<Expr>(Data->getChildren()[PrevLowerBoundVariableOffset]); 1405 } getPrevUpperBoundVariable()1406 Expr *getPrevUpperBoundVariable() const { 1407 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1408 "expected loop bound sharing directive"); 1409 return cast<Expr>(Data->getChildren()[PrevUpperBoundVariableOffset]); 1410 } getDistInc()1411 Expr *getDistInc() const { 1412 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1413 "expected loop bound sharing directive"); 1414 return cast<Expr>(Data->getChildren()[DistIncOffset]); 1415 } getPrevEnsureUpperBound()1416 Expr *getPrevEnsureUpperBound() const { 1417 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1418 "expected loop bound sharing directive"); 1419 return cast<Expr>(Data->getChildren()[PrevEnsureUpperBoundOffset]); 1420 } getCombinedLowerBoundVariable()1421 Expr *getCombinedLowerBoundVariable() const { 1422 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1423 "expected loop bound sharing directive"); 1424 return cast<Expr>(Data->getChildren()[CombinedLowerBoundVariableOffset]); 1425 } getCombinedUpperBoundVariable()1426 Expr *getCombinedUpperBoundVariable() const { 1427 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1428 "expected loop bound sharing directive"); 1429 return cast<Expr>(Data->getChildren()[CombinedUpperBoundVariableOffset]); 1430 } getCombinedEnsureUpperBound()1431 Expr *getCombinedEnsureUpperBound() const { 1432 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1433 "expected loop bound sharing directive"); 1434 return cast<Expr>(Data->getChildren()[CombinedEnsureUpperBoundOffset]); 1435 } getCombinedInit()1436 Expr *getCombinedInit() const { 1437 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1438 "expected loop bound sharing directive"); 1439 return cast<Expr>(Data->getChildren()[CombinedInitOffset]); 1440 } getCombinedCond()1441 Expr *getCombinedCond() const { 1442 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1443 "expected loop bound sharing directive"); 1444 return cast<Expr>(Data->getChildren()[CombinedConditionOffset]); 1445 } getCombinedNextLowerBound()1446 Expr *getCombinedNextLowerBound() const { 1447 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1448 "expected loop bound sharing directive"); 1449 return cast<Expr>(Data->getChildren()[CombinedNextLowerBoundOffset]); 1450 } getCombinedNextUpperBound()1451 Expr *getCombinedNextUpperBound() const { 1452 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1453 "expected loop bound sharing directive"); 1454 return cast<Expr>(Data->getChildren()[CombinedNextUpperBoundOffset]); 1455 } getCombinedDistCond()1456 Expr *getCombinedDistCond() const { 1457 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1458 "expected loop bound distribute sharing directive"); 1459 return cast<Expr>(Data->getChildren()[CombinedDistConditionOffset]); 1460 } getCombinedParForInDistCond()1461 Expr *getCombinedParForInDistCond() const { 1462 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1463 "expected loop bound distribute sharing directive"); 1464 return cast<Expr>(Data->getChildren()[CombinedParForInDistConditionOffset]); 1465 } 1466 Stmt *getBody(); getBody()1467 const Stmt *getBody() const { 1468 return const_cast<OMPLoopDirective *>(this)->getBody(); 1469 } 1470 counters()1471 ArrayRef<Expr *> counters() { return getCounters(); } 1472 counters()1473 ArrayRef<Expr *> counters() const { 1474 return const_cast<OMPLoopDirective *>(this)->getCounters(); 1475 } 1476 private_counters()1477 ArrayRef<Expr *> private_counters() { return getPrivateCounters(); } 1478 private_counters()1479 ArrayRef<Expr *> private_counters() const { 1480 return const_cast<OMPLoopDirective *>(this)->getPrivateCounters(); 1481 } 1482 inits()1483 ArrayRef<Expr *> inits() { return getInits(); } 1484 inits()1485 ArrayRef<Expr *> inits() const { 1486 return const_cast<OMPLoopDirective *>(this)->getInits(); 1487 } 1488 updates()1489 ArrayRef<Expr *> updates() { return getUpdates(); } 1490 updates()1491 ArrayRef<Expr *> updates() const { 1492 return const_cast<OMPLoopDirective *>(this)->getUpdates(); 1493 } 1494 finals()1495 ArrayRef<Expr *> finals() { return getFinals(); } 1496 finals()1497 ArrayRef<Expr *> finals() const { 1498 return const_cast<OMPLoopDirective *>(this)->getFinals(); 1499 } 1500 dependent_counters()1501 ArrayRef<Expr *> dependent_counters() { return getDependentCounters(); } 1502 dependent_counters()1503 ArrayRef<Expr *> dependent_counters() const { 1504 return const_cast<OMPLoopDirective *>(this)->getDependentCounters(); 1505 } 1506 dependent_inits()1507 ArrayRef<Expr *> dependent_inits() { return getDependentInits(); } 1508 dependent_inits()1509 ArrayRef<Expr *> dependent_inits() const { 1510 return const_cast<OMPLoopDirective *>(this)->getDependentInits(); 1511 } 1512 finals_conditions()1513 ArrayRef<Expr *> finals_conditions() { return getFinalsConditions(); } 1514 finals_conditions()1515 ArrayRef<Expr *> finals_conditions() const { 1516 return const_cast<OMPLoopDirective *>(this)->getFinalsConditions(); 1517 } 1518 classof(const Stmt * T)1519 static bool classof(const Stmt *T) { 1520 return T->getStmtClass() == OMPSimdDirectiveClass || 1521 T->getStmtClass() == OMPForDirectiveClass || 1522 T->getStmtClass() == OMPForSimdDirectiveClass || 1523 T->getStmtClass() == OMPParallelForDirectiveClass || 1524 T->getStmtClass() == OMPParallelForSimdDirectiveClass || 1525 T->getStmtClass() == OMPTaskLoopDirectiveClass || 1526 T->getStmtClass() == OMPTaskLoopSimdDirectiveClass || 1527 T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass || 1528 T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass || 1529 T->getStmtClass() == OMPMasterTaskLoopDirectiveClass || 1530 T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass || 1531 T->getStmtClass() == OMPGenericLoopDirectiveClass || 1532 T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass || 1533 T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass || 1534 T->getStmtClass() == OMPParallelGenericLoopDirectiveClass || 1535 T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass || 1536 T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass || 1537 T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass || 1538 T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass || 1539 T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass || 1540 T->getStmtClass() == OMPDistributeDirectiveClass || 1541 T->getStmtClass() == OMPTargetParallelForDirectiveClass || 1542 T->getStmtClass() == OMPDistributeParallelForDirectiveClass || 1543 T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass || 1544 T->getStmtClass() == OMPDistributeSimdDirectiveClass || 1545 T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass || 1546 T->getStmtClass() == OMPTargetSimdDirectiveClass || 1547 T->getStmtClass() == OMPTeamsDistributeDirectiveClass || 1548 T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass || 1549 T->getStmtClass() == 1550 OMPTeamsDistributeParallelForSimdDirectiveClass || 1551 T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass || 1552 T->getStmtClass() == 1553 OMPTargetTeamsDistributeParallelForDirectiveClass || 1554 T->getStmtClass() == 1555 OMPTargetTeamsDistributeParallelForSimdDirectiveClass || 1556 T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass || 1557 T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass; 1558 } 1559 }; 1560 1561 /// This represents '#pragma omp simd' directive. 1562 /// 1563 /// \code 1564 /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d) 1565 /// \endcode 1566 /// In this example directive '#pragma omp simd' has clauses 'private' 1567 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and 1568 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'. 1569 /// 1570 class OMPSimdDirective : public OMPLoopDirective { 1571 friend class ASTStmtReader; 1572 friend class OMPExecutableDirective; 1573 /// Build directive with the given start and end location. 1574 /// 1575 /// \param StartLoc Starting location of the directive kind. 1576 /// \param EndLoc Ending location of the directive. 1577 /// \param CollapsedNum Number of collapsed nested loops. 1578 /// OMPSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)1579 OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1580 unsigned CollapsedNum) 1581 : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, StartLoc, 1582 EndLoc, CollapsedNum) {} 1583 1584 /// Build an empty directive. 1585 /// 1586 /// \param CollapsedNum Number of collapsed nested loops. 1587 /// OMPSimdDirective(unsigned CollapsedNum)1588 explicit OMPSimdDirective(unsigned CollapsedNum) 1589 : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, 1590 SourceLocation(), SourceLocation(), CollapsedNum) {} 1591 1592 public: 1593 /// Creates directive with a list of \a Clauses. 1594 /// 1595 /// \param C AST context. 1596 /// \param StartLoc Starting location of the directive kind. 1597 /// \param EndLoc Ending Location of the directive. 1598 /// \param CollapsedNum Number of collapsed loops. 1599 /// \param Clauses List of clauses. 1600 /// \param AssociatedStmt Statement, associated with the directive. 1601 /// \param Exprs Helper expressions for CodeGen. 1602 /// 1603 static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc, 1604 SourceLocation EndLoc, unsigned CollapsedNum, 1605 ArrayRef<OMPClause *> Clauses, 1606 Stmt *AssociatedStmt, 1607 const HelperExprs &Exprs); 1608 1609 /// Creates an empty directive with the place 1610 /// for \a NumClauses clauses. 1611 /// 1612 /// \param C AST context. 1613 /// \param CollapsedNum Number of collapsed nested loops. 1614 /// \param NumClauses Number of clauses. 1615 /// 1616 static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 1617 unsigned CollapsedNum, EmptyShell); 1618 classof(const Stmt * T)1619 static bool classof(const Stmt *T) { 1620 return T->getStmtClass() == OMPSimdDirectiveClass; 1621 } 1622 }; 1623 1624 /// This represents '#pragma omp for' directive. 1625 /// 1626 /// \code 1627 /// #pragma omp for private(a,b) reduction(+:c,d) 1628 /// \endcode 1629 /// In this example directive '#pragma omp for' has clauses 'private' with the 1630 /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c' 1631 /// and 'd'. 1632 /// 1633 class OMPForDirective : public OMPLoopDirective { 1634 friend class ASTStmtReader; 1635 friend class OMPExecutableDirective; 1636 /// true if current directive has inner cancel directive. 1637 bool HasCancel = false; 1638 1639 /// Build directive with the given start and end location. 1640 /// 1641 /// \param StartLoc Starting location of the directive kind. 1642 /// \param EndLoc Ending location of the directive. 1643 /// \param CollapsedNum Number of collapsed nested loops. 1644 /// OMPForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)1645 OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1646 unsigned CollapsedNum) 1647 : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, StartLoc, 1648 EndLoc, CollapsedNum) {} 1649 1650 /// Build an empty directive. 1651 /// 1652 /// \param CollapsedNum Number of collapsed nested loops. 1653 /// OMPForDirective(unsigned CollapsedNum)1654 explicit OMPForDirective(unsigned CollapsedNum) 1655 : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, 1656 SourceLocation(), SourceLocation(), CollapsedNum) {} 1657 1658 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)1659 void setTaskReductionRefExpr(Expr *E) { 1660 Data->getChildren()[numLoopChildren(getLoopsNumber(), 1661 llvm::omp::OMPD_for)] = E; 1662 } 1663 1664 /// Set cancel state. setHasCancel(bool Has)1665 void setHasCancel(bool Has) { HasCancel = Has; } 1666 1667 public: 1668 /// Creates directive with a list of \a Clauses. 1669 /// 1670 /// \param C AST context. 1671 /// \param StartLoc Starting location of the directive kind. 1672 /// \param EndLoc Ending Location of the directive. 1673 /// \param CollapsedNum Number of collapsed loops. 1674 /// \param Clauses List of clauses. 1675 /// \param AssociatedStmt Statement, associated with the directive. 1676 /// \param Exprs Helper expressions for CodeGen. 1677 /// \param TaskRedRef Task reduction special reference expression to handle 1678 /// taskgroup descriptor. 1679 /// \param HasCancel true if current directive has inner cancel directive. 1680 /// 1681 static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc, 1682 SourceLocation EndLoc, unsigned CollapsedNum, 1683 ArrayRef<OMPClause *> Clauses, 1684 Stmt *AssociatedStmt, const HelperExprs &Exprs, 1685 Expr *TaskRedRef, bool HasCancel); 1686 1687 /// Creates an empty directive with the place 1688 /// for \a NumClauses clauses. 1689 /// 1690 /// \param C AST context. 1691 /// \param CollapsedNum Number of collapsed nested loops. 1692 /// \param NumClauses Number of clauses. 1693 /// 1694 static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 1695 unsigned CollapsedNum, EmptyShell); 1696 1697 /// Returns special task reduction reference expression. getTaskReductionRefExpr()1698 Expr *getTaskReductionRefExpr() { 1699 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 1700 getLoopsNumber(), llvm::omp::OMPD_for)]); 1701 } getTaskReductionRefExpr()1702 const Expr *getTaskReductionRefExpr() const { 1703 return const_cast<OMPForDirective *>(this)->getTaskReductionRefExpr(); 1704 } 1705 1706 /// Return true if current directive has inner cancel directive. hasCancel()1707 bool hasCancel() const { return HasCancel; } 1708 classof(const Stmt * T)1709 static bool classof(const Stmt *T) { 1710 return T->getStmtClass() == OMPForDirectiveClass; 1711 } 1712 }; 1713 1714 /// This represents '#pragma omp for simd' directive. 1715 /// 1716 /// \code 1717 /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d) 1718 /// \endcode 1719 /// In this example directive '#pragma omp for simd' has clauses 'private' 1720 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and 1721 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'. 1722 /// 1723 class OMPForSimdDirective : public OMPLoopDirective { 1724 friend class ASTStmtReader; 1725 friend class OMPExecutableDirective; 1726 /// Build directive with the given start and end location. 1727 /// 1728 /// \param StartLoc Starting location of the directive kind. 1729 /// \param EndLoc Ending location of the directive. 1730 /// \param CollapsedNum Number of collapsed nested loops. 1731 /// OMPForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)1732 OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1733 unsigned CollapsedNum) 1734 : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd, 1735 StartLoc, EndLoc, CollapsedNum) {} 1736 1737 /// Build an empty directive. 1738 /// 1739 /// \param CollapsedNum Number of collapsed nested loops. 1740 /// OMPForSimdDirective(unsigned CollapsedNum)1741 explicit OMPForSimdDirective(unsigned CollapsedNum) 1742 : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd, 1743 SourceLocation(), SourceLocation(), CollapsedNum) {} 1744 1745 public: 1746 /// Creates directive with a list of \a Clauses. 1747 /// 1748 /// \param C AST context. 1749 /// \param StartLoc Starting location of the directive kind. 1750 /// \param EndLoc Ending Location of the directive. 1751 /// \param CollapsedNum Number of collapsed loops. 1752 /// \param Clauses List of clauses. 1753 /// \param AssociatedStmt Statement, associated with the directive. 1754 /// \param Exprs Helper expressions for CodeGen. 1755 /// 1756 static OMPForSimdDirective * 1757 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1758 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 1759 Stmt *AssociatedStmt, const HelperExprs &Exprs); 1760 1761 /// Creates an empty directive with the place 1762 /// for \a NumClauses clauses. 1763 /// 1764 /// \param C AST context. 1765 /// \param CollapsedNum Number of collapsed nested loops. 1766 /// \param NumClauses Number of clauses. 1767 /// 1768 static OMPForSimdDirective *CreateEmpty(const ASTContext &C, 1769 unsigned NumClauses, 1770 unsigned CollapsedNum, EmptyShell); 1771 classof(const Stmt * T)1772 static bool classof(const Stmt *T) { 1773 return T->getStmtClass() == OMPForSimdDirectiveClass; 1774 } 1775 }; 1776 1777 /// This represents '#pragma omp sections' directive. 1778 /// 1779 /// \code 1780 /// #pragma omp sections private(a,b) reduction(+:c,d) 1781 /// \endcode 1782 /// In this example directive '#pragma omp sections' has clauses 'private' with 1783 /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables 1784 /// 'c' and 'd'. 1785 /// 1786 class OMPSectionsDirective : public OMPExecutableDirective { 1787 friend class ASTStmtReader; 1788 friend class OMPExecutableDirective; 1789 1790 /// true if current directive has inner cancel directive. 1791 bool HasCancel = false; 1792 1793 /// Build directive with the given start and end location. 1794 /// 1795 /// \param StartLoc Starting location of the directive kind. 1796 /// \param EndLoc Ending location of the directive. 1797 /// OMPSectionsDirective(SourceLocation StartLoc,SourceLocation EndLoc)1798 OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1799 : OMPExecutableDirective(OMPSectionsDirectiveClass, 1800 llvm::omp::OMPD_sections, StartLoc, EndLoc) {} 1801 1802 /// Build an empty directive. 1803 /// OMPSectionsDirective()1804 explicit OMPSectionsDirective() 1805 : OMPExecutableDirective(OMPSectionsDirectiveClass, 1806 llvm::omp::OMPD_sections, SourceLocation(), 1807 SourceLocation()) {} 1808 1809 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)1810 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 1811 1812 /// Set cancel state. setHasCancel(bool Has)1813 void setHasCancel(bool Has) { HasCancel = Has; } 1814 1815 public: 1816 /// Creates directive with a list of \a Clauses. 1817 /// 1818 /// \param C AST context. 1819 /// \param StartLoc Starting location of the directive kind. 1820 /// \param EndLoc Ending Location of the directive. 1821 /// \param Clauses List of clauses. 1822 /// \param AssociatedStmt Statement, associated with the directive. 1823 /// \param TaskRedRef Task reduction special reference expression to handle 1824 /// taskgroup descriptor. 1825 /// \param HasCancel true if current directive has inner directive. 1826 /// 1827 static OMPSectionsDirective * 1828 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1829 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, 1830 bool HasCancel); 1831 1832 /// Creates an empty directive with the place for \a NumClauses 1833 /// clauses. 1834 /// 1835 /// \param C AST context. 1836 /// \param NumClauses Number of clauses. 1837 /// 1838 static OMPSectionsDirective *CreateEmpty(const ASTContext &C, 1839 unsigned NumClauses, EmptyShell); 1840 1841 /// Returns special task reduction reference expression. getTaskReductionRefExpr()1842 Expr *getTaskReductionRefExpr() { 1843 return cast_or_null<Expr>(Data->getChildren()[0]); 1844 } getTaskReductionRefExpr()1845 const Expr *getTaskReductionRefExpr() const { 1846 return const_cast<OMPSectionsDirective *>(this)->getTaskReductionRefExpr(); 1847 } 1848 1849 /// Return true if current directive has inner cancel directive. hasCancel()1850 bool hasCancel() const { return HasCancel; } 1851 classof(const Stmt * T)1852 static bool classof(const Stmt *T) { 1853 return T->getStmtClass() == OMPSectionsDirectiveClass; 1854 } 1855 }; 1856 1857 /// This represents '#pragma omp section' directive. 1858 /// 1859 /// \code 1860 /// #pragma omp section 1861 /// \endcode 1862 /// 1863 class OMPSectionDirective : public OMPExecutableDirective { 1864 friend class ASTStmtReader; 1865 friend class OMPExecutableDirective; 1866 1867 /// true if current directive has inner cancel directive. 1868 bool HasCancel = false; 1869 1870 /// Build directive with the given start and end location. 1871 /// 1872 /// \param StartLoc Starting location of the directive kind. 1873 /// \param EndLoc Ending location of the directive. 1874 /// OMPSectionDirective(SourceLocation StartLoc,SourceLocation EndLoc)1875 OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1876 : OMPExecutableDirective(OMPSectionDirectiveClass, 1877 llvm::omp::OMPD_section, StartLoc, EndLoc) {} 1878 1879 /// Build an empty directive. 1880 /// OMPSectionDirective()1881 explicit OMPSectionDirective() 1882 : OMPExecutableDirective(OMPSectionDirectiveClass, 1883 llvm::omp::OMPD_section, SourceLocation(), 1884 SourceLocation()) {} 1885 1886 public: 1887 /// Creates directive. 1888 /// 1889 /// \param C AST context. 1890 /// \param StartLoc Starting location of the directive kind. 1891 /// \param EndLoc Ending Location of the directive. 1892 /// \param AssociatedStmt Statement, associated with the directive. 1893 /// \param HasCancel true if current directive has inner directive. 1894 /// 1895 static OMPSectionDirective *Create(const ASTContext &C, 1896 SourceLocation StartLoc, 1897 SourceLocation EndLoc, 1898 Stmt *AssociatedStmt, bool HasCancel); 1899 1900 /// Creates an empty directive. 1901 /// 1902 /// \param C AST context. 1903 /// 1904 static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell); 1905 1906 /// Set cancel state. setHasCancel(bool Has)1907 void setHasCancel(bool Has) { HasCancel = Has; } 1908 1909 /// Return true if current directive has inner cancel directive. hasCancel()1910 bool hasCancel() const { return HasCancel; } 1911 classof(const Stmt * T)1912 static bool classof(const Stmt *T) { 1913 return T->getStmtClass() == OMPSectionDirectiveClass; 1914 } 1915 }; 1916 1917 /// This represents '#pragma omp single' directive. 1918 /// 1919 /// \code 1920 /// #pragma omp single private(a,b) copyprivate(c,d) 1921 /// \endcode 1922 /// In this example directive '#pragma omp single' has clauses 'private' with 1923 /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'. 1924 /// 1925 class OMPSingleDirective : public OMPExecutableDirective { 1926 friend class ASTStmtReader; 1927 friend class OMPExecutableDirective; 1928 /// Build directive with the given start and end location. 1929 /// 1930 /// \param StartLoc Starting location of the directive kind. 1931 /// \param EndLoc Ending location of the directive. 1932 /// OMPSingleDirective(SourceLocation StartLoc,SourceLocation EndLoc)1933 OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1934 : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single, 1935 StartLoc, EndLoc) {} 1936 1937 /// Build an empty directive. 1938 /// OMPSingleDirective()1939 explicit OMPSingleDirective() 1940 : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single, 1941 SourceLocation(), SourceLocation()) {} 1942 1943 public: 1944 /// Creates directive with a list of \a Clauses. 1945 /// 1946 /// \param C AST context. 1947 /// \param StartLoc Starting location of the directive kind. 1948 /// \param EndLoc Ending Location of the directive. 1949 /// \param Clauses List of clauses. 1950 /// \param AssociatedStmt Statement, associated with the directive. 1951 /// 1952 static OMPSingleDirective * 1953 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1954 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 1955 1956 /// Creates an empty directive with the place for \a NumClauses 1957 /// clauses. 1958 /// 1959 /// \param C AST context. 1960 /// \param NumClauses Number of clauses. 1961 /// 1962 static OMPSingleDirective *CreateEmpty(const ASTContext &C, 1963 unsigned NumClauses, EmptyShell); 1964 classof(const Stmt * T)1965 static bool classof(const Stmt *T) { 1966 return T->getStmtClass() == OMPSingleDirectiveClass; 1967 } 1968 }; 1969 1970 /// This represents '#pragma omp master' directive. 1971 /// 1972 /// \code 1973 /// #pragma omp master 1974 /// \endcode 1975 /// 1976 class OMPMasterDirective : public OMPExecutableDirective { 1977 friend class ASTStmtReader; 1978 friend class OMPExecutableDirective; 1979 /// Build directive with the given start and end location. 1980 /// 1981 /// \param StartLoc Starting location of the directive kind. 1982 /// \param EndLoc Ending location of the directive. 1983 /// OMPMasterDirective(SourceLocation StartLoc,SourceLocation EndLoc)1984 OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1985 : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master, 1986 StartLoc, EndLoc) {} 1987 1988 /// Build an empty directive. 1989 /// OMPMasterDirective()1990 explicit OMPMasterDirective() 1991 : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master, 1992 SourceLocation(), SourceLocation()) {} 1993 1994 public: 1995 /// Creates directive. 1996 /// 1997 /// \param C AST context. 1998 /// \param StartLoc Starting location of the directive kind. 1999 /// \param EndLoc Ending Location of the directive. 2000 /// \param AssociatedStmt Statement, associated with the directive. 2001 /// 2002 static OMPMasterDirective *Create(const ASTContext &C, 2003 SourceLocation StartLoc, 2004 SourceLocation EndLoc, 2005 Stmt *AssociatedStmt); 2006 2007 /// Creates an empty directive. 2008 /// 2009 /// \param C AST context. 2010 /// 2011 static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell); 2012 classof(const Stmt * T)2013 static bool classof(const Stmt *T) { 2014 return T->getStmtClass() == OMPMasterDirectiveClass; 2015 } 2016 }; 2017 2018 /// This represents '#pragma omp critical' directive. 2019 /// 2020 /// \code 2021 /// #pragma omp critical 2022 /// \endcode 2023 /// 2024 class OMPCriticalDirective : public OMPExecutableDirective { 2025 friend class ASTStmtReader; 2026 friend class OMPExecutableDirective; 2027 /// Name of the directive. 2028 DeclarationNameInfo DirName; 2029 /// Build directive with the given start and end location. 2030 /// 2031 /// \param Name Name of the directive. 2032 /// \param StartLoc Starting location of the directive kind. 2033 /// \param EndLoc Ending location of the directive. 2034 /// OMPCriticalDirective(const DeclarationNameInfo & Name,SourceLocation StartLoc,SourceLocation EndLoc)2035 OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc, 2036 SourceLocation EndLoc) 2037 : OMPExecutableDirective(OMPCriticalDirectiveClass, 2038 llvm::omp::OMPD_critical, StartLoc, EndLoc), 2039 DirName(Name) {} 2040 2041 /// Build an empty directive. 2042 /// OMPCriticalDirective()2043 explicit OMPCriticalDirective() 2044 : OMPExecutableDirective(OMPCriticalDirectiveClass, 2045 llvm::omp::OMPD_critical, SourceLocation(), 2046 SourceLocation()) {} 2047 2048 /// Set name of the directive. 2049 /// 2050 /// \param Name Name of the directive. 2051 /// setDirectiveName(const DeclarationNameInfo & Name)2052 void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; } 2053 2054 public: 2055 /// Creates directive. 2056 /// 2057 /// \param C AST context. 2058 /// \param Name Name of the directive. 2059 /// \param StartLoc Starting location of the directive kind. 2060 /// \param EndLoc Ending Location of the directive. 2061 /// \param Clauses List of clauses. 2062 /// \param AssociatedStmt Statement, associated with the directive. 2063 /// 2064 static OMPCriticalDirective * 2065 Create(const ASTContext &C, const DeclarationNameInfo &Name, 2066 SourceLocation StartLoc, SourceLocation EndLoc, 2067 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 2068 2069 /// Creates an empty directive. 2070 /// 2071 /// \param C AST context. 2072 /// \param NumClauses Number of clauses. 2073 /// 2074 static OMPCriticalDirective *CreateEmpty(const ASTContext &C, 2075 unsigned NumClauses, EmptyShell); 2076 2077 /// Return name of the directive. 2078 /// getDirectiveName()2079 DeclarationNameInfo getDirectiveName() const { return DirName; } 2080 classof(const Stmt * T)2081 static bool classof(const Stmt *T) { 2082 return T->getStmtClass() == OMPCriticalDirectiveClass; 2083 } 2084 }; 2085 2086 /// This represents '#pragma omp parallel for' directive. 2087 /// 2088 /// \code 2089 /// #pragma omp parallel for private(a,b) reduction(+:c,d) 2090 /// \endcode 2091 /// In this example directive '#pragma omp parallel for' has clauses 'private' 2092 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and 2093 /// variables 'c' and 'd'. 2094 /// 2095 class OMPParallelForDirective : public OMPLoopDirective { 2096 friend class ASTStmtReader; 2097 friend class OMPExecutableDirective; 2098 2099 /// true if current region has inner cancel directive. 2100 bool HasCancel = false; 2101 2102 /// Build directive with the given start and end location. 2103 /// 2104 /// \param StartLoc Starting location of the directive kind. 2105 /// \param EndLoc Ending location of the directive. 2106 /// \param CollapsedNum Number of collapsed nested loops. 2107 /// OMPParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)2108 OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2109 unsigned CollapsedNum) 2110 : OMPLoopDirective(OMPParallelForDirectiveClass, 2111 llvm::omp::OMPD_parallel_for, StartLoc, EndLoc, 2112 CollapsedNum) {} 2113 2114 /// Build an empty directive. 2115 /// 2116 /// \param CollapsedNum Number of collapsed nested loops. 2117 /// OMPParallelForDirective(unsigned CollapsedNum)2118 explicit OMPParallelForDirective(unsigned CollapsedNum) 2119 : OMPLoopDirective(OMPParallelForDirectiveClass, 2120 llvm::omp::OMPD_parallel_for, SourceLocation(), 2121 SourceLocation(), CollapsedNum) {} 2122 2123 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)2124 void setTaskReductionRefExpr(Expr *E) { 2125 Data->getChildren()[numLoopChildren(getLoopsNumber(), 2126 llvm::omp::OMPD_parallel_for)] = E; 2127 } 2128 2129 /// Set cancel state. setHasCancel(bool Has)2130 void setHasCancel(bool Has) { HasCancel = Has; } 2131 2132 public: 2133 /// Creates directive with a list of \a Clauses. 2134 /// 2135 /// \param C AST context. 2136 /// \param StartLoc Starting location of the directive kind. 2137 /// \param EndLoc Ending Location of the directive. 2138 /// \param CollapsedNum Number of collapsed loops. 2139 /// \param Clauses List of clauses. 2140 /// \param AssociatedStmt Statement, associated with the directive. 2141 /// \param Exprs Helper expressions for CodeGen. 2142 /// \param TaskRedRef Task reduction special reference expression to handle 2143 /// taskgroup descriptor. 2144 /// \param HasCancel true if current directive has inner cancel directive. 2145 /// 2146 static OMPParallelForDirective * 2147 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2148 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 2149 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 2150 bool HasCancel); 2151 2152 /// Creates an empty directive with the place 2153 /// for \a NumClauses clauses. 2154 /// 2155 /// \param C AST context. 2156 /// \param CollapsedNum Number of collapsed nested loops. 2157 /// \param NumClauses Number of clauses. 2158 /// 2159 static OMPParallelForDirective *CreateEmpty(const ASTContext &C, 2160 unsigned NumClauses, 2161 unsigned CollapsedNum, 2162 EmptyShell); 2163 2164 /// Returns special task reduction reference expression. getTaskReductionRefExpr()2165 Expr *getTaskReductionRefExpr() { 2166 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 2167 getLoopsNumber(), llvm::omp::OMPD_parallel_for)]); 2168 } getTaskReductionRefExpr()2169 const Expr *getTaskReductionRefExpr() const { 2170 return const_cast<OMPParallelForDirective *>(this) 2171 ->getTaskReductionRefExpr(); 2172 } 2173 2174 /// Return true if current directive has inner cancel directive. hasCancel()2175 bool hasCancel() const { return HasCancel; } 2176 classof(const Stmt * T)2177 static bool classof(const Stmt *T) { 2178 return T->getStmtClass() == OMPParallelForDirectiveClass; 2179 } 2180 }; 2181 2182 /// This represents '#pragma omp parallel for simd' directive. 2183 /// 2184 /// \code 2185 /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d) 2186 /// \endcode 2187 /// In this example directive '#pragma omp parallel for simd' has clauses 2188 /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j' 2189 /// and linear step 's', 'reduction' with operator '+' and variables 'c' and 2190 /// 'd'. 2191 /// 2192 class OMPParallelForSimdDirective : public OMPLoopDirective { 2193 friend class ASTStmtReader; 2194 friend class OMPExecutableDirective; 2195 /// Build directive with the given start and end location. 2196 /// 2197 /// \param StartLoc Starting location of the directive kind. 2198 /// \param EndLoc Ending location of the directive. 2199 /// \param CollapsedNum Number of collapsed nested loops. 2200 /// OMPParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)2201 OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2202 unsigned CollapsedNum) 2203 : OMPLoopDirective(OMPParallelForSimdDirectiveClass, 2204 llvm::omp::OMPD_parallel_for_simd, StartLoc, EndLoc, 2205 CollapsedNum) {} 2206 2207 /// Build an empty directive. 2208 /// 2209 /// \param CollapsedNum Number of collapsed nested loops. 2210 /// OMPParallelForSimdDirective(unsigned CollapsedNum)2211 explicit OMPParallelForSimdDirective(unsigned CollapsedNum) 2212 : OMPLoopDirective(OMPParallelForSimdDirectiveClass, 2213 llvm::omp::OMPD_parallel_for_simd, SourceLocation(), 2214 SourceLocation(), CollapsedNum) {} 2215 2216 public: 2217 /// Creates directive with a list of \a Clauses. 2218 /// 2219 /// \param C AST context. 2220 /// \param StartLoc Starting location of the directive kind. 2221 /// \param EndLoc Ending Location of the directive. 2222 /// \param CollapsedNum Number of collapsed loops. 2223 /// \param Clauses List of clauses. 2224 /// \param AssociatedStmt Statement, associated with the directive. 2225 /// \param Exprs Helper expressions for CodeGen. 2226 /// 2227 static OMPParallelForSimdDirective * 2228 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2229 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 2230 Stmt *AssociatedStmt, const HelperExprs &Exprs); 2231 2232 /// Creates an empty directive with the place 2233 /// for \a NumClauses clauses. 2234 /// 2235 /// \param C AST context. 2236 /// \param CollapsedNum Number of collapsed nested loops. 2237 /// \param NumClauses Number of clauses. 2238 /// 2239 static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C, 2240 unsigned NumClauses, 2241 unsigned CollapsedNum, 2242 EmptyShell); 2243 classof(const Stmt * T)2244 static bool classof(const Stmt *T) { 2245 return T->getStmtClass() == OMPParallelForSimdDirectiveClass; 2246 } 2247 }; 2248 2249 /// This represents '#pragma omp parallel master' directive. 2250 /// 2251 /// \code 2252 /// #pragma omp parallel master private(a,b) 2253 /// \endcode 2254 /// In this example directive '#pragma omp parallel master' has clauses 2255 /// 'private' with the variables 'a' and 'b' 2256 /// 2257 class OMPParallelMasterDirective : public OMPExecutableDirective { 2258 friend class ASTStmtReader; 2259 friend class OMPExecutableDirective; 2260 OMPParallelMasterDirective(SourceLocation StartLoc,SourceLocation EndLoc)2261 OMPParallelMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2262 : OMPExecutableDirective(OMPParallelMasterDirectiveClass, 2263 llvm::omp::OMPD_parallel_master, StartLoc, 2264 EndLoc) {} 2265 OMPParallelMasterDirective()2266 explicit OMPParallelMasterDirective() 2267 : OMPExecutableDirective(OMPParallelMasterDirectiveClass, 2268 llvm::omp::OMPD_parallel_master, 2269 SourceLocation(), SourceLocation()) {} 2270 2271 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)2272 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 2273 2274 public: 2275 /// Creates directive with a list of \a Clauses. 2276 /// 2277 /// \param C AST context. 2278 /// \param StartLoc Starting location of the directive kind. 2279 /// \param EndLoc Ending Location of the directive. 2280 /// \param Clauses List of clauses. 2281 /// \param AssociatedStmt Statement, associated with the directive. 2282 /// \param TaskRedRef Task reduction special reference expression to handle 2283 /// taskgroup descriptor. 2284 /// 2285 static OMPParallelMasterDirective * 2286 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2287 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef); 2288 2289 /// Creates an empty directive with the place for \a NumClauses 2290 /// clauses. 2291 /// 2292 /// \param C AST context. 2293 /// \param NumClauses Number of clauses. 2294 /// 2295 static OMPParallelMasterDirective * 2296 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 2297 2298 /// Returns special task reduction reference expression. getTaskReductionRefExpr()2299 Expr *getTaskReductionRefExpr() { 2300 return cast_or_null<Expr>(Data->getChildren()[0]); 2301 } getTaskReductionRefExpr()2302 const Expr *getTaskReductionRefExpr() const { 2303 return const_cast<OMPParallelMasterDirective *>(this) 2304 ->getTaskReductionRefExpr(); 2305 } 2306 classof(const Stmt * T)2307 static bool classof(const Stmt *T) { 2308 return T->getStmtClass() == OMPParallelMasterDirectiveClass; 2309 } 2310 }; 2311 2312 /// This represents '#pragma omp parallel masked' directive. 2313 /// 2314 /// \code 2315 /// #pragma omp parallel masked filter(tid) 2316 /// \endcode 2317 /// In this example directive '#pragma omp parallel masked' has a clause 2318 /// 'filter' with the variable tid 2319 /// 2320 class OMPParallelMaskedDirective final : public OMPExecutableDirective { 2321 friend class ASTStmtReader; 2322 friend class OMPExecutableDirective; 2323 OMPParallelMaskedDirective(SourceLocation StartLoc,SourceLocation EndLoc)2324 OMPParallelMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2325 : OMPExecutableDirective(OMPParallelMaskedDirectiveClass, 2326 llvm::omp::OMPD_parallel_masked, StartLoc, 2327 EndLoc) {} 2328 OMPParallelMaskedDirective()2329 explicit OMPParallelMaskedDirective() 2330 : OMPExecutableDirective(OMPParallelMaskedDirectiveClass, 2331 llvm::omp::OMPD_parallel_masked, 2332 SourceLocation(), SourceLocation()) {} 2333 2334 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)2335 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 2336 2337 public: 2338 /// Creates directive with a list of \a Clauses. 2339 /// 2340 /// \param C AST context. 2341 /// \param StartLoc Starting location of the directive kind. 2342 /// \param EndLoc Ending Location of the directive. 2343 /// \param Clauses List of clauses. 2344 /// \param AssociatedStmt Statement, associated with the directive. 2345 /// \param TaskRedRef Task reduction special reference expression to handle 2346 /// taskgroup descriptor. 2347 /// 2348 static OMPParallelMaskedDirective * 2349 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2350 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef); 2351 2352 /// Creates an empty directive with the place for \a NumClauses 2353 /// clauses. 2354 /// 2355 /// \param C AST context. 2356 /// \param NumClauses Number of clauses. 2357 /// 2358 static OMPParallelMaskedDirective * 2359 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 2360 2361 /// Returns special task reduction reference expression. getTaskReductionRefExpr()2362 Expr *getTaskReductionRefExpr() { 2363 return cast_or_null<Expr>(Data->getChildren()[0]); 2364 } getTaskReductionRefExpr()2365 const Expr *getTaskReductionRefExpr() const { 2366 return const_cast<OMPParallelMaskedDirective *>(this) 2367 ->getTaskReductionRefExpr(); 2368 } 2369 classof(const Stmt * T)2370 static bool classof(const Stmt *T) { 2371 return T->getStmtClass() == OMPParallelMaskedDirectiveClass; 2372 } 2373 }; 2374 2375 /// This represents '#pragma omp parallel sections' directive. 2376 /// 2377 /// \code 2378 /// #pragma omp parallel sections private(a,b) reduction(+:c,d) 2379 /// \endcode 2380 /// In this example directive '#pragma omp parallel sections' has clauses 2381 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+' 2382 /// and variables 'c' and 'd'. 2383 /// 2384 class OMPParallelSectionsDirective : public OMPExecutableDirective { 2385 friend class ASTStmtReader; 2386 friend class OMPExecutableDirective; 2387 2388 /// true if current directive has inner cancel directive. 2389 bool HasCancel = false; 2390 2391 /// Build directive with the given start and end location. 2392 /// 2393 /// \param StartLoc Starting location of the directive kind. 2394 /// \param EndLoc Ending location of the directive. 2395 /// OMPParallelSectionsDirective(SourceLocation StartLoc,SourceLocation EndLoc)2396 OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2397 : OMPExecutableDirective(OMPParallelSectionsDirectiveClass, 2398 llvm::omp::OMPD_parallel_sections, StartLoc, 2399 EndLoc) {} 2400 2401 /// Build an empty directive. 2402 /// OMPParallelSectionsDirective()2403 explicit OMPParallelSectionsDirective() 2404 : OMPExecutableDirective(OMPParallelSectionsDirectiveClass, 2405 llvm::omp::OMPD_parallel_sections, 2406 SourceLocation(), SourceLocation()) {} 2407 2408 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)2409 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 2410 2411 /// Set cancel state. setHasCancel(bool Has)2412 void setHasCancel(bool Has) { HasCancel = Has; } 2413 2414 public: 2415 /// Creates directive with a list of \a Clauses. 2416 /// 2417 /// \param C AST context. 2418 /// \param StartLoc Starting location of the directive kind. 2419 /// \param EndLoc Ending Location of the directive. 2420 /// \param Clauses List of clauses. 2421 /// \param AssociatedStmt Statement, associated with the directive. 2422 /// \param TaskRedRef Task reduction special reference expression to handle 2423 /// taskgroup descriptor. 2424 /// \param HasCancel true if current directive has inner cancel directive. 2425 /// 2426 static OMPParallelSectionsDirective * 2427 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2428 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, 2429 bool HasCancel); 2430 2431 /// Creates an empty directive with the place for \a NumClauses 2432 /// clauses. 2433 /// 2434 /// \param C AST context. 2435 /// \param NumClauses Number of clauses. 2436 /// 2437 static OMPParallelSectionsDirective * 2438 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 2439 2440 /// Returns special task reduction reference expression. getTaskReductionRefExpr()2441 Expr *getTaskReductionRefExpr() { 2442 return cast_or_null<Expr>(Data->getChildren()[0]); 2443 } getTaskReductionRefExpr()2444 const Expr *getTaskReductionRefExpr() const { 2445 return const_cast<OMPParallelSectionsDirective *>(this) 2446 ->getTaskReductionRefExpr(); 2447 } 2448 2449 /// Return true if current directive has inner cancel directive. hasCancel()2450 bool hasCancel() const { return HasCancel; } 2451 classof(const Stmt * T)2452 static bool classof(const Stmt *T) { 2453 return T->getStmtClass() == OMPParallelSectionsDirectiveClass; 2454 } 2455 }; 2456 2457 /// This represents '#pragma omp task' directive. 2458 /// 2459 /// \code 2460 /// #pragma omp task private(a,b) final(d) 2461 /// \endcode 2462 /// In this example directive '#pragma omp task' has clauses 'private' with the 2463 /// variables 'a' and 'b' and 'final' with condition 'd'. 2464 /// 2465 class OMPTaskDirective : public OMPExecutableDirective { 2466 friend class ASTStmtReader; 2467 friend class OMPExecutableDirective; 2468 /// true if this directive has inner cancel directive. 2469 bool HasCancel = false; 2470 2471 /// Build directive with the given start and end location. 2472 /// 2473 /// \param StartLoc Starting location of the directive kind. 2474 /// \param EndLoc Ending location of the directive. 2475 /// OMPTaskDirective(SourceLocation StartLoc,SourceLocation EndLoc)2476 OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2477 : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task, 2478 StartLoc, EndLoc) {} 2479 2480 /// Build an empty directive. 2481 /// OMPTaskDirective()2482 explicit OMPTaskDirective() 2483 : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task, 2484 SourceLocation(), SourceLocation()) {} 2485 2486 /// Set cancel state. setHasCancel(bool Has)2487 void setHasCancel(bool Has) { HasCancel = Has; } 2488 2489 public: 2490 /// Creates directive with a list of \a Clauses. 2491 /// 2492 /// \param C AST context. 2493 /// \param StartLoc Starting location of the directive kind. 2494 /// \param EndLoc Ending Location of the directive. 2495 /// \param Clauses List of clauses. 2496 /// \param AssociatedStmt Statement, associated with the directive. 2497 /// \param HasCancel true, if current directive has inner cancel directive. 2498 /// 2499 static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc, 2500 SourceLocation EndLoc, 2501 ArrayRef<OMPClause *> Clauses, 2502 Stmt *AssociatedStmt, bool HasCancel); 2503 2504 /// Creates an empty directive with the place for \a NumClauses 2505 /// clauses. 2506 /// 2507 /// \param C AST context. 2508 /// \param NumClauses Number of clauses. 2509 /// 2510 static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 2511 EmptyShell); 2512 2513 /// Return true if current directive has inner cancel directive. hasCancel()2514 bool hasCancel() const { return HasCancel; } 2515 classof(const Stmt * T)2516 static bool classof(const Stmt *T) { 2517 return T->getStmtClass() == OMPTaskDirectiveClass; 2518 } 2519 }; 2520 2521 /// This represents '#pragma omp taskyield' directive. 2522 /// 2523 /// \code 2524 /// #pragma omp taskyield 2525 /// \endcode 2526 /// 2527 class OMPTaskyieldDirective : public OMPExecutableDirective { 2528 friend class ASTStmtReader; 2529 friend class OMPExecutableDirective; 2530 /// Build directive with the given start and end location. 2531 /// 2532 /// \param StartLoc Starting location of the directive kind. 2533 /// \param EndLoc Ending location of the directive. 2534 /// OMPTaskyieldDirective(SourceLocation StartLoc,SourceLocation EndLoc)2535 OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2536 : OMPExecutableDirective(OMPTaskyieldDirectiveClass, 2537 llvm::omp::OMPD_taskyield, StartLoc, EndLoc) {} 2538 2539 /// Build an empty directive. 2540 /// OMPTaskyieldDirective()2541 explicit OMPTaskyieldDirective() 2542 : OMPExecutableDirective(OMPTaskyieldDirectiveClass, 2543 llvm::omp::OMPD_taskyield, SourceLocation(), 2544 SourceLocation()) {} 2545 2546 public: 2547 /// Creates directive. 2548 /// 2549 /// \param C AST context. 2550 /// \param StartLoc Starting location of the directive kind. 2551 /// \param EndLoc Ending Location of the directive. 2552 /// 2553 static OMPTaskyieldDirective * 2554 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); 2555 2556 /// Creates an empty directive. 2557 /// 2558 /// \param C AST context. 2559 /// 2560 static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell); 2561 classof(const Stmt * T)2562 static bool classof(const Stmt *T) { 2563 return T->getStmtClass() == OMPTaskyieldDirectiveClass; 2564 } 2565 }; 2566 2567 /// This represents '#pragma omp barrier' directive. 2568 /// 2569 /// \code 2570 /// #pragma omp barrier 2571 /// \endcode 2572 /// 2573 class OMPBarrierDirective : public OMPExecutableDirective { 2574 friend class ASTStmtReader; 2575 friend class OMPExecutableDirective; 2576 /// Build directive with the given start and end location. 2577 /// 2578 /// \param StartLoc Starting location of the directive kind. 2579 /// \param EndLoc Ending location of the directive. 2580 /// OMPBarrierDirective(SourceLocation StartLoc,SourceLocation EndLoc)2581 OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2582 : OMPExecutableDirective(OMPBarrierDirectiveClass, 2583 llvm::omp::OMPD_barrier, StartLoc, EndLoc) {} 2584 2585 /// Build an empty directive. 2586 /// OMPBarrierDirective()2587 explicit OMPBarrierDirective() 2588 : OMPExecutableDirective(OMPBarrierDirectiveClass, 2589 llvm::omp::OMPD_barrier, SourceLocation(), 2590 SourceLocation()) {} 2591 2592 public: 2593 /// Creates directive. 2594 /// 2595 /// \param C AST context. 2596 /// \param StartLoc Starting location of the directive kind. 2597 /// \param EndLoc Ending Location of the directive. 2598 /// 2599 static OMPBarrierDirective * 2600 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); 2601 2602 /// Creates an empty directive. 2603 /// 2604 /// \param C AST context. 2605 /// 2606 static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell); 2607 classof(const Stmt * T)2608 static bool classof(const Stmt *T) { 2609 return T->getStmtClass() == OMPBarrierDirectiveClass; 2610 } 2611 }; 2612 2613 /// This represents '#pragma omp taskwait' directive. 2614 /// 2615 /// \code 2616 /// #pragma omp taskwait 2617 /// \endcode 2618 /// 2619 class OMPTaskwaitDirective : public OMPExecutableDirective { 2620 friend class ASTStmtReader; 2621 friend class OMPExecutableDirective; 2622 /// Build directive with the given start and end location. 2623 /// 2624 /// \param StartLoc Starting location of the directive kind. 2625 /// \param EndLoc Ending location of the directive. 2626 /// OMPTaskwaitDirective(SourceLocation StartLoc,SourceLocation EndLoc)2627 OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2628 : OMPExecutableDirective(OMPTaskwaitDirectiveClass, 2629 llvm::omp::OMPD_taskwait, StartLoc, EndLoc) {} 2630 2631 /// Build an empty directive. 2632 /// OMPTaskwaitDirective()2633 explicit OMPTaskwaitDirective() 2634 : OMPExecutableDirective(OMPTaskwaitDirectiveClass, 2635 llvm::omp::OMPD_taskwait, SourceLocation(), 2636 SourceLocation()) {} 2637 2638 public: 2639 /// Creates directive. 2640 /// 2641 /// \param C AST context. 2642 /// \param StartLoc Starting location of the directive kind. 2643 /// \param EndLoc Ending Location of the directive. 2644 /// \param Clauses List of clauses. 2645 /// 2646 static OMPTaskwaitDirective *Create(const ASTContext &C, 2647 SourceLocation StartLoc, 2648 SourceLocation EndLoc, 2649 ArrayRef<OMPClause *> Clauses); 2650 2651 /// Creates an empty directive. 2652 /// 2653 /// \param C AST context. 2654 /// \param NumClauses Number of clauses. 2655 /// 2656 static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, 2657 unsigned NumClauses, EmptyShell); 2658 classof(const Stmt * T)2659 static bool classof(const Stmt *T) { 2660 return T->getStmtClass() == OMPTaskwaitDirectiveClass; 2661 } 2662 }; 2663 2664 /// This represents '#pragma omp taskgroup' directive. 2665 /// 2666 /// \code 2667 /// #pragma omp taskgroup 2668 /// \endcode 2669 /// 2670 class OMPTaskgroupDirective : public OMPExecutableDirective { 2671 friend class ASTStmtReader; 2672 friend class OMPExecutableDirective; 2673 /// Build directive with the given start and end location. 2674 /// 2675 /// \param StartLoc Starting location of the directive kind. 2676 /// \param EndLoc Ending location of the directive. 2677 /// OMPTaskgroupDirective(SourceLocation StartLoc,SourceLocation EndLoc)2678 OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2679 : OMPExecutableDirective(OMPTaskgroupDirectiveClass, 2680 llvm::omp::OMPD_taskgroup, StartLoc, EndLoc) {} 2681 2682 /// Build an empty directive. 2683 /// OMPTaskgroupDirective()2684 explicit OMPTaskgroupDirective() 2685 : OMPExecutableDirective(OMPTaskgroupDirectiveClass, 2686 llvm::omp::OMPD_taskgroup, SourceLocation(), 2687 SourceLocation()) {} 2688 2689 /// Sets the task_reduction return variable. setReductionRef(Expr * RR)2690 void setReductionRef(Expr *RR) { Data->getChildren()[0] = RR; } 2691 2692 public: 2693 /// Creates directive. 2694 /// 2695 /// \param C AST context. 2696 /// \param StartLoc Starting location of the directive kind. 2697 /// \param EndLoc Ending Location of the directive. 2698 /// \param Clauses List of clauses. 2699 /// \param AssociatedStmt Statement, associated with the directive. 2700 /// \param ReductionRef Reference to the task_reduction return variable. 2701 /// 2702 static OMPTaskgroupDirective * 2703 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2704 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, 2705 Expr *ReductionRef); 2706 2707 /// Creates an empty directive. 2708 /// 2709 /// \param C AST context. 2710 /// \param NumClauses Number of clauses. 2711 /// 2712 static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C, 2713 unsigned NumClauses, EmptyShell); 2714 2715 2716 /// Returns reference to the task_reduction return variable. getReductionRef()2717 const Expr *getReductionRef() const { 2718 return const_cast<OMPTaskgroupDirective *>(this)->getReductionRef(); 2719 } getReductionRef()2720 Expr *getReductionRef() { return cast_or_null<Expr>(Data->getChildren()[0]); } 2721 classof(const Stmt * T)2722 static bool classof(const Stmt *T) { 2723 return T->getStmtClass() == OMPTaskgroupDirectiveClass; 2724 } 2725 }; 2726 2727 /// This represents '#pragma omp flush' directive. 2728 /// 2729 /// \code 2730 /// #pragma omp flush(a,b) 2731 /// \endcode 2732 /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a' 2733 /// and 'b'. 2734 /// 'omp flush' directive does not have clauses but have an optional list of 2735 /// variables to flush. This list of variables is stored within some fake clause 2736 /// FlushClause. 2737 class OMPFlushDirective : public OMPExecutableDirective { 2738 friend class ASTStmtReader; 2739 friend class OMPExecutableDirective; 2740 /// Build directive with the given start and end location. 2741 /// 2742 /// \param StartLoc Starting location of the directive kind. 2743 /// \param EndLoc Ending location of the directive. 2744 /// OMPFlushDirective(SourceLocation StartLoc,SourceLocation EndLoc)2745 OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2746 : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush, 2747 StartLoc, EndLoc) {} 2748 2749 /// Build an empty directive. 2750 /// OMPFlushDirective()2751 explicit OMPFlushDirective() 2752 : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush, 2753 SourceLocation(), SourceLocation()) {} 2754 2755 public: 2756 /// Creates directive with a list of \a Clauses. 2757 /// 2758 /// \param C AST context. 2759 /// \param StartLoc Starting location of the directive kind. 2760 /// \param EndLoc Ending Location of the directive. 2761 /// \param Clauses List of clauses (only single OMPFlushClause clause is 2762 /// allowed). 2763 /// 2764 static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc, 2765 SourceLocation EndLoc, 2766 ArrayRef<OMPClause *> Clauses); 2767 2768 /// Creates an empty directive with the place for \a NumClauses 2769 /// clauses. 2770 /// 2771 /// \param C AST context. 2772 /// \param NumClauses Number of clauses. 2773 /// 2774 static OMPFlushDirective *CreateEmpty(const ASTContext &C, 2775 unsigned NumClauses, EmptyShell); 2776 classof(const Stmt * T)2777 static bool classof(const Stmt *T) { 2778 return T->getStmtClass() == OMPFlushDirectiveClass; 2779 } 2780 }; 2781 2782 /// This represents '#pragma omp depobj' directive. 2783 /// 2784 /// \code 2785 /// #pragma omp depobj(a) depend(in:x,y) 2786 /// \endcode 2787 /// In this example directive '#pragma omp depobj' initializes a depobj object 2788 /// 'a' with dependence type 'in' and a list with 'x' and 'y' locators. 2789 class OMPDepobjDirective final : public OMPExecutableDirective { 2790 friend class ASTStmtReader; 2791 friend class OMPExecutableDirective; 2792 2793 /// Build directive with the given start and end location. 2794 /// 2795 /// \param StartLoc Starting location of the directive kind. 2796 /// \param EndLoc Ending location of the directive. 2797 /// OMPDepobjDirective(SourceLocation StartLoc,SourceLocation EndLoc)2798 OMPDepobjDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2799 : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj, 2800 StartLoc, EndLoc) {} 2801 2802 /// Build an empty directive. 2803 /// OMPDepobjDirective()2804 explicit OMPDepobjDirective() 2805 : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj, 2806 SourceLocation(), SourceLocation()) {} 2807 2808 public: 2809 /// Creates directive with a list of \a Clauses. 2810 /// 2811 /// \param C AST context. 2812 /// \param StartLoc Starting location of the directive kind. 2813 /// \param EndLoc Ending Location of the directive. 2814 /// \param Clauses List of clauses. 2815 /// 2816 static OMPDepobjDirective *Create(const ASTContext &C, 2817 SourceLocation StartLoc, 2818 SourceLocation EndLoc, 2819 ArrayRef<OMPClause *> Clauses); 2820 2821 /// Creates an empty directive with the place for \a NumClauses 2822 /// clauses. 2823 /// 2824 /// \param C AST context. 2825 /// \param NumClauses Number of clauses. 2826 /// 2827 static OMPDepobjDirective *CreateEmpty(const ASTContext &C, 2828 unsigned NumClauses, EmptyShell); 2829 classof(const Stmt * T)2830 static bool classof(const Stmt *T) { 2831 return T->getStmtClass() == OMPDepobjDirectiveClass; 2832 } 2833 }; 2834 2835 /// This represents '#pragma omp ordered' directive. 2836 /// 2837 /// \code 2838 /// #pragma omp ordered 2839 /// \endcode 2840 /// 2841 class OMPOrderedDirective : public OMPExecutableDirective { 2842 friend class ASTStmtReader; 2843 friend class OMPExecutableDirective; 2844 /// Build directive with the given start and end location. 2845 /// 2846 /// \param StartLoc Starting location of the directive kind. 2847 /// \param EndLoc Ending location of the directive. 2848 /// OMPOrderedDirective(SourceLocation StartLoc,SourceLocation EndLoc)2849 OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2850 : OMPExecutableDirective(OMPOrderedDirectiveClass, 2851 llvm::omp::OMPD_ordered, StartLoc, EndLoc) {} 2852 2853 /// Build an empty directive. 2854 /// OMPOrderedDirective()2855 explicit OMPOrderedDirective() 2856 : OMPExecutableDirective(OMPOrderedDirectiveClass, 2857 llvm::omp::OMPD_ordered, SourceLocation(), 2858 SourceLocation()) {} 2859 2860 public: 2861 /// Creates directive. 2862 /// 2863 /// \param C AST context. 2864 /// \param StartLoc Starting location of the directive kind. 2865 /// \param EndLoc Ending Location of the directive. 2866 /// \param Clauses List of clauses. 2867 /// \param AssociatedStmt Statement, associated with the directive. 2868 /// 2869 static OMPOrderedDirective * 2870 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2871 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 2872 2873 /// Creates an empty directive. 2874 /// 2875 /// \param C AST context. 2876 /// \param NumClauses Number of clauses. 2877 /// \param IsStandalone true, if the standalone directive is created. 2878 /// 2879 static OMPOrderedDirective *CreateEmpty(const ASTContext &C, 2880 unsigned NumClauses, 2881 bool IsStandalone, EmptyShell); 2882 classof(const Stmt * T)2883 static bool classof(const Stmt *T) { 2884 return T->getStmtClass() == OMPOrderedDirectiveClass; 2885 } 2886 }; 2887 2888 /// This represents '#pragma omp atomic' directive. 2889 /// 2890 /// \code 2891 /// #pragma omp atomic capture 2892 /// \endcode 2893 /// In this example directive '#pragma omp atomic' has clause 'capture'. 2894 /// 2895 class OMPAtomicDirective : public OMPExecutableDirective { 2896 friend class ASTStmtReader; 2897 friend class OMPExecutableDirective; 2898 2899 struct FlagTy { 2900 /// Used for 'atomic update' or 'atomic capture' constructs. They may 2901 /// have atomic expressions of forms: 2902 /// \code 2903 /// x = x binop expr; 2904 /// x = expr binop x; 2905 /// \endcode 2906 /// This field is 1 for the first form of the expression and 0 for the 2907 /// second. Required for correct codegen of non-associative operations (like 2908 /// << or >>). 2909 uint8_t IsXLHSInRHSPart : 1; 2910 /// Used for 'atomic update' or 'atomic capture' constructs. They may 2911 /// have atomic expressions of forms: 2912 /// \code 2913 /// v = x; <update x>; 2914 /// <update x>; v = x; 2915 /// \endcode 2916 /// This field is 1 for the first(postfix) form of the expression and 0 2917 /// otherwise. 2918 uint8_t IsPostfixUpdate : 1; 2919 /// 1 if 'v' is updated only when the condition is false (compare capture 2920 /// only). 2921 uint8_t IsFailOnly : 1; 2922 } Flags; 2923 2924 /// Build directive with the given start and end location. 2925 /// 2926 /// \param StartLoc Starting location of the directive kind. 2927 /// \param EndLoc Ending location of the directive. 2928 /// OMPAtomicDirective(SourceLocation StartLoc,SourceLocation EndLoc)2929 OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2930 : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic, 2931 StartLoc, EndLoc) {} 2932 2933 /// Build an empty directive. 2934 /// OMPAtomicDirective()2935 explicit OMPAtomicDirective() 2936 : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic, 2937 SourceLocation(), SourceLocation()) {} 2938 2939 enum DataPositionTy : size_t { 2940 POS_X = 0, 2941 POS_V, 2942 POS_E, 2943 POS_UpdateExpr, 2944 POS_D, 2945 POS_Cond, 2946 POS_R, 2947 }; 2948 2949 /// Set 'x' part of the associated expression/statement. setX(Expr * X)2950 void setX(Expr *X) { Data->getChildren()[DataPositionTy::POS_X] = X; } 2951 /// Set helper expression of the form 2952 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 2953 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. setUpdateExpr(Expr * UE)2954 void setUpdateExpr(Expr *UE) { 2955 Data->getChildren()[DataPositionTy::POS_UpdateExpr] = UE; 2956 } 2957 /// Set 'v' part of the associated expression/statement. setV(Expr * V)2958 void setV(Expr *V) { Data->getChildren()[DataPositionTy::POS_V] = V; } 2959 /// Set 'r' part of the associated expression/statement. setR(Expr * R)2960 void setR(Expr *R) { Data->getChildren()[DataPositionTy::POS_R] = R; } 2961 /// Set 'expr' part of the associated expression/statement. setExpr(Expr * E)2962 void setExpr(Expr *E) { Data->getChildren()[DataPositionTy::POS_E] = E; } 2963 /// Set 'd' part of the associated expression/statement. setD(Expr * D)2964 void setD(Expr *D) { Data->getChildren()[DataPositionTy::POS_D] = D; } 2965 /// Set conditional expression in `atomic compare`. setCond(Expr * C)2966 void setCond(Expr *C) { Data->getChildren()[DataPositionTy::POS_Cond] = C; } 2967 2968 public: 2969 struct Expressions { 2970 /// 'x' part of the associated expression/statement. 2971 Expr *X = nullptr; 2972 /// 'v' part of the associated expression/statement. 2973 Expr *V = nullptr; 2974 // 'r' part of the associated expression/statement. 2975 Expr *R = nullptr; 2976 /// 'expr' part of the associated expression/statement. 2977 Expr *E = nullptr; 2978 /// UE Helper expression of the form: 2979 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 2980 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 2981 Expr *UE = nullptr; 2982 /// 'd' part of the associated expression/statement. 2983 Expr *D = nullptr; 2984 /// Conditional expression in `atomic compare` construct. 2985 Expr *Cond = nullptr; 2986 /// True if UE has the first form and false if the second. 2987 bool IsXLHSInRHSPart; 2988 /// True if original value of 'x' must be stored in 'v', not an updated one. 2989 bool IsPostfixUpdate; 2990 /// True if 'v' is updated only when the condition is false (compare capture 2991 /// only). 2992 bool IsFailOnly; 2993 }; 2994 2995 /// Creates directive with a list of \a Clauses and 'x', 'v' and 'expr' 2996 /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for 2997 /// detailed description of 'x', 'v' and 'expr'). 2998 /// 2999 /// \param C AST context. 3000 /// \param StartLoc Starting location of the directive kind. 3001 /// \param EndLoc Ending Location of the directive. 3002 /// \param Clauses List of clauses. 3003 /// \param AssociatedStmt Statement, associated with the directive. 3004 /// \param Exprs Associated expressions or statements. 3005 static OMPAtomicDirective *Create(const ASTContext &C, 3006 SourceLocation StartLoc, 3007 SourceLocation EndLoc, 3008 ArrayRef<OMPClause *> Clauses, 3009 Stmt *AssociatedStmt, Expressions Exprs); 3010 3011 /// Creates an empty directive with the place for \a NumClauses 3012 /// clauses. 3013 /// 3014 /// \param C AST context. 3015 /// \param NumClauses Number of clauses. 3016 /// 3017 static OMPAtomicDirective *CreateEmpty(const ASTContext &C, 3018 unsigned NumClauses, EmptyShell); 3019 3020 /// Get 'x' part of the associated expression/statement. getX()3021 Expr *getX() { 3022 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]); 3023 } getX()3024 const Expr *getX() const { 3025 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]); 3026 } 3027 /// Get helper expression of the form 3028 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 3029 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. getUpdateExpr()3030 Expr *getUpdateExpr() { 3031 return cast_or_null<Expr>( 3032 Data->getChildren()[DataPositionTy::POS_UpdateExpr]); 3033 } getUpdateExpr()3034 const Expr *getUpdateExpr() const { 3035 return cast_or_null<Expr>( 3036 Data->getChildren()[DataPositionTy::POS_UpdateExpr]); 3037 } 3038 /// Return true if helper update expression has form 3039 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form 3040 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. isXLHSInRHSPart()3041 bool isXLHSInRHSPart() const { return Flags.IsXLHSInRHSPart; } 3042 /// Return true if 'v' expression must be updated to original value of 3043 /// 'x', false if 'v' must be updated to the new value of 'x'. isPostfixUpdate()3044 bool isPostfixUpdate() const { return Flags.IsPostfixUpdate; } 3045 /// Return true if 'v' is updated only when the condition is evaluated false 3046 /// (compare capture only). isFailOnly()3047 bool isFailOnly() const { return Flags.IsFailOnly; } 3048 /// Get 'v' part of the associated expression/statement. getV()3049 Expr *getV() { 3050 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]); 3051 } getV()3052 const Expr *getV() const { 3053 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]); 3054 } 3055 /// Get 'r' part of the associated expression/statement. getR()3056 Expr *getR() { 3057 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]); 3058 } getR()3059 const Expr *getR() const { 3060 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]); 3061 } 3062 /// Get 'expr' part of the associated expression/statement. getExpr()3063 Expr *getExpr() { 3064 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]); 3065 } getExpr()3066 const Expr *getExpr() const { 3067 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]); 3068 } 3069 /// Get 'd' part of the associated expression/statement. getD()3070 Expr *getD() { 3071 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]); 3072 } getD()3073 Expr *getD() const { 3074 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]); 3075 } 3076 /// Get the 'cond' part of the source atomic expression. getCondExpr()3077 Expr *getCondExpr() { 3078 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]); 3079 } getCondExpr()3080 Expr *getCondExpr() const { 3081 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]); 3082 } 3083 classof(const Stmt * T)3084 static bool classof(const Stmt *T) { 3085 return T->getStmtClass() == OMPAtomicDirectiveClass; 3086 } 3087 }; 3088 3089 /// This represents '#pragma omp target' directive. 3090 /// 3091 /// \code 3092 /// #pragma omp target if(a) 3093 /// \endcode 3094 /// In this example directive '#pragma omp target' has clause 'if' with 3095 /// condition 'a'. 3096 /// 3097 class OMPTargetDirective : public OMPExecutableDirective { 3098 friend class ASTStmtReader; 3099 friend class OMPExecutableDirective; 3100 /// Build directive with the given start and end location. 3101 /// 3102 /// \param StartLoc Starting location of the directive kind. 3103 /// \param EndLoc Ending location of the directive. 3104 /// OMPTargetDirective(SourceLocation StartLoc,SourceLocation EndLoc)3105 OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3106 : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target, 3107 StartLoc, EndLoc) {} 3108 3109 /// Build an empty directive. 3110 /// OMPTargetDirective()3111 explicit OMPTargetDirective() 3112 : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target, 3113 SourceLocation(), SourceLocation()) {} 3114 3115 public: 3116 /// Creates directive with a list of \a Clauses. 3117 /// 3118 /// \param C AST context. 3119 /// \param StartLoc Starting location of the directive kind. 3120 /// \param EndLoc Ending Location of the directive. 3121 /// \param Clauses List of clauses. 3122 /// \param AssociatedStmt Statement, associated with the directive. 3123 /// 3124 static OMPTargetDirective * 3125 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3126 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 3127 3128 /// Creates an empty directive with the place for \a NumClauses 3129 /// clauses. 3130 /// 3131 /// \param C AST context. 3132 /// \param NumClauses Number of clauses. 3133 /// 3134 static OMPTargetDirective *CreateEmpty(const ASTContext &C, 3135 unsigned NumClauses, EmptyShell); 3136 classof(const Stmt * T)3137 static bool classof(const Stmt *T) { 3138 return T->getStmtClass() == OMPTargetDirectiveClass; 3139 } 3140 }; 3141 3142 /// This represents '#pragma omp target data' directive. 3143 /// 3144 /// \code 3145 /// #pragma omp target data device(0) if(a) map(b[:]) 3146 /// \endcode 3147 /// In this example directive '#pragma omp target data' has clauses 'device' 3148 /// with the value '0', 'if' with condition 'a' and 'map' with array 3149 /// section 'b[:]'. 3150 /// 3151 class OMPTargetDataDirective : public OMPExecutableDirective { 3152 friend class ASTStmtReader; 3153 friend class OMPExecutableDirective; 3154 /// Build directive with the given start and end location. 3155 /// 3156 /// \param StartLoc Starting location of the directive kind. 3157 /// \param EndLoc Ending Location of the directive. 3158 /// OMPTargetDataDirective(SourceLocation StartLoc,SourceLocation EndLoc)3159 OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3160 : OMPExecutableDirective(OMPTargetDataDirectiveClass, 3161 llvm::omp::OMPD_target_data, StartLoc, EndLoc) {} 3162 3163 /// Build an empty directive. 3164 /// OMPTargetDataDirective()3165 explicit OMPTargetDataDirective() 3166 : OMPExecutableDirective(OMPTargetDataDirectiveClass, 3167 llvm::omp::OMPD_target_data, SourceLocation(), 3168 SourceLocation()) {} 3169 3170 public: 3171 /// Creates directive with a list of \a Clauses. 3172 /// 3173 /// \param C AST context. 3174 /// \param StartLoc Starting location of the directive kind. 3175 /// \param EndLoc Ending Location of the directive. 3176 /// \param Clauses List of clauses. 3177 /// \param AssociatedStmt Statement, associated with the directive. 3178 /// 3179 static OMPTargetDataDirective * 3180 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3181 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 3182 3183 /// Creates an empty directive with the place for \a N clauses. 3184 /// 3185 /// \param C AST context. 3186 /// \param N The number of clauses. 3187 /// 3188 static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N, 3189 EmptyShell); 3190 classof(const Stmt * T)3191 static bool classof(const Stmt *T) { 3192 return T->getStmtClass() == OMPTargetDataDirectiveClass; 3193 } 3194 }; 3195 3196 /// This represents '#pragma omp target enter data' directive. 3197 /// 3198 /// \code 3199 /// #pragma omp target enter data device(0) if(a) map(b[:]) 3200 /// \endcode 3201 /// In this example directive '#pragma omp target enter data' has clauses 3202 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array 3203 /// section 'b[:]'. 3204 /// 3205 class OMPTargetEnterDataDirective : public OMPExecutableDirective { 3206 friend class ASTStmtReader; 3207 friend class OMPExecutableDirective; 3208 /// Build directive with the given start and end location. 3209 /// 3210 /// \param StartLoc Starting location of the directive kind. 3211 /// \param EndLoc Ending Location of the directive. 3212 /// OMPTargetEnterDataDirective(SourceLocation StartLoc,SourceLocation EndLoc)3213 OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3214 : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass, 3215 llvm::omp::OMPD_target_enter_data, StartLoc, 3216 EndLoc) {} 3217 3218 /// Build an empty directive. 3219 /// OMPTargetEnterDataDirective()3220 explicit OMPTargetEnterDataDirective() 3221 : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass, 3222 llvm::omp::OMPD_target_enter_data, 3223 SourceLocation(), SourceLocation()) {} 3224 3225 public: 3226 /// Creates directive with a list of \a Clauses. 3227 /// 3228 /// \param C AST context. 3229 /// \param StartLoc Starting location of the directive kind. 3230 /// \param EndLoc Ending Location of the directive. 3231 /// \param Clauses List of clauses. 3232 /// \param AssociatedStmt Statement, associated with the directive. 3233 /// 3234 static OMPTargetEnterDataDirective * 3235 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3236 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 3237 3238 /// Creates an empty directive with the place for \a N clauses. 3239 /// 3240 /// \param C AST context. 3241 /// \param N The number of clauses. 3242 /// 3243 static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C, 3244 unsigned N, EmptyShell); 3245 classof(const Stmt * T)3246 static bool classof(const Stmt *T) { 3247 return T->getStmtClass() == OMPTargetEnterDataDirectiveClass; 3248 } 3249 }; 3250 3251 /// This represents '#pragma omp target exit data' directive. 3252 /// 3253 /// \code 3254 /// #pragma omp target exit data device(0) if(a) map(b[:]) 3255 /// \endcode 3256 /// In this example directive '#pragma omp target exit data' has clauses 3257 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array 3258 /// section 'b[:]'. 3259 /// 3260 class OMPTargetExitDataDirective : public OMPExecutableDirective { 3261 friend class ASTStmtReader; 3262 friend class OMPExecutableDirective; 3263 /// Build directive with the given start and end location. 3264 /// 3265 /// \param StartLoc Starting location of the directive kind. 3266 /// \param EndLoc Ending Location of the directive. 3267 /// OMPTargetExitDataDirective(SourceLocation StartLoc,SourceLocation EndLoc)3268 OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3269 : OMPExecutableDirective(OMPTargetExitDataDirectiveClass, 3270 llvm::omp::OMPD_target_exit_data, StartLoc, 3271 EndLoc) {} 3272 3273 /// Build an empty directive. 3274 /// OMPTargetExitDataDirective()3275 explicit OMPTargetExitDataDirective() 3276 : OMPExecutableDirective(OMPTargetExitDataDirectiveClass, 3277 llvm::omp::OMPD_target_exit_data, 3278 SourceLocation(), SourceLocation()) {} 3279 3280 public: 3281 /// Creates directive with a list of \a Clauses. 3282 /// 3283 /// \param C AST context. 3284 /// \param StartLoc Starting location of the directive kind. 3285 /// \param EndLoc Ending Location of the directive. 3286 /// \param Clauses List of clauses. 3287 /// \param AssociatedStmt Statement, associated with the directive. 3288 /// 3289 static OMPTargetExitDataDirective * 3290 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3291 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 3292 3293 /// Creates an empty directive with the place for \a N clauses. 3294 /// 3295 /// \param C AST context. 3296 /// \param N The number of clauses. 3297 /// 3298 static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C, 3299 unsigned N, EmptyShell); 3300 classof(const Stmt * T)3301 static bool classof(const Stmt *T) { 3302 return T->getStmtClass() == OMPTargetExitDataDirectiveClass; 3303 } 3304 }; 3305 3306 /// This represents '#pragma omp target parallel' directive. 3307 /// 3308 /// \code 3309 /// #pragma omp target parallel if(a) 3310 /// \endcode 3311 /// In this example directive '#pragma omp target parallel' has clause 'if' with 3312 /// condition 'a'. 3313 /// 3314 class OMPTargetParallelDirective : public OMPExecutableDirective { 3315 friend class ASTStmtReader; 3316 friend class OMPExecutableDirective; 3317 /// true if the construct has inner cancel directive. 3318 bool HasCancel = false; 3319 3320 /// Build directive with the given start and end location. 3321 /// 3322 /// \param StartLoc Starting location of the directive kind. 3323 /// \param EndLoc Ending location of the directive. 3324 /// OMPTargetParallelDirective(SourceLocation StartLoc,SourceLocation EndLoc)3325 OMPTargetParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3326 : OMPExecutableDirective(OMPTargetParallelDirectiveClass, 3327 llvm::omp::OMPD_target_parallel, StartLoc, 3328 EndLoc) {} 3329 3330 /// Build an empty directive. 3331 /// OMPTargetParallelDirective()3332 explicit OMPTargetParallelDirective() 3333 : OMPExecutableDirective(OMPTargetParallelDirectiveClass, 3334 llvm::omp::OMPD_target_parallel, 3335 SourceLocation(), SourceLocation()) {} 3336 3337 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)3338 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 3339 /// Set cancel state. setHasCancel(bool Has)3340 void setHasCancel(bool Has) { HasCancel = Has; } 3341 3342 public: 3343 /// Creates directive with a list of \a Clauses. 3344 /// 3345 /// \param C AST context. 3346 /// \param StartLoc Starting location of the directive kind. 3347 /// \param EndLoc Ending Location of the directive. 3348 /// \param Clauses List of clauses. 3349 /// \param AssociatedStmt Statement, associated with the directive. 3350 /// \param TaskRedRef Task reduction special reference expression to handle 3351 /// taskgroup descriptor. 3352 /// \param HasCancel true if this directive has inner cancel directive. 3353 /// 3354 static OMPTargetParallelDirective * 3355 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3356 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, 3357 bool HasCancel); 3358 3359 /// Creates an empty directive with the place for \a NumClauses 3360 /// clauses. 3361 /// 3362 /// \param C AST context. 3363 /// \param NumClauses Number of clauses. 3364 /// 3365 static OMPTargetParallelDirective * 3366 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 3367 3368 /// Returns special task reduction reference expression. getTaskReductionRefExpr()3369 Expr *getTaskReductionRefExpr() { 3370 return cast_or_null<Expr>(Data->getChildren()[0]); 3371 } getTaskReductionRefExpr()3372 const Expr *getTaskReductionRefExpr() const { 3373 return const_cast<OMPTargetParallelDirective *>(this) 3374 ->getTaskReductionRefExpr(); 3375 } 3376 3377 /// Return true if current directive has inner cancel directive. hasCancel()3378 bool hasCancel() const { return HasCancel; } 3379 classof(const Stmt * T)3380 static bool classof(const Stmt *T) { 3381 return T->getStmtClass() == OMPTargetParallelDirectiveClass; 3382 } 3383 }; 3384 3385 /// This represents '#pragma omp target parallel for' directive. 3386 /// 3387 /// \code 3388 /// #pragma omp target parallel for private(a,b) reduction(+:c,d) 3389 /// \endcode 3390 /// In this example directive '#pragma omp target parallel for' has clauses 3391 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+' 3392 /// and variables 'c' and 'd'. 3393 /// 3394 class OMPTargetParallelForDirective : public OMPLoopDirective { 3395 friend class ASTStmtReader; 3396 friend class OMPExecutableDirective; 3397 3398 /// true if current region has inner cancel directive. 3399 bool HasCancel = false; 3400 3401 /// Build directive with the given start and end location. 3402 /// 3403 /// \param StartLoc Starting location of the directive kind. 3404 /// \param EndLoc Ending location of the directive. 3405 /// \param CollapsedNum Number of collapsed nested loops. 3406 /// OMPTargetParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)3407 OMPTargetParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3408 unsigned CollapsedNum) 3409 : OMPLoopDirective(OMPTargetParallelForDirectiveClass, 3410 llvm::omp::OMPD_target_parallel_for, StartLoc, EndLoc, 3411 CollapsedNum) {} 3412 3413 /// Build an empty directive. 3414 /// 3415 /// \param CollapsedNum Number of collapsed nested loops. 3416 /// OMPTargetParallelForDirective(unsigned CollapsedNum)3417 explicit OMPTargetParallelForDirective(unsigned CollapsedNum) 3418 : OMPLoopDirective(OMPTargetParallelForDirectiveClass, 3419 llvm::omp::OMPD_target_parallel_for, SourceLocation(), 3420 SourceLocation(), CollapsedNum) {} 3421 3422 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)3423 void setTaskReductionRefExpr(Expr *E) { 3424 Data->getChildren()[numLoopChildren( 3425 getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)] = E; 3426 } 3427 3428 /// Set cancel state. setHasCancel(bool Has)3429 void setHasCancel(bool Has) { HasCancel = Has; } 3430 3431 public: 3432 /// Creates directive with a list of \a Clauses. 3433 /// 3434 /// \param C AST context. 3435 /// \param StartLoc Starting location of the directive kind. 3436 /// \param EndLoc Ending Location of the directive. 3437 /// \param CollapsedNum Number of collapsed loops. 3438 /// \param Clauses List of clauses. 3439 /// \param AssociatedStmt Statement, associated with the directive. 3440 /// \param Exprs Helper expressions for CodeGen. 3441 /// \param TaskRedRef Task reduction special reference expression to handle 3442 /// taskgroup descriptor. 3443 /// \param HasCancel true if current directive has inner cancel directive. 3444 /// 3445 static OMPTargetParallelForDirective * 3446 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3447 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3448 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 3449 bool HasCancel); 3450 3451 /// Creates an empty directive with the place 3452 /// for \a NumClauses clauses. 3453 /// 3454 /// \param C AST context. 3455 /// \param CollapsedNum Number of collapsed nested loops. 3456 /// \param NumClauses Number of clauses. 3457 /// 3458 static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C, 3459 unsigned NumClauses, 3460 unsigned CollapsedNum, 3461 EmptyShell); 3462 3463 /// Returns special task reduction reference expression. getTaskReductionRefExpr()3464 Expr *getTaskReductionRefExpr() { 3465 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 3466 getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)]); 3467 } getTaskReductionRefExpr()3468 const Expr *getTaskReductionRefExpr() const { 3469 return const_cast<OMPTargetParallelForDirective *>(this) 3470 ->getTaskReductionRefExpr(); 3471 } 3472 3473 /// Return true if current directive has inner cancel directive. hasCancel()3474 bool hasCancel() const { return HasCancel; } 3475 classof(const Stmt * T)3476 static bool classof(const Stmt *T) { 3477 return T->getStmtClass() == OMPTargetParallelForDirectiveClass; 3478 } 3479 }; 3480 3481 /// This represents '#pragma omp teams' directive. 3482 /// 3483 /// \code 3484 /// #pragma omp teams if(a) 3485 /// \endcode 3486 /// In this example directive '#pragma omp teams' has clause 'if' with 3487 /// condition 'a'. 3488 /// 3489 class OMPTeamsDirective : public OMPExecutableDirective { 3490 friend class ASTStmtReader; 3491 friend class OMPExecutableDirective; 3492 /// Build directive with the given start and end location. 3493 /// 3494 /// \param StartLoc Starting location of the directive kind. 3495 /// \param EndLoc Ending location of the directive. 3496 /// OMPTeamsDirective(SourceLocation StartLoc,SourceLocation EndLoc)3497 OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3498 : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams, 3499 StartLoc, EndLoc) {} 3500 3501 /// Build an empty directive. 3502 /// OMPTeamsDirective()3503 explicit OMPTeamsDirective() 3504 : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams, 3505 SourceLocation(), SourceLocation()) {} 3506 3507 public: 3508 /// Creates directive with a list of \a Clauses. 3509 /// 3510 /// \param C AST context. 3511 /// \param StartLoc Starting location of the directive kind. 3512 /// \param EndLoc Ending Location of the directive. 3513 /// \param Clauses List of clauses. 3514 /// \param AssociatedStmt Statement, associated with the directive. 3515 /// 3516 static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc, 3517 SourceLocation EndLoc, 3518 ArrayRef<OMPClause *> Clauses, 3519 Stmt *AssociatedStmt); 3520 3521 /// Creates an empty directive with the place for \a NumClauses 3522 /// clauses. 3523 /// 3524 /// \param C AST context. 3525 /// \param NumClauses Number of clauses. 3526 /// 3527 static OMPTeamsDirective *CreateEmpty(const ASTContext &C, 3528 unsigned NumClauses, EmptyShell); 3529 classof(const Stmt * T)3530 static bool classof(const Stmt *T) { 3531 return T->getStmtClass() == OMPTeamsDirectiveClass; 3532 } 3533 }; 3534 3535 /// This represents '#pragma omp cancellation point' directive. 3536 /// 3537 /// \code 3538 /// #pragma omp cancellation point for 3539 /// \endcode 3540 /// 3541 /// In this example a cancellation point is created for innermost 'for' region. 3542 class OMPCancellationPointDirective : public OMPExecutableDirective { 3543 friend class ASTStmtReader; 3544 friend class OMPExecutableDirective; 3545 OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown; 3546 /// Build directive with the given start and end location. 3547 /// 3548 /// \param StartLoc Starting location of the directive kind. 3549 /// \param EndLoc Ending location of the directive. 3550 /// statements and child expressions. 3551 /// OMPCancellationPointDirective(SourceLocation StartLoc,SourceLocation EndLoc)3552 OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3553 : OMPExecutableDirective(OMPCancellationPointDirectiveClass, 3554 llvm::omp::OMPD_cancellation_point, StartLoc, 3555 EndLoc) {} 3556 3557 /// Build an empty directive. OMPCancellationPointDirective()3558 explicit OMPCancellationPointDirective() 3559 : OMPExecutableDirective(OMPCancellationPointDirectiveClass, 3560 llvm::omp::OMPD_cancellation_point, 3561 SourceLocation(), SourceLocation()) {} 3562 3563 /// Set cancel region for current cancellation point. 3564 /// \param CR Cancellation region. setCancelRegion(OpenMPDirectiveKind CR)3565 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; } 3566 3567 public: 3568 /// Creates directive. 3569 /// 3570 /// \param C AST context. 3571 /// \param StartLoc Starting location of the directive kind. 3572 /// \param EndLoc Ending Location of the directive. 3573 /// 3574 static OMPCancellationPointDirective * 3575 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3576 OpenMPDirectiveKind CancelRegion); 3577 3578 /// Creates an empty directive. 3579 /// 3580 /// \param C AST context. 3581 /// 3582 static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C, 3583 EmptyShell); 3584 3585 /// Get cancellation region for the current cancellation point. getCancelRegion()3586 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } 3587 classof(const Stmt * T)3588 static bool classof(const Stmt *T) { 3589 return T->getStmtClass() == OMPCancellationPointDirectiveClass; 3590 } 3591 }; 3592 3593 /// This represents '#pragma omp cancel' directive. 3594 /// 3595 /// \code 3596 /// #pragma omp cancel for 3597 /// \endcode 3598 /// 3599 /// In this example a cancel is created for innermost 'for' region. 3600 class OMPCancelDirective : public OMPExecutableDirective { 3601 friend class ASTStmtReader; 3602 friend class OMPExecutableDirective; 3603 OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown; 3604 /// Build directive with the given start and end location. 3605 /// 3606 /// \param StartLoc Starting location of the directive kind. 3607 /// \param EndLoc Ending location of the directive. 3608 /// OMPCancelDirective(SourceLocation StartLoc,SourceLocation EndLoc)3609 OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3610 : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel, 3611 StartLoc, EndLoc) {} 3612 3613 /// Build an empty directive. 3614 /// OMPCancelDirective()3615 explicit OMPCancelDirective() 3616 : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel, 3617 SourceLocation(), SourceLocation()) {} 3618 3619 /// Set cancel region for current cancellation point. 3620 /// \param CR Cancellation region. setCancelRegion(OpenMPDirectiveKind CR)3621 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; } 3622 3623 public: 3624 /// Creates directive. 3625 /// 3626 /// \param C AST context. 3627 /// \param StartLoc Starting location of the directive kind. 3628 /// \param EndLoc Ending Location of the directive. 3629 /// \param Clauses List of clauses. 3630 /// 3631 static OMPCancelDirective * 3632 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3633 ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion); 3634 3635 /// Creates an empty directive. 3636 /// 3637 /// \param C AST context. 3638 /// \param NumClauses Number of clauses. 3639 /// 3640 static OMPCancelDirective *CreateEmpty(const ASTContext &C, 3641 unsigned NumClauses, EmptyShell); 3642 3643 /// Get cancellation region for the current cancellation point. getCancelRegion()3644 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } 3645 classof(const Stmt * T)3646 static bool classof(const Stmt *T) { 3647 return T->getStmtClass() == OMPCancelDirectiveClass; 3648 } 3649 }; 3650 3651 /// This represents '#pragma omp taskloop' directive. 3652 /// 3653 /// \code 3654 /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num) 3655 /// \endcode 3656 /// In this example directive '#pragma omp taskloop' has clauses 'private' 3657 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and 3658 /// 'num_tasks' with expression 'num'. 3659 /// 3660 class OMPTaskLoopDirective : public OMPLoopDirective { 3661 friend class ASTStmtReader; 3662 friend class OMPExecutableDirective; 3663 /// true if the construct has inner cancel directive. 3664 bool HasCancel = false; 3665 3666 /// Build directive with the given start and end location. 3667 /// 3668 /// \param StartLoc Starting location of the directive kind. 3669 /// \param EndLoc Ending location of the directive. 3670 /// \param CollapsedNum Number of collapsed nested loops. 3671 /// OMPTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)3672 OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3673 unsigned CollapsedNum) 3674 : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop, 3675 StartLoc, EndLoc, CollapsedNum) {} 3676 3677 /// Build an empty directive. 3678 /// 3679 /// \param CollapsedNum Number of collapsed nested loops. 3680 /// OMPTaskLoopDirective(unsigned CollapsedNum)3681 explicit OMPTaskLoopDirective(unsigned CollapsedNum) 3682 : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop, 3683 SourceLocation(), SourceLocation(), CollapsedNum) {} 3684 3685 /// Set cancel state. setHasCancel(bool Has)3686 void setHasCancel(bool Has) { HasCancel = Has; } 3687 3688 public: 3689 /// Creates directive with a list of \a Clauses. 3690 /// 3691 /// \param C AST context. 3692 /// \param StartLoc Starting location of the directive kind. 3693 /// \param EndLoc Ending Location of the directive. 3694 /// \param CollapsedNum Number of collapsed loops. 3695 /// \param Clauses List of clauses. 3696 /// \param AssociatedStmt Statement, associated with the directive. 3697 /// \param Exprs Helper expressions for CodeGen. 3698 /// \param HasCancel true if this directive has inner cancel directive. 3699 /// 3700 static OMPTaskLoopDirective * 3701 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3702 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3703 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 3704 3705 /// Creates an empty directive with the place 3706 /// for \a NumClauses clauses. 3707 /// 3708 /// \param C AST context. 3709 /// \param CollapsedNum Number of collapsed nested loops. 3710 /// \param NumClauses Number of clauses. 3711 /// 3712 static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C, 3713 unsigned NumClauses, 3714 unsigned CollapsedNum, EmptyShell); 3715 3716 /// Return true if current directive has inner cancel directive. hasCancel()3717 bool hasCancel() const { return HasCancel; } 3718 classof(const Stmt * T)3719 static bool classof(const Stmt *T) { 3720 return T->getStmtClass() == OMPTaskLoopDirectiveClass; 3721 } 3722 }; 3723 3724 /// This represents '#pragma omp taskloop simd' directive. 3725 /// 3726 /// \code 3727 /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num) 3728 /// \endcode 3729 /// In this example directive '#pragma omp taskloop simd' has clauses 'private' 3730 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and 3731 /// 'num_tasks' with expression 'num'. 3732 /// 3733 class OMPTaskLoopSimdDirective : public OMPLoopDirective { 3734 friend class ASTStmtReader; 3735 friend class OMPExecutableDirective; 3736 /// Build directive with the given start and end location. 3737 /// 3738 /// \param StartLoc Starting location of the directive kind. 3739 /// \param EndLoc Ending location of the directive. 3740 /// \param CollapsedNum Number of collapsed nested loops. 3741 /// OMPTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)3742 OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3743 unsigned CollapsedNum) 3744 : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass, 3745 llvm::omp::OMPD_taskloop_simd, StartLoc, EndLoc, 3746 CollapsedNum) {} 3747 3748 /// Build an empty directive. 3749 /// 3750 /// \param CollapsedNum Number of collapsed nested loops. 3751 /// OMPTaskLoopSimdDirective(unsigned CollapsedNum)3752 explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum) 3753 : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass, 3754 llvm::omp::OMPD_taskloop_simd, SourceLocation(), 3755 SourceLocation(), CollapsedNum) {} 3756 3757 public: 3758 /// Creates directive with a list of \a Clauses. 3759 /// 3760 /// \param C AST context. 3761 /// \param StartLoc Starting location of the directive kind. 3762 /// \param EndLoc Ending Location of the directive. 3763 /// \param CollapsedNum Number of collapsed loops. 3764 /// \param Clauses List of clauses. 3765 /// \param AssociatedStmt Statement, associated with the directive. 3766 /// \param Exprs Helper expressions for CodeGen. 3767 /// 3768 static OMPTaskLoopSimdDirective * 3769 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3770 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3771 Stmt *AssociatedStmt, const HelperExprs &Exprs); 3772 3773 /// Creates an empty directive with the place 3774 /// for \a NumClauses clauses. 3775 /// 3776 /// \param C AST context. 3777 /// \param CollapsedNum Number of collapsed nested loops. 3778 /// \param NumClauses Number of clauses. 3779 /// 3780 static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, 3781 unsigned NumClauses, 3782 unsigned CollapsedNum, 3783 EmptyShell); 3784 classof(const Stmt * T)3785 static bool classof(const Stmt *T) { 3786 return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass; 3787 } 3788 }; 3789 3790 /// This represents '#pragma omp master taskloop' directive. 3791 /// 3792 /// \code 3793 /// #pragma omp master taskloop private(a,b) grainsize(val) num_tasks(num) 3794 /// \endcode 3795 /// In this example directive '#pragma omp master taskloop' has clauses 3796 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 3797 /// and 'num_tasks' with expression 'num'. 3798 /// 3799 class OMPMasterTaskLoopDirective : public OMPLoopDirective { 3800 friend class ASTStmtReader; 3801 friend class OMPExecutableDirective; 3802 /// true if the construct has inner cancel directive. 3803 bool HasCancel = false; 3804 3805 /// Build directive with the given start and end location. 3806 /// 3807 /// \param StartLoc Starting location of the directive kind. 3808 /// \param EndLoc Ending location of the directive. 3809 /// \param CollapsedNum Number of collapsed nested loops. 3810 /// OMPMasterTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)3811 OMPMasterTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3812 unsigned CollapsedNum) 3813 : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass, 3814 llvm::omp::OMPD_master_taskloop, StartLoc, EndLoc, 3815 CollapsedNum) {} 3816 3817 /// Build an empty directive. 3818 /// 3819 /// \param CollapsedNum Number of collapsed nested loops. 3820 /// OMPMasterTaskLoopDirective(unsigned CollapsedNum)3821 explicit OMPMasterTaskLoopDirective(unsigned CollapsedNum) 3822 : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass, 3823 llvm::omp::OMPD_master_taskloop, SourceLocation(), 3824 SourceLocation(), CollapsedNum) {} 3825 3826 /// Set cancel state. setHasCancel(bool Has)3827 void setHasCancel(bool Has) { HasCancel = Has; } 3828 3829 public: 3830 /// Creates directive with a list of \a Clauses. 3831 /// 3832 /// \param C AST context. 3833 /// \param StartLoc Starting location of the directive kind. 3834 /// \param EndLoc Ending Location of the directive. 3835 /// \param CollapsedNum Number of collapsed loops. 3836 /// \param Clauses List of clauses. 3837 /// \param AssociatedStmt Statement, associated with the directive. 3838 /// \param Exprs Helper expressions for CodeGen. 3839 /// \param HasCancel true if this directive has inner cancel directive. 3840 /// 3841 static OMPMasterTaskLoopDirective * 3842 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3843 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3844 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 3845 3846 /// Creates an empty directive with the place 3847 /// for \a NumClauses clauses. 3848 /// 3849 /// \param C AST context. 3850 /// \param CollapsedNum Number of collapsed nested loops. 3851 /// \param NumClauses Number of clauses. 3852 /// 3853 static OMPMasterTaskLoopDirective *CreateEmpty(const ASTContext &C, 3854 unsigned NumClauses, 3855 unsigned CollapsedNum, 3856 EmptyShell); 3857 3858 /// Return true if current directive has inner cancel directive. hasCancel()3859 bool hasCancel() const { return HasCancel; } 3860 classof(const Stmt * T)3861 static bool classof(const Stmt *T) { 3862 return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass; 3863 } 3864 }; 3865 3866 /// This represents '#pragma omp masked taskloop' directive. 3867 /// 3868 /// \code 3869 /// #pragma omp masked taskloop private(a,b) grainsize(val) num_tasks(num) 3870 /// \endcode 3871 /// In this example directive '#pragma omp masked taskloop' has clauses 3872 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 3873 /// and 'num_tasks' with expression 'num'. 3874 /// 3875 class OMPMaskedTaskLoopDirective final : public OMPLoopDirective { 3876 friend class ASTStmtReader; 3877 friend class OMPExecutableDirective; 3878 /// true if the construct has inner cancel directive. 3879 bool HasCancel = false; 3880 3881 /// Build directive with the given start and end location. 3882 /// 3883 /// \param StartLoc Starting location of the directive kind. 3884 /// \param EndLoc Ending location of the directive. 3885 /// \param CollapsedNum Number of collapsed nested loops. 3886 /// OMPMaskedTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)3887 OMPMaskedTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3888 unsigned CollapsedNum) 3889 : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass, 3890 llvm::omp::OMPD_masked_taskloop, StartLoc, EndLoc, 3891 CollapsedNum) {} 3892 3893 /// Build an empty directive. 3894 /// 3895 /// \param CollapsedNum Number of collapsed nested loops. 3896 /// OMPMaskedTaskLoopDirective(unsigned CollapsedNum)3897 explicit OMPMaskedTaskLoopDirective(unsigned CollapsedNum) 3898 : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass, 3899 llvm::omp::OMPD_masked_taskloop, SourceLocation(), 3900 SourceLocation(), CollapsedNum) {} 3901 3902 /// Set cancel state. setHasCancel(bool Has)3903 void setHasCancel(bool Has) { HasCancel = Has; } 3904 3905 public: 3906 /// Creates directive with a list of \a Clauses. 3907 /// 3908 /// \param C AST context. 3909 /// \param StartLoc Starting location of the directive kind. 3910 /// \param EndLoc Ending Location of the directive. 3911 /// \param CollapsedNum Number of collapsed loops. 3912 /// \param Clauses List of clauses. 3913 /// \param AssociatedStmt Statement, associated with the directive. 3914 /// \param Exprs Helper expressions for CodeGen. 3915 /// \param HasCancel true if this directive has inner cancel directive. 3916 /// 3917 static OMPMaskedTaskLoopDirective * 3918 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3919 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3920 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 3921 3922 /// Creates an empty directive with the place 3923 /// for \a NumClauses clauses. 3924 /// 3925 /// \param C AST context. 3926 /// \param CollapsedNum Number of collapsed nested loops. 3927 /// \param NumClauses Number of clauses. 3928 /// 3929 static OMPMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C, 3930 unsigned NumClauses, 3931 unsigned CollapsedNum, 3932 EmptyShell); 3933 3934 /// Return true if current directive has inner cancel directive. hasCancel()3935 bool hasCancel() const { return HasCancel; } 3936 classof(const Stmt * T)3937 static bool classof(const Stmt *T) { 3938 return T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass; 3939 } 3940 }; 3941 3942 /// This represents '#pragma omp master taskloop simd' directive. 3943 /// 3944 /// \code 3945 /// #pragma omp master taskloop simd private(a,b) grainsize(val) num_tasks(num) 3946 /// \endcode 3947 /// In this example directive '#pragma omp master taskloop simd' has clauses 3948 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 3949 /// and 'num_tasks' with expression 'num'. 3950 /// 3951 class OMPMasterTaskLoopSimdDirective : public OMPLoopDirective { 3952 friend class ASTStmtReader; 3953 friend class OMPExecutableDirective; 3954 /// Build directive with the given start and end location. 3955 /// 3956 /// \param StartLoc Starting location of the directive kind. 3957 /// \param EndLoc Ending location of the directive. 3958 /// \param CollapsedNum Number of collapsed nested loops. 3959 /// OMPMasterTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)3960 OMPMasterTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3961 unsigned CollapsedNum) 3962 : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass, 3963 llvm::omp::OMPD_master_taskloop_simd, StartLoc, EndLoc, 3964 CollapsedNum) {} 3965 3966 /// Build an empty directive. 3967 /// 3968 /// \param CollapsedNum Number of collapsed nested loops. 3969 /// OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum)3970 explicit OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum) 3971 : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass, 3972 llvm::omp::OMPD_master_taskloop_simd, SourceLocation(), 3973 SourceLocation(), CollapsedNum) {} 3974 3975 public: 3976 /// Creates directive with a list of \p Clauses. 3977 /// 3978 /// \param C AST context. 3979 /// \param StartLoc Starting location of the directive kind. 3980 /// \param EndLoc Ending Location of the directive. 3981 /// \param CollapsedNum Number of collapsed loops. 3982 /// \param Clauses List of clauses. 3983 /// \param AssociatedStmt Statement, associated with the directive. 3984 /// \param Exprs Helper expressions for CodeGen. 3985 /// 3986 static OMPMasterTaskLoopSimdDirective * 3987 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3988 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3989 Stmt *AssociatedStmt, const HelperExprs &Exprs); 3990 3991 /// Creates an empty directive with the place for \p NumClauses clauses. 3992 /// 3993 /// \param C AST context. 3994 /// \param CollapsedNum Number of collapsed nested loops. 3995 /// \param NumClauses Number of clauses. 3996 /// 3997 static OMPMasterTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, 3998 unsigned NumClauses, 3999 unsigned CollapsedNum, 4000 EmptyShell); 4001 classof(const Stmt * T)4002 static bool classof(const Stmt *T) { 4003 return T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass; 4004 } 4005 }; 4006 4007 /// This represents '#pragma omp masked taskloop simd' directive. 4008 /// 4009 /// \code 4010 /// #pragma omp masked taskloop simd private(a,b) grainsize(val) num_tasks(num) 4011 /// \endcode 4012 /// In this example directive '#pragma omp masked taskloop simd' has clauses 4013 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 4014 /// and 'num_tasks' with expression 'num'. 4015 /// 4016 class OMPMaskedTaskLoopSimdDirective final : public OMPLoopDirective { 4017 friend class ASTStmtReader; 4018 friend class OMPExecutableDirective; 4019 /// Build directive with the given start and end location. 4020 /// 4021 /// \param StartLoc Starting location of the directive kind. 4022 /// \param EndLoc Ending location of the directive. 4023 /// \param CollapsedNum Number of collapsed nested loops. 4024 /// OMPMaskedTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4025 OMPMaskedTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4026 unsigned CollapsedNum) 4027 : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass, 4028 llvm::omp::OMPD_masked_taskloop_simd, StartLoc, EndLoc, 4029 CollapsedNum) {} 4030 4031 /// Build an empty directive. 4032 /// 4033 /// \param CollapsedNum Number of collapsed nested loops. 4034 /// OMPMaskedTaskLoopSimdDirective(unsigned CollapsedNum)4035 explicit OMPMaskedTaskLoopSimdDirective(unsigned CollapsedNum) 4036 : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass, 4037 llvm::omp::OMPD_masked_taskloop_simd, SourceLocation(), 4038 SourceLocation(), CollapsedNum) {} 4039 4040 public: 4041 /// Creates directive with a list of \p Clauses. 4042 /// 4043 /// \param C AST context. 4044 /// \param StartLoc Starting location of the directive kind. 4045 /// \param EndLoc Ending Location of the directive. 4046 /// \param CollapsedNum Number of collapsed loops. 4047 /// \param Clauses List of clauses. 4048 /// \param AssociatedStmt Statement, associated with the directive. 4049 /// \param Exprs Helper expressions for CodeGen. 4050 /// 4051 static OMPMaskedTaskLoopSimdDirective * 4052 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4053 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4054 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4055 4056 /// Creates an empty directive with the place for \p NumClauses clauses. 4057 /// 4058 /// \param C AST context. 4059 /// \param CollapsedNum Number of collapsed nested loops. 4060 /// \param NumClauses Number of clauses. 4061 /// 4062 static OMPMaskedTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, 4063 unsigned NumClauses, 4064 unsigned CollapsedNum, 4065 EmptyShell); 4066 classof(const Stmt * T)4067 static bool classof(const Stmt *T) { 4068 return T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass; 4069 } 4070 }; 4071 4072 /// This represents '#pragma omp parallel master taskloop' directive. 4073 /// 4074 /// \code 4075 /// #pragma omp parallel master taskloop private(a,b) grainsize(val) 4076 /// num_tasks(num) 4077 /// \endcode 4078 /// In this example directive '#pragma omp parallel master taskloop' has clauses 4079 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 4080 /// and 'num_tasks' with expression 'num'. 4081 /// 4082 class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective { 4083 friend class ASTStmtReader; 4084 friend class OMPExecutableDirective; 4085 /// true if the construct has inner cancel directive. 4086 bool HasCancel = false; 4087 4088 /// Build directive with the given start and end location. 4089 /// 4090 /// \param StartLoc Starting location of the directive kind. 4091 /// \param EndLoc Ending location of the directive. 4092 /// \param CollapsedNum Number of collapsed nested loops. 4093 /// OMPParallelMasterTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4094 OMPParallelMasterTaskLoopDirective(SourceLocation StartLoc, 4095 SourceLocation EndLoc, 4096 unsigned CollapsedNum) 4097 : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass, 4098 llvm::omp::OMPD_parallel_master_taskloop, StartLoc, 4099 EndLoc, CollapsedNum) {} 4100 4101 /// Build an empty directive. 4102 /// 4103 /// \param CollapsedNum Number of collapsed nested loops. 4104 /// OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum)4105 explicit OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum) 4106 : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass, 4107 llvm::omp::OMPD_parallel_master_taskloop, 4108 SourceLocation(), SourceLocation(), CollapsedNum) {} 4109 4110 /// Set cancel state. setHasCancel(bool Has)4111 void setHasCancel(bool Has) { HasCancel = Has; } 4112 4113 public: 4114 /// Creates directive with a list of \a Clauses. 4115 /// 4116 /// \param C AST context. 4117 /// \param StartLoc Starting location of the directive kind. 4118 /// \param EndLoc Ending Location of the directive. 4119 /// \param CollapsedNum Number of collapsed loops. 4120 /// \param Clauses List of clauses. 4121 /// \param AssociatedStmt Statement, associated with the directive. 4122 /// \param Exprs Helper expressions for CodeGen. 4123 /// \param HasCancel true if this directive has inner cancel directive. 4124 /// 4125 static OMPParallelMasterTaskLoopDirective * 4126 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4127 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4128 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 4129 4130 /// Creates an empty directive with the place 4131 /// for \a NumClauses clauses. 4132 /// 4133 /// \param C AST context. 4134 /// \param CollapsedNum Number of collapsed nested loops. 4135 /// \param NumClauses Number of clauses. 4136 /// 4137 static OMPParallelMasterTaskLoopDirective *CreateEmpty(const ASTContext &C, 4138 unsigned NumClauses, 4139 unsigned CollapsedNum, 4140 EmptyShell); 4141 4142 /// Return true if current directive has inner cancel directive. hasCancel()4143 bool hasCancel() const { return HasCancel; } 4144 classof(const Stmt * T)4145 static bool classof(const Stmt *T) { 4146 return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass; 4147 } 4148 }; 4149 4150 /// This represents '#pragma omp parallel masked taskloop' directive. 4151 /// 4152 /// \code 4153 /// #pragma omp parallel masked taskloop private(a,b) grainsize(val) 4154 /// num_tasks(num) 4155 /// \endcode 4156 /// In this example directive '#pragma omp parallel masked taskloop' has clauses 4157 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 4158 /// and 'num_tasks' with expression 'num'. 4159 /// 4160 class OMPParallelMaskedTaskLoopDirective final : public OMPLoopDirective { 4161 friend class ASTStmtReader; 4162 friend class OMPExecutableDirective; 4163 /// true if the construct has inner cancel directive. 4164 bool HasCancel = false; 4165 4166 /// Build directive with the given start and end location. 4167 /// 4168 /// \param StartLoc Starting location of the directive kind. 4169 /// \param EndLoc Ending location of the directive. 4170 /// \param CollapsedNum Number of collapsed nested loops. 4171 /// OMPParallelMaskedTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4172 OMPParallelMaskedTaskLoopDirective(SourceLocation StartLoc, 4173 SourceLocation EndLoc, 4174 unsigned CollapsedNum) 4175 : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass, 4176 llvm::omp::OMPD_parallel_masked_taskloop, StartLoc, 4177 EndLoc, CollapsedNum) {} 4178 4179 /// Build an empty directive. 4180 /// 4181 /// \param CollapsedNum Number of collapsed nested loops. 4182 /// OMPParallelMaskedTaskLoopDirective(unsigned CollapsedNum)4183 explicit OMPParallelMaskedTaskLoopDirective(unsigned CollapsedNum) 4184 : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass, 4185 llvm::omp::OMPD_parallel_masked_taskloop, 4186 SourceLocation(), SourceLocation(), CollapsedNum) {} 4187 4188 /// Set cancel state. setHasCancel(bool Has)4189 void setHasCancel(bool Has) { HasCancel = Has; } 4190 4191 public: 4192 /// Creates directive with a list of \a Clauses. 4193 /// 4194 /// \param C AST context. 4195 /// \param StartLoc Starting location of the directive kind. 4196 /// \param EndLoc Ending Location of the directive. 4197 /// \param CollapsedNum Number of collapsed loops. 4198 /// \param Clauses List of clauses. 4199 /// \param AssociatedStmt Statement, associated with the directive. 4200 /// \param Exprs Helper expressions for CodeGen. 4201 /// \param HasCancel true if this directive has inner cancel directive. 4202 /// 4203 static OMPParallelMaskedTaskLoopDirective * 4204 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4205 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4206 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 4207 4208 /// Creates an empty directive with the place 4209 /// for \a NumClauses clauses. 4210 /// 4211 /// \param C AST context. 4212 /// \param CollapsedNum Number of collapsed nested loops. 4213 /// \param NumClauses Number of clauses. 4214 /// 4215 static OMPParallelMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C, 4216 unsigned NumClauses, 4217 unsigned CollapsedNum, 4218 EmptyShell); 4219 4220 /// Return true if current directive has inner cancel directive. hasCancel()4221 bool hasCancel() const { return HasCancel; } 4222 classof(const Stmt * T)4223 static bool classof(const Stmt *T) { 4224 return T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass; 4225 } 4226 }; 4227 4228 /// This represents '#pragma omp parallel master taskloop simd' directive. 4229 /// 4230 /// \code 4231 /// #pragma omp parallel master taskloop simd private(a,b) grainsize(val) 4232 /// num_tasks(num) 4233 /// \endcode 4234 /// In this example directive '#pragma omp parallel master taskloop simd' has 4235 /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with 4236 /// expression 'val' and 'num_tasks' with expression 'num'. 4237 /// 4238 class OMPParallelMasterTaskLoopSimdDirective : public OMPLoopDirective { 4239 friend class ASTStmtReader; 4240 friend class OMPExecutableDirective; 4241 /// Build directive with the given start and end location. 4242 /// 4243 /// \param StartLoc Starting location of the directive kind. 4244 /// \param EndLoc Ending location of the directive. 4245 /// \param CollapsedNum Number of collapsed nested loops. 4246 /// OMPParallelMasterTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4247 OMPParallelMasterTaskLoopSimdDirective(SourceLocation StartLoc, 4248 SourceLocation EndLoc, 4249 unsigned CollapsedNum) 4250 : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass, 4251 llvm::omp::OMPD_parallel_master_taskloop_simd, 4252 StartLoc, EndLoc, CollapsedNum) {} 4253 4254 /// Build an empty directive. 4255 /// 4256 /// \param CollapsedNum Number of collapsed nested loops. 4257 /// OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum)4258 explicit OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum) 4259 : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass, 4260 llvm::omp::OMPD_parallel_master_taskloop_simd, 4261 SourceLocation(), SourceLocation(), CollapsedNum) {} 4262 4263 public: 4264 /// Creates directive with a list of \p Clauses. 4265 /// 4266 /// \param C AST context. 4267 /// \param StartLoc Starting location of the directive kind. 4268 /// \param EndLoc Ending Location of the directive. 4269 /// \param CollapsedNum Number of collapsed loops. 4270 /// \param Clauses List of clauses. 4271 /// \param AssociatedStmt Statement, associated with the directive. 4272 /// \param Exprs Helper expressions for CodeGen. 4273 /// 4274 static OMPParallelMasterTaskLoopSimdDirective * 4275 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4276 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4277 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4278 4279 /// Creates an empty directive with the place 4280 /// for \a NumClauses clauses. 4281 /// 4282 /// \param C AST context. 4283 /// \param CollapsedNum Number of collapsed nested loops. 4284 /// \param NumClauses Number of clauses. 4285 /// 4286 static OMPParallelMasterTaskLoopSimdDirective * 4287 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 4288 EmptyShell); 4289 classof(const Stmt * T)4290 static bool classof(const Stmt *T) { 4291 return T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass; 4292 } 4293 }; 4294 4295 /// This represents '#pragma omp parallel masked taskloop simd' directive. 4296 /// 4297 /// \code 4298 /// #pragma omp parallel masked taskloop simd private(a,b) grainsize(val) 4299 /// num_tasks(num) 4300 /// \endcode 4301 /// In this example directive '#pragma omp parallel masked taskloop simd' has 4302 /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with 4303 /// expression 'val' and 'num_tasks' with expression 'num'. 4304 /// 4305 class OMPParallelMaskedTaskLoopSimdDirective final : public OMPLoopDirective { 4306 friend class ASTStmtReader; 4307 friend class OMPExecutableDirective; 4308 /// Build directive with the given start and end location. 4309 /// 4310 /// \param StartLoc Starting location of the directive kind. 4311 /// \param EndLoc Ending location of the directive. 4312 /// \param CollapsedNum Number of collapsed nested loops. 4313 /// OMPParallelMaskedTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4314 OMPParallelMaskedTaskLoopSimdDirective(SourceLocation StartLoc, 4315 SourceLocation EndLoc, 4316 unsigned CollapsedNum) 4317 : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass, 4318 llvm::omp::OMPD_parallel_masked_taskloop_simd, 4319 StartLoc, EndLoc, CollapsedNum) {} 4320 4321 /// Build an empty directive. 4322 /// 4323 /// \param CollapsedNum Number of collapsed nested loops. 4324 /// OMPParallelMaskedTaskLoopSimdDirective(unsigned CollapsedNum)4325 explicit OMPParallelMaskedTaskLoopSimdDirective(unsigned CollapsedNum) 4326 : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass, 4327 llvm::omp::OMPD_parallel_masked_taskloop_simd, 4328 SourceLocation(), SourceLocation(), CollapsedNum) {} 4329 4330 public: 4331 /// Creates directive with a list of \p Clauses. 4332 /// 4333 /// \param C AST context. 4334 /// \param StartLoc Starting location of the directive kind. 4335 /// \param EndLoc Ending Location of the directive. 4336 /// \param CollapsedNum Number of collapsed loops. 4337 /// \param Clauses List of clauses. 4338 /// \param AssociatedStmt Statement, associated with the directive. 4339 /// \param Exprs Helper expressions for CodeGen. 4340 /// 4341 static OMPParallelMaskedTaskLoopSimdDirective * 4342 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4343 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4344 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4345 4346 /// Creates an empty directive with the place 4347 /// for \a NumClauses clauses. 4348 /// 4349 /// \param C AST context. 4350 /// \param CollapsedNum Number of collapsed nested loops. 4351 /// \param NumClauses Number of clauses. 4352 /// 4353 static OMPParallelMaskedTaskLoopSimdDirective * 4354 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 4355 EmptyShell); 4356 classof(const Stmt * T)4357 static bool classof(const Stmt *T) { 4358 return T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass; 4359 } 4360 }; 4361 4362 /// This represents '#pragma omp distribute' directive. 4363 /// 4364 /// \code 4365 /// #pragma omp distribute private(a,b) 4366 /// \endcode 4367 /// In this example directive '#pragma omp distribute' has clauses 'private' 4368 /// with the variables 'a' and 'b' 4369 /// 4370 class OMPDistributeDirective : public OMPLoopDirective { 4371 friend class ASTStmtReader; 4372 friend class OMPExecutableDirective; 4373 4374 /// Build directive with the given start and end location. 4375 /// 4376 /// \param StartLoc Starting location of the directive kind. 4377 /// \param EndLoc Ending location of the directive. 4378 /// \param CollapsedNum Number of collapsed nested loops. 4379 /// OMPDistributeDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4380 OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4381 unsigned CollapsedNum) 4382 : OMPLoopDirective(OMPDistributeDirectiveClass, 4383 llvm::omp::OMPD_distribute, StartLoc, EndLoc, 4384 CollapsedNum) {} 4385 4386 /// Build an empty directive. 4387 /// 4388 /// \param CollapsedNum Number of collapsed nested loops. 4389 /// OMPDistributeDirective(unsigned CollapsedNum)4390 explicit OMPDistributeDirective(unsigned CollapsedNum) 4391 : OMPLoopDirective(OMPDistributeDirectiveClass, 4392 llvm::omp::OMPD_distribute, SourceLocation(), 4393 SourceLocation(), CollapsedNum) {} 4394 4395 public: 4396 /// Creates directive with a list of \a Clauses. 4397 /// 4398 /// \param C AST context. 4399 /// \param StartLoc Starting location of the directive kind. 4400 /// \param EndLoc Ending Location of the directive. 4401 /// \param CollapsedNum Number of collapsed loops. 4402 /// \param Clauses List of clauses. 4403 /// \param AssociatedStmt Statement, associated with the directive. 4404 /// \param Exprs Helper expressions for CodeGen. 4405 /// 4406 static OMPDistributeDirective * 4407 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4408 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4409 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4410 4411 /// Creates an empty directive with the place 4412 /// for \a NumClauses clauses. 4413 /// 4414 /// \param C AST context. 4415 /// \param CollapsedNum Number of collapsed nested loops. 4416 /// \param NumClauses Number of clauses. 4417 /// 4418 static OMPDistributeDirective *CreateEmpty(const ASTContext &C, 4419 unsigned NumClauses, 4420 unsigned CollapsedNum, EmptyShell); 4421 classof(const Stmt * T)4422 static bool classof(const Stmt *T) { 4423 return T->getStmtClass() == OMPDistributeDirectiveClass; 4424 } 4425 }; 4426 4427 /// This represents '#pragma omp target update' directive. 4428 /// 4429 /// \code 4430 /// #pragma omp target update to(a) from(b) device(1) 4431 /// \endcode 4432 /// In this example directive '#pragma omp target update' has clause 'to' with 4433 /// argument 'a', clause 'from' with argument 'b' and clause 'device' with 4434 /// argument '1'. 4435 /// 4436 class OMPTargetUpdateDirective : public OMPExecutableDirective { 4437 friend class ASTStmtReader; 4438 friend class OMPExecutableDirective; 4439 /// Build directive with the given start and end location. 4440 /// 4441 /// \param StartLoc Starting location of the directive kind. 4442 /// \param EndLoc Ending Location of the directive. 4443 /// OMPTargetUpdateDirective(SourceLocation StartLoc,SourceLocation EndLoc)4444 OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc) 4445 : OMPExecutableDirective(OMPTargetUpdateDirectiveClass, 4446 llvm::omp::OMPD_target_update, StartLoc, 4447 EndLoc) {} 4448 4449 /// Build an empty directive. 4450 /// OMPTargetUpdateDirective()4451 explicit OMPTargetUpdateDirective() 4452 : OMPExecutableDirective(OMPTargetUpdateDirectiveClass, 4453 llvm::omp::OMPD_target_update, SourceLocation(), 4454 SourceLocation()) {} 4455 4456 public: 4457 /// Creates directive with a list of \a Clauses. 4458 /// 4459 /// \param C AST context. 4460 /// \param StartLoc Starting location of the directive kind. 4461 /// \param EndLoc Ending Location of the directive. 4462 /// \param Clauses List of clauses. 4463 /// \param AssociatedStmt Statement, associated with the directive. 4464 /// 4465 static OMPTargetUpdateDirective * 4466 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4467 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 4468 4469 /// Creates an empty directive with the place for \a NumClauses 4470 /// clauses. 4471 /// 4472 /// \param C AST context. 4473 /// \param NumClauses The number of clauses. 4474 /// 4475 static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C, 4476 unsigned NumClauses, EmptyShell); 4477 classof(const Stmt * T)4478 static bool classof(const Stmt *T) { 4479 return T->getStmtClass() == OMPTargetUpdateDirectiveClass; 4480 } 4481 }; 4482 4483 /// This represents '#pragma omp distribute parallel for' composite 4484 /// directive. 4485 /// 4486 /// \code 4487 /// #pragma omp distribute parallel for private(a,b) 4488 /// \endcode 4489 /// In this example directive '#pragma omp distribute parallel for' has clause 4490 /// 'private' with the variables 'a' and 'b' 4491 /// 4492 class OMPDistributeParallelForDirective : public OMPLoopDirective { 4493 friend class ASTStmtReader; 4494 friend class OMPExecutableDirective; 4495 /// true if the construct has inner cancel directive. 4496 bool HasCancel = false; 4497 4498 /// Build directive with the given start and end location. 4499 /// 4500 /// \param StartLoc Starting location of the directive kind. 4501 /// \param EndLoc Ending location of the directive. 4502 /// \param CollapsedNum Number of collapsed nested loops. 4503 /// OMPDistributeParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4504 OMPDistributeParallelForDirective(SourceLocation StartLoc, 4505 SourceLocation EndLoc, 4506 unsigned CollapsedNum) 4507 : OMPLoopDirective(OMPDistributeParallelForDirectiveClass, 4508 llvm::omp::OMPD_distribute_parallel_for, StartLoc, 4509 EndLoc, CollapsedNum) {} 4510 4511 /// Build an empty directive. 4512 /// 4513 /// \param CollapsedNum Number of collapsed nested loops. 4514 /// OMPDistributeParallelForDirective(unsigned CollapsedNum)4515 explicit OMPDistributeParallelForDirective(unsigned CollapsedNum) 4516 : OMPLoopDirective(OMPDistributeParallelForDirectiveClass, 4517 llvm::omp::OMPD_distribute_parallel_for, 4518 SourceLocation(), SourceLocation(), CollapsedNum) {} 4519 4520 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)4521 void setTaskReductionRefExpr(Expr *E) { 4522 Data->getChildren()[numLoopChildren( 4523 getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)] = E; 4524 } 4525 4526 /// Set cancel state. setHasCancel(bool Has)4527 void setHasCancel(bool Has) { HasCancel = Has; } 4528 4529 public: 4530 /// Creates directive with a list of \a Clauses. 4531 /// 4532 /// \param C AST context. 4533 /// \param StartLoc Starting location of the directive kind. 4534 /// \param EndLoc Ending Location of the directive. 4535 /// \param CollapsedNum Number of collapsed loops. 4536 /// \param Clauses List of clauses. 4537 /// \param AssociatedStmt Statement, associated with the directive. 4538 /// \param Exprs Helper expressions for CodeGen. 4539 /// \param TaskRedRef Task reduction special reference expression to handle 4540 /// taskgroup descriptor. 4541 /// \param HasCancel true if this directive has inner cancel directive. 4542 /// 4543 static OMPDistributeParallelForDirective * 4544 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4545 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4546 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 4547 bool HasCancel); 4548 4549 /// Creates an empty directive with the place 4550 /// for \a NumClauses clauses. 4551 /// 4552 /// \param C AST context. 4553 /// \param CollapsedNum Number of collapsed nested loops. 4554 /// \param NumClauses Number of clauses. 4555 /// 4556 static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C, 4557 unsigned NumClauses, 4558 unsigned CollapsedNum, 4559 EmptyShell); 4560 4561 /// Returns special task reduction reference expression. getTaskReductionRefExpr()4562 Expr *getTaskReductionRefExpr() { 4563 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 4564 getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)]); 4565 } getTaskReductionRefExpr()4566 const Expr *getTaskReductionRefExpr() const { 4567 return const_cast<OMPDistributeParallelForDirective *>(this) 4568 ->getTaskReductionRefExpr(); 4569 } 4570 4571 /// Return true if current directive has inner cancel directive. hasCancel()4572 bool hasCancel() const { return HasCancel; } 4573 classof(const Stmt * T)4574 static bool classof(const Stmt *T) { 4575 return T->getStmtClass() == OMPDistributeParallelForDirectiveClass; 4576 } 4577 }; 4578 4579 /// This represents '#pragma omp distribute parallel for simd' composite 4580 /// directive. 4581 /// 4582 /// \code 4583 /// #pragma omp distribute parallel for simd private(x) 4584 /// \endcode 4585 /// In this example directive '#pragma omp distribute parallel for simd' has 4586 /// clause 'private' with the variables 'x' 4587 /// 4588 class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective { 4589 friend class ASTStmtReader; 4590 friend class OMPExecutableDirective; 4591 4592 /// Build directive with the given start and end location. 4593 /// 4594 /// \param StartLoc Starting location of the directive kind. 4595 /// \param EndLoc Ending location of the directive. 4596 /// \param CollapsedNum Number of collapsed nested loops. 4597 /// OMPDistributeParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4598 OMPDistributeParallelForSimdDirective(SourceLocation StartLoc, 4599 SourceLocation EndLoc, 4600 unsigned CollapsedNum) 4601 : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass, 4602 llvm::omp::OMPD_distribute_parallel_for_simd, StartLoc, 4603 EndLoc, CollapsedNum) {} 4604 4605 /// Build an empty directive. 4606 /// 4607 /// \param CollapsedNum Number of collapsed nested loops. 4608 /// OMPDistributeParallelForSimdDirective(unsigned CollapsedNum)4609 explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum) 4610 : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass, 4611 llvm::omp::OMPD_distribute_parallel_for_simd, 4612 SourceLocation(), SourceLocation(), CollapsedNum) {} 4613 4614 public: 4615 /// Creates directive with a list of \a Clauses. 4616 /// 4617 /// \param C AST context. 4618 /// \param StartLoc Starting location of the directive kind. 4619 /// \param EndLoc Ending Location of the directive. 4620 /// \param CollapsedNum Number of collapsed loops. 4621 /// \param Clauses List of clauses. 4622 /// \param AssociatedStmt Statement, associated with the directive. 4623 /// \param Exprs Helper expressions for CodeGen. 4624 /// 4625 static OMPDistributeParallelForSimdDirective *Create( 4626 const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4627 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4628 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4629 4630 /// Creates an empty directive with the place for \a NumClauses clauses. 4631 /// 4632 /// \param C AST context. 4633 /// \param CollapsedNum Number of collapsed nested loops. 4634 /// \param NumClauses Number of clauses. 4635 /// 4636 static OMPDistributeParallelForSimdDirective *CreateEmpty( 4637 const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 4638 EmptyShell); 4639 classof(const Stmt * T)4640 static bool classof(const Stmt *T) { 4641 return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass; 4642 } 4643 }; 4644 4645 /// This represents '#pragma omp distribute simd' composite directive. 4646 /// 4647 /// \code 4648 /// #pragma omp distribute simd private(x) 4649 /// \endcode 4650 /// In this example directive '#pragma omp distribute simd' has clause 4651 /// 'private' with the variables 'x' 4652 /// 4653 class OMPDistributeSimdDirective final : public OMPLoopDirective { 4654 friend class ASTStmtReader; 4655 friend class OMPExecutableDirective; 4656 4657 /// Build directive with the given start and end location. 4658 /// 4659 /// \param StartLoc Starting location of the directive kind. 4660 /// \param EndLoc Ending location of the directive. 4661 /// \param CollapsedNum Number of collapsed nested loops. 4662 /// OMPDistributeSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4663 OMPDistributeSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4664 unsigned CollapsedNum) 4665 : OMPLoopDirective(OMPDistributeSimdDirectiveClass, 4666 llvm::omp::OMPD_distribute_simd, StartLoc, EndLoc, 4667 CollapsedNum) {} 4668 4669 /// Build an empty directive. 4670 /// 4671 /// \param CollapsedNum Number of collapsed nested loops. 4672 /// OMPDistributeSimdDirective(unsigned CollapsedNum)4673 explicit OMPDistributeSimdDirective(unsigned CollapsedNum) 4674 : OMPLoopDirective(OMPDistributeSimdDirectiveClass, 4675 llvm::omp::OMPD_distribute_simd, SourceLocation(), 4676 SourceLocation(), CollapsedNum) {} 4677 4678 public: 4679 /// Creates directive with a list of \a Clauses. 4680 /// 4681 /// \param C AST context. 4682 /// \param StartLoc Starting location of the directive kind. 4683 /// \param EndLoc Ending Location of the directive. 4684 /// \param CollapsedNum Number of collapsed loops. 4685 /// \param Clauses List of clauses. 4686 /// \param AssociatedStmt Statement, associated with the directive. 4687 /// \param Exprs Helper expressions for CodeGen. 4688 /// 4689 static OMPDistributeSimdDirective * 4690 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4691 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4692 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4693 4694 /// Creates an empty directive with the place for \a NumClauses clauses. 4695 /// 4696 /// \param C AST context. 4697 /// \param CollapsedNum Number of collapsed nested loops. 4698 /// \param NumClauses Number of clauses. 4699 /// 4700 static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C, 4701 unsigned NumClauses, 4702 unsigned CollapsedNum, 4703 EmptyShell); 4704 classof(const Stmt * T)4705 static bool classof(const Stmt *T) { 4706 return T->getStmtClass() == OMPDistributeSimdDirectiveClass; 4707 } 4708 }; 4709 4710 /// This represents '#pragma omp target parallel for simd' directive. 4711 /// 4712 /// \code 4713 /// #pragma omp target parallel for simd private(a) map(b) safelen(c) 4714 /// \endcode 4715 /// In this example directive '#pragma omp target parallel for simd' has clauses 4716 /// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen' 4717 /// with the variable 'c'. 4718 /// 4719 class OMPTargetParallelForSimdDirective final : public OMPLoopDirective { 4720 friend class ASTStmtReader; 4721 friend class OMPExecutableDirective; 4722 4723 /// Build directive with the given start and end location. 4724 /// 4725 /// \param StartLoc Starting location of the directive kind. 4726 /// \param EndLoc Ending location of the directive. 4727 /// \param CollapsedNum Number of collapsed nested loops. 4728 /// OMPTargetParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4729 OMPTargetParallelForSimdDirective(SourceLocation StartLoc, 4730 SourceLocation EndLoc, 4731 unsigned CollapsedNum) 4732 : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass, 4733 llvm::omp::OMPD_target_parallel_for_simd, StartLoc, 4734 EndLoc, CollapsedNum) {} 4735 4736 /// Build an empty directive. 4737 /// 4738 /// \param CollapsedNum Number of collapsed nested loops. 4739 /// OMPTargetParallelForSimdDirective(unsigned CollapsedNum)4740 explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum) 4741 : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass, 4742 llvm::omp::OMPD_target_parallel_for_simd, 4743 SourceLocation(), SourceLocation(), CollapsedNum) {} 4744 4745 public: 4746 /// Creates directive with a list of \a Clauses. 4747 /// 4748 /// \param C AST context. 4749 /// \param StartLoc Starting location of the directive kind. 4750 /// \param EndLoc Ending Location of the directive. 4751 /// \param CollapsedNum Number of collapsed loops. 4752 /// \param Clauses List of clauses. 4753 /// \param AssociatedStmt Statement, associated with the directive. 4754 /// \param Exprs Helper expressions for CodeGen. 4755 /// 4756 static OMPTargetParallelForSimdDirective * 4757 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4758 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4759 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4760 4761 /// Creates an empty directive with the place for \a NumClauses clauses. 4762 /// 4763 /// \param C AST context. 4764 /// \param CollapsedNum Number of collapsed nested loops. 4765 /// \param NumClauses Number of clauses. 4766 /// 4767 static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C, 4768 unsigned NumClauses, 4769 unsigned CollapsedNum, 4770 EmptyShell); 4771 classof(const Stmt * T)4772 static bool classof(const Stmt *T) { 4773 return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass; 4774 } 4775 }; 4776 4777 /// This represents '#pragma omp target simd' directive. 4778 /// 4779 /// \code 4780 /// #pragma omp target simd private(a) map(b) safelen(c) 4781 /// \endcode 4782 /// In this example directive '#pragma omp target simd' has clauses 'private' 4783 /// with the variable 'a', 'map' with the variable 'b' and 'safelen' with 4784 /// the variable 'c'. 4785 /// 4786 class OMPTargetSimdDirective final : public OMPLoopDirective { 4787 friend class ASTStmtReader; 4788 friend class OMPExecutableDirective; 4789 4790 /// Build directive with the given start and end location. 4791 /// 4792 /// \param StartLoc Starting location of the directive kind. 4793 /// \param EndLoc Ending location of the directive. 4794 /// \param CollapsedNum Number of collapsed nested loops. 4795 /// OMPTargetSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4796 OMPTargetSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4797 unsigned CollapsedNum) 4798 : OMPLoopDirective(OMPTargetSimdDirectiveClass, 4799 llvm::omp::OMPD_target_simd, StartLoc, EndLoc, 4800 CollapsedNum) {} 4801 4802 /// Build an empty directive. 4803 /// 4804 /// \param CollapsedNum Number of collapsed nested loops. 4805 /// OMPTargetSimdDirective(unsigned CollapsedNum)4806 explicit OMPTargetSimdDirective(unsigned CollapsedNum) 4807 : OMPLoopDirective(OMPTargetSimdDirectiveClass, 4808 llvm::omp::OMPD_target_simd, SourceLocation(), 4809 SourceLocation(), CollapsedNum) {} 4810 4811 public: 4812 /// Creates directive with a list of \a Clauses. 4813 /// 4814 /// \param C AST context. 4815 /// \param StartLoc Starting location of the directive kind. 4816 /// \param EndLoc Ending Location of the directive. 4817 /// \param CollapsedNum Number of collapsed loops. 4818 /// \param Clauses List of clauses. 4819 /// \param AssociatedStmt Statement, associated with the directive. 4820 /// \param Exprs Helper expressions for CodeGen. 4821 /// 4822 static OMPTargetSimdDirective * 4823 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4824 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4825 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4826 4827 /// Creates an empty directive with the place for \a NumClauses clauses. 4828 /// 4829 /// \param C AST context. 4830 /// \param CollapsedNum Number of collapsed nested loops. 4831 /// \param NumClauses Number of clauses. 4832 /// 4833 static OMPTargetSimdDirective *CreateEmpty(const ASTContext &C, 4834 unsigned NumClauses, 4835 unsigned CollapsedNum, 4836 EmptyShell); 4837 classof(const Stmt * T)4838 static bool classof(const Stmt *T) { 4839 return T->getStmtClass() == OMPTargetSimdDirectiveClass; 4840 } 4841 }; 4842 4843 /// This represents '#pragma omp teams distribute' directive. 4844 /// 4845 /// \code 4846 /// #pragma omp teams distribute private(a,b) 4847 /// \endcode 4848 /// In this example directive '#pragma omp teams distribute' has clauses 4849 /// 'private' with the variables 'a' and 'b' 4850 /// 4851 class OMPTeamsDistributeDirective final : public OMPLoopDirective { 4852 friend class ASTStmtReader; 4853 friend class OMPExecutableDirective; 4854 4855 /// Build directive with the given start and end location. 4856 /// 4857 /// \param StartLoc Starting location of the directive kind. 4858 /// \param EndLoc Ending location of the directive. 4859 /// \param CollapsedNum Number of collapsed nested loops. 4860 /// OMPTeamsDistributeDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4861 OMPTeamsDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4862 unsigned CollapsedNum) 4863 : OMPLoopDirective(OMPTeamsDistributeDirectiveClass, 4864 llvm::omp::OMPD_teams_distribute, StartLoc, EndLoc, 4865 CollapsedNum) {} 4866 4867 /// Build an empty directive. 4868 /// 4869 /// \param CollapsedNum Number of collapsed nested loops. 4870 /// OMPTeamsDistributeDirective(unsigned CollapsedNum)4871 explicit OMPTeamsDistributeDirective(unsigned CollapsedNum) 4872 : OMPLoopDirective(OMPTeamsDistributeDirectiveClass, 4873 llvm::omp::OMPD_teams_distribute, SourceLocation(), 4874 SourceLocation(), CollapsedNum) {} 4875 4876 public: 4877 /// Creates directive with a list of \a Clauses. 4878 /// 4879 /// \param C AST context. 4880 /// \param StartLoc Starting location of the directive kind. 4881 /// \param EndLoc Ending Location of the directive. 4882 /// \param CollapsedNum Number of collapsed loops. 4883 /// \param Clauses List of clauses. 4884 /// \param AssociatedStmt Statement, associated with the directive. 4885 /// \param Exprs Helper expressions for CodeGen. 4886 /// 4887 static OMPTeamsDistributeDirective * 4888 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4889 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4890 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4891 4892 /// Creates an empty directive with the place for \a NumClauses clauses. 4893 /// 4894 /// \param C AST context. 4895 /// \param CollapsedNum Number of collapsed nested loops. 4896 /// \param NumClauses Number of clauses. 4897 /// 4898 static OMPTeamsDistributeDirective *CreateEmpty(const ASTContext &C, 4899 unsigned NumClauses, 4900 unsigned CollapsedNum, 4901 EmptyShell); 4902 classof(const Stmt * T)4903 static bool classof(const Stmt *T) { 4904 return T->getStmtClass() == OMPTeamsDistributeDirectiveClass; 4905 } 4906 }; 4907 4908 /// This represents '#pragma omp teams distribute simd' 4909 /// combined directive. 4910 /// 4911 /// \code 4912 /// #pragma omp teams distribute simd private(a,b) 4913 /// \endcode 4914 /// In this example directive '#pragma omp teams distribute simd' 4915 /// has clause 'private' with the variables 'a' and 'b' 4916 /// 4917 class OMPTeamsDistributeSimdDirective final : public OMPLoopDirective { 4918 friend class ASTStmtReader; 4919 friend class OMPExecutableDirective; 4920 4921 /// Build directive with the given start and end location. 4922 /// 4923 /// \param StartLoc Starting location of the directive kind. 4924 /// \param EndLoc Ending location of the directive. 4925 /// \param CollapsedNum Number of collapsed nested loops. 4926 /// OMPTeamsDistributeSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4927 OMPTeamsDistributeSimdDirective(SourceLocation StartLoc, 4928 SourceLocation EndLoc, unsigned CollapsedNum) 4929 : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass, 4930 llvm::omp::OMPD_teams_distribute_simd, StartLoc, 4931 EndLoc, CollapsedNum) {} 4932 4933 /// Build an empty directive. 4934 /// 4935 /// \param CollapsedNum Number of collapsed nested loops. 4936 /// OMPTeamsDistributeSimdDirective(unsigned CollapsedNum)4937 explicit OMPTeamsDistributeSimdDirective(unsigned CollapsedNum) 4938 : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass, 4939 llvm::omp::OMPD_teams_distribute_simd, 4940 SourceLocation(), SourceLocation(), CollapsedNum) {} 4941 4942 public: 4943 /// Creates directive with a list of \a Clauses. 4944 /// 4945 /// \param C AST context. 4946 /// \param StartLoc Starting location of the directive kind. 4947 /// \param EndLoc Ending Location of the directive. 4948 /// \param CollapsedNum Number of collapsed loops. 4949 /// \param Clauses List of clauses. 4950 /// \param AssociatedStmt Statement, associated with the directive. 4951 /// \param Exprs Helper expressions for CodeGen. 4952 /// 4953 static OMPTeamsDistributeSimdDirective * 4954 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4955 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4956 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4957 4958 /// Creates an empty directive with the place 4959 /// for \a NumClauses clauses. 4960 /// 4961 /// \param C AST context. 4962 /// \param CollapsedNum Number of collapsed nested loops. 4963 /// \param NumClauses Number of clauses. 4964 /// 4965 static OMPTeamsDistributeSimdDirective *CreateEmpty(const ASTContext &C, 4966 unsigned NumClauses, 4967 unsigned CollapsedNum, 4968 EmptyShell); 4969 classof(const Stmt * T)4970 static bool classof(const Stmt *T) { 4971 return T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass; 4972 } 4973 }; 4974 4975 /// This represents '#pragma omp teams distribute parallel for simd' composite 4976 /// directive. 4977 /// 4978 /// \code 4979 /// #pragma omp teams distribute parallel for simd private(x) 4980 /// \endcode 4981 /// In this example directive '#pragma omp teams distribute parallel for simd' 4982 /// has clause 'private' with the variables 'x' 4983 /// 4984 class OMPTeamsDistributeParallelForSimdDirective final 4985 : public OMPLoopDirective { 4986 friend class ASTStmtReader; 4987 friend class OMPExecutableDirective; 4988 4989 /// Build directive with the given start and end location. 4990 /// 4991 /// \param StartLoc Starting location of the directive kind. 4992 /// \param EndLoc Ending location of the directive. 4993 /// \param CollapsedNum Number of collapsed nested loops. 4994 /// OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4995 OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc, 4996 SourceLocation EndLoc, 4997 unsigned CollapsedNum) 4998 : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass, 4999 llvm::omp::OMPD_teams_distribute_parallel_for_simd, 5000 StartLoc, EndLoc, CollapsedNum) {} 5001 5002 /// Build an empty directive. 5003 /// 5004 /// \param CollapsedNum Number of collapsed nested loops. 5005 /// OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum)5006 explicit OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum) 5007 : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass, 5008 llvm::omp::OMPD_teams_distribute_parallel_for_simd, 5009 SourceLocation(), SourceLocation(), CollapsedNum) {} 5010 5011 public: 5012 /// Creates directive with a list of \a Clauses. 5013 /// 5014 /// \param C AST context. 5015 /// \param StartLoc Starting location of the directive kind. 5016 /// \param EndLoc Ending Location of the directive. 5017 /// \param CollapsedNum Number of collapsed loops. 5018 /// \param Clauses List of clauses. 5019 /// \param AssociatedStmt Statement, associated with the directive. 5020 /// \param Exprs Helper expressions for CodeGen. 5021 /// 5022 static OMPTeamsDistributeParallelForSimdDirective * 5023 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5024 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 5025 Stmt *AssociatedStmt, const HelperExprs &Exprs); 5026 5027 /// Creates an empty directive with the place for \a NumClauses clauses. 5028 /// 5029 /// \param C AST context. 5030 /// \param CollapsedNum Number of collapsed nested loops. 5031 /// \param NumClauses Number of clauses. 5032 /// 5033 static OMPTeamsDistributeParallelForSimdDirective * 5034 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 5035 EmptyShell); 5036 classof(const Stmt * T)5037 static bool classof(const Stmt *T) { 5038 return T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass; 5039 } 5040 }; 5041 5042 /// This represents '#pragma omp teams distribute parallel for' composite 5043 /// directive. 5044 /// 5045 /// \code 5046 /// #pragma omp teams distribute parallel for private(x) 5047 /// \endcode 5048 /// In this example directive '#pragma omp teams distribute parallel for' 5049 /// has clause 'private' with the variables 'x' 5050 /// 5051 class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective { 5052 friend class ASTStmtReader; 5053 friend class OMPExecutableDirective; 5054 /// true if the construct has inner cancel directive. 5055 bool HasCancel = false; 5056 5057 /// Build directive with the given start and end location. 5058 /// 5059 /// \param StartLoc Starting location of the directive kind. 5060 /// \param EndLoc Ending location of the directive. 5061 /// \param CollapsedNum Number of collapsed nested loops. 5062 /// OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)5063 OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc, 5064 SourceLocation EndLoc, 5065 unsigned CollapsedNum) 5066 : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass, 5067 llvm::omp::OMPD_teams_distribute_parallel_for, 5068 StartLoc, EndLoc, CollapsedNum) {} 5069 5070 /// Build an empty directive. 5071 /// 5072 /// \param CollapsedNum Number of collapsed nested loops. 5073 /// OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum)5074 explicit OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum) 5075 : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass, 5076 llvm::omp::OMPD_teams_distribute_parallel_for, 5077 SourceLocation(), SourceLocation(), CollapsedNum) {} 5078 5079 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)5080 void setTaskReductionRefExpr(Expr *E) { 5081 Data->getChildren()[numLoopChildren( 5082 getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)] = E; 5083 } 5084 5085 /// Set cancel state. setHasCancel(bool Has)5086 void setHasCancel(bool Has) { HasCancel = Has; } 5087 5088 public: 5089 /// Creates directive with a list of \a Clauses. 5090 /// 5091 /// \param C AST context. 5092 /// \param StartLoc Starting location of the directive kind. 5093 /// \param EndLoc Ending Location of the directive. 5094 /// \param CollapsedNum Number of collapsed loops. 5095 /// \param Clauses List of clauses. 5096 /// \param AssociatedStmt Statement, associated with the directive. 5097 /// \param Exprs Helper expressions for CodeGen. 5098 /// \param TaskRedRef Task reduction special reference expression to handle 5099 /// taskgroup descriptor. 5100 /// \param HasCancel true if this directive has inner cancel directive. 5101 /// 5102 static OMPTeamsDistributeParallelForDirective * 5103 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5104 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 5105 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 5106 bool HasCancel); 5107 5108 /// Creates an empty directive with the place for \a NumClauses clauses. 5109 /// 5110 /// \param C AST context. 5111 /// \param CollapsedNum Number of collapsed nested loops. 5112 /// \param NumClauses Number of clauses. 5113 /// 5114 static OMPTeamsDistributeParallelForDirective * 5115 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 5116 EmptyShell); 5117 5118 /// Returns special task reduction reference expression. getTaskReductionRefExpr()5119 Expr *getTaskReductionRefExpr() { 5120 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 5121 getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)]); 5122 } getTaskReductionRefExpr()5123 const Expr *getTaskReductionRefExpr() const { 5124 return const_cast<OMPTeamsDistributeParallelForDirective *>(this) 5125 ->getTaskReductionRefExpr(); 5126 } 5127 5128 /// Return true if current directive has inner cancel directive. hasCancel()5129 bool hasCancel() const { return HasCancel; } 5130 classof(const Stmt * T)5131 static bool classof(const Stmt *T) { 5132 return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass; 5133 } 5134 }; 5135 5136 /// This represents '#pragma omp target teams' directive. 5137 /// 5138 /// \code 5139 /// #pragma omp target teams if(a>0) 5140 /// \endcode 5141 /// In this example directive '#pragma omp target teams' has clause 'if' with 5142 /// condition 'a>0'. 5143 /// 5144 class OMPTargetTeamsDirective final : public OMPExecutableDirective { 5145 friend class ASTStmtReader; 5146 friend class OMPExecutableDirective; 5147 /// Build directive with the given start and end location. 5148 /// 5149 /// \param StartLoc Starting location of the directive kind. 5150 /// \param EndLoc Ending location of the directive. 5151 /// OMPTargetTeamsDirective(SourceLocation StartLoc,SourceLocation EndLoc)5152 OMPTargetTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5153 : OMPExecutableDirective(OMPTargetTeamsDirectiveClass, 5154 llvm::omp::OMPD_target_teams, StartLoc, EndLoc) { 5155 } 5156 5157 /// Build an empty directive. 5158 /// OMPTargetTeamsDirective()5159 explicit OMPTargetTeamsDirective() 5160 : OMPExecutableDirective(OMPTargetTeamsDirectiveClass, 5161 llvm::omp::OMPD_target_teams, SourceLocation(), 5162 SourceLocation()) {} 5163 5164 public: 5165 /// Creates directive with a list of \a Clauses. 5166 /// 5167 /// \param C AST context. 5168 /// \param StartLoc Starting location of the directive kind. 5169 /// \param EndLoc Ending Location of the directive. 5170 /// \param Clauses List of clauses. 5171 /// \param AssociatedStmt Statement, associated with the directive. 5172 /// 5173 static OMPTargetTeamsDirective *Create(const ASTContext &C, 5174 SourceLocation StartLoc, 5175 SourceLocation EndLoc, 5176 ArrayRef<OMPClause *> Clauses, 5177 Stmt *AssociatedStmt); 5178 5179 /// Creates an empty directive with the place for \a NumClauses clauses. 5180 /// 5181 /// \param C AST context. 5182 /// \param NumClauses Number of clauses. 5183 /// 5184 static OMPTargetTeamsDirective *CreateEmpty(const ASTContext &C, 5185 unsigned NumClauses, EmptyShell); 5186 classof(const Stmt * T)5187 static bool classof(const Stmt *T) { 5188 return T->getStmtClass() == OMPTargetTeamsDirectiveClass; 5189 } 5190 }; 5191 5192 /// This represents '#pragma omp target teams distribute' combined directive. 5193 /// 5194 /// \code 5195 /// #pragma omp target teams distribute private(x) 5196 /// \endcode 5197 /// In this example directive '#pragma omp target teams distribute' has clause 5198 /// 'private' with the variables 'x' 5199 /// 5200 class OMPTargetTeamsDistributeDirective final : public OMPLoopDirective { 5201 friend class ASTStmtReader; 5202 friend class OMPExecutableDirective; 5203 5204 /// Build directive with the given start and end location. 5205 /// 5206 /// \param StartLoc Starting location of the directive kind. 5207 /// \param EndLoc Ending location of the directive. 5208 /// \param CollapsedNum Number of collapsed nested loops. 5209 /// OMPTargetTeamsDistributeDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)5210 OMPTargetTeamsDistributeDirective(SourceLocation StartLoc, 5211 SourceLocation EndLoc, 5212 unsigned CollapsedNum) 5213 : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass, 5214 llvm::omp::OMPD_target_teams_distribute, StartLoc, 5215 EndLoc, CollapsedNum) {} 5216 5217 /// Build an empty directive. 5218 /// 5219 /// \param CollapsedNum Number of collapsed nested loops. 5220 /// OMPTargetTeamsDistributeDirective(unsigned CollapsedNum)5221 explicit OMPTargetTeamsDistributeDirective(unsigned CollapsedNum) 5222 : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass, 5223 llvm::omp::OMPD_target_teams_distribute, 5224 SourceLocation(), SourceLocation(), CollapsedNum) {} 5225 5226 public: 5227 /// Creates directive with a list of \a Clauses. 5228 /// 5229 /// \param C AST context. 5230 /// \param StartLoc Starting location of the directive kind. 5231 /// \param EndLoc Ending Location of the directive. 5232 /// \param CollapsedNum Number of collapsed loops. 5233 /// \param Clauses List of clauses. 5234 /// \param AssociatedStmt Statement, associated with the directive. 5235 /// \param Exprs Helper expressions for CodeGen. 5236 /// 5237 static OMPTargetTeamsDistributeDirective * 5238 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5239 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 5240 Stmt *AssociatedStmt, const HelperExprs &Exprs); 5241 5242 /// Creates an empty directive with the place for \a NumClauses clauses. 5243 /// 5244 /// \param C AST context. 5245 /// \param CollapsedNum Number of collapsed nested loops. 5246 /// \param NumClauses Number of clauses. 5247 /// 5248 static OMPTargetTeamsDistributeDirective * 5249 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 5250 EmptyShell); 5251 classof(const Stmt * T)5252 static bool classof(const Stmt *T) { 5253 return T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass; 5254 } 5255 }; 5256 5257 /// This represents '#pragma omp target teams distribute parallel for' combined 5258 /// directive. 5259 /// 5260 /// \code 5261 /// #pragma omp target teams distribute parallel for private(x) 5262 /// \endcode 5263 /// In this example directive '#pragma omp target teams distribute parallel 5264 /// for' has clause 'private' with the variables 'x' 5265 /// 5266 class OMPTargetTeamsDistributeParallelForDirective final 5267 : public OMPLoopDirective { 5268 friend class ASTStmtReader; 5269 friend class OMPExecutableDirective; 5270 /// true if the construct has inner cancel directive. 5271 bool HasCancel = false; 5272 5273 /// Build directive with the given start and end location. 5274 /// 5275 /// \param StartLoc Starting location of the directive kind. 5276 /// \param EndLoc Ending location of the directive. 5277 /// \param CollapsedNum Number of collapsed nested loops. 5278 /// OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)5279 OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc, 5280 SourceLocation EndLoc, 5281 unsigned CollapsedNum) 5282 : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass, 5283 llvm::omp::OMPD_target_teams_distribute_parallel_for, 5284 StartLoc, EndLoc, CollapsedNum) {} 5285 5286 /// Build an empty directive. 5287 /// 5288 /// \param CollapsedNum Number of collapsed nested loops. 5289 /// OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum)5290 explicit OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum) 5291 : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass, 5292 llvm::omp::OMPD_target_teams_distribute_parallel_for, 5293 SourceLocation(), SourceLocation(), CollapsedNum) {} 5294 5295 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)5296 void setTaskReductionRefExpr(Expr *E) { 5297 Data->getChildren()[numLoopChildren( 5298 getLoopsNumber(), 5299 llvm::omp::OMPD_target_teams_distribute_parallel_for)] = E; 5300 } 5301 5302 /// Set cancel state. setHasCancel(bool Has)5303 void setHasCancel(bool Has) { HasCancel = Has; } 5304 5305 public: 5306 /// Creates directive with a list of \a Clauses. 5307 /// 5308 /// \param C AST context. 5309 /// \param StartLoc Starting location of the directive kind. 5310 /// \param EndLoc Ending Location of the directive. 5311 /// \param CollapsedNum Number of collapsed loops. 5312 /// \param Clauses List of clauses. 5313 /// \param AssociatedStmt Statement, associated with the directive. 5314 /// \param Exprs Helper expressions for CodeGen. 5315 /// \param TaskRedRef Task reduction special reference expression to handle 5316 /// taskgroup descriptor. 5317 /// \param HasCancel true if this directive has inner cancel directive. 5318 /// 5319 static OMPTargetTeamsDistributeParallelForDirective * 5320 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5321 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 5322 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 5323 bool HasCancel); 5324 5325 /// Creates an empty directive with the place for \a NumClauses clauses. 5326 /// 5327 /// \param C AST context. 5328 /// \param CollapsedNum Number of collapsed nested loops. 5329 /// \param NumClauses Number of clauses. 5330 /// 5331 static OMPTargetTeamsDistributeParallelForDirective * 5332 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 5333 EmptyShell); 5334 5335 /// Returns special task reduction reference expression. getTaskReductionRefExpr()5336 Expr *getTaskReductionRefExpr() { 5337 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 5338 getLoopsNumber(), 5339 llvm::omp::OMPD_target_teams_distribute_parallel_for)]); 5340 } getTaskReductionRefExpr()5341 const Expr *getTaskReductionRefExpr() const { 5342 return const_cast<OMPTargetTeamsDistributeParallelForDirective *>(this) 5343 ->getTaskReductionRefExpr(); 5344 } 5345 5346 /// Return true if current directive has inner cancel directive. hasCancel()5347 bool hasCancel() const { return HasCancel; } 5348 classof(const Stmt * T)5349 static bool classof(const Stmt *T) { 5350 return T->getStmtClass() == 5351 OMPTargetTeamsDistributeParallelForDirectiveClass; 5352 } 5353 }; 5354 5355 /// This represents '#pragma omp target teams distribute parallel for simd' 5356 /// combined directive. 5357 /// 5358 /// \code 5359 /// #pragma omp target teams distribute parallel for simd private(x) 5360 /// \endcode 5361 /// In this example directive '#pragma omp target teams distribute parallel 5362 /// for simd' has clause 'private' with the variables 'x' 5363 /// 5364 class OMPTargetTeamsDistributeParallelForSimdDirective final 5365 : public OMPLoopDirective { 5366 friend class ASTStmtReader; 5367 friend class OMPExecutableDirective; 5368 5369 /// Build directive with the given start and end location. 5370 /// 5371 /// \param StartLoc Starting location of the directive kind. 5372 /// \param EndLoc Ending location of the directive. 5373 /// \param CollapsedNum Number of collapsed nested loops. 5374 /// OMPTargetTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)5375 OMPTargetTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc, 5376 SourceLocation EndLoc, 5377 unsigned CollapsedNum) 5378 : OMPLoopDirective( 5379 OMPTargetTeamsDistributeParallelForSimdDirectiveClass, 5380 llvm::omp::OMPD_target_teams_distribute_parallel_for_simd, StartLoc, 5381 EndLoc, CollapsedNum) {} 5382 5383 /// Build an empty directive. 5384 /// 5385 /// \param CollapsedNum Number of collapsed nested loops. 5386 /// OMPTargetTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum)5387 explicit OMPTargetTeamsDistributeParallelForSimdDirective( 5388 unsigned CollapsedNum) 5389 : OMPLoopDirective( 5390 OMPTargetTeamsDistributeParallelForSimdDirectiveClass, 5391 llvm::omp::OMPD_target_teams_distribute_parallel_for_simd, 5392 SourceLocation(), SourceLocation(), CollapsedNum) {} 5393 5394 public: 5395 /// Creates directive with a list of \a Clauses. 5396 /// 5397 /// \param C AST context. 5398 /// \param StartLoc Starting location of the directive kind. 5399 /// \param EndLoc Ending Location of the directive. 5400 /// \param CollapsedNum Number of collapsed loops. 5401 /// \param Clauses List of clauses. 5402 /// \param AssociatedStmt Statement, associated with the directive. 5403 /// \param Exprs Helper expressions for CodeGen. 5404 /// 5405 static OMPTargetTeamsDistributeParallelForSimdDirective * 5406 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5407 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 5408 Stmt *AssociatedStmt, const HelperExprs &Exprs); 5409 5410 /// Creates an empty directive with the place for \a NumClauses clauses. 5411 /// 5412 /// \param C AST context. 5413 /// \param CollapsedNum Number of collapsed nested loops. 5414 /// \param NumClauses Number of clauses. 5415 /// 5416 static OMPTargetTeamsDistributeParallelForSimdDirective * 5417 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 5418 EmptyShell); 5419 classof(const Stmt * T)5420 static bool classof(const Stmt *T) { 5421 return T->getStmtClass() == 5422 OMPTargetTeamsDistributeParallelForSimdDirectiveClass; 5423 } 5424 }; 5425 5426 /// This represents '#pragma omp target teams distribute simd' combined 5427 /// directive. 5428 /// 5429 /// \code 5430 /// #pragma omp target teams distribute simd private(x) 5431 /// \endcode 5432 /// In this example directive '#pragma omp target teams distribute simd' 5433 /// has clause 'private' with the variables 'x' 5434 /// 5435 class OMPTargetTeamsDistributeSimdDirective final : public OMPLoopDirective { 5436 friend class ASTStmtReader; 5437 friend class OMPExecutableDirective; 5438 5439 /// Build directive with the given start and end location. 5440 /// 5441 /// \param StartLoc Starting location of the directive kind. 5442 /// \param EndLoc Ending location of the directive. 5443 /// \param CollapsedNum Number of collapsed nested loops. 5444 /// OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)5445 OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc, 5446 SourceLocation EndLoc, 5447 unsigned CollapsedNum) 5448 : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass, 5449 llvm::omp::OMPD_target_teams_distribute_simd, StartLoc, 5450 EndLoc, CollapsedNum) {} 5451 5452 /// Build an empty directive. 5453 /// 5454 /// \param CollapsedNum Number of collapsed nested loops. 5455 /// OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum)5456 explicit OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum) 5457 : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass, 5458 llvm::omp::OMPD_target_teams_distribute_simd, 5459 SourceLocation(), SourceLocation(), CollapsedNum) {} 5460 5461 public: 5462 /// Creates directive with a list of \a Clauses. 5463 /// 5464 /// \param C AST context. 5465 /// \param StartLoc Starting location of the directive kind. 5466 /// \param EndLoc Ending Location of the directive. 5467 /// \param CollapsedNum Number of collapsed loops. 5468 /// \param Clauses List of clauses. 5469 /// \param AssociatedStmt Statement, associated with the directive. 5470 /// \param Exprs Helper expressions for CodeGen. 5471 /// 5472 static OMPTargetTeamsDistributeSimdDirective * 5473 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5474 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 5475 Stmt *AssociatedStmt, const HelperExprs &Exprs); 5476 5477 /// Creates an empty directive with the place for \a NumClauses clauses. 5478 /// 5479 /// \param C AST context. 5480 /// \param CollapsedNum Number of collapsed nested loops. 5481 /// \param NumClauses Number of clauses. 5482 /// 5483 static OMPTargetTeamsDistributeSimdDirective * 5484 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 5485 EmptyShell); 5486 classof(const Stmt * T)5487 static bool classof(const Stmt *T) { 5488 return T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass; 5489 } 5490 }; 5491 5492 /// This represents the '#pragma omp tile' loop transformation directive. 5493 class OMPTileDirective final : public OMPLoopTransformationDirective { 5494 friend class ASTStmtReader; 5495 friend class OMPExecutableDirective; 5496 5497 /// Default list of offsets. 5498 enum { 5499 PreInitsOffset = 0, 5500 TransformedStmtOffset, 5501 }; 5502 OMPTileDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumLoops)5503 explicit OMPTileDirective(SourceLocation StartLoc, SourceLocation EndLoc, 5504 unsigned NumLoops) 5505 : OMPLoopTransformationDirective(OMPTileDirectiveClass, 5506 llvm::omp::OMPD_tile, StartLoc, EndLoc, 5507 NumLoops) { 5508 setNumGeneratedLoops(3 * NumLoops); 5509 } 5510 setPreInits(Stmt * PreInits)5511 void setPreInits(Stmt *PreInits) { 5512 Data->getChildren()[PreInitsOffset] = PreInits; 5513 } 5514 setTransformedStmt(Stmt * S)5515 void setTransformedStmt(Stmt *S) { 5516 Data->getChildren()[TransformedStmtOffset] = S; 5517 } 5518 5519 public: 5520 /// Create a new AST node representation for '#pragma omp tile'. 5521 /// 5522 /// \param C Context of the AST. 5523 /// \param StartLoc Location of the introducer (e.g. the 'omp' token). 5524 /// \param EndLoc Location of the directive's end (e.g. the tok::eod). 5525 /// \param Clauses The directive's clauses. 5526 /// \param NumLoops Number of associated loops (number of items in the 5527 /// 'sizes' clause). 5528 /// \param AssociatedStmt The outermost associated loop. 5529 /// \param TransformedStmt The loop nest after tiling, or nullptr in 5530 /// dependent contexts. 5531 /// \param PreInits Helper preinits statements for the loop nest. 5532 static OMPTileDirective *Create(const ASTContext &C, SourceLocation StartLoc, 5533 SourceLocation EndLoc, 5534 ArrayRef<OMPClause *> Clauses, 5535 unsigned NumLoops, Stmt *AssociatedStmt, 5536 Stmt *TransformedStmt, Stmt *PreInits); 5537 5538 /// Build an empty '#pragma omp tile' AST node for deserialization. 5539 /// 5540 /// \param C Context of the AST. 5541 /// \param NumClauses Number of clauses to allocate. 5542 /// \param NumLoops Number of associated loops to allocate. 5543 static OMPTileDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 5544 unsigned NumLoops); 5545 5546 /// Gets/sets the associated loops after tiling. 5547 /// 5548 /// This is in de-sugared format stored as a CompoundStmt. 5549 /// 5550 /// \code 5551 /// for (...) 5552 /// ... 5553 /// \endcode 5554 /// 5555 /// Note that if the generated loops a become associated loops of another 5556 /// directive, they may need to be hoisted before them. getTransformedStmt()5557 Stmt *getTransformedStmt() const { 5558 return Data->getChildren()[TransformedStmtOffset]; 5559 } 5560 5561 /// Return preinits statement. getPreInits()5562 Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; } 5563 classof(const Stmt * T)5564 static bool classof(const Stmt *T) { 5565 return T->getStmtClass() == OMPTileDirectiveClass; 5566 } 5567 }; 5568 5569 /// This represents the '#pragma omp unroll' loop transformation directive. 5570 /// 5571 /// \code 5572 /// #pragma omp unroll 5573 /// for (int i = 0; i < 64; ++i) 5574 /// \endcode 5575 class OMPUnrollDirective final : public OMPLoopTransformationDirective { 5576 friend class ASTStmtReader; 5577 friend class OMPExecutableDirective; 5578 5579 /// Default list of offsets. 5580 enum { 5581 PreInitsOffset = 0, 5582 TransformedStmtOffset, 5583 }; 5584 OMPUnrollDirective(SourceLocation StartLoc,SourceLocation EndLoc)5585 explicit OMPUnrollDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5586 : OMPLoopTransformationDirective(OMPUnrollDirectiveClass, 5587 llvm::omp::OMPD_unroll, StartLoc, EndLoc, 5588 1) {} 5589 5590 /// Set the pre-init statements. setPreInits(Stmt * PreInits)5591 void setPreInits(Stmt *PreInits) { 5592 Data->getChildren()[PreInitsOffset] = PreInits; 5593 } 5594 5595 /// Set the de-sugared statement. setTransformedStmt(Stmt * S)5596 void setTransformedStmt(Stmt *S) { 5597 Data->getChildren()[TransformedStmtOffset] = S; 5598 } 5599 5600 public: 5601 /// Create a new AST node representation for '#pragma omp unroll'. 5602 /// 5603 /// \param C Context of the AST. 5604 /// \param StartLoc Location of the introducer (e.g. the 'omp' token). 5605 /// \param EndLoc Location of the directive's end (e.g. the tok::eod). 5606 /// \param Clauses The directive's clauses. 5607 /// \param AssociatedStmt The outermost associated loop. 5608 /// \param TransformedStmt The loop nest after tiling, or nullptr in 5609 /// dependent contexts. 5610 /// \param PreInits Helper preinits statements for the loop nest. 5611 static OMPUnrollDirective * 5612 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5613 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, 5614 unsigned NumGeneratedLoops, Stmt *TransformedStmt, Stmt *PreInits); 5615 5616 /// Build an empty '#pragma omp unroll' AST node for deserialization. 5617 /// 5618 /// \param C Context of the AST. 5619 /// \param NumClauses Number of clauses to allocate. 5620 static OMPUnrollDirective *CreateEmpty(const ASTContext &C, 5621 unsigned NumClauses); 5622 5623 /// Get the de-sugared associated loops after unrolling. 5624 /// 5625 /// This is only used if the unrolled loop becomes an associated loop of 5626 /// another directive, otherwise the loop is emitted directly using loop 5627 /// transformation metadata. When the unrolled loop cannot be used by another 5628 /// directive (e.g. because of the full clause), the transformed stmt can also 5629 /// be nullptr. getTransformedStmt()5630 Stmt *getTransformedStmt() const { 5631 return Data->getChildren()[TransformedStmtOffset]; 5632 } 5633 5634 /// Return the pre-init statements. getPreInits()5635 Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; } 5636 classof(const Stmt * T)5637 static bool classof(const Stmt *T) { 5638 return T->getStmtClass() == OMPUnrollDirectiveClass; 5639 } 5640 }; 5641 5642 /// This represents '#pragma omp scan' directive. 5643 /// 5644 /// \code 5645 /// #pragma omp scan inclusive(a) 5646 /// \endcode 5647 /// In this example directive '#pragma omp scan' has clause 'inclusive' with 5648 /// list item 'a'. 5649 class OMPScanDirective final : public OMPExecutableDirective { 5650 friend class ASTStmtReader; 5651 friend class OMPExecutableDirective; 5652 /// Build directive with the given start and end location. 5653 /// 5654 /// \param StartLoc Starting location of the directive kind. 5655 /// \param EndLoc Ending location of the directive. 5656 /// OMPScanDirective(SourceLocation StartLoc,SourceLocation EndLoc)5657 OMPScanDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5658 : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan, 5659 StartLoc, EndLoc) {} 5660 5661 /// Build an empty directive. 5662 /// OMPScanDirective()5663 explicit OMPScanDirective() 5664 : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan, 5665 SourceLocation(), SourceLocation()) {} 5666 5667 public: 5668 /// Creates directive with a list of \a Clauses. 5669 /// 5670 /// \param C AST context. 5671 /// \param StartLoc Starting location of the directive kind. 5672 /// \param EndLoc Ending Location of the directive. 5673 /// \param Clauses List of clauses (only single OMPFlushClause clause is 5674 /// allowed). 5675 /// 5676 static OMPScanDirective *Create(const ASTContext &C, SourceLocation StartLoc, 5677 SourceLocation EndLoc, 5678 ArrayRef<OMPClause *> Clauses); 5679 5680 /// Creates an empty directive with the place for \a NumClauses 5681 /// clauses. 5682 /// 5683 /// \param C AST context. 5684 /// \param NumClauses Number of clauses. 5685 /// 5686 static OMPScanDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 5687 EmptyShell); 5688 classof(const Stmt * T)5689 static bool classof(const Stmt *T) { 5690 return T->getStmtClass() == OMPScanDirectiveClass; 5691 } 5692 }; 5693 5694 /// This represents '#pragma omp interop' directive. 5695 /// 5696 /// \code 5697 /// #pragma omp interop init(target:obj) device(x) depend(inout:y) nowait 5698 /// \endcode 5699 /// In this example directive '#pragma omp interop' has 5700 /// clauses 'init', 'device', 'depend' and 'nowait'. 5701 /// 5702 class OMPInteropDirective final : public OMPExecutableDirective { 5703 friend class ASTStmtReader; 5704 friend class OMPExecutableDirective; 5705 5706 /// Build directive with the given start and end location. 5707 /// 5708 /// \param StartLoc Starting location of the directive. 5709 /// \param EndLoc Ending location of the directive. 5710 /// OMPInteropDirective(SourceLocation StartLoc,SourceLocation EndLoc)5711 OMPInteropDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5712 : OMPExecutableDirective(OMPInteropDirectiveClass, 5713 llvm::omp::OMPD_interop, StartLoc, EndLoc) {} 5714 5715 /// Build an empty directive. 5716 /// OMPInteropDirective()5717 explicit OMPInteropDirective() 5718 : OMPExecutableDirective(OMPInteropDirectiveClass, 5719 llvm::omp::OMPD_interop, SourceLocation(), 5720 SourceLocation()) {} 5721 5722 public: 5723 /// Creates directive. 5724 /// 5725 /// \param C AST context. 5726 /// \param StartLoc Starting location of the directive. 5727 /// \param EndLoc Ending Location of the directive. 5728 /// \param Clauses The directive's clauses. 5729 /// 5730 static OMPInteropDirective *Create(const ASTContext &C, 5731 SourceLocation StartLoc, 5732 SourceLocation EndLoc, 5733 ArrayRef<OMPClause *> Clauses); 5734 5735 /// Creates an empty directive. 5736 /// 5737 /// \param C AST context. 5738 /// 5739 static OMPInteropDirective *CreateEmpty(const ASTContext &C, 5740 unsigned NumClauses, EmptyShell); 5741 classof(const Stmt * T)5742 static bool classof(const Stmt *T) { 5743 return T->getStmtClass() == OMPInteropDirectiveClass; 5744 } 5745 }; 5746 5747 /// This represents '#pragma omp dispatch' directive. 5748 /// 5749 /// \code 5750 /// #pragma omp dispatch device(dnum) 5751 /// \endcode 5752 /// This example shows a directive '#pragma omp dispatch' with a 5753 /// device clause with variable 'dnum'. 5754 /// 5755 class OMPDispatchDirective final : public OMPExecutableDirective { 5756 friend class ASTStmtReader; 5757 friend class OMPExecutableDirective; 5758 5759 /// The location of the target-call. 5760 SourceLocation TargetCallLoc; 5761 5762 /// Set the location of the target-call. setTargetCallLoc(SourceLocation Loc)5763 void setTargetCallLoc(SourceLocation Loc) { TargetCallLoc = Loc; } 5764 5765 /// Build directive with the given start and end location. 5766 /// 5767 /// \param StartLoc Starting location of the directive kind. 5768 /// \param EndLoc Ending location of the directive. 5769 /// OMPDispatchDirective(SourceLocation StartLoc,SourceLocation EndLoc)5770 OMPDispatchDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5771 : OMPExecutableDirective(OMPDispatchDirectiveClass, 5772 llvm::omp::OMPD_dispatch, StartLoc, EndLoc) {} 5773 5774 /// Build an empty directive. 5775 /// OMPDispatchDirective()5776 explicit OMPDispatchDirective() 5777 : OMPExecutableDirective(OMPDispatchDirectiveClass, 5778 llvm::omp::OMPD_dispatch, SourceLocation(), 5779 SourceLocation()) {} 5780 5781 public: 5782 /// Creates directive with a list of \a Clauses. 5783 /// 5784 /// \param C AST context. 5785 /// \param StartLoc Starting location of the directive kind. 5786 /// \param EndLoc Ending Location of the directive. 5787 /// \param Clauses List of clauses. 5788 /// \param AssociatedStmt Statement, associated with the directive. 5789 /// \param TargetCallLoc Location of the target-call. 5790 /// 5791 static OMPDispatchDirective * 5792 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5793 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, 5794 SourceLocation TargetCallLoc); 5795 5796 /// Creates an empty directive with the place for \a NumClauses 5797 /// clauses. 5798 /// 5799 /// \param C AST context. 5800 /// \param NumClauses Number of clauses. 5801 /// 5802 static OMPDispatchDirective *CreateEmpty(const ASTContext &C, 5803 unsigned NumClauses, EmptyShell); 5804 5805 /// Return location of target-call. getTargetCallLoc()5806 SourceLocation getTargetCallLoc() const { return TargetCallLoc; } 5807 classof(const Stmt * T)5808 static bool classof(const Stmt *T) { 5809 return T->getStmtClass() == OMPDispatchDirectiveClass; 5810 } 5811 }; 5812 5813 /// This represents '#pragma omp masked' directive. 5814 /// \code 5815 /// #pragma omp masked filter(tid) 5816 /// \endcode 5817 /// This example shows a directive '#pragma omp masked' with a filter clause 5818 /// with variable 'tid'. 5819 /// 5820 class OMPMaskedDirective final : public OMPExecutableDirective { 5821 friend class ASTStmtReader; 5822 friend class OMPExecutableDirective; 5823 5824 /// Build directive with the given start and end location. 5825 /// 5826 /// \param StartLoc Starting location of the directive kind. 5827 /// \param EndLoc Ending location of the directive. 5828 /// OMPMaskedDirective(SourceLocation StartLoc,SourceLocation EndLoc)5829 OMPMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5830 : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked, 5831 StartLoc, EndLoc) {} 5832 5833 /// Build an empty directive. 5834 /// OMPMaskedDirective()5835 explicit OMPMaskedDirective() 5836 : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked, 5837 SourceLocation(), SourceLocation()) {} 5838 5839 public: 5840 /// Creates directive. 5841 /// 5842 /// \param C AST context. 5843 /// \param StartLoc Starting location of the directive kind. 5844 /// \param EndLoc Ending Location of the directive. 5845 /// \param AssociatedStmt Statement, associated with the directive. 5846 /// 5847 static OMPMaskedDirective * 5848 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5849 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 5850 5851 /// Creates an empty directive. 5852 /// 5853 /// \param C AST context. 5854 /// 5855 static OMPMaskedDirective *CreateEmpty(const ASTContext &C, 5856 unsigned NumClauses, EmptyShell); 5857 classof(const Stmt * T)5858 static bool classof(const Stmt *T) { 5859 return T->getStmtClass() == OMPMaskedDirectiveClass; 5860 } 5861 }; 5862 5863 /// This represents '#pragma omp metadirective' directive. 5864 /// 5865 /// \code 5866 /// #pragma omp metadirective when(user={condition(N>10)}: parallel for) 5867 /// \endcode 5868 /// In this example directive '#pragma omp metadirective' has clauses 'when' 5869 /// with a dynamic user condition to check if a variable 'N > 10' 5870 /// 5871 class OMPMetaDirective final : public OMPExecutableDirective { 5872 friend class ASTStmtReader; 5873 friend class OMPExecutableDirective; 5874 Stmt *IfStmt; 5875 OMPMetaDirective(SourceLocation StartLoc,SourceLocation EndLoc)5876 OMPMetaDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5877 : OMPExecutableDirective(OMPMetaDirectiveClass, 5878 llvm::omp::OMPD_metadirective, StartLoc, 5879 EndLoc) {} OMPMetaDirective()5880 explicit OMPMetaDirective() 5881 : OMPExecutableDirective(OMPMetaDirectiveClass, 5882 llvm::omp::OMPD_metadirective, SourceLocation(), 5883 SourceLocation()) {} 5884 setIfStmt(Stmt * S)5885 void setIfStmt(Stmt *S) { IfStmt = S; } 5886 5887 public: 5888 static OMPMetaDirective *Create(const ASTContext &C, SourceLocation StartLoc, 5889 SourceLocation EndLoc, 5890 ArrayRef<OMPClause *> Clauses, 5891 Stmt *AssociatedStmt, Stmt *IfStmt); 5892 static OMPMetaDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 5893 EmptyShell); getIfStmt()5894 Stmt *getIfStmt() const { return IfStmt; } 5895 classof(const Stmt * T)5896 static bool classof(const Stmt *T) { 5897 return T->getStmtClass() == OMPMetaDirectiveClass; 5898 } 5899 }; 5900 5901 /// This represents '#pragma omp loop' directive. 5902 /// 5903 /// \code 5904 /// #pragma omp loop private(a,b) binding(parallel) order(concurrent) 5905 /// \endcode 5906 /// In this example directive '#pragma omp loop' has 5907 /// clauses 'private' with the variables 'a' and 'b', 'binding' with 5908 /// modifier 'parallel' and 'order(concurrent). 5909 /// 5910 class OMPGenericLoopDirective final : public OMPLoopDirective { 5911 friend class ASTStmtReader; 5912 friend class OMPExecutableDirective; 5913 /// Build directive with the given start and end location. 5914 /// 5915 /// \param StartLoc Starting location of the directive kind. 5916 /// \param EndLoc Ending location of the directive. 5917 /// \param CollapsedNum Number of collapsed nested loops. 5918 /// OMPGenericLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)5919 OMPGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 5920 unsigned CollapsedNum) 5921 : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop, 5922 StartLoc, EndLoc, CollapsedNum) {} 5923 5924 /// Build an empty directive. 5925 /// 5926 /// \param CollapsedNum Number of collapsed nested loops. 5927 /// OMPGenericLoopDirective(unsigned CollapsedNum)5928 explicit OMPGenericLoopDirective(unsigned CollapsedNum) 5929 : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop, 5930 SourceLocation(), SourceLocation(), CollapsedNum) {} 5931 5932 public: 5933 /// Creates directive with a list of \p Clauses. 5934 /// 5935 /// \param C AST context. 5936 /// \param StartLoc Starting location of the directive kind. 5937 /// \param EndLoc Ending Location of the directive. 5938 /// \param CollapsedNum Number of collapsed loops. 5939 /// \param Clauses List of clauses. 5940 /// \param AssociatedStmt Statement, associated with the directive. 5941 /// \param Exprs Helper expressions for CodeGen. 5942 /// 5943 static OMPGenericLoopDirective * 5944 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5945 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 5946 Stmt *AssociatedStmt, const HelperExprs &Exprs); 5947 5948 /// Creates an empty directive with a place for \a NumClauses clauses. 5949 /// 5950 /// \param C AST context. 5951 /// \param NumClauses Number of clauses. 5952 /// \param CollapsedNum Number of collapsed nested loops. 5953 /// 5954 static OMPGenericLoopDirective *CreateEmpty(const ASTContext &C, 5955 unsigned NumClauses, 5956 unsigned CollapsedNum, 5957 EmptyShell); 5958 classof(const Stmt * T)5959 static bool classof(const Stmt *T) { 5960 return T->getStmtClass() == OMPGenericLoopDirectiveClass; 5961 } 5962 }; 5963 5964 /// This represents '#pragma omp teams loop' directive. 5965 /// 5966 /// \code 5967 /// #pragma omp teams loop private(a,b) order(concurrent) 5968 /// \endcode 5969 /// In this example directive '#pragma omp teams loop' has 5970 /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). 5971 /// 5972 class OMPTeamsGenericLoopDirective final : public OMPLoopDirective { 5973 friend class ASTStmtReader; 5974 friend class OMPExecutableDirective; 5975 /// Build directive with the given start and end location. 5976 /// 5977 /// \param StartLoc Starting location of the directive kind. 5978 /// \param EndLoc Ending location of the directive. 5979 /// \param CollapsedNum Number of collapsed nested loops. 5980 /// OMPTeamsGenericLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)5981 OMPTeamsGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 5982 unsigned CollapsedNum) 5983 : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass, 5984 llvm::omp::OMPD_teams_loop, StartLoc, EndLoc, 5985 CollapsedNum) {} 5986 5987 /// Build an empty directive. 5988 /// 5989 /// \param CollapsedNum Number of collapsed nested loops. 5990 /// OMPTeamsGenericLoopDirective(unsigned CollapsedNum)5991 explicit OMPTeamsGenericLoopDirective(unsigned CollapsedNum) 5992 : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass, 5993 llvm::omp::OMPD_teams_loop, SourceLocation(), 5994 SourceLocation(), CollapsedNum) {} 5995 5996 public: 5997 /// Creates directive with a list of \p Clauses. 5998 /// 5999 /// \param C AST context. 6000 /// \param StartLoc Starting location of the directive kind. 6001 /// \param EndLoc Ending Location of the directive. 6002 /// \param CollapsedNum Number of collapsed loops. 6003 /// \param Clauses List of clauses. 6004 /// \param AssociatedStmt Statement, associated with the directive. 6005 /// \param Exprs Helper expressions for CodeGen. 6006 /// 6007 static OMPTeamsGenericLoopDirective * 6008 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 6009 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 6010 Stmt *AssociatedStmt, const HelperExprs &Exprs); 6011 6012 /// Creates an empty directive with the place 6013 /// for \a NumClauses clauses. 6014 /// 6015 /// \param C AST context. 6016 /// \param CollapsedNum Number of collapsed nested loops. 6017 /// \param NumClauses Number of clauses. 6018 /// 6019 static OMPTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C, 6020 unsigned NumClauses, 6021 unsigned CollapsedNum, 6022 EmptyShell); 6023 classof(const Stmt * T)6024 static bool classof(const Stmt *T) { 6025 return T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass; 6026 } 6027 }; 6028 6029 /// This represents '#pragma omp target teams loop' directive. 6030 /// 6031 /// \code 6032 /// #pragma omp target teams loop private(a,b) order(concurrent) 6033 /// \endcode 6034 /// In this example directive '#pragma omp target teams loop' has 6035 /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). 6036 /// 6037 class OMPTargetTeamsGenericLoopDirective final : public OMPLoopDirective { 6038 friend class ASTStmtReader; 6039 friend class OMPExecutableDirective; 6040 /// Build directive with the given start and end location. 6041 /// 6042 /// \param StartLoc Starting location of the directive kind. 6043 /// \param EndLoc Ending location of the directive. 6044 /// \param CollapsedNum Number of collapsed nested loops. 6045 /// OMPTargetTeamsGenericLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)6046 OMPTargetTeamsGenericLoopDirective(SourceLocation StartLoc, 6047 SourceLocation EndLoc, 6048 unsigned CollapsedNum) 6049 : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass, 6050 llvm::omp::OMPD_target_teams_loop, StartLoc, EndLoc, 6051 CollapsedNum) {} 6052 6053 /// Build an empty directive. 6054 /// 6055 /// \param CollapsedNum Number of collapsed nested loops. 6056 /// OMPTargetTeamsGenericLoopDirective(unsigned CollapsedNum)6057 explicit OMPTargetTeamsGenericLoopDirective(unsigned CollapsedNum) 6058 : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass, 6059 llvm::omp::OMPD_target_teams_loop, SourceLocation(), 6060 SourceLocation(), CollapsedNum) {} 6061 6062 public: 6063 /// Creates directive with a list of \p Clauses. 6064 /// 6065 /// \param C AST context. 6066 /// \param StartLoc Starting location of the directive kind. 6067 /// \param EndLoc Ending Location of the directive. 6068 /// \param CollapsedNum Number of collapsed loops. 6069 /// \param Clauses List of clauses. 6070 /// \param AssociatedStmt Statement, associated with the directive. 6071 /// \param Exprs Helper expressions for CodeGen. 6072 /// 6073 static OMPTargetTeamsGenericLoopDirective * 6074 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 6075 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 6076 Stmt *AssociatedStmt, const HelperExprs &Exprs); 6077 6078 /// Creates an empty directive with the place 6079 /// for \a NumClauses clauses. 6080 /// 6081 /// \param C AST context. 6082 /// \param CollapsedNum Number of collapsed nested loops. 6083 /// \param NumClauses Number of clauses. 6084 /// 6085 static OMPTargetTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C, 6086 unsigned NumClauses, 6087 unsigned CollapsedNum, 6088 EmptyShell); 6089 classof(const Stmt * T)6090 static bool classof(const Stmt *T) { 6091 return T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass; 6092 } 6093 }; 6094 6095 /// This represents '#pragma omp parallel loop' directive. 6096 /// 6097 /// \code 6098 /// #pragma omp parallel loop private(a,b) order(concurrent) 6099 /// \endcode 6100 /// In this example directive '#pragma omp parallel loop' has 6101 /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). 6102 /// 6103 class OMPParallelGenericLoopDirective final : public OMPLoopDirective { 6104 friend class ASTStmtReader; 6105 friend class OMPExecutableDirective; 6106 /// Build directive with the given start and end location. 6107 /// 6108 /// \param StartLoc Starting location of the directive kind. 6109 /// \param EndLoc Ending location of the directive. 6110 /// \param CollapsedNum Number of collapsed nested loops. 6111 /// OMPParallelGenericLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)6112 OMPParallelGenericLoopDirective(SourceLocation StartLoc, 6113 SourceLocation EndLoc, unsigned CollapsedNum) 6114 : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass, 6115 llvm::omp::OMPD_parallel_loop, StartLoc, EndLoc, 6116 CollapsedNum) {} 6117 6118 /// Build an empty directive. 6119 /// 6120 /// \param CollapsedNum Number of collapsed nested loops. 6121 /// OMPParallelGenericLoopDirective(unsigned CollapsedNum)6122 explicit OMPParallelGenericLoopDirective(unsigned CollapsedNum) 6123 : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass, 6124 llvm::omp::OMPD_parallel_loop, SourceLocation(), 6125 SourceLocation(), CollapsedNum) {} 6126 6127 public: 6128 /// Creates directive with a list of \p Clauses. 6129 /// 6130 /// \param C AST context. 6131 /// \param StartLoc Starting location of the directive kind. 6132 /// \param EndLoc Ending Location of the directive. 6133 /// \param CollapsedNum Number of collapsed loops. 6134 /// \param Clauses List of clauses. 6135 /// \param AssociatedStmt Statement, associated with the directive. 6136 /// \param Exprs Helper expressions for CodeGen. 6137 /// 6138 static OMPParallelGenericLoopDirective * 6139 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 6140 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 6141 Stmt *AssociatedStmt, const HelperExprs &Exprs); 6142 6143 /// Creates an empty directive with the place 6144 /// for \a NumClauses clauses. 6145 /// 6146 /// \param C AST context. 6147 /// \param CollapsedNum Number of collapsed nested loops. 6148 /// \param NumClauses Number of clauses. 6149 /// 6150 static OMPParallelGenericLoopDirective *CreateEmpty(const ASTContext &C, 6151 unsigned NumClauses, 6152 unsigned CollapsedNum, 6153 EmptyShell); 6154 classof(const Stmt * T)6155 static bool classof(const Stmt *T) { 6156 return T->getStmtClass() == OMPParallelGenericLoopDirectiveClass; 6157 } 6158 }; 6159 6160 /// This represents '#pragma omp target parallel loop' directive. 6161 /// 6162 /// \code 6163 /// #pragma omp target parallel loop private(a,b) order(concurrent) 6164 /// \endcode 6165 /// In this example directive '#pragma omp target parallel loop' has 6166 /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). 6167 /// 6168 class OMPTargetParallelGenericLoopDirective final : public OMPLoopDirective { 6169 friend class ASTStmtReader; 6170 friend class OMPExecutableDirective; 6171 /// Build directive with the given start and end location. 6172 /// 6173 /// \param StartLoc Starting location of the directive kind. 6174 /// \param EndLoc Ending location of the directive. 6175 /// \param CollapsedNum Number of collapsed nested loops. 6176 /// OMPTargetParallelGenericLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)6177 OMPTargetParallelGenericLoopDirective(SourceLocation StartLoc, 6178 SourceLocation EndLoc, 6179 unsigned CollapsedNum) 6180 : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass, 6181 llvm::omp::OMPD_target_parallel_loop, StartLoc, EndLoc, 6182 CollapsedNum) {} 6183 6184 /// Build an empty directive. 6185 /// 6186 /// \param CollapsedNum Number of collapsed nested loops. 6187 /// OMPTargetParallelGenericLoopDirective(unsigned CollapsedNum)6188 explicit OMPTargetParallelGenericLoopDirective(unsigned CollapsedNum) 6189 : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass, 6190 llvm::omp::OMPD_target_parallel_loop, SourceLocation(), 6191 SourceLocation(), CollapsedNum) {} 6192 6193 public: 6194 /// Creates directive with a list of \p Clauses. 6195 /// 6196 /// \param C AST context. 6197 /// \param StartLoc Starting location of the directive kind. 6198 /// \param EndLoc Ending Location of the directive. 6199 /// \param CollapsedNum Number of collapsed loops. 6200 /// \param Clauses List of clauses. 6201 /// \param AssociatedStmt Statement, associated with the directive. 6202 /// \param Exprs Helper expressions for CodeGen. 6203 /// 6204 static OMPTargetParallelGenericLoopDirective * 6205 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 6206 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 6207 Stmt *AssociatedStmt, const HelperExprs &Exprs); 6208 6209 /// Creates an empty directive with the place 6210 /// for \a NumClauses clauses. 6211 /// 6212 /// \param C AST context. 6213 /// \param CollapsedNum Number of collapsed nested loops. 6214 /// \param NumClauses Number of clauses. 6215 /// 6216 static OMPTargetParallelGenericLoopDirective * 6217 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 6218 EmptyShell); 6219 classof(const Stmt * T)6220 static bool classof(const Stmt *T) { 6221 return T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass; 6222 } 6223 }; 6224 6225 /// This represents '#pragma omp error' directive. 6226 /// 6227 /// \code 6228 /// #pragma omp error 6229 /// \endcode 6230 class OMPErrorDirective final : public OMPExecutableDirective { 6231 friend class ASTStmtReader; 6232 friend class OMPExecutableDirective; 6233 /// Build directive with the given start and end location. 6234 /// 6235 /// \param StartLoc Starting location of the directive kind. 6236 /// \param EndLoc Ending location of the directive. 6237 /// OMPErrorDirective(SourceLocation StartLoc,SourceLocation EndLoc)6238 OMPErrorDirective(SourceLocation StartLoc, SourceLocation EndLoc) 6239 : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error, 6240 StartLoc, EndLoc) {} 6241 /// Build an empty directive. 6242 /// OMPErrorDirective()6243 explicit OMPErrorDirective() 6244 : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error, 6245 SourceLocation(), SourceLocation()) {} 6246 6247 public: 6248 /// 6249 /// \param C AST context. 6250 /// \param StartLoc Starting location of the directive kind. 6251 /// \param EndLoc Ending Location of the directive. 6252 /// \param Clauses List of clauses. 6253 /// 6254 static OMPErrorDirective *Create(const ASTContext &C, SourceLocation StartLoc, 6255 SourceLocation EndLoc, 6256 ArrayRef<OMPClause *> Clauses); 6257 6258 /// Creates an empty directive. 6259 /// 6260 /// \param C AST context. 6261 /// 6262 static OMPErrorDirective *CreateEmpty(const ASTContext &C, 6263 unsigned NumClauses, EmptyShell); 6264 classof(const Stmt * T)6265 static bool classof(const Stmt *T) { 6266 return T->getStmtClass() == OMPErrorDirectiveClass; 6267 } 6268 }; 6269 } // end namespace clang 6270 6271 #endif 6272