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