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