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