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