1 //===- StmtOpenMP.h - Classes for OpenMP directives ------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 /// \brief This file defines OpenMP AST classes for executable directives and
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_CLANG_AST_STMTOPENMP_H
16 #define LLVM_CLANG_AST_STMTOPENMP_H
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"
26 //===----------------------------------------------------------------------===//
27 // AST classes for directives.
28 //===----------------------------------------------------------------------===//
30 /// \brief This is a basic class for representing single OpenMP executable
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;
51 /// \brief Get the clauses storage.
52 MutableArrayRef<OMPClause *> getClauses() {
53 OMPClause **ClauseStorage = reinterpret_cast<OMPClause **>(
54 reinterpret_cast<char *>(this) + ClausesOffset);
55 return MutableArrayRef<OMPClause *>(ClauseStorage, NumClauses);
59 /// \brief Build instance of directive of class \a K.
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.
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::alignTo(sizeof(T), llvm::alignOf<OMPClause *>())) {}
75 /// \brief Sets the list of variables for this clause.
77 /// \param Clauses The list of clauses for the directive.
79 void setClauses(ArrayRef<OMPClause *> Clauses);
81 /// \brief Set the associated statement for the directive.
83 /// /param S Associated statement.
85 void setAssociatedStmt(Stmt *S) {
86 assert(hasAssociatedStmt() && "no associated statement.");
91 /// \brief Iterates over a filtered subrange of clauses applied to a
94 /// This iterator visits only clauses of type SpecificClause.
95 template <typename SpecificClause>
96 class specific_clause_iterator
97 : public llvm::iterator_adaptor_base<
98 specific_clause_iterator<SpecificClause>,
99 ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag,
100 const SpecificClause *, ptrdiff_t, const SpecificClause *,
101 const SpecificClause *> {
102 ArrayRef<OMPClause *>::const_iterator End;
104 void SkipToNextClause() {
105 while (this->I != End && !isa<SpecificClause>(*this->I))
110 explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses)
111 : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()),
116 const SpecificClause *operator*() const {
117 return cast<SpecificClause>(*this->I);
119 const SpecificClause *operator->() const { return **this; }
121 specific_clause_iterator &operator++() {
128 template <typename SpecificClause>
129 static llvm::iterator_range<specific_clause_iterator<SpecificClause>>
130 getClausesOfKind(ArrayRef<OMPClause *> Clauses) {
131 return {specific_clause_iterator<SpecificClause>(Clauses),
132 specific_clause_iterator<SpecificClause>(
133 llvm::makeArrayRef(Clauses.end(), 0))};
136 template <typename SpecificClause>
137 llvm::iterator_range<specific_clause_iterator<SpecificClause>>
138 getClausesOfKind() const {
139 return getClausesOfKind<SpecificClause>(clauses());
142 /// Gets a single clause of the specified kind associated with the
143 /// current directive iff there is only one clause of this kind (and assertion
144 /// is fired if there is more than one clause is associated with the
145 /// directive). Returns nullptr if no clause of this kind is associated with
147 template <typename SpecificClause>
148 const SpecificClause *getSingleClause() const {
149 auto Clauses = getClausesOfKind<SpecificClause>();
151 if (Clauses.begin() != Clauses.end()) {
152 assert(std::next(Clauses.begin()) == Clauses.end() &&
153 "There are at least 2 clauses of the specified kind");
154 return *Clauses.begin();
159 /// Returns true if the current directive has one or more clauses of a
161 template <typename SpecificClause>
162 bool hasClausesOfKind() const {
163 auto Clauses = getClausesOfKind<SpecificClause>();
164 return Clauses.begin() != Clauses.end();
167 /// \brief Returns starting location of directive kind.
168 SourceLocation getLocStart() const { return StartLoc; }
169 /// \brief Returns ending location of directive.
170 SourceLocation getLocEnd() const { return EndLoc; }
172 /// \brief Set starting location of directive kind.
174 /// \param Loc New starting location of directive.
176 void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
177 /// \brief Set ending location of directive.
179 /// \param Loc New ending location of directive.
181 void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
183 /// \brief Get number of clauses.
184 unsigned getNumClauses() const { return NumClauses; }
186 /// \brief Returns specified clause.
188 /// \param i Number of clause.
190 OMPClause *getClause(unsigned i) const { return clauses()[i]; }
192 /// \brief Returns true if directive has associated statement.
193 bool hasAssociatedStmt() const { return NumChildren > 0; }
195 /// \brief Returns statement associated with the directive.
196 Stmt *getAssociatedStmt() const {
197 assert(hasAssociatedStmt() && "no associated statement.");
198 return const_cast<Stmt *>(*child_begin());
201 OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
203 static bool classof(const Stmt *S) {
204 return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
205 S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
208 child_range children() {
209 if (!hasAssociatedStmt())
210 return child_range(child_iterator(), child_iterator());
211 Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end());
212 return child_range(ChildStorage, ChildStorage + NumChildren);
215 ArrayRef<OMPClause *> clauses() { return getClauses(); }
217 ArrayRef<OMPClause *> clauses() const {
218 return const_cast<OMPExecutableDirective *>(this)->getClauses();
222 /// \brief This represents '#pragma omp parallel' directive.
225 /// #pragma omp parallel private(a,b) reduction(+: c,d)
227 /// In this example directive '#pragma omp parallel' has clauses 'private'
228 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
229 /// variables 'c' and 'd'.
231 class OMPParallelDirective : public OMPExecutableDirective {
232 friend class ASTStmtReader;
233 /// \brief true if the construct has inner cancel directive.
236 /// \brief Build directive with the given start and end location.
238 /// \param StartLoc Starting location of the directive (directive keyword).
239 /// \param EndLoc Ending Location of the directive.
241 OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
243 : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
244 StartLoc, EndLoc, NumClauses, 1),
247 /// \brief Build an empty directive.
249 /// \param NumClauses Number of clauses.
251 explicit OMPParallelDirective(unsigned NumClauses)
252 : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
253 SourceLocation(), SourceLocation(), NumClauses,
257 /// \brief Set cancel state.
258 void setHasCancel(bool Has) { HasCancel = Has; }
261 /// \brief Creates directive with a list of \a Clauses.
263 /// \param C AST context.
264 /// \param StartLoc Starting location of the directive kind.
265 /// \param EndLoc Ending Location of the directive.
266 /// \param Clauses List of clauses.
267 /// \param AssociatedStmt Statement associated with the directive.
268 /// \param HasCancel true if this directive has inner cancel directive.
270 static OMPParallelDirective *
271 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
272 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
274 /// \brief Creates an empty directive with the place for \a N clauses.
276 /// \param C AST context.
277 /// \param NumClauses Number of clauses.
279 static OMPParallelDirective *CreateEmpty(const ASTContext &C,
280 unsigned NumClauses, EmptyShell);
282 /// \brief Return true if current directive has inner cancel directive.
283 bool hasCancel() const { return HasCancel; }
285 static bool classof(const Stmt *T) {
286 return T->getStmtClass() == OMPParallelDirectiveClass;
290 /// \brief This is a common base class for loop directives ('omp simd', 'omp
291 /// for', 'omp for simd' etc.). It is responsible for the loop code generation.
293 class OMPLoopDirective : public OMPExecutableDirective {
294 friend class ASTStmtReader;
295 /// \brief Number of collapsed loops as specified by 'collapse' clause.
296 unsigned CollapsedNum;
298 /// \brief Offsets to the stored exprs.
299 /// This enumeration contains offsets to all the pointers to children
300 /// expressions stored in OMPLoopDirective.
301 /// The first 9 children are nesessary for all the loop directives, and
302 /// the next 10 are specific to the worksharing ones.
303 /// After the fixed children, three arrays of length CollapsedNum are
304 /// allocated: loop counters, their updates and final values.
305 /// PrevLowerBound and PrevUpperBound are used to communicate blocking
306 /// information in composite constructs which require loop blocking
309 AssociatedStmtOffset = 0,
310 IterationVariableOffset = 1,
311 LastIterationOffset = 2,
312 CalcLastIterationOffset = 3,
313 PreConditionOffset = 4,
318 // The '...End' enumerators do not correspond to child expressions - they
319 // specify the offset to the end (and start of the following counters/
320 // updates/finals arrays).
322 // The following 7 exprs are used by worksharing loops only.
323 IsLastIterVariableOffset = 9,
324 LowerBoundVariableOffset = 10,
325 UpperBoundVariableOffset = 11,
326 StrideVariableOffset = 12,
327 EnsureUpperBoundOffset = 13,
328 NextLowerBoundOffset = 14,
329 NextUpperBoundOffset = 15,
330 NumIterationsOffset = 16,
331 PrevLowerBoundVariableOffset = 17,
332 PrevUpperBoundVariableOffset = 18,
333 // Offset to the end (and start of the following counters/updates/finals
334 // arrays) for worksharing loop directives.
338 /// \brief Get the counters storage.
339 MutableArrayRef<Expr *> getCounters() {
340 Expr **Storage = reinterpret_cast<Expr **>(
341 &(*(std::next(child_begin(), getArraysOffset(getDirectiveKind())))));
342 return MutableArrayRef<Expr *>(Storage, CollapsedNum);
345 /// \brief Get the private counters storage.
346 MutableArrayRef<Expr *> getPrivateCounters() {
347 Expr **Storage = reinterpret_cast<Expr **>(&*std::next(
348 child_begin(), getArraysOffset(getDirectiveKind()) + CollapsedNum));
349 return MutableArrayRef<Expr *>(Storage, CollapsedNum);
352 /// \brief Get the updates storage.
353 MutableArrayRef<Expr *> getInits() {
354 Expr **Storage = reinterpret_cast<Expr **>(
355 &*std::next(child_begin(),
356 getArraysOffset(getDirectiveKind()) + 2 * CollapsedNum));
357 return MutableArrayRef<Expr *>(Storage, CollapsedNum);
360 /// \brief Get the updates storage.
361 MutableArrayRef<Expr *> getUpdates() {
362 Expr **Storage = reinterpret_cast<Expr **>(
363 &*std::next(child_begin(),
364 getArraysOffset(getDirectiveKind()) + 3 * CollapsedNum));
365 return MutableArrayRef<Expr *>(Storage, CollapsedNum);
368 /// \brief Get the final counter updates storage.
369 MutableArrayRef<Expr *> getFinals() {
370 Expr **Storage = reinterpret_cast<Expr **>(
371 &*std::next(child_begin(),
372 getArraysOffset(getDirectiveKind()) + 4 * CollapsedNum));
373 return MutableArrayRef<Expr *>(Storage, CollapsedNum);
377 /// \brief Build instance of loop directive of class \a Kind.
379 /// \param SC Statement class.
380 /// \param Kind Kind of OpenMP directive.
381 /// \param StartLoc Starting location of the directive (directive keyword).
382 /// \param EndLoc Ending location of the directive.
383 /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
384 /// \param NumClauses Number of clauses.
385 /// \param NumSpecialChildren Number of additional directive-specific stmts.
387 template <typename T>
388 OMPLoopDirective(const T *That, StmtClass SC, OpenMPDirectiveKind Kind,
389 SourceLocation StartLoc, SourceLocation EndLoc,
390 unsigned CollapsedNum, unsigned NumClauses,
391 unsigned NumSpecialChildren = 0)
392 : OMPExecutableDirective(That, SC, Kind, StartLoc, EndLoc, NumClauses,
393 numLoopChildren(CollapsedNum, Kind) +
395 CollapsedNum(CollapsedNum) {}
397 /// \brief Offset to the start of children expression arrays.
398 static unsigned getArraysOffset(OpenMPDirectiveKind Kind) {
399 return (isOpenMPWorksharingDirective(Kind) ||
400 isOpenMPTaskLoopDirective(Kind) ||
401 isOpenMPDistributeDirective(Kind))
406 /// \brief Children number.
407 static unsigned numLoopChildren(unsigned CollapsedNum,
408 OpenMPDirectiveKind Kind) {
409 return getArraysOffset(Kind) + 5 * CollapsedNum; // Counters,
410 // PrivateCounters, Inits,
411 // Updates and Finals
414 void setIterationVariable(Expr *IV) {
415 *std::next(child_begin(), IterationVariableOffset) = IV;
417 void setLastIteration(Expr *LI) {
418 *std::next(child_begin(), LastIterationOffset) = LI;
420 void setCalcLastIteration(Expr *CLI) {
421 *std::next(child_begin(), CalcLastIterationOffset) = CLI;
423 void setPreCond(Expr *PC) {
424 *std::next(child_begin(), PreConditionOffset) = PC;
426 void setCond(Expr *Cond) {
427 *std::next(child_begin(), CondOffset) = Cond;
429 void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; }
430 void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; }
431 void setPreInits(Stmt *PreInits) {
432 *std::next(child_begin(), PreInitsOffset) = PreInits;
434 void setIsLastIterVariable(Expr *IL) {
435 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
436 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
437 isOpenMPDistributeDirective(getDirectiveKind())) &&
438 "expected worksharing loop directive");
439 *std::next(child_begin(), IsLastIterVariableOffset) = IL;
441 void setLowerBoundVariable(Expr *LB) {
442 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
443 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
444 isOpenMPDistributeDirective(getDirectiveKind())) &&
445 "expected worksharing loop directive");
446 *std::next(child_begin(), LowerBoundVariableOffset) = LB;
448 void setUpperBoundVariable(Expr *UB) {
449 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
450 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
451 isOpenMPDistributeDirective(getDirectiveKind())) &&
452 "expected worksharing loop directive");
453 *std::next(child_begin(), UpperBoundVariableOffset) = UB;
455 void setStrideVariable(Expr *ST) {
456 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
457 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
458 isOpenMPDistributeDirective(getDirectiveKind())) &&
459 "expected worksharing loop directive");
460 *std::next(child_begin(), StrideVariableOffset) = ST;
462 void setEnsureUpperBound(Expr *EUB) {
463 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
464 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
465 isOpenMPDistributeDirective(getDirectiveKind())) &&
466 "expected worksharing loop directive");
467 *std::next(child_begin(), EnsureUpperBoundOffset) = EUB;
469 void setNextLowerBound(Expr *NLB) {
470 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
471 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
472 isOpenMPDistributeDirective(getDirectiveKind())) &&
473 "expected worksharing loop directive");
474 *std::next(child_begin(), NextLowerBoundOffset) = NLB;
476 void setNextUpperBound(Expr *NUB) {
477 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
478 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
479 isOpenMPDistributeDirective(getDirectiveKind())) &&
480 "expected worksharing loop directive");
481 *std::next(child_begin(), NextUpperBoundOffset) = NUB;
483 void setNumIterations(Expr *NI) {
484 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
485 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
486 isOpenMPDistributeDirective(getDirectiveKind())) &&
487 "expected worksharing loop directive");
488 *std::next(child_begin(), NumIterationsOffset) = NI;
490 void setPrevLowerBoundVariable(Expr *PrevLB) {
491 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
492 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
493 isOpenMPDistributeDirective(getDirectiveKind())) &&
494 "expected worksharing loop directive");
495 *std::next(child_begin(), PrevLowerBoundVariableOffset) = PrevLB;
497 void setPrevUpperBoundVariable(Expr *PrevUB) {
498 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
499 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
500 isOpenMPDistributeDirective(getDirectiveKind())) &&
501 "expected worksharing loop directive");
502 *std::next(child_begin(), PrevUpperBoundVariableOffset) = PrevUB;
504 void setCounters(ArrayRef<Expr *> A);
505 void setPrivateCounters(ArrayRef<Expr *> A);
506 void setInits(ArrayRef<Expr *> A);
507 void setUpdates(ArrayRef<Expr *> A);
508 void setFinals(ArrayRef<Expr *> A);
511 /// \brief The expressions built for the OpenMP loop CodeGen for the
512 /// whole collapsed loop nest.
514 /// \brief Loop iteration variable.
515 Expr *IterationVarRef;
516 /// \brief Loop last iteration number.
518 /// \brief Loop number of iterations.
520 /// \brief Calculation of last iteration.
521 Expr *CalcLastIteration;
522 /// \brief Loop pre-condition.
524 /// \brief Loop condition.
526 /// \brief Loop iteration variable init.
528 /// \brief Loop increment.
530 /// \brief IsLastIteration - local flag variable passed to runtime.
532 /// \brief LowerBound - local variable passed to runtime.
534 /// \brief UpperBound - local variable passed to runtime.
536 /// \brief Stride - local variable passed to runtime.
538 /// \brief EnsureUpperBound -- expression LB = min(LB, NumIterations).
540 /// \brief Update of LowerBound for statically sheduled 'omp for' loops.
542 /// \brief Update of UpperBound for statically sheduled 'omp for' loops.
544 /// \brief PreviousLowerBound - local variable passed to runtime in the
545 /// enclosing schedule or null if that does not apply.
547 /// \brief PreviousUpperBound - local variable passed to runtime in the
548 /// enclosing schedule or null if that does not apply.
550 /// \brief Counters Loop counters.
551 SmallVector<Expr *, 4> Counters;
552 /// \brief PrivateCounters Loop counters.
553 SmallVector<Expr *, 4> PrivateCounters;
554 /// \brief Expressions for loop counters inits for CodeGen.
555 SmallVector<Expr *, 4> Inits;
556 /// \brief Expressions for loop counters update for CodeGen.
557 SmallVector<Expr *, 4> Updates;
558 /// \brief Final loop counter values for GodeGen.
559 SmallVector<Expr *, 4> Finals;
560 /// Init statement for all captured expressions.
563 /// \brief Check if all the expressions are built (does not check the
564 /// worksharing ones).
566 return IterationVarRef != nullptr && LastIteration != nullptr &&
567 NumIterations != nullptr && PreCond != nullptr &&
568 Cond != nullptr && Init != nullptr && Inc != nullptr;
571 /// \brief Initialize all the fields to null.
572 /// \param Size Number of elements in the counters/finals/updates arrays.
573 void clear(unsigned Size) {
574 IterationVarRef = nullptr;
575 LastIteration = nullptr;
576 CalcLastIteration = nullptr;
588 NumIterations = nullptr;
591 Counters.resize(Size);
592 PrivateCounters.resize(Size);
594 Updates.resize(Size);
596 for (unsigned i = 0; i < Size; ++i) {
597 Counters[i] = nullptr;
598 PrivateCounters[i] = nullptr;
600 Updates[i] = nullptr;
607 /// \brief Get number of collapsed loops.
608 unsigned getCollapsedNumber() const { return CollapsedNum; }
610 Expr *getIterationVariable() const {
611 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
612 *std::next(child_begin(), IterationVariableOffset)));
614 Expr *getLastIteration() const {
615 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
616 *std::next(child_begin(), LastIterationOffset)));
618 Expr *getCalcLastIteration() const {
619 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
620 *std::next(child_begin(), CalcLastIterationOffset)));
622 Expr *getPreCond() const {
623 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
624 *std::next(child_begin(), PreConditionOffset)));
626 Expr *getCond() const {
627 return const_cast<Expr *>(
628 reinterpret_cast<const Expr *>(*std::next(child_begin(), CondOffset)));
630 Expr *getInit() const {
631 return const_cast<Expr *>(
632 reinterpret_cast<const Expr *>(*std::next(child_begin(), InitOffset)));
634 Expr *getInc() const {
635 return const_cast<Expr *>(
636 reinterpret_cast<const Expr *>(*std::next(child_begin(), IncOffset)));
638 const Stmt *getPreInits() const {
639 return *std::next(child_begin(), PreInitsOffset);
641 Stmt *getPreInits() { return *std::next(child_begin(), PreInitsOffset); }
642 Expr *getIsLastIterVariable() const {
643 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
644 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
645 isOpenMPDistributeDirective(getDirectiveKind())) &&
646 "expected worksharing loop directive");
647 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
648 *std::next(child_begin(), IsLastIterVariableOffset)));
650 Expr *getLowerBoundVariable() const {
651 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
652 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
653 isOpenMPDistributeDirective(getDirectiveKind())) &&
654 "expected worksharing loop directive");
655 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
656 *std::next(child_begin(), LowerBoundVariableOffset)));
658 Expr *getUpperBoundVariable() const {
659 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
660 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
661 isOpenMPDistributeDirective(getDirectiveKind())) &&
662 "expected worksharing loop directive");
663 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
664 *std::next(child_begin(), UpperBoundVariableOffset)));
666 Expr *getStrideVariable() const {
667 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
668 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
669 isOpenMPDistributeDirective(getDirectiveKind())) &&
670 "expected worksharing loop directive");
671 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
672 *std::next(child_begin(), StrideVariableOffset)));
674 Expr *getEnsureUpperBound() const {
675 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
676 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
677 isOpenMPDistributeDirective(getDirectiveKind())) &&
678 "expected worksharing loop directive");
679 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
680 *std::next(child_begin(), EnsureUpperBoundOffset)));
682 Expr *getNextLowerBound() const {
683 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
684 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
685 isOpenMPDistributeDirective(getDirectiveKind())) &&
686 "expected worksharing loop directive");
687 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
688 *std::next(child_begin(), NextLowerBoundOffset)));
690 Expr *getNextUpperBound() const {
691 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
692 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
693 isOpenMPDistributeDirective(getDirectiveKind())) &&
694 "expected worksharing loop directive");
695 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
696 *std::next(child_begin(), NextUpperBoundOffset)));
698 Expr *getNumIterations() const {
699 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
700 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
701 isOpenMPDistributeDirective(getDirectiveKind())) &&
702 "expected worksharing loop directive");
703 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
704 *std::next(child_begin(), NumIterationsOffset)));
706 Expr *getPrevLowerBoundVariable() const {
707 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
708 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
709 isOpenMPDistributeDirective(getDirectiveKind())) &&
710 "expected worksharing loop directive");
711 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
712 *std::next(child_begin(), PrevLowerBoundVariableOffset)));
714 Expr *getPrevUpperBoundVariable() const {
715 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
716 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
717 isOpenMPDistributeDirective(getDirectiveKind())) &&
718 "expected worksharing loop directive");
719 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
720 *std::next(child_begin(), PrevUpperBoundVariableOffset)));
722 const Stmt *getBody() const {
723 // This relies on the loop form is already checked by Sema.
724 Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
725 Body = cast<ForStmt>(Body)->getBody();
726 for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) {
727 Body = Body->IgnoreContainers();
728 Body = cast<ForStmt>(Body)->getBody();
733 ArrayRef<Expr *> counters() { return getCounters(); }
735 ArrayRef<Expr *> counters() const {
736 return const_cast<OMPLoopDirective *>(this)->getCounters();
739 ArrayRef<Expr *> private_counters() { return getPrivateCounters(); }
741 ArrayRef<Expr *> private_counters() const {
742 return const_cast<OMPLoopDirective *>(this)->getPrivateCounters();
745 ArrayRef<Expr *> inits() { return getInits(); }
747 ArrayRef<Expr *> inits() const {
748 return const_cast<OMPLoopDirective *>(this)->getInits();
751 ArrayRef<Expr *> updates() { return getUpdates(); }
753 ArrayRef<Expr *> updates() const {
754 return const_cast<OMPLoopDirective *>(this)->getUpdates();
757 ArrayRef<Expr *> finals() { return getFinals(); }
759 ArrayRef<Expr *> finals() const {
760 return const_cast<OMPLoopDirective *>(this)->getFinals();
763 static bool classof(const Stmt *T) {
764 return T->getStmtClass() == OMPSimdDirectiveClass ||
765 T->getStmtClass() == OMPForDirectiveClass ||
766 T->getStmtClass() == OMPForSimdDirectiveClass ||
767 T->getStmtClass() == OMPParallelForDirectiveClass ||
768 T->getStmtClass() == OMPParallelForSimdDirectiveClass ||
769 T->getStmtClass() == OMPTaskLoopDirectiveClass ||
770 T->getStmtClass() == OMPTaskLoopSimdDirectiveClass ||
771 T->getStmtClass() == OMPDistributeDirectiveClass ||
772 T->getStmtClass() == OMPTargetParallelForDirectiveClass ||
773 T->getStmtClass() == OMPDistributeParallelForDirectiveClass ||
774 T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass ||
775 T->getStmtClass() == OMPDistributeSimdDirectiveClass ||
776 T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass;
780 /// \brief This represents '#pragma omp simd' directive.
783 /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
785 /// In this example directive '#pragma omp simd' has clauses 'private'
786 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
787 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
789 class OMPSimdDirective : public OMPLoopDirective {
790 friend class ASTStmtReader;
791 /// \brief Build directive with the given start and end location.
793 /// \param StartLoc Starting location of the directive kind.
794 /// \param EndLoc Ending location of the directive.
795 /// \param CollapsedNum Number of collapsed nested loops.
796 /// \param NumClauses Number of clauses.
798 OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
799 unsigned CollapsedNum, unsigned NumClauses)
800 : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
801 EndLoc, CollapsedNum, NumClauses) {}
803 /// \brief Build an empty directive.
805 /// \param CollapsedNum Number of collapsed nested loops.
806 /// \param NumClauses Number of clauses.
808 explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
809 : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd,
810 SourceLocation(), SourceLocation(), CollapsedNum,
814 /// \brief Creates directive with a list of \a Clauses.
816 /// \param C AST context.
817 /// \param StartLoc Starting location of the directive kind.
818 /// \param EndLoc Ending Location of the directive.
819 /// \param CollapsedNum Number of collapsed loops.
820 /// \param Clauses List of clauses.
821 /// \param AssociatedStmt Statement, associated with the directive.
822 /// \param Exprs Helper expressions for CodeGen.
824 static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
825 SourceLocation EndLoc, unsigned CollapsedNum,
826 ArrayRef<OMPClause *> Clauses,
827 Stmt *AssociatedStmt,
828 const HelperExprs &Exprs);
830 /// \brief Creates an empty directive with the place
831 /// for \a NumClauses clauses.
833 /// \param C AST context.
834 /// \param CollapsedNum Number of collapsed nested loops.
835 /// \param NumClauses Number of clauses.
837 static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
838 unsigned CollapsedNum, EmptyShell);
840 static bool classof(const Stmt *T) {
841 return T->getStmtClass() == OMPSimdDirectiveClass;
845 /// \brief This represents '#pragma omp for' directive.
848 /// #pragma omp for private(a,b) reduction(+:c,d)
850 /// In this example directive '#pragma omp for' has clauses 'private' with the
851 /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
854 class OMPForDirective : public OMPLoopDirective {
855 friend class ASTStmtReader;
857 /// \brief true if current directive has inner cancel directive.
860 /// \brief Build directive with the given start and end location.
862 /// \param StartLoc Starting location of the directive kind.
863 /// \param EndLoc Ending location of the directive.
864 /// \param CollapsedNum Number of collapsed nested loops.
865 /// \param NumClauses Number of clauses.
867 OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
868 unsigned CollapsedNum, unsigned NumClauses)
869 : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, EndLoc,
870 CollapsedNum, NumClauses),
873 /// \brief Build an empty directive.
875 /// \param CollapsedNum Number of collapsed nested loops.
876 /// \param NumClauses Number of clauses.
878 explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses)
879 : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, SourceLocation(),
880 SourceLocation(), CollapsedNum, NumClauses),
883 /// \brief Set cancel state.
884 void setHasCancel(bool Has) { HasCancel = Has; }
887 /// \brief Creates directive with a list of \a Clauses.
889 /// \param C AST context.
890 /// \param StartLoc Starting location of the directive kind.
891 /// \param EndLoc Ending Location of the directive.
892 /// \param CollapsedNum Number of collapsed loops.
893 /// \param Clauses List of clauses.
894 /// \param AssociatedStmt Statement, associated with the directive.
895 /// \param Exprs Helper expressions for CodeGen.
896 /// \param HasCancel true if current directive has inner cancel directive.
898 static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
899 SourceLocation EndLoc, unsigned CollapsedNum,
900 ArrayRef<OMPClause *> Clauses,
901 Stmt *AssociatedStmt, const HelperExprs &Exprs,
904 /// \brief Creates an empty directive with the place
905 /// for \a NumClauses clauses.
907 /// \param C AST context.
908 /// \param CollapsedNum Number of collapsed nested loops.
909 /// \param NumClauses Number of clauses.
911 static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
912 unsigned CollapsedNum, EmptyShell);
914 /// \brief Return true if current directive has inner cancel directive.
915 bool hasCancel() const { return HasCancel; }
917 static bool classof(const Stmt *T) {
918 return T->getStmtClass() == OMPForDirectiveClass;
922 /// \brief This represents '#pragma omp for simd' directive.
925 /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
927 /// In this example directive '#pragma omp for simd' has clauses 'private'
928 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
929 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
931 class OMPForSimdDirective : public OMPLoopDirective {
932 friend class ASTStmtReader;
933 /// \brief Build directive with the given start and end location.
935 /// \param StartLoc Starting location of the directive kind.
936 /// \param EndLoc Ending location of the directive.
937 /// \param CollapsedNum Number of collapsed nested loops.
938 /// \param NumClauses Number of clauses.
940 OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
941 unsigned CollapsedNum, unsigned NumClauses)
942 : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
943 StartLoc, EndLoc, CollapsedNum, NumClauses) {}
945 /// \brief Build an empty directive.
947 /// \param CollapsedNum Number of collapsed nested loops.
948 /// \param NumClauses Number of clauses.
950 explicit OMPForSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
951 : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
952 SourceLocation(), SourceLocation(), CollapsedNum,
956 /// \brief Creates directive with a list of \a Clauses.
958 /// \param C AST context.
959 /// \param StartLoc Starting location of the directive kind.
960 /// \param EndLoc Ending Location of the directive.
961 /// \param CollapsedNum Number of collapsed loops.
962 /// \param Clauses List of clauses.
963 /// \param AssociatedStmt Statement, associated with the directive.
964 /// \param Exprs Helper expressions for CodeGen.
966 static OMPForSimdDirective *
967 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
968 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
969 Stmt *AssociatedStmt, const HelperExprs &Exprs);
971 /// \brief Creates an empty directive with the place
972 /// for \a NumClauses clauses.
974 /// \param C AST context.
975 /// \param CollapsedNum Number of collapsed nested loops.
976 /// \param NumClauses Number of clauses.
978 static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
980 unsigned CollapsedNum, EmptyShell);
982 static bool classof(const Stmt *T) {
983 return T->getStmtClass() == OMPForSimdDirectiveClass;
987 /// \brief This represents '#pragma omp sections' directive.
990 /// #pragma omp sections private(a,b) reduction(+:c,d)
992 /// In this example directive '#pragma omp sections' has clauses 'private' with
993 /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
996 class OMPSectionsDirective : public OMPExecutableDirective {
997 friend class ASTStmtReader;
999 /// \brief true if current directive has inner cancel directive.
1002 /// \brief Build directive with the given start and end location.
1004 /// \param StartLoc Starting location of the directive kind.
1005 /// \param EndLoc Ending location of the directive.
1006 /// \param NumClauses Number of clauses.
1008 OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1009 unsigned NumClauses)
1010 : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
1011 StartLoc, EndLoc, NumClauses, 1),
1014 /// \brief Build an empty directive.
1016 /// \param NumClauses Number of clauses.
1018 explicit OMPSectionsDirective(unsigned NumClauses)
1019 : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
1020 SourceLocation(), SourceLocation(), NumClauses,
1024 /// \brief Set cancel state.
1025 void setHasCancel(bool Has) { HasCancel = Has; }
1028 /// \brief Creates directive with a list of \a Clauses.
1030 /// \param C AST context.
1031 /// \param StartLoc Starting location of the directive kind.
1032 /// \param EndLoc Ending Location of the directive.
1033 /// \param Clauses List of clauses.
1034 /// \param AssociatedStmt Statement, associated with the directive.
1035 /// \param HasCancel true if current directive has inner directive.
1037 static OMPSectionsDirective *
1038 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1039 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
1041 /// \brief Creates an empty directive with the place for \a NumClauses
1044 /// \param C AST context.
1045 /// \param NumClauses Number of clauses.
1047 static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
1048 unsigned NumClauses, EmptyShell);
1050 /// \brief Return true if current directive has inner cancel directive.
1051 bool hasCancel() const { return HasCancel; }
1053 static bool classof(const Stmt *T) {
1054 return T->getStmtClass() == OMPSectionsDirectiveClass;
1058 /// \brief This represents '#pragma omp section' directive.
1061 /// #pragma omp section
1064 class OMPSectionDirective : public OMPExecutableDirective {
1065 friend class ASTStmtReader;
1067 /// \brief true if current directive has inner cancel directive.
1070 /// \brief Build directive with the given start and end location.
1072 /// \param StartLoc Starting location of the directive kind.
1073 /// \param EndLoc Ending location of the directive.
1075 OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1076 : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
1077 StartLoc, EndLoc, 0, 1),
1080 /// \brief Build an empty directive.
1082 explicit OMPSectionDirective()
1083 : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
1084 SourceLocation(), SourceLocation(), 0, 1),
1088 /// \brief Creates directive.
1090 /// \param C AST context.
1091 /// \param StartLoc Starting location of the directive kind.
1092 /// \param EndLoc Ending Location of the directive.
1093 /// \param AssociatedStmt Statement, associated with the directive.
1094 /// \param HasCancel true if current directive has inner directive.
1096 static OMPSectionDirective *Create(const ASTContext &C,
1097 SourceLocation StartLoc,
1098 SourceLocation EndLoc,
1099 Stmt *AssociatedStmt, bool HasCancel);
1101 /// \brief Creates an empty directive.
1103 /// \param C AST context.
1105 static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1107 /// \brief Set cancel state.
1108 void setHasCancel(bool Has) { HasCancel = Has; }
1110 /// \brief Return true if current directive has inner cancel directive.
1111 bool hasCancel() const { return HasCancel; }
1113 static bool classof(const Stmt *T) {
1114 return T->getStmtClass() == OMPSectionDirectiveClass;
1118 /// \brief This represents '#pragma omp single' directive.
1121 /// #pragma omp single private(a,b) copyprivate(c,d)
1123 /// In this example directive '#pragma omp single' has clauses 'private' with
1124 /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
1126 class OMPSingleDirective : public OMPExecutableDirective {
1127 friend class ASTStmtReader;
1128 /// \brief Build directive with the given start and end location.
1130 /// \param StartLoc Starting location of the directive kind.
1131 /// \param EndLoc Ending location of the directive.
1132 /// \param NumClauses Number of clauses.
1134 OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1135 unsigned NumClauses)
1136 : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
1137 StartLoc, EndLoc, NumClauses, 1) {}
1139 /// \brief Build an empty directive.
1141 /// \param NumClauses Number of clauses.
1143 explicit OMPSingleDirective(unsigned NumClauses)
1144 : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
1145 SourceLocation(), SourceLocation(), NumClauses,
1149 /// \brief Creates directive with a list of \a Clauses.
1151 /// \param C AST context.
1152 /// \param StartLoc Starting location of the directive kind.
1153 /// \param EndLoc Ending Location of the directive.
1154 /// \param Clauses List of clauses.
1155 /// \param AssociatedStmt Statement, associated with the directive.
1157 static OMPSingleDirective *
1158 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1159 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1161 /// \brief Creates an empty directive with the place for \a NumClauses
1164 /// \param C AST context.
1165 /// \param NumClauses Number of clauses.
1167 static OMPSingleDirective *CreateEmpty(const ASTContext &C,
1168 unsigned NumClauses, EmptyShell);
1170 static bool classof(const Stmt *T) {
1171 return T->getStmtClass() == OMPSingleDirectiveClass;
1175 /// \brief This represents '#pragma omp master' directive.
1178 /// #pragma omp master
1181 class OMPMasterDirective : public OMPExecutableDirective {
1182 friend class ASTStmtReader;
1183 /// \brief Build directive with the given start and end location.
1185 /// \param StartLoc Starting location of the directive kind.
1186 /// \param EndLoc Ending location of the directive.
1188 OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1189 : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
1190 StartLoc, EndLoc, 0, 1) {}
1192 /// \brief Build an empty directive.
1194 explicit OMPMasterDirective()
1195 : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
1196 SourceLocation(), SourceLocation(), 0, 1) {}
1199 /// \brief Creates directive.
1201 /// \param C AST context.
1202 /// \param StartLoc Starting location of the directive kind.
1203 /// \param EndLoc Ending Location of the directive.
1204 /// \param AssociatedStmt Statement, associated with the directive.
1206 static OMPMasterDirective *Create(const ASTContext &C,
1207 SourceLocation StartLoc,
1208 SourceLocation EndLoc,
1209 Stmt *AssociatedStmt);
1211 /// \brief Creates an empty directive.
1213 /// \param C AST context.
1215 static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1217 static bool classof(const Stmt *T) {
1218 return T->getStmtClass() == OMPMasterDirectiveClass;
1222 /// \brief This represents '#pragma omp critical' directive.
1225 /// #pragma omp critical
1228 class OMPCriticalDirective : public OMPExecutableDirective {
1229 friend class ASTStmtReader;
1230 /// \brief Name of the directive.
1231 DeclarationNameInfo DirName;
1232 /// \brief Build directive with the given start and end location.
1234 /// \param Name Name of the directive.
1235 /// \param StartLoc Starting location of the directive kind.
1236 /// \param EndLoc Ending location of the directive.
1237 /// \param NumClauses Number of clauses.
1239 OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
1240 SourceLocation EndLoc, unsigned NumClauses)
1241 : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
1242 StartLoc, EndLoc, NumClauses, 1),
1245 /// \brief Build an empty directive.
1247 /// \param NumClauses Number of clauses.
1249 explicit OMPCriticalDirective(unsigned NumClauses)
1250 : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
1251 SourceLocation(), SourceLocation(), NumClauses,
1255 /// \brief Set name of the directive.
1257 /// \param Name Name of the directive.
1259 void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
1262 /// \brief Creates directive.
1264 /// \param C AST context.
1265 /// \param Name Name of the directive.
1266 /// \param StartLoc Starting location of the directive kind.
1267 /// \param EndLoc Ending Location of the directive.
1268 /// \param Clauses List of clauses.
1269 /// \param AssociatedStmt Statement, associated with the directive.
1271 static OMPCriticalDirective *
1272 Create(const ASTContext &C, const DeclarationNameInfo &Name,
1273 SourceLocation StartLoc, SourceLocation EndLoc,
1274 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1276 /// \brief Creates an empty directive.
1278 /// \param C AST context.
1279 /// \param NumClauses Number of clauses.
1281 static OMPCriticalDirective *CreateEmpty(const ASTContext &C,
1282 unsigned NumClauses, EmptyShell);
1284 /// \brief Return name of the directive.
1286 DeclarationNameInfo getDirectiveName() const { return DirName; }
1288 static bool classof(const Stmt *T) {
1289 return T->getStmtClass() == OMPCriticalDirectiveClass;
1293 /// \brief This represents '#pragma omp parallel for' directive.
1296 /// #pragma omp parallel for private(a,b) reduction(+:c,d)
1298 /// In this example directive '#pragma omp parallel for' has clauses 'private'
1299 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
1300 /// variables 'c' and 'd'.
1302 class OMPParallelForDirective : public OMPLoopDirective {
1303 friend class ASTStmtReader;
1305 /// \brief true if current region has inner cancel directive.
1308 /// \brief Build directive with the given start and end location.
1310 /// \param StartLoc Starting location of the directive kind.
1311 /// \param EndLoc Ending location of the directive.
1312 /// \param CollapsedNum Number of collapsed nested loops.
1313 /// \param NumClauses Number of clauses.
1315 OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1316 unsigned CollapsedNum, unsigned NumClauses)
1317 : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
1318 StartLoc, EndLoc, CollapsedNum, NumClauses),
1321 /// \brief Build an empty directive.
1323 /// \param CollapsedNum Number of collapsed nested loops.
1324 /// \param NumClauses Number of clauses.
1326 explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses)
1327 : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
1328 SourceLocation(), SourceLocation(), CollapsedNum,
1332 /// \brief Set cancel state.
1333 void setHasCancel(bool Has) { HasCancel = Has; }
1336 /// \brief Creates directive with a list of \a Clauses.
1338 /// \param C AST context.
1339 /// \param StartLoc Starting location of the directive kind.
1340 /// \param EndLoc Ending Location of the directive.
1341 /// \param CollapsedNum Number of collapsed loops.
1342 /// \param Clauses List of clauses.
1343 /// \param AssociatedStmt Statement, associated with the directive.
1344 /// \param Exprs Helper expressions for CodeGen.
1345 /// \param HasCancel true if current directive has inner cancel directive.
1347 static OMPParallelForDirective *
1348 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1349 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1350 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
1352 /// \brief Creates an empty directive with the place
1353 /// for \a NumClauses clauses.
1355 /// \param C AST context.
1356 /// \param CollapsedNum Number of collapsed nested loops.
1357 /// \param NumClauses Number of clauses.
1359 static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
1360 unsigned NumClauses,
1361 unsigned CollapsedNum,
1364 /// \brief Return true if current directive has inner cancel directive.
1365 bool hasCancel() const { return HasCancel; }
1367 static bool classof(const Stmt *T) {
1368 return T->getStmtClass() == OMPParallelForDirectiveClass;
1372 /// \brief This represents '#pragma omp parallel for simd' directive.
1375 /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
1377 /// In this example directive '#pragma omp parallel for simd' has clauses
1378 /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
1379 /// and linear step 's', 'reduction' with operator '+' and variables 'c' and
1382 class OMPParallelForSimdDirective : public OMPLoopDirective {
1383 friend class ASTStmtReader;
1384 /// \brief Build directive with the given start and end location.
1386 /// \param StartLoc Starting location of the directive kind.
1387 /// \param EndLoc Ending location of the directive.
1388 /// \param CollapsedNum Number of collapsed nested loops.
1389 /// \param NumClauses Number of clauses.
1391 OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1392 unsigned CollapsedNum, unsigned NumClauses)
1393 : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
1394 OMPD_parallel_for_simd, StartLoc, EndLoc, CollapsedNum,
1397 /// \brief Build an empty directive.
1399 /// \param CollapsedNum Number of collapsed nested loops.
1400 /// \param NumClauses Number of clauses.
1402 explicit OMPParallelForSimdDirective(unsigned CollapsedNum,
1403 unsigned NumClauses)
1404 : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
1405 OMPD_parallel_for_simd, SourceLocation(),
1406 SourceLocation(), CollapsedNum, NumClauses) {}
1409 /// \brief Creates directive with a list of \a Clauses.
1411 /// \param C AST context.
1412 /// \param StartLoc Starting location of the directive kind.
1413 /// \param EndLoc Ending Location of the directive.
1414 /// \param CollapsedNum Number of collapsed loops.
1415 /// \param Clauses List of clauses.
1416 /// \param AssociatedStmt Statement, associated with the directive.
1417 /// \param Exprs Helper expressions for CodeGen.
1419 static OMPParallelForSimdDirective *
1420 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1421 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1422 Stmt *AssociatedStmt, const HelperExprs &Exprs);
1424 /// \brief Creates an empty directive with the place
1425 /// for \a NumClauses clauses.
1427 /// \param C AST context.
1428 /// \param CollapsedNum Number of collapsed nested loops.
1429 /// \param NumClauses Number of clauses.
1431 static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
1432 unsigned NumClauses,
1433 unsigned CollapsedNum,
1436 static bool classof(const Stmt *T) {
1437 return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
1441 /// \brief This represents '#pragma omp parallel sections' directive.
1444 /// #pragma omp parallel sections private(a,b) reduction(+:c,d)
1446 /// In this example directive '#pragma omp parallel sections' has clauses
1447 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
1448 /// and variables 'c' and 'd'.
1450 class OMPParallelSectionsDirective : public OMPExecutableDirective {
1451 friend class ASTStmtReader;
1453 /// \brief true if current directive has inner cancel directive.
1456 /// \brief Build directive with the given start and end location.
1458 /// \param StartLoc Starting location of the directive kind.
1459 /// \param EndLoc Ending location of the directive.
1460 /// \param NumClauses Number of clauses.
1462 OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1463 unsigned NumClauses)
1464 : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
1465 OMPD_parallel_sections, StartLoc, EndLoc,
1469 /// \brief Build an empty directive.
1471 /// \param NumClauses Number of clauses.
1473 explicit OMPParallelSectionsDirective(unsigned NumClauses)
1474 : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
1475 OMPD_parallel_sections, SourceLocation(),
1476 SourceLocation(), NumClauses, 1),
1479 /// \brief Set cancel state.
1480 void setHasCancel(bool Has) { HasCancel = Has; }
1483 /// \brief Creates directive with a list of \a Clauses.
1485 /// \param C AST context.
1486 /// \param StartLoc Starting location of the directive kind.
1487 /// \param EndLoc Ending Location of the directive.
1488 /// \param Clauses List of clauses.
1489 /// \param AssociatedStmt Statement, associated with the directive.
1490 /// \param HasCancel true if current directive has inner cancel directive.
1492 static OMPParallelSectionsDirective *
1493 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1494 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
1496 /// \brief Creates an empty directive with the place for \a NumClauses
1499 /// \param C AST context.
1500 /// \param NumClauses Number of clauses.
1502 static OMPParallelSectionsDirective *
1503 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
1505 /// \brief Return true if current directive has inner cancel directive.
1506 bool hasCancel() const { return HasCancel; }
1508 static bool classof(const Stmt *T) {
1509 return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
1513 /// \brief This represents '#pragma omp task' directive.
1516 /// #pragma omp task private(a,b) final(d)
1518 /// In this example directive '#pragma omp task' has clauses 'private' with the
1519 /// variables 'a' and 'b' and 'final' with condition 'd'.
1521 class OMPTaskDirective : public OMPExecutableDirective {
1522 friend class ASTStmtReader;
1523 /// \brief true if this directive has inner cancel directive.
1526 /// \brief Build directive with the given start and end location.
1528 /// \param StartLoc Starting location of the directive kind.
1529 /// \param EndLoc Ending location of the directive.
1530 /// \param NumClauses Number of clauses.
1532 OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1533 unsigned NumClauses)
1534 : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc,
1535 EndLoc, NumClauses, 1),
1538 /// \brief Build an empty directive.
1540 /// \param NumClauses Number of clauses.
1542 explicit OMPTaskDirective(unsigned NumClauses)
1543 : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task,
1544 SourceLocation(), SourceLocation(), NumClauses,
1548 /// \brief Set cancel state.
1549 void setHasCancel(bool Has) { HasCancel = Has; }
1552 /// \brief Creates directive with a list of \a Clauses.
1554 /// \param C AST context.
1555 /// \param StartLoc Starting location of the directive kind.
1556 /// \param EndLoc Ending Location of the directive.
1557 /// \param Clauses List of clauses.
1558 /// \param AssociatedStmt Statement, associated with the directive.
1559 /// \param HasCancel true, if current directive has inner cancel directive.
1561 static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1562 SourceLocation EndLoc,
1563 ArrayRef<OMPClause *> Clauses,
1564 Stmt *AssociatedStmt, bool HasCancel);
1566 /// \brief Creates an empty directive with the place for \a NumClauses
1569 /// \param C AST context.
1570 /// \param NumClauses Number of clauses.
1572 static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1575 /// \brief Return true if current directive has inner cancel directive.
1576 bool hasCancel() const { return HasCancel; }
1578 static bool classof(const Stmt *T) {
1579 return T->getStmtClass() == OMPTaskDirectiveClass;
1583 /// \brief This represents '#pragma omp taskyield' directive.
1586 /// #pragma omp taskyield
1589 class OMPTaskyieldDirective : public OMPExecutableDirective {
1590 friend class ASTStmtReader;
1591 /// \brief Build directive with the given start and end location.
1593 /// \param StartLoc Starting location of the directive kind.
1594 /// \param EndLoc Ending location of the directive.
1596 OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1597 : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
1598 StartLoc, EndLoc, 0, 0) {}
1600 /// \brief Build an empty directive.
1602 explicit OMPTaskyieldDirective()
1603 : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
1604 SourceLocation(), SourceLocation(), 0, 0) {}
1607 /// \brief Creates directive.
1609 /// \param C AST context.
1610 /// \param StartLoc Starting location of the directive kind.
1611 /// \param EndLoc Ending Location of the directive.
1613 static OMPTaskyieldDirective *
1614 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1616 /// \brief Creates an empty directive.
1618 /// \param C AST context.
1620 static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1622 static bool classof(const Stmt *T) {
1623 return T->getStmtClass() == OMPTaskyieldDirectiveClass;
1627 /// \brief This represents '#pragma omp barrier' directive.
1630 /// #pragma omp barrier
1633 class OMPBarrierDirective : public OMPExecutableDirective {
1634 friend class ASTStmtReader;
1635 /// \brief Build directive with the given start and end location.
1637 /// \param StartLoc Starting location of the directive kind.
1638 /// \param EndLoc Ending location of the directive.
1640 OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1641 : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
1642 StartLoc, EndLoc, 0, 0) {}
1644 /// \brief Build an empty directive.
1646 explicit OMPBarrierDirective()
1647 : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
1648 SourceLocation(), SourceLocation(), 0, 0) {}
1651 /// \brief Creates directive.
1653 /// \param C AST context.
1654 /// \param StartLoc Starting location of the directive kind.
1655 /// \param EndLoc Ending Location of the directive.
1657 static OMPBarrierDirective *
1658 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1660 /// \brief Creates an empty directive.
1662 /// \param C AST context.
1664 static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1666 static bool classof(const Stmt *T) {
1667 return T->getStmtClass() == OMPBarrierDirectiveClass;
1671 /// \brief This represents '#pragma omp taskwait' directive.
1674 /// #pragma omp taskwait
1677 class OMPTaskwaitDirective : public OMPExecutableDirective {
1678 friend class ASTStmtReader;
1679 /// \brief Build directive with the given start and end location.
1681 /// \param StartLoc Starting location of the directive kind.
1682 /// \param EndLoc Ending location of the directive.
1684 OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1685 : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
1686 StartLoc, EndLoc, 0, 0) {}
1688 /// \brief Build an empty directive.
1690 explicit OMPTaskwaitDirective()
1691 : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
1692 SourceLocation(), SourceLocation(), 0, 0) {}
1695 /// \brief Creates directive.
1697 /// \param C AST context.
1698 /// \param StartLoc Starting location of the directive kind.
1699 /// \param EndLoc Ending Location of the directive.
1701 static OMPTaskwaitDirective *
1702 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1704 /// \brief Creates an empty directive.
1706 /// \param C AST context.
1708 static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1710 static bool classof(const Stmt *T) {
1711 return T->getStmtClass() == OMPTaskwaitDirectiveClass;
1715 /// \brief This represents '#pragma omp taskgroup' directive.
1718 /// #pragma omp taskgroup
1721 class OMPTaskgroupDirective : public OMPExecutableDirective {
1722 friend class ASTStmtReader;
1723 /// \brief Build directive with the given start and end location.
1725 /// \param StartLoc Starting location of the directive kind.
1726 /// \param EndLoc Ending location of the directive.
1728 OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1729 : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
1730 StartLoc, EndLoc, 0, 1) {}
1732 /// \brief Build an empty directive.
1734 explicit OMPTaskgroupDirective()
1735 : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
1736 SourceLocation(), SourceLocation(), 0, 1) {}
1739 /// \brief Creates directive.
1741 /// \param C AST context.
1742 /// \param StartLoc Starting location of the directive kind.
1743 /// \param EndLoc Ending Location of the directive.
1744 /// \param AssociatedStmt Statement, associated with the directive.
1746 static OMPTaskgroupDirective *Create(const ASTContext &C,
1747 SourceLocation StartLoc,
1748 SourceLocation EndLoc,
1749 Stmt *AssociatedStmt);
1751 /// \brief Creates an empty directive.
1753 /// \param C AST context.
1755 static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1757 static bool classof(const Stmt *T) {
1758 return T->getStmtClass() == OMPTaskgroupDirectiveClass;
1762 /// \brief This represents '#pragma omp flush' directive.
1765 /// #pragma omp flush(a,b)
1767 /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
1769 /// 'omp flush' directive does not have clauses but have an optional list of
1770 /// variables to flush. This list of variables is stored within some fake clause
1772 class OMPFlushDirective : public OMPExecutableDirective {
1773 friend class ASTStmtReader;
1774 /// \brief Build directive with the given start and end location.
1776 /// \param StartLoc Starting location of the directive kind.
1777 /// \param EndLoc Ending location of the directive.
1778 /// \param NumClauses Number of clauses.
1780 OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1781 unsigned NumClauses)
1782 : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
1783 StartLoc, EndLoc, NumClauses, 0) {}
1785 /// \brief Build an empty directive.
1787 /// \param NumClauses Number of clauses.
1789 explicit OMPFlushDirective(unsigned NumClauses)
1790 : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
1791 SourceLocation(), SourceLocation(), NumClauses,
1795 /// \brief Creates directive with a list of \a Clauses.
1797 /// \param C AST context.
1798 /// \param StartLoc Starting location of the directive kind.
1799 /// \param EndLoc Ending Location of the directive.
1800 /// \param Clauses List of clauses (only single OMPFlushClause clause is
1803 static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1804 SourceLocation EndLoc,
1805 ArrayRef<OMPClause *> Clauses);
1807 /// \brief Creates an empty directive with the place for \a NumClauses
1810 /// \param C AST context.
1811 /// \param NumClauses Number of clauses.
1813 static OMPFlushDirective *CreateEmpty(const ASTContext &C,
1814 unsigned NumClauses, EmptyShell);
1816 static bool classof(const Stmt *T) {
1817 return T->getStmtClass() == OMPFlushDirectiveClass;
1821 /// \brief This represents '#pragma omp ordered' directive.
1824 /// #pragma omp ordered
1827 class OMPOrderedDirective : public OMPExecutableDirective {
1828 friend class ASTStmtReader;
1829 /// \brief Build directive with the given start and end location.
1831 /// \param StartLoc Starting location of the directive kind.
1832 /// \param EndLoc Ending location of the directive.
1833 /// \param NumClauses Number of clauses.
1835 OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1836 unsigned NumClauses)
1837 : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
1838 StartLoc, EndLoc, NumClauses, 1) {}
1840 /// \brief Build an empty directive.
1842 /// \param NumClauses Number of clauses.
1844 explicit OMPOrderedDirective(unsigned NumClauses)
1845 : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
1846 SourceLocation(), SourceLocation(), NumClauses,
1850 /// \brief Creates directive.
1852 /// \param C AST context.
1853 /// \param StartLoc Starting location of the directive kind.
1854 /// \param EndLoc Ending Location of the directive.
1855 /// \param Clauses List of clauses.
1856 /// \param AssociatedStmt Statement, associated with the directive.
1858 static OMPOrderedDirective *
1859 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1860 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1862 /// \brief Creates an empty directive.
1864 /// \param C AST context.
1865 /// \param NumClauses Number of clauses.
1867 static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
1868 unsigned NumClauses, EmptyShell);
1870 static bool classof(const Stmt *T) {
1871 return T->getStmtClass() == OMPOrderedDirectiveClass;
1875 /// \brief This represents '#pragma omp atomic' directive.
1878 /// #pragma omp atomic capture
1880 /// In this example directive '#pragma omp atomic' has clause 'capture'.
1882 class OMPAtomicDirective : public OMPExecutableDirective {
1883 friend class ASTStmtReader;
1884 /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
1885 /// have atomic expressions of forms
1887 /// x = x binop expr;
1888 /// x = expr binop x;
1890 /// This field is true for the first form of the expression and false for the
1891 /// second. Required for correct codegen of non-associative operations (like
1893 bool IsXLHSInRHSPart;
1894 /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
1895 /// have atomic expressions of forms
1897 /// v = x; <update x>;
1898 /// <update x>; v = x;
1900 /// This field is true for the first(postfix) form of the expression and false
1902 bool IsPostfixUpdate;
1904 /// \brief Build directive with the given start and end location.
1906 /// \param StartLoc Starting location of the directive kind.
1907 /// \param EndLoc Ending location of the directive.
1908 /// \param NumClauses Number of clauses.
1910 OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1911 unsigned NumClauses)
1912 : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
1913 StartLoc, EndLoc, NumClauses, 5),
1914 IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
1916 /// \brief Build an empty directive.
1918 /// \param NumClauses Number of clauses.
1920 explicit OMPAtomicDirective(unsigned NumClauses)
1921 : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
1922 SourceLocation(), SourceLocation(), NumClauses,
1924 IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
1926 /// \brief Set 'x' part of the associated expression/statement.
1927 void setX(Expr *X) { *std::next(child_begin()) = X; }
1928 /// \brief Set helper expression of the form
1929 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
1930 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
1931 void setUpdateExpr(Expr *UE) { *std::next(child_begin(), 2) = UE; }
1932 /// \brief Set 'v' part of the associated expression/statement.
1933 void setV(Expr *V) { *std::next(child_begin(), 3) = V; }
1934 /// \brief Set 'expr' part of the associated expression/statement.
1935 void setExpr(Expr *E) { *std::next(child_begin(), 4) = E; }
1938 /// \brief Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
1939 /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
1940 /// detailed description of 'x', 'v' and 'expr').
1942 /// \param C AST context.
1943 /// \param StartLoc Starting location of the directive kind.
1944 /// \param EndLoc Ending Location of the directive.
1945 /// \param Clauses List of clauses.
1946 /// \param AssociatedStmt Statement, associated with the directive.
1947 /// \param X 'x' part of the associated expression/statement.
1948 /// \param V 'v' part of the associated expression/statement.
1949 /// \param E 'expr' part of the associated expression/statement.
1950 /// \param UE Helper expression of the form
1951 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
1952 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
1953 /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the
1955 /// \param IsPostfixUpdate true if original value of 'x' must be stored in
1956 /// 'v', not an updated one.
1957 static OMPAtomicDirective *
1958 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1959 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V,
1960 Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate);
1962 /// \brief Creates an empty directive with the place for \a NumClauses
1965 /// \param C AST context.
1966 /// \param NumClauses Number of clauses.
1968 static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
1969 unsigned NumClauses, EmptyShell);
1971 /// \brief Get 'x' part of the associated expression/statement.
1972 Expr *getX() { return cast_or_null<Expr>(*std::next(child_begin())); }
1973 const Expr *getX() const {
1974 return cast_or_null<Expr>(*std::next(child_begin()));
1976 /// \brief Get helper expression of the form
1977 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
1978 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
1979 Expr *getUpdateExpr() {
1980 return cast_or_null<Expr>(*std::next(child_begin(), 2));
1982 const Expr *getUpdateExpr() const {
1983 return cast_or_null<Expr>(*std::next(child_begin(), 2));
1985 /// \brief Return true if helper update expression has form
1986 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
1987 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
1988 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
1989 /// \brief Return true if 'v' expression must be updated to original value of
1990 /// 'x', false if 'v' must be updated to the new value of 'x'.
1991 bool isPostfixUpdate() const { return IsPostfixUpdate; }
1992 /// \brief Get 'v' part of the associated expression/statement.
1993 Expr *getV() { return cast_or_null<Expr>(*std::next(child_begin(), 3)); }
1994 const Expr *getV() const {
1995 return cast_or_null<Expr>(*std::next(child_begin(), 3));
1997 /// \brief Get 'expr' part of the associated expression/statement.
1998 Expr *getExpr() { return cast_or_null<Expr>(*std::next(child_begin(), 4)); }
1999 const Expr *getExpr() const {
2000 return cast_or_null<Expr>(*std::next(child_begin(), 4));
2003 static bool classof(const Stmt *T) {
2004 return T->getStmtClass() == OMPAtomicDirectiveClass;
2008 /// \brief This represents '#pragma omp target' directive.
2011 /// #pragma omp target if(a)
2013 /// In this example directive '#pragma omp target' has clause 'if' with
2016 class OMPTargetDirective : public OMPExecutableDirective {
2017 friend class ASTStmtReader;
2018 /// \brief Build directive with the given start and end location.
2020 /// \param StartLoc Starting location of the directive kind.
2021 /// \param EndLoc Ending location of the directive.
2022 /// \param NumClauses Number of clauses.
2024 OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2025 unsigned NumClauses)
2026 : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
2027 StartLoc, EndLoc, NumClauses, 1) {}
2029 /// \brief Build an empty directive.
2031 /// \param NumClauses Number of clauses.
2033 explicit OMPTargetDirective(unsigned NumClauses)
2034 : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
2035 SourceLocation(), SourceLocation(), NumClauses,
2039 /// \brief Creates directive with a list of \a Clauses.
2041 /// \param C AST context.
2042 /// \param StartLoc Starting location of the directive kind.
2043 /// \param EndLoc Ending Location of the directive.
2044 /// \param Clauses List of clauses.
2045 /// \param AssociatedStmt Statement, associated with the directive.
2047 static OMPTargetDirective *
2048 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2049 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2051 /// \brief Creates an empty directive with the place for \a NumClauses
2054 /// \param C AST context.
2055 /// \param NumClauses Number of clauses.
2057 static OMPTargetDirective *CreateEmpty(const ASTContext &C,
2058 unsigned NumClauses, EmptyShell);
2060 static bool classof(const Stmt *T) {
2061 return T->getStmtClass() == OMPTargetDirectiveClass;
2065 /// \brief This represents '#pragma omp target data' directive.
2068 /// #pragma omp target data device(0) if(a) map(b[:])
2070 /// In this example directive '#pragma omp target data' has clauses 'device'
2071 /// with the value '0', 'if' with condition 'a' and 'map' with array
2074 class OMPTargetDataDirective : public OMPExecutableDirective {
2075 friend class ASTStmtReader;
2076 /// \brief Build directive with the given start and end location.
2078 /// \param StartLoc Starting location of the directive kind.
2079 /// \param EndLoc Ending Location of the directive.
2080 /// \param NumClauses The number of clauses.
2082 OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2083 unsigned NumClauses)
2084 : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
2085 OMPD_target_data, StartLoc, EndLoc, NumClauses,
2088 /// \brief Build an empty directive.
2090 /// \param NumClauses Number of clauses.
2092 explicit OMPTargetDataDirective(unsigned NumClauses)
2093 : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
2094 OMPD_target_data, SourceLocation(),
2095 SourceLocation(), NumClauses, 1) {}
2098 /// \brief Creates directive with a list of \a Clauses.
2100 /// \param C AST context.
2101 /// \param StartLoc Starting location of the directive kind.
2102 /// \param EndLoc Ending Location of the directive.
2103 /// \param Clauses List of clauses.
2104 /// \param AssociatedStmt Statement, associated with the directive.
2106 static OMPTargetDataDirective *
2107 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2108 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2110 /// \brief Creates an empty directive with the place for \a N clauses.
2112 /// \param C AST context.
2113 /// \param N The number of clauses.
2115 static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N,
2118 static bool classof(const Stmt *T) {
2119 return T->getStmtClass() == OMPTargetDataDirectiveClass;
2123 /// \brief This represents '#pragma omp target enter data' directive.
2126 /// #pragma omp target enter data device(0) if(a) map(b[:])
2128 /// In this example directive '#pragma omp target enter data' has clauses
2129 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
2132 class OMPTargetEnterDataDirective : public OMPExecutableDirective {
2133 friend class ASTStmtReader;
2134 /// \brief Build directive with the given start and end location.
2136 /// \param StartLoc Starting location of the directive kind.
2137 /// \param EndLoc Ending Location of the directive.
2138 /// \param NumClauses The number of clauses.
2140 OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2141 unsigned NumClauses)
2142 : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass,
2143 OMPD_target_enter_data, StartLoc, EndLoc,
2144 NumClauses, /*NumChildren=*/0) {}
2146 /// \brief Build an empty directive.
2148 /// \param NumClauses Number of clauses.
2150 explicit OMPTargetEnterDataDirective(unsigned NumClauses)
2151 : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass,
2152 OMPD_target_enter_data, SourceLocation(),
2153 SourceLocation(), NumClauses,
2154 /*NumChildren=*/0) {}
2157 /// \brief Creates directive with a list of \a Clauses.
2159 /// \param C AST context.
2160 /// \param StartLoc Starting location of the directive kind.
2161 /// \param EndLoc Ending Location of the directive.
2162 /// \param Clauses List of clauses.
2164 static OMPTargetEnterDataDirective *Create(const ASTContext &C,
2165 SourceLocation StartLoc,
2166 SourceLocation EndLoc,
2167 ArrayRef<OMPClause *> Clauses);
2169 /// \brief Creates an empty directive with the place for \a N clauses.
2171 /// \param C AST context.
2172 /// \param N The number of clauses.
2174 static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C,
2175 unsigned N, EmptyShell);
2177 static bool classof(const Stmt *T) {
2178 return T->getStmtClass() == OMPTargetEnterDataDirectiveClass;
2182 /// \brief This represents '#pragma omp target exit data' directive.
2185 /// #pragma omp target exit data device(0) if(a) map(b[:])
2187 /// In this example directive '#pragma omp target exit data' has clauses
2188 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
2191 class OMPTargetExitDataDirective : public OMPExecutableDirective {
2192 friend class ASTStmtReader;
2193 /// \brief Build directive with the given start and end location.
2195 /// \param StartLoc Starting location of the directive kind.
2196 /// \param EndLoc Ending Location of the directive.
2197 /// \param NumClauses The number of clauses.
2199 OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2200 unsigned NumClauses)
2201 : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass,
2202 OMPD_target_exit_data, StartLoc, EndLoc,
2203 NumClauses, /*NumChildren=*/0) {}
2205 /// \brief Build an empty directive.
2207 /// \param NumClauses Number of clauses.
2209 explicit OMPTargetExitDataDirective(unsigned NumClauses)
2210 : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass,
2211 OMPD_target_exit_data, SourceLocation(),
2212 SourceLocation(), NumClauses,
2213 /*NumChildren=*/0) {}
2216 /// \brief Creates directive with a list of \a Clauses.
2218 /// \param C AST context.
2219 /// \param StartLoc Starting location of the directive kind.
2220 /// \param EndLoc Ending Location of the directive.
2221 /// \param Clauses List of clauses.
2223 static OMPTargetExitDataDirective *Create(const ASTContext &C,
2224 SourceLocation StartLoc,
2225 SourceLocation EndLoc,
2226 ArrayRef<OMPClause *> Clauses);
2228 /// \brief Creates an empty directive with the place for \a N clauses.
2230 /// \param C AST context.
2231 /// \param N The number of clauses.
2233 static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C,
2234 unsigned N, EmptyShell);
2236 static bool classof(const Stmt *T) {
2237 return T->getStmtClass() == OMPTargetExitDataDirectiveClass;
2241 /// \brief This represents '#pragma omp target parallel' directive.
2244 /// #pragma omp target parallel if(a)
2246 /// In this example directive '#pragma omp target parallel' has clause 'if' with
2249 class OMPTargetParallelDirective : public OMPExecutableDirective {
2250 friend class ASTStmtReader;
2251 /// \brief Build directive with the given start and end location.
2253 /// \param StartLoc Starting location of the directive kind.
2254 /// \param EndLoc Ending location of the directive.
2255 /// \param NumClauses Number of clauses.
2257 OMPTargetParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2258 unsigned NumClauses)
2259 : OMPExecutableDirective(this, OMPTargetParallelDirectiveClass,
2260 OMPD_target_parallel, StartLoc, EndLoc,
2261 NumClauses, /*NumChildren=*/1) {}
2263 /// \brief Build an empty directive.
2265 /// \param NumClauses Number of clauses.
2267 explicit OMPTargetParallelDirective(unsigned NumClauses)
2268 : OMPExecutableDirective(this, OMPTargetParallelDirectiveClass,
2269 OMPD_target_parallel, SourceLocation(),
2270 SourceLocation(), NumClauses,
2271 /*NumChildren=*/1) {}
2274 /// \brief Creates directive with a list of \a Clauses.
2276 /// \param C AST context.
2277 /// \param StartLoc Starting location of the directive kind.
2278 /// \param EndLoc Ending Location of the directive.
2279 /// \param Clauses List of clauses.
2280 /// \param AssociatedStmt Statement, associated with the directive.
2282 static OMPTargetParallelDirective *
2283 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2284 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2286 /// \brief Creates an empty directive with the place for \a NumClauses
2289 /// \param C AST context.
2290 /// \param NumClauses Number of clauses.
2292 static OMPTargetParallelDirective *
2293 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2295 static bool classof(const Stmt *T) {
2296 return T->getStmtClass() == OMPTargetParallelDirectiveClass;
2300 /// \brief This represents '#pragma omp target parallel for' directive.
2303 /// #pragma omp target parallel for private(a,b) reduction(+:c,d)
2305 /// In this example directive '#pragma omp target parallel for' has clauses
2306 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
2307 /// and variables 'c' and 'd'.
2309 class OMPTargetParallelForDirective : public OMPLoopDirective {
2310 friend class ASTStmtReader;
2312 /// \brief true if current region has inner cancel directive.
2315 /// \brief Build directive with the given start and end location.
2317 /// \param StartLoc Starting location of the directive kind.
2318 /// \param EndLoc Ending location of the directive.
2319 /// \param CollapsedNum Number of collapsed nested loops.
2320 /// \param NumClauses Number of clauses.
2322 OMPTargetParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2323 unsigned CollapsedNum, unsigned NumClauses)
2324 : OMPLoopDirective(this, OMPTargetParallelForDirectiveClass,
2325 OMPD_target_parallel_for, StartLoc, EndLoc,
2326 CollapsedNum, NumClauses),
2329 /// \brief Build an empty directive.
2331 /// \param CollapsedNum Number of collapsed nested loops.
2332 /// \param NumClauses Number of clauses.
2334 explicit OMPTargetParallelForDirective(unsigned CollapsedNum,
2335 unsigned NumClauses)
2336 : OMPLoopDirective(this, OMPTargetParallelForDirectiveClass,
2337 OMPD_target_parallel_for, SourceLocation(),
2338 SourceLocation(), CollapsedNum, NumClauses),
2341 /// \brief Set cancel state.
2342 void setHasCancel(bool Has) { HasCancel = Has; }
2345 /// \brief Creates directive with a list of \a Clauses.
2347 /// \param C AST context.
2348 /// \param StartLoc Starting location of the directive kind.
2349 /// \param EndLoc Ending Location of the directive.
2350 /// \param CollapsedNum Number of collapsed loops.
2351 /// \param Clauses List of clauses.
2352 /// \param AssociatedStmt Statement, associated with the directive.
2353 /// \param Exprs Helper expressions for CodeGen.
2354 /// \param HasCancel true if current directive has inner cancel directive.
2356 static OMPTargetParallelForDirective *
2357 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2358 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2359 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
2361 /// \brief Creates an empty directive with the place
2362 /// for \a NumClauses clauses.
2364 /// \param C AST context.
2365 /// \param CollapsedNum Number of collapsed nested loops.
2366 /// \param NumClauses Number of clauses.
2368 static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C,
2369 unsigned NumClauses,
2370 unsigned CollapsedNum,
2373 /// \brief Return true if current directive has inner cancel directive.
2374 bool hasCancel() const { return HasCancel; }
2376 static bool classof(const Stmt *T) {
2377 return T->getStmtClass() == OMPTargetParallelForDirectiveClass;
2381 /// \brief This represents '#pragma omp teams' directive.
2384 /// #pragma omp teams if(a)
2386 /// In this example directive '#pragma omp teams' has clause 'if' with
2389 class OMPTeamsDirective : public OMPExecutableDirective {
2390 friend class ASTStmtReader;
2391 /// \brief Build directive with the given start and end location.
2393 /// \param StartLoc Starting location of the directive kind.
2394 /// \param EndLoc Ending location of the directive.
2395 /// \param NumClauses Number of clauses.
2397 OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2398 unsigned NumClauses)
2399 : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
2400 StartLoc, EndLoc, NumClauses, 1) {}
2402 /// \brief Build an empty directive.
2404 /// \param NumClauses Number of clauses.
2406 explicit OMPTeamsDirective(unsigned NumClauses)
2407 : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
2408 SourceLocation(), SourceLocation(), NumClauses,
2412 /// \brief Creates directive with a list of \a Clauses.
2414 /// \param C AST context.
2415 /// \param StartLoc Starting location of the directive kind.
2416 /// \param EndLoc Ending Location of the directive.
2417 /// \param Clauses List of clauses.
2418 /// \param AssociatedStmt Statement, associated with the directive.
2420 static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2421 SourceLocation EndLoc,
2422 ArrayRef<OMPClause *> Clauses,
2423 Stmt *AssociatedStmt);
2425 /// \brief Creates an empty directive with the place for \a NumClauses
2428 /// \param C AST context.
2429 /// \param NumClauses Number of clauses.
2431 static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
2432 unsigned NumClauses, EmptyShell);
2434 static bool classof(const Stmt *T) {
2435 return T->getStmtClass() == OMPTeamsDirectiveClass;
2439 /// \brief This represents '#pragma omp cancellation point' directive.
2442 /// #pragma omp cancellation point for
2445 /// In this example a cancellation point is created for innermost 'for' region.
2446 class OMPCancellationPointDirective : public OMPExecutableDirective {
2447 friend class ASTStmtReader;
2448 OpenMPDirectiveKind CancelRegion;
2449 /// \brief Build directive with the given start and end location.
2451 /// \param StartLoc Starting location of the directive kind.
2452 /// \param EndLoc Ending location of the directive.
2454 OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2455 : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
2456 OMPD_cancellation_point, StartLoc, EndLoc, 0, 0),
2457 CancelRegion(OMPD_unknown) {}
2459 /// \brief Build an empty directive.
2461 explicit OMPCancellationPointDirective()
2462 : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
2463 OMPD_cancellation_point, SourceLocation(),
2464 SourceLocation(), 0, 0),
2465 CancelRegion(OMPD_unknown) {}
2467 /// \brief Set cancel region for current cancellation point.
2468 /// \param CR Cancellation region.
2469 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
2472 /// \brief Creates directive.
2474 /// \param C AST context.
2475 /// \param StartLoc Starting location of the directive kind.
2476 /// \param EndLoc Ending Location of the directive.
2478 static OMPCancellationPointDirective *
2479 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2480 OpenMPDirectiveKind CancelRegion);
2482 /// \brief Creates an empty directive.
2484 /// \param C AST context.
2486 static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
2489 /// \brief Get cancellation region for the current cancellation point.
2490 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
2492 static bool classof(const Stmt *T) {
2493 return T->getStmtClass() == OMPCancellationPointDirectiveClass;
2497 /// \brief This represents '#pragma omp cancel' directive.
2500 /// #pragma omp cancel for
2503 /// In this example a cancel is created for innermost 'for' region.
2504 class OMPCancelDirective : public OMPExecutableDirective {
2505 friend class ASTStmtReader;
2506 OpenMPDirectiveKind CancelRegion;
2507 /// \brief Build directive with the given start and end location.
2509 /// \param StartLoc Starting location of the directive kind.
2510 /// \param EndLoc Ending location of the directive.
2511 /// \param NumClauses Number of clauses.
2513 OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2514 unsigned NumClauses)
2515 : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
2516 StartLoc, EndLoc, NumClauses, 0),
2517 CancelRegion(OMPD_unknown) {}
2519 /// \brief Build an empty directive.
2521 /// \param NumClauses Number of clauses.
2522 explicit OMPCancelDirective(unsigned NumClauses)
2523 : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
2524 SourceLocation(), SourceLocation(), NumClauses,
2526 CancelRegion(OMPD_unknown) {}
2528 /// \brief Set cancel region for current cancellation point.
2529 /// \param CR Cancellation region.
2530 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
2533 /// \brief Creates directive.
2535 /// \param C AST context.
2536 /// \param StartLoc Starting location of the directive kind.
2537 /// \param EndLoc Ending Location of the directive.
2538 /// \param Clauses List of clauses.
2540 static OMPCancelDirective *
2541 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2542 ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
2544 /// \brief Creates an empty directive.
2546 /// \param C AST context.
2547 /// \param NumClauses Number of clauses.
2549 static OMPCancelDirective *CreateEmpty(const ASTContext &C,
2550 unsigned NumClauses, EmptyShell);
2552 /// \brief Get cancellation region for the current cancellation point.
2553 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
2555 static bool classof(const Stmt *T) {
2556 return T->getStmtClass() == OMPCancelDirectiveClass;
2560 /// \brief This represents '#pragma omp taskloop' directive.
2563 /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
2565 /// In this example directive '#pragma omp taskloop' has clauses 'private'
2566 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
2567 /// 'num_tasks' with expression 'num'.
2569 class OMPTaskLoopDirective : public OMPLoopDirective {
2570 friend class ASTStmtReader;
2571 /// \brief Build directive with the given start and end location.
2573 /// \param StartLoc Starting location of the directive kind.
2574 /// \param EndLoc Ending location of the directive.
2575 /// \param CollapsedNum Number of collapsed nested loops.
2576 /// \param NumClauses Number of clauses.
2578 OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2579 unsigned CollapsedNum, unsigned NumClauses)
2580 : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
2581 StartLoc, EndLoc, CollapsedNum, NumClauses) {}
2583 /// \brief Build an empty directive.
2585 /// \param CollapsedNum Number of collapsed nested loops.
2586 /// \param NumClauses Number of clauses.
2588 explicit OMPTaskLoopDirective(unsigned CollapsedNum, unsigned NumClauses)
2589 : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
2590 SourceLocation(), SourceLocation(), CollapsedNum,
2594 /// \brief Creates directive with a list of \a Clauses.
2596 /// \param C AST context.
2597 /// \param StartLoc Starting location of the directive kind.
2598 /// \param EndLoc Ending Location of the directive.
2599 /// \param CollapsedNum Number of collapsed loops.
2600 /// \param Clauses List of clauses.
2601 /// \param AssociatedStmt Statement, associated with the directive.
2602 /// \param Exprs Helper expressions for CodeGen.
2604 static OMPTaskLoopDirective *
2605 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2606 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2607 Stmt *AssociatedStmt, const HelperExprs &Exprs);
2609 /// \brief Creates an empty directive with the place
2610 /// for \a NumClauses clauses.
2612 /// \param C AST context.
2613 /// \param CollapsedNum Number of collapsed nested loops.
2614 /// \param NumClauses Number of clauses.
2616 static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C,
2617 unsigned NumClauses,
2618 unsigned CollapsedNum, EmptyShell);
2620 static bool classof(const Stmt *T) {
2621 return T->getStmtClass() == OMPTaskLoopDirectiveClass;
2625 /// \brief This represents '#pragma omp taskloop simd' directive.
2628 /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
2630 /// In this example directive '#pragma omp taskloop simd' has clauses 'private'
2631 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
2632 /// 'num_tasks' with expression 'num'.
2634 class OMPTaskLoopSimdDirective : public OMPLoopDirective {
2635 friend class ASTStmtReader;
2636 /// \brief Build directive with the given start and end location.
2638 /// \param StartLoc Starting location of the directive kind.
2639 /// \param EndLoc Ending location of the directive.
2640 /// \param CollapsedNum Number of collapsed nested loops.
2641 /// \param NumClauses Number of clauses.
2643 OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2644 unsigned CollapsedNum, unsigned NumClauses)
2645 : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
2646 OMPD_taskloop_simd, StartLoc, EndLoc, CollapsedNum,
2649 /// \brief Build an empty directive.
2651 /// \param CollapsedNum Number of collapsed nested loops.
2652 /// \param NumClauses Number of clauses.
2654 explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
2655 : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
2656 OMPD_taskloop_simd, SourceLocation(), SourceLocation(),
2657 CollapsedNum, NumClauses) {}
2660 /// \brief Creates directive with a list of \a Clauses.
2662 /// \param C AST context.
2663 /// \param StartLoc Starting location of the directive kind.
2664 /// \param EndLoc Ending Location of the directive.
2665 /// \param CollapsedNum Number of collapsed loops.
2666 /// \param Clauses List of clauses.
2667 /// \param AssociatedStmt Statement, associated with the directive.
2668 /// \param Exprs Helper expressions for CodeGen.
2670 static OMPTaskLoopSimdDirective *
2671 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2672 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2673 Stmt *AssociatedStmt, const HelperExprs &Exprs);
2675 /// \brief Creates an empty directive with the place
2676 /// for \a NumClauses clauses.
2678 /// \param C AST context.
2679 /// \param CollapsedNum Number of collapsed nested loops.
2680 /// \param NumClauses Number of clauses.
2682 static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
2683 unsigned NumClauses,
2684 unsigned CollapsedNum,
2687 static bool classof(const Stmt *T) {
2688 return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass;
2692 /// \brief This represents '#pragma omp distribute' directive.
2695 /// #pragma omp distribute private(a,b)
2697 /// In this example directive '#pragma omp distribute' has clauses 'private'
2698 /// with the variables 'a' and 'b'
2700 class OMPDistributeDirective : public OMPLoopDirective {
2701 friend class ASTStmtReader;
2703 /// \brief Build directive with the given start and end location.
2705 /// \param StartLoc Starting location of the directive kind.
2706 /// \param EndLoc Ending location of the directive.
2707 /// \param CollapsedNum Number of collapsed nested loops.
2708 /// \param NumClauses Number of clauses.
2710 OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2711 unsigned CollapsedNum, unsigned NumClauses)
2712 : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
2713 StartLoc, EndLoc, CollapsedNum, NumClauses)
2716 /// \brief Build an empty directive.
2718 /// \param CollapsedNum Number of collapsed nested loops.
2719 /// \param NumClauses Number of clauses.
2721 explicit OMPDistributeDirective(unsigned CollapsedNum, unsigned NumClauses)
2722 : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
2723 SourceLocation(), SourceLocation(), CollapsedNum,
2728 /// \brief Creates directive with a list of \a Clauses.
2730 /// \param C AST context.
2731 /// \param StartLoc Starting location of the directive kind.
2732 /// \param EndLoc Ending Location of the directive.
2733 /// \param CollapsedNum Number of collapsed loops.
2734 /// \param Clauses List of clauses.
2735 /// \param AssociatedStmt Statement, associated with the directive.
2736 /// \param Exprs Helper expressions for CodeGen.
2738 static OMPDistributeDirective *
2739 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2740 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2741 Stmt *AssociatedStmt, const HelperExprs &Exprs);
2743 /// \brief Creates an empty directive with the place
2744 /// for \a NumClauses clauses.
2746 /// \param C AST context.
2747 /// \param CollapsedNum Number of collapsed nested loops.
2748 /// \param NumClauses Number of clauses.
2750 static OMPDistributeDirective *CreateEmpty(const ASTContext &C,
2751 unsigned NumClauses,
2752 unsigned CollapsedNum, EmptyShell);
2754 static bool classof(const Stmt *T) {
2755 return T->getStmtClass() == OMPDistributeDirectiveClass;
2759 /// \brief This represents '#pragma omp target update' directive.
2762 /// #pragma omp target update to(a) from(b) device(1)
2764 /// In this example directive '#pragma omp target update' has clause 'to' with
2765 /// argument 'a', clause 'from' with argument 'b' and clause 'device' with
2768 class OMPTargetUpdateDirective : public OMPExecutableDirective {
2769 friend class ASTStmtReader;
2770 /// \brief Build directive with the given start and end location.
2772 /// \param StartLoc Starting location of the directive kind.
2773 /// \param EndLoc Ending Location of the directive.
2774 /// \param NumClauses The number of clauses.
2776 OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2777 unsigned NumClauses)
2778 : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass,
2779 OMPD_target_update, StartLoc, EndLoc, NumClauses,
2782 /// \brief Build an empty directive.
2784 /// \param NumClauses Number of clauses.
2786 explicit OMPTargetUpdateDirective(unsigned NumClauses)
2787 : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass,
2788 OMPD_target_update, SourceLocation(),
2789 SourceLocation(), NumClauses, 0) {}
2792 /// \brief Creates directive with a list of \a Clauses.
2794 /// \param C AST context.
2795 /// \param StartLoc Starting location of the directive kind.
2796 /// \param EndLoc Ending Location of the directive.
2797 /// \param Clauses List of clauses.
2799 static OMPTargetUpdateDirective *Create(const ASTContext &C,
2800 SourceLocation StartLoc,
2801 SourceLocation EndLoc,
2802 ArrayRef<OMPClause *> Clauses);
2804 /// \brief Creates an empty directive with the place for \a NumClauses
2807 /// \param C AST context.
2808 /// \param NumClauses The number of clauses.
2810 static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C,
2811 unsigned NumClauses, EmptyShell);
2813 static bool classof(const Stmt *T) {
2814 return T->getStmtClass() == OMPTargetUpdateDirectiveClass;
2818 /// \brief This represents '#pragma omp distribute parallel for' composite
2822 /// #pragma omp distribute parallel for private(a,b)
2824 /// In this example directive '#pragma omp distribute parallel for' has clause
2825 /// 'private' with the variables 'a' and 'b'
2827 class OMPDistributeParallelForDirective : public OMPLoopDirective {
2828 friend class ASTStmtReader;
2830 /// \brief Build directive with the given start and end location.
2832 /// \param StartLoc Starting location of the directive kind.
2833 /// \param EndLoc Ending location of the directive.
2834 /// \param CollapsedNum Number of collapsed nested loops.
2835 /// \param NumClauses Number of clauses.
2837 OMPDistributeParallelForDirective(SourceLocation StartLoc,
2838 SourceLocation EndLoc,
2839 unsigned CollapsedNum, unsigned NumClauses)
2840 : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass,
2841 OMPD_distribute_parallel_for, StartLoc, EndLoc,
2842 CollapsedNum, NumClauses) {}
2844 /// \brief Build an empty directive.
2846 /// \param CollapsedNum Number of collapsed nested loops.
2847 /// \param NumClauses Number of clauses.
2849 explicit OMPDistributeParallelForDirective(unsigned CollapsedNum,
2850 unsigned NumClauses)
2851 : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass,
2852 OMPD_distribute_parallel_for, SourceLocation(),
2853 SourceLocation(), CollapsedNum, NumClauses) {}
2856 /// \brief Creates directive with a list of \a Clauses.
2858 /// \param C AST context.
2859 /// \param StartLoc Starting location of the directive kind.
2860 /// \param EndLoc Ending Location of the directive.
2861 /// \param CollapsedNum Number of collapsed loops.
2862 /// \param Clauses List of clauses.
2863 /// \param AssociatedStmt Statement, associated with the directive.
2864 /// \param Exprs Helper expressions for CodeGen.
2866 static OMPDistributeParallelForDirective *
2867 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2868 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2869 Stmt *AssociatedStmt, const HelperExprs &Exprs);
2871 /// \brief Creates an empty directive with the place
2872 /// for \a NumClauses clauses.
2874 /// \param C AST context.
2875 /// \param CollapsedNum Number of collapsed nested loops.
2876 /// \param NumClauses Number of clauses.
2878 static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C,
2879 unsigned NumClauses,
2880 unsigned CollapsedNum,
2883 static bool classof(const Stmt *T) {
2884 return T->getStmtClass() == OMPDistributeParallelForDirectiveClass;
2888 /// This represents '#pragma omp distribute parallel for simd' composite
2892 /// #pragma omp distribute parallel for simd private(x)
2894 /// In this example directive '#pragma omp distribute parallel for simd' has
2895 /// clause 'private' with the variables 'x'
2897 class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective {
2898 friend class ASTStmtReader;
2900 /// Build directive with the given start and end location.
2902 /// \param StartLoc Starting location of the directive kind.
2903 /// \param EndLoc Ending location of the directive.
2904 /// \param CollapsedNum Number of collapsed nested loops.
2905 /// \param NumClauses Number of clauses.
2907 OMPDistributeParallelForSimdDirective(SourceLocation StartLoc,
2908 SourceLocation EndLoc,
2909 unsigned CollapsedNum,
2910 unsigned NumClauses)
2911 : OMPLoopDirective(this, OMPDistributeParallelForSimdDirectiveClass,
2912 OMPD_distribute_parallel_for_simd, StartLoc,
2913 EndLoc, CollapsedNum, NumClauses) {}
2915 /// Build an empty directive.
2917 /// \param CollapsedNum Number of collapsed nested loops.
2918 /// \param NumClauses Number of clauses.
2920 explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum,
2921 unsigned NumClauses)
2922 : OMPLoopDirective(this, OMPDistributeParallelForSimdDirectiveClass,
2923 OMPD_distribute_parallel_for_simd,
2924 SourceLocation(), SourceLocation(), CollapsedNum,
2928 /// Creates directive with a list of \a Clauses.
2930 /// \param C AST context.
2931 /// \param StartLoc Starting location of the directive kind.
2932 /// \param EndLoc Ending Location of the directive.
2933 /// \param CollapsedNum Number of collapsed loops.
2934 /// \param Clauses List of clauses.
2935 /// \param AssociatedStmt Statement, associated with the directive.
2936 /// \param Exprs Helper expressions for CodeGen.
2938 static OMPDistributeParallelForSimdDirective *Create(
2939 const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2940 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2941 Stmt *AssociatedStmt, const HelperExprs &Exprs);
2943 /// Creates an empty directive with the place for \a NumClauses clauses.
2945 /// \param C AST context.
2946 /// \param CollapsedNum Number of collapsed nested loops.
2947 /// \param NumClauses Number of clauses.
2949 static OMPDistributeParallelForSimdDirective *CreateEmpty(
2950 const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
2953 static bool classof(const Stmt *T) {
2954 return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass;
2958 /// This represents '#pragma omp distribute simd' composite directive.
2961 /// #pragma omp distribute simd private(x)
2963 /// In this example directive '#pragma omp distribute simd' has clause
2964 /// 'private' with the variables 'x'
2966 class OMPDistributeSimdDirective final : public OMPLoopDirective {
2967 friend class ASTStmtReader;
2969 /// Build directive with the given start and end location.
2971 /// \param StartLoc Starting location of the directive kind.
2972 /// \param EndLoc Ending location of the directive.
2973 /// \param CollapsedNum Number of collapsed nested loops.
2974 /// \param NumClauses Number of clauses.
2976 OMPDistributeSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2977 unsigned CollapsedNum, unsigned NumClauses)
2978 : OMPLoopDirective(this, OMPDistributeSimdDirectiveClass,
2979 OMPD_distribute_simd, StartLoc, EndLoc, CollapsedNum,
2982 /// Build an empty directive.
2984 /// \param CollapsedNum Number of collapsed nested loops.
2985 /// \param NumClauses Number of clauses.
2987 explicit OMPDistributeSimdDirective(unsigned CollapsedNum,
2988 unsigned NumClauses)
2989 : OMPLoopDirective(this, OMPDistributeSimdDirectiveClass,
2990 OMPD_distribute_simd, SourceLocation(),
2991 SourceLocation(), CollapsedNum, NumClauses) {}
2994 /// Creates directive with a list of \a Clauses.
2996 /// \param C AST context.
2997 /// \param StartLoc Starting location of the directive kind.
2998 /// \param EndLoc Ending Location of the directive.
2999 /// \param CollapsedNum Number of collapsed loops.
3000 /// \param Clauses List of clauses.
3001 /// \param AssociatedStmt Statement, associated with the directive.
3002 /// \param Exprs Helper expressions for CodeGen.
3004 static OMPDistributeSimdDirective *
3005 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3006 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3007 Stmt *AssociatedStmt, const HelperExprs &Exprs);
3009 /// Creates an empty directive with the place for \a NumClauses clauses.
3011 /// \param C AST context.
3012 /// \param CollapsedNum Number of collapsed nested loops.
3013 /// \param NumClauses Number of clauses.
3015 static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C,
3016 unsigned NumClauses,
3017 unsigned CollapsedNum,
3020 static bool classof(const Stmt *T) {
3021 return T->getStmtClass() == OMPDistributeSimdDirectiveClass;
3025 /// This represents '#pragma omp target parallel for simd' directive.
3028 /// #pragma omp target parallel for simd private(a) map(b) safelen(c)
3030 /// In this example directive '#pragma omp target parallel for simd' has clauses
3031 /// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen'
3032 /// with the variable 'c'.
3034 class OMPTargetParallelForSimdDirective final : public OMPLoopDirective {
3035 friend class ASTStmtReader;
3037 /// Build directive with the given start and end location.
3039 /// \param StartLoc Starting location of the directive kind.
3040 /// \param EndLoc Ending location of the directive.
3041 /// \param CollapsedNum Number of collapsed nested loops.
3042 /// \param NumClauses Number of clauses.
3044 OMPTargetParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3045 unsigned CollapsedNum, unsigned NumClauses)
3046 : OMPLoopDirective(this, OMPTargetParallelForSimdDirectiveClass,
3047 OMPD_target_parallel_for_simd, StartLoc, EndLoc,
3048 CollapsedNum, NumClauses) {}
3050 /// Build an empty directive.
3052 /// \param CollapsedNum Number of collapsed nested loops.
3053 /// \param NumClauses Number of clauses.
3055 explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum,
3056 unsigned NumClauses)
3057 : OMPLoopDirective(this, OMPTargetParallelForSimdDirectiveClass,
3058 OMPD_target_parallel_for_simd, SourceLocation(),
3059 SourceLocation(), CollapsedNum, NumClauses) {}
3062 /// Creates directive with a list of \a Clauses.
3064 /// \param C AST context.
3065 /// \param StartLoc Starting location of the directive kind.
3066 /// \param EndLoc Ending Location of the directive.
3067 /// \param CollapsedNum Number of collapsed loops.
3068 /// \param Clauses List of clauses.
3069 /// \param AssociatedStmt Statement, associated with the directive.
3070 /// \param Exprs Helper expressions for CodeGen.
3072 static OMPTargetParallelForSimdDirective *
3073 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3074 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3075 Stmt *AssociatedStmt, const HelperExprs &Exprs);
3077 /// Creates an empty directive with the place for \a NumClauses clauses.
3079 /// \param C AST context.
3080 /// \param CollapsedNum Number of collapsed nested loops.
3081 /// \param NumClauses Number of clauses.
3083 static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C,
3084 unsigned NumClauses,
3085 unsigned CollapsedNum,
3088 static bool classof(const Stmt *T) {
3089 return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass;
3093 } // end namespace clang