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::RoundUpToAlignment(sizeof(T),
74 llvm::alignOf<OMPClause *>())) {}
76 /// \brief Sets the list of variables for this clause.
78 /// \param Clauses The list of clauses for the directive.
80 void setClauses(ArrayRef<OMPClause *> Clauses);
82 /// \brief Set the associated statement for the directive.
84 /// /param S Associated statement.
86 void setAssociatedStmt(Stmt *S) {
87 assert(hasAssociatedStmt() && "no associated statement.");
92 /// \brief Iterates over a filtered subrange of clauses applied to a
95 /// This iterator visits only clauses of type SpecificClause.
96 template <typename SpecificClause>
97 class specific_clause_iterator
98 : public llvm::iterator_adaptor_base<
99 specific_clause_iterator<SpecificClause>,
100 ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag,
101 const SpecificClause *, ptrdiff_t, const SpecificClause *,
102 const SpecificClause *> {
103 ArrayRef<OMPClause *>::const_iterator End;
105 void SkipToNextClause() {
106 while (this->I != End && !isa<SpecificClause>(*this->I))
111 explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses)
112 : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()),
117 const SpecificClause *operator*() const {
118 return cast<SpecificClause>(*this->I);
120 const SpecificClause *operator->() const { return **this; }
122 specific_clause_iterator &operator++() {
129 template <typename SpecificClause>
130 static llvm::iterator_range<specific_clause_iterator<SpecificClause>>
131 getClausesOfKind(ArrayRef<OMPClause *> Clauses) {
132 return {specific_clause_iterator<SpecificClause>(Clauses),
133 specific_clause_iterator<SpecificClause>(
134 llvm::makeArrayRef(Clauses.end(), 0))};
137 template <typename SpecificClause>
138 llvm::iterator_range<specific_clause_iterator<SpecificClause>>
139 getClausesOfKind() const {
140 return getClausesOfKind<SpecificClause>(clauses());
143 /// Gets a single clause of the specified kind associated with the
144 /// current directive iff there is only one clause of this kind (and assertion
145 /// is fired if there is more than one clause is associated with the
146 /// directive). Returns nullptr if no clause of this kind is associated with
148 template <typename SpecificClause>
149 const SpecificClause *getSingleClause() const {
150 auto Clauses = getClausesOfKind<SpecificClause>();
152 if (Clauses.begin() != Clauses.end()) {
153 assert(std::next(Clauses.begin()) == Clauses.end() &&
154 "There are at least 2 clauses of the specified kind");
155 return *Clauses.begin();
160 /// Returns true if the current directive has one or more clauses of a
162 template <typename SpecificClause>
163 bool hasClausesOfKind() const {
164 auto Clauses = getClausesOfKind<SpecificClause>();
165 return Clauses.begin() != Clauses.end();
168 /// \brief Returns starting location of directive kind.
169 SourceLocation getLocStart() const { return StartLoc; }
170 /// \brief Returns ending location of directive.
171 SourceLocation getLocEnd() const { return EndLoc; }
173 /// \brief Set starting location of directive kind.
175 /// \param Loc New starting location of directive.
177 void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
178 /// \brief Set ending location of directive.
180 /// \param Loc New ending location of directive.
182 void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
184 /// \brief Get number of clauses.
185 unsigned getNumClauses() const { return NumClauses; }
187 /// \brief Returns specified clause.
189 /// \param i Number of clause.
191 OMPClause *getClause(unsigned i) const { return clauses()[i]; }
193 /// \brief Returns true if directive has associated statement.
194 bool hasAssociatedStmt() const { return NumChildren > 0; }
196 /// \brief Returns statement associated with the directive.
197 Stmt *getAssociatedStmt() const {
198 assert(hasAssociatedStmt() && "no associated statement.");
199 return const_cast<Stmt *>(*child_begin());
202 OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
204 static bool classof(const Stmt *S) {
205 return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
206 S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
209 child_range children() {
210 if (!hasAssociatedStmt())
211 return child_range(child_iterator(), child_iterator());
212 Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end());
213 return child_range(ChildStorage, ChildStorage + NumChildren);
216 ArrayRef<OMPClause *> clauses() { return getClauses(); }
218 ArrayRef<OMPClause *> clauses() const {
219 return const_cast<OMPExecutableDirective *>(this)->getClauses();
223 /// \brief This represents '#pragma omp parallel' directive.
226 /// #pragma omp parallel private(a,b) reduction(+: c,d)
228 /// In this example directive '#pragma omp parallel' has clauses 'private'
229 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
230 /// variables 'c' and 'd'.
232 class OMPParallelDirective : public OMPExecutableDirective {
233 friend class ASTStmtReader;
234 /// \brief true if the construct has inner cancel directive.
237 /// \brief Build directive with the given start and end location.
239 /// \param StartLoc Starting location of the directive (directive keyword).
240 /// \param EndLoc Ending Location of the directive.
242 OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
244 : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
245 StartLoc, EndLoc, NumClauses, 1),
248 /// \brief Build an empty directive.
250 /// \param NumClauses Number of clauses.
252 explicit OMPParallelDirective(unsigned NumClauses)
253 : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
254 SourceLocation(), SourceLocation(), NumClauses,
258 /// \brief Set cancel state.
259 void setHasCancel(bool Has) { HasCancel = Has; }
262 /// \brief Creates directive with a list of \a Clauses.
264 /// \param C AST context.
265 /// \param StartLoc Starting location of the directive kind.
266 /// \param EndLoc Ending Location of the directive.
267 /// \param Clauses List of clauses.
268 /// \param AssociatedStmt Statement associated with the directive.
269 /// \param HasCancel true if this directive has inner cancel directive.
271 static OMPParallelDirective *
272 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
273 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
275 /// \brief Creates an empty directive with the place for \a N clauses.
277 /// \param C AST context.
278 /// \param NumClauses Number of clauses.
280 static OMPParallelDirective *CreateEmpty(const ASTContext &C,
281 unsigned NumClauses, EmptyShell);
283 /// \brief Return true if current directive has inner cancel directive.
284 bool hasCancel() const { return HasCancel; }
286 static bool classof(const Stmt *T) {
287 return T->getStmtClass() == OMPParallelDirectiveClass;
291 /// \brief This is a common base class for loop directives ('omp simd', 'omp
292 /// for', 'omp for simd' etc.). It is responsible for the loop code generation.
294 class OMPLoopDirective : public OMPExecutableDirective {
295 friend class ASTStmtReader;
296 /// \brief Number of collapsed loops as specified by 'collapse' clause.
297 unsigned CollapsedNum;
299 /// \brief Offsets to the stored exprs.
300 /// This enumeration contains offsets to all the pointers to children
301 /// expressions stored in OMPLoopDirective.
302 /// The first 9 children are nesessary for all the loop directives, and
303 /// the next 7 are specific to the worksharing ones.
304 /// After the fixed children, three arrays of length CollapsedNum are
305 /// allocated: loop counters, their updates and final values.
308 AssociatedStmtOffset = 0,
309 IterationVariableOffset = 1,
310 LastIterationOffset = 2,
311 CalcLastIterationOffset = 3,
312 PreConditionOffset = 4,
316 // The '...End' enumerators do not correspond to child expressions - they
317 // specify the offset to the end (and start of the following counters/
318 // updates/finals arrays).
320 // The following 7 exprs are used by worksharing loops only.
321 IsLastIterVariableOffset = 8,
322 LowerBoundVariableOffset = 9,
323 UpperBoundVariableOffset = 10,
324 StrideVariableOffset = 11,
325 EnsureUpperBoundOffset = 12,
326 NextLowerBoundOffset = 13,
327 NextUpperBoundOffset = 14,
328 // Offset to the end (and start of the following counters/updates/finals
329 // arrays) for worksharing loop directives.
333 /// \brief Get the counters storage.
334 MutableArrayRef<Expr *> getCounters() {
335 Expr **Storage = reinterpret_cast<Expr **>(
336 &(*(std::next(child_begin(), getArraysOffset(getDirectiveKind())))));
337 return MutableArrayRef<Expr *>(Storage, CollapsedNum);
340 /// \brief Get the private counters storage.
341 MutableArrayRef<Expr *> getPrivateCounters() {
342 Expr **Storage = reinterpret_cast<Expr **>(&*std::next(
343 child_begin(), getArraysOffset(getDirectiveKind()) + CollapsedNum));
344 return MutableArrayRef<Expr *>(Storage, CollapsedNum);
347 /// \brief Get the updates storage.
348 MutableArrayRef<Expr *> getInits() {
349 Expr **Storage = reinterpret_cast<Expr **>(
350 &*std::next(child_begin(),
351 getArraysOffset(getDirectiveKind()) + 2 * CollapsedNum));
352 return MutableArrayRef<Expr *>(Storage, CollapsedNum);
355 /// \brief Get the updates storage.
356 MutableArrayRef<Expr *> getUpdates() {
357 Expr **Storage = reinterpret_cast<Expr **>(
358 &*std::next(child_begin(),
359 getArraysOffset(getDirectiveKind()) + 3 * CollapsedNum));
360 return MutableArrayRef<Expr *>(Storage, CollapsedNum);
363 /// \brief Get the final counter updates storage.
364 MutableArrayRef<Expr *> getFinals() {
365 Expr **Storage = reinterpret_cast<Expr **>(
366 &*std::next(child_begin(),
367 getArraysOffset(getDirectiveKind()) + 4 * CollapsedNum));
368 return MutableArrayRef<Expr *>(Storage, CollapsedNum);
372 /// \brief Build instance of loop directive of class \a Kind.
374 /// \param SC Statement class.
375 /// \param Kind Kind of OpenMP directive.
376 /// \param StartLoc Starting location of the directive (directive keyword).
377 /// \param EndLoc Ending location of the directive.
378 /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
379 /// \param NumClauses Number of clauses.
380 /// \param NumSpecialChildren Number of additional directive-specific stmts.
382 template <typename T>
383 OMPLoopDirective(const T *That, StmtClass SC, OpenMPDirectiveKind Kind,
384 SourceLocation StartLoc, SourceLocation EndLoc,
385 unsigned CollapsedNum, unsigned NumClauses,
386 unsigned NumSpecialChildren = 0)
387 : OMPExecutableDirective(That, SC, Kind, StartLoc, EndLoc, NumClauses,
388 numLoopChildren(CollapsedNum, Kind) +
390 CollapsedNum(CollapsedNum) {}
392 /// \brief Offset to the start of children expression arrays.
393 static unsigned getArraysOffset(OpenMPDirectiveKind Kind) {
394 return (isOpenMPWorksharingDirective(Kind) ||
395 isOpenMPTaskLoopDirective(Kind) ||
396 isOpenMPDistributeDirective(Kind))
401 /// \brief Children number.
402 static unsigned numLoopChildren(unsigned CollapsedNum,
403 OpenMPDirectiveKind Kind) {
404 return getArraysOffset(Kind) + 5 * CollapsedNum; // Counters,
405 // PrivateCounters, Inits,
406 // Updates and Finals
409 void setIterationVariable(Expr *IV) {
410 *std::next(child_begin(), IterationVariableOffset) = IV;
412 void setLastIteration(Expr *LI) {
413 *std::next(child_begin(), LastIterationOffset) = LI;
415 void setCalcLastIteration(Expr *CLI) {
416 *std::next(child_begin(), CalcLastIterationOffset) = CLI;
418 void setPreCond(Expr *PC) {
419 *std::next(child_begin(), PreConditionOffset) = PC;
421 void setCond(Expr *Cond) {
422 *std::next(child_begin(), CondOffset) = Cond;
424 void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; }
425 void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; }
426 void setIsLastIterVariable(Expr *IL) {
427 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
428 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
429 isOpenMPDistributeDirective(getDirectiveKind())) &&
430 "expected worksharing loop directive");
431 *std::next(child_begin(), IsLastIterVariableOffset) = IL;
433 void setLowerBoundVariable(Expr *LB) {
434 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
435 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
436 isOpenMPDistributeDirective(getDirectiveKind())) &&
437 "expected worksharing loop directive");
438 *std::next(child_begin(), LowerBoundVariableOffset) = LB;
440 void setUpperBoundVariable(Expr *UB) {
441 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
442 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
443 isOpenMPDistributeDirective(getDirectiveKind())) &&
444 "expected worksharing loop directive");
445 *std::next(child_begin(), UpperBoundVariableOffset) = UB;
447 void setStrideVariable(Expr *ST) {
448 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
449 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
450 isOpenMPDistributeDirective(getDirectiveKind())) &&
451 "expected worksharing loop directive");
452 *std::next(child_begin(), StrideVariableOffset) = ST;
454 void setEnsureUpperBound(Expr *EUB) {
455 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
456 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
457 isOpenMPDistributeDirective(getDirectiveKind())) &&
458 "expected worksharing loop directive");
459 *std::next(child_begin(), EnsureUpperBoundOffset) = EUB;
461 void setNextLowerBound(Expr *NLB) {
462 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
463 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
464 isOpenMPDistributeDirective(getDirectiveKind())) &&
465 "expected worksharing loop directive");
466 *std::next(child_begin(), NextLowerBoundOffset) = NLB;
468 void setNextUpperBound(Expr *NUB) {
469 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
470 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
471 isOpenMPDistributeDirective(getDirectiveKind())) &&
472 "expected worksharing loop directive");
473 *std::next(child_begin(), NextUpperBoundOffset) = NUB;
475 void setCounters(ArrayRef<Expr *> A);
476 void setPrivateCounters(ArrayRef<Expr *> A);
477 void setInits(ArrayRef<Expr *> A);
478 void setUpdates(ArrayRef<Expr *> A);
479 void setFinals(ArrayRef<Expr *> A);
482 /// \brief The expressions built for the OpenMP loop CodeGen for the
483 /// whole collapsed loop nest.
485 /// \brief Loop iteration variable.
486 Expr *IterationVarRef;
487 /// \brief Loop last iteration number.
489 /// \brief Loop number of iterations.
491 /// \brief Calculation of last iteration.
492 Expr *CalcLastIteration;
493 /// \brief Loop pre-condition.
495 /// \brief Loop condition.
497 /// \brief Loop iteration variable init.
499 /// \brief Loop increment.
501 /// \brief IsLastIteration - local flag variable passed to runtime.
503 /// \brief LowerBound - local variable passed to runtime.
505 /// \brief UpperBound - local variable passed to runtime.
507 /// \brief Stride - local variable passed to runtime.
509 /// \brief EnsureUpperBound -- expression LB = min(LB, NumIterations).
511 /// \brief Update of LowerBound for statically sheduled 'omp for' loops.
513 /// \brief Update of UpperBound for statically sheduled 'omp for' loops.
515 /// \brief Counters Loop counters.
516 SmallVector<Expr *, 4> Counters;
517 /// \brief PrivateCounters Loop counters.
518 SmallVector<Expr *, 4> PrivateCounters;
519 /// \brief Expressions for loop counters inits for CodeGen.
520 SmallVector<Expr *, 4> Inits;
521 /// \brief Expressions for loop counters update for CodeGen.
522 SmallVector<Expr *, 4> Updates;
523 /// \brief Final loop counter values for GodeGen.
524 SmallVector<Expr *, 4> Finals;
526 /// \brief Check if all the expressions are built (does not check the
527 /// worksharing ones).
529 return IterationVarRef != nullptr && LastIteration != nullptr &&
530 NumIterations != nullptr && PreCond != nullptr &&
531 Cond != nullptr && Init != nullptr && Inc != nullptr;
534 /// \brief Initialize all the fields to null.
535 /// \param Size Number of elements in the counters/finals/updates arrays.
536 void clear(unsigned Size) {
537 IterationVarRef = nullptr;
538 LastIteration = nullptr;
539 CalcLastIteration = nullptr;
551 Counters.resize(Size);
552 PrivateCounters.resize(Size);
554 Updates.resize(Size);
556 for (unsigned i = 0; i < Size; ++i) {
557 Counters[i] = nullptr;
558 PrivateCounters[i] = nullptr;
560 Updates[i] = nullptr;
566 /// \brief Get number of collapsed loops.
567 unsigned getCollapsedNumber() const { return CollapsedNum; }
569 Expr *getIterationVariable() const {
570 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
571 *std::next(child_begin(), IterationVariableOffset)));
573 Expr *getLastIteration() const {
574 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
575 *std::next(child_begin(), LastIterationOffset)));
577 Expr *getCalcLastIteration() const {
578 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
579 *std::next(child_begin(), CalcLastIterationOffset)));
581 Expr *getPreCond() const {
582 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
583 *std::next(child_begin(), PreConditionOffset)));
585 Expr *getCond() const {
586 return const_cast<Expr *>(
587 reinterpret_cast<const Expr *>(*std::next(child_begin(), CondOffset)));
589 Expr *getInit() const {
590 return const_cast<Expr *>(
591 reinterpret_cast<const Expr *>(*std::next(child_begin(), InitOffset)));
593 Expr *getInc() const {
594 return const_cast<Expr *>(
595 reinterpret_cast<const Expr *>(*std::next(child_begin(), IncOffset)));
597 Expr *getIsLastIterVariable() const {
598 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
599 isOpenMPTaskLoopDirective(getDirectiveKind())) &&
600 "expected worksharing loop directive");
601 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
602 *std::next(child_begin(), IsLastIterVariableOffset)));
604 Expr *getLowerBoundVariable() const {
605 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
606 isOpenMPTaskLoopDirective(getDirectiveKind())) &&
607 "expected worksharing loop directive");
608 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
609 *std::next(child_begin(), LowerBoundVariableOffset)));
611 Expr *getUpperBoundVariable() const {
612 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
613 isOpenMPTaskLoopDirective(getDirectiveKind())) &&
614 "expected worksharing loop directive");
615 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
616 *std::next(child_begin(), UpperBoundVariableOffset)));
618 Expr *getStrideVariable() const {
619 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
620 isOpenMPTaskLoopDirective(getDirectiveKind())) &&
621 "expected worksharing loop directive");
622 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
623 *std::next(child_begin(), StrideVariableOffset)));
625 Expr *getEnsureUpperBound() const {
626 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
627 isOpenMPTaskLoopDirective(getDirectiveKind())) &&
628 "expected worksharing loop directive");
629 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
630 *std::next(child_begin(), EnsureUpperBoundOffset)));
632 Expr *getNextLowerBound() const {
633 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
634 isOpenMPTaskLoopDirective(getDirectiveKind())) &&
635 "expected worksharing loop directive");
636 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
637 *std::next(child_begin(), NextLowerBoundOffset)));
639 Expr *getNextUpperBound() const {
640 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
641 isOpenMPTaskLoopDirective(getDirectiveKind())) &&
642 "expected worksharing loop directive");
643 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
644 *std::next(child_begin(), NextUpperBoundOffset)));
646 const Stmt *getBody() const {
647 // This relies on the loop form is already checked by Sema.
648 Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
649 Body = cast<ForStmt>(Body)->getBody();
650 for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) {
651 Body = Body->IgnoreContainers();
652 Body = cast<ForStmt>(Body)->getBody();
657 ArrayRef<Expr *> counters() { return getCounters(); }
659 ArrayRef<Expr *> counters() const {
660 return const_cast<OMPLoopDirective *>(this)->getCounters();
663 ArrayRef<Expr *> private_counters() { return getPrivateCounters(); }
665 ArrayRef<Expr *> private_counters() const {
666 return const_cast<OMPLoopDirective *>(this)->getPrivateCounters();
669 ArrayRef<Expr *> inits() { return getInits(); }
671 ArrayRef<Expr *> inits() const {
672 return const_cast<OMPLoopDirective *>(this)->getInits();
675 ArrayRef<Expr *> updates() { return getUpdates(); }
677 ArrayRef<Expr *> updates() const {
678 return const_cast<OMPLoopDirective *>(this)->getUpdates();
681 ArrayRef<Expr *> finals() { return getFinals(); }
683 ArrayRef<Expr *> finals() const {
684 return const_cast<OMPLoopDirective *>(this)->getFinals();
687 static bool classof(const Stmt *T) {
688 return T->getStmtClass() == OMPSimdDirectiveClass ||
689 T->getStmtClass() == OMPForDirectiveClass ||
690 T->getStmtClass() == OMPForSimdDirectiveClass ||
691 T->getStmtClass() == OMPParallelForDirectiveClass ||
692 T->getStmtClass() == OMPParallelForSimdDirectiveClass ||
693 T->getStmtClass() == OMPTaskLoopDirectiveClass ||
694 T->getStmtClass() == OMPTaskLoopSimdDirectiveClass ||
695 T->getStmtClass() == OMPDistributeDirectiveClass;
699 /// \brief This represents '#pragma omp simd' directive.
702 /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
704 /// In this example directive '#pragma omp simd' has clauses 'private'
705 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
706 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
708 class OMPSimdDirective : public OMPLoopDirective {
709 friend class ASTStmtReader;
710 /// \brief Build directive with the given start and end location.
712 /// \param StartLoc Starting location of the directive kind.
713 /// \param EndLoc Ending location of the directive.
714 /// \param CollapsedNum Number of collapsed nested loops.
715 /// \param NumClauses Number of clauses.
717 OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
718 unsigned CollapsedNum, unsigned NumClauses)
719 : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
720 EndLoc, CollapsedNum, NumClauses) {}
722 /// \brief Build an empty directive.
724 /// \param CollapsedNum Number of collapsed nested loops.
725 /// \param NumClauses Number of clauses.
727 explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
728 : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd,
729 SourceLocation(), SourceLocation(), CollapsedNum,
733 /// \brief Creates directive with a list of \a Clauses.
735 /// \param C AST context.
736 /// \param StartLoc Starting location of the directive kind.
737 /// \param EndLoc Ending Location of the directive.
738 /// \param CollapsedNum Number of collapsed loops.
739 /// \param Clauses List of clauses.
740 /// \param AssociatedStmt Statement, associated with the directive.
741 /// \param Exprs Helper expressions for CodeGen.
743 static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
744 SourceLocation EndLoc, unsigned CollapsedNum,
745 ArrayRef<OMPClause *> Clauses,
746 Stmt *AssociatedStmt,
747 const HelperExprs &Exprs);
749 /// \brief Creates an empty directive with the place
750 /// for \a NumClauses clauses.
752 /// \param C AST context.
753 /// \param CollapsedNum Number of collapsed nested loops.
754 /// \param NumClauses Number of clauses.
756 static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
757 unsigned CollapsedNum, EmptyShell);
759 static bool classof(const Stmt *T) {
760 return T->getStmtClass() == OMPSimdDirectiveClass;
764 /// \brief This represents '#pragma omp for' directive.
767 /// #pragma omp for private(a,b) reduction(+:c,d)
769 /// In this example directive '#pragma omp for' has clauses 'private' with the
770 /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
773 class OMPForDirective : public OMPLoopDirective {
774 friend class ASTStmtReader;
776 /// \brief true if current directive has inner cancel directive.
779 /// \brief Build directive with the given start and end location.
781 /// \param StartLoc Starting location of the directive kind.
782 /// \param EndLoc Ending location of the directive.
783 /// \param CollapsedNum Number of collapsed nested loops.
784 /// \param NumClauses Number of clauses.
786 OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
787 unsigned CollapsedNum, unsigned NumClauses)
788 : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, EndLoc,
789 CollapsedNum, NumClauses),
792 /// \brief Build an empty directive.
794 /// \param CollapsedNum Number of collapsed nested loops.
795 /// \param NumClauses Number of clauses.
797 explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses)
798 : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, SourceLocation(),
799 SourceLocation(), CollapsedNum, NumClauses),
802 /// \brief Set cancel state.
803 void setHasCancel(bool Has) { HasCancel = Has; }
806 /// \brief Creates directive with a list of \a Clauses.
808 /// \param C AST context.
809 /// \param StartLoc Starting location of the directive kind.
810 /// \param EndLoc Ending Location of the directive.
811 /// \param CollapsedNum Number of collapsed loops.
812 /// \param Clauses List of clauses.
813 /// \param AssociatedStmt Statement, associated with the directive.
814 /// \param Exprs Helper expressions for CodeGen.
815 /// \param HasCancel true if current directive has inner cancel directive.
817 static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
818 SourceLocation EndLoc, unsigned CollapsedNum,
819 ArrayRef<OMPClause *> Clauses,
820 Stmt *AssociatedStmt, const HelperExprs &Exprs,
823 /// \brief Creates an empty directive with the place
824 /// for \a NumClauses clauses.
826 /// \param C AST context.
827 /// \param CollapsedNum Number of collapsed nested loops.
828 /// \param NumClauses Number of clauses.
830 static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
831 unsigned CollapsedNum, EmptyShell);
833 /// \brief Return true if current directive has inner cancel directive.
834 bool hasCancel() const { return HasCancel; }
836 static bool classof(const Stmt *T) {
837 return T->getStmtClass() == OMPForDirectiveClass;
841 /// \brief This represents '#pragma omp for simd' directive.
844 /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
846 /// In this example directive '#pragma omp for simd' has clauses 'private'
847 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
848 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
850 class OMPForSimdDirective : public OMPLoopDirective {
851 friend class ASTStmtReader;
852 /// \brief Build directive with the given start and end location.
854 /// \param StartLoc Starting location of the directive kind.
855 /// \param EndLoc Ending location of the directive.
856 /// \param CollapsedNum Number of collapsed nested loops.
857 /// \param NumClauses Number of clauses.
859 OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
860 unsigned CollapsedNum, unsigned NumClauses)
861 : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
862 StartLoc, EndLoc, CollapsedNum, NumClauses) {}
864 /// \brief Build an empty directive.
866 /// \param CollapsedNum Number of collapsed nested loops.
867 /// \param NumClauses Number of clauses.
869 explicit OMPForSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
870 : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
871 SourceLocation(), SourceLocation(), CollapsedNum,
875 /// \brief Creates directive with a list of \a Clauses.
877 /// \param C AST context.
878 /// \param StartLoc Starting location of the directive kind.
879 /// \param EndLoc Ending Location of the directive.
880 /// \param CollapsedNum Number of collapsed loops.
881 /// \param Clauses List of clauses.
882 /// \param AssociatedStmt Statement, associated with the directive.
883 /// \param Exprs Helper expressions for CodeGen.
885 static OMPForSimdDirective *
886 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
887 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
888 Stmt *AssociatedStmt, const HelperExprs &Exprs);
890 /// \brief Creates an empty directive with the place
891 /// for \a NumClauses clauses.
893 /// \param C AST context.
894 /// \param CollapsedNum Number of collapsed nested loops.
895 /// \param NumClauses Number of clauses.
897 static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
899 unsigned CollapsedNum, EmptyShell);
901 static bool classof(const Stmt *T) {
902 return T->getStmtClass() == OMPForSimdDirectiveClass;
906 /// \brief This represents '#pragma omp sections' directive.
909 /// #pragma omp sections private(a,b) reduction(+:c,d)
911 /// In this example directive '#pragma omp sections' has clauses 'private' with
912 /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
915 class OMPSectionsDirective : public OMPExecutableDirective {
916 friend class ASTStmtReader;
918 /// \brief true if current directive has inner cancel directive.
921 /// \brief Build directive with the given start and end location.
923 /// \param StartLoc Starting location of the directive kind.
924 /// \param EndLoc Ending location of the directive.
925 /// \param NumClauses Number of clauses.
927 OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
929 : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
930 StartLoc, EndLoc, NumClauses, 1),
933 /// \brief Build an empty directive.
935 /// \param NumClauses Number of clauses.
937 explicit OMPSectionsDirective(unsigned NumClauses)
938 : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
939 SourceLocation(), SourceLocation(), NumClauses,
943 /// \brief Set cancel state.
944 void setHasCancel(bool Has) { HasCancel = Has; }
947 /// \brief Creates directive with a list of \a Clauses.
949 /// \param C AST context.
950 /// \param StartLoc Starting location of the directive kind.
951 /// \param EndLoc Ending Location of the directive.
952 /// \param Clauses List of clauses.
953 /// \param AssociatedStmt Statement, associated with the directive.
954 /// \param HasCancel true if current directive has inner directive.
956 static OMPSectionsDirective *
957 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
958 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
960 /// \brief Creates an empty directive with the place for \a NumClauses
963 /// \param C AST context.
964 /// \param NumClauses Number of clauses.
966 static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
967 unsigned NumClauses, EmptyShell);
969 /// \brief Return true if current directive has inner cancel directive.
970 bool hasCancel() const { return HasCancel; }
972 static bool classof(const Stmt *T) {
973 return T->getStmtClass() == OMPSectionsDirectiveClass;
977 /// \brief This represents '#pragma omp section' directive.
980 /// #pragma omp section
983 class OMPSectionDirective : public OMPExecutableDirective {
984 friend class ASTStmtReader;
986 /// \brief true if current directive has inner cancel directive.
989 /// \brief Build directive with the given start and end location.
991 /// \param StartLoc Starting location of the directive kind.
992 /// \param EndLoc Ending location of the directive.
994 OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
995 : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
996 StartLoc, EndLoc, 0, 1),
999 /// \brief Build an empty directive.
1001 explicit OMPSectionDirective()
1002 : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
1003 SourceLocation(), SourceLocation(), 0, 1),
1007 /// \brief Creates directive.
1009 /// \param C AST context.
1010 /// \param StartLoc Starting location of the directive kind.
1011 /// \param EndLoc Ending Location of the directive.
1012 /// \param AssociatedStmt Statement, associated with the directive.
1013 /// \param HasCancel true if current directive has inner directive.
1015 static OMPSectionDirective *Create(const ASTContext &C,
1016 SourceLocation StartLoc,
1017 SourceLocation EndLoc,
1018 Stmt *AssociatedStmt, bool HasCancel);
1020 /// \brief Creates an empty directive.
1022 /// \param C AST context.
1024 static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1026 /// \brief Set cancel state.
1027 void setHasCancel(bool Has) { HasCancel = Has; }
1029 /// \brief Return true if current directive has inner cancel directive.
1030 bool hasCancel() const { return HasCancel; }
1032 static bool classof(const Stmt *T) {
1033 return T->getStmtClass() == OMPSectionDirectiveClass;
1037 /// \brief This represents '#pragma omp single' directive.
1040 /// #pragma omp single private(a,b) copyprivate(c,d)
1042 /// In this example directive '#pragma omp single' has clauses 'private' with
1043 /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
1045 class OMPSingleDirective : public OMPExecutableDirective {
1046 friend class ASTStmtReader;
1047 /// \brief Build directive with the given start and end location.
1049 /// \param StartLoc Starting location of the directive kind.
1050 /// \param EndLoc Ending location of the directive.
1051 /// \param NumClauses Number of clauses.
1053 OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1054 unsigned NumClauses)
1055 : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
1056 StartLoc, EndLoc, NumClauses, 1) {}
1058 /// \brief Build an empty directive.
1060 /// \param NumClauses Number of clauses.
1062 explicit OMPSingleDirective(unsigned NumClauses)
1063 : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
1064 SourceLocation(), SourceLocation(), NumClauses,
1068 /// \brief Creates directive with a list of \a Clauses.
1070 /// \param C AST context.
1071 /// \param StartLoc Starting location of the directive kind.
1072 /// \param EndLoc Ending Location of the directive.
1073 /// \param Clauses List of clauses.
1074 /// \param AssociatedStmt Statement, associated with the directive.
1076 static OMPSingleDirective *
1077 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1078 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1080 /// \brief Creates an empty directive with the place for \a NumClauses
1083 /// \param C AST context.
1084 /// \param NumClauses Number of clauses.
1086 static OMPSingleDirective *CreateEmpty(const ASTContext &C,
1087 unsigned NumClauses, EmptyShell);
1089 static bool classof(const Stmt *T) {
1090 return T->getStmtClass() == OMPSingleDirectiveClass;
1094 /// \brief This represents '#pragma omp master' directive.
1097 /// #pragma omp master
1100 class OMPMasterDirective : public OMPExecutableDirective {
1101 friend class ASTStmtReader;
1102 /// \brief Build directive with the given start and end location.
1104 /// \param StartLoc Starting location of the directive kind.
1105 /// \param EndLoc Ending location of the directive.
1107 OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1108 : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
1109 StartLoc, EndLoc, 0, 1) {}
1111 /// \brief Build an empty directive.
1113 explicit OMPMasterDirective()
1114 : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
1115 SourceLocation(), SourceLocation(), 0, 1) {}
1118 /// \brief Creates directive.
1120 /// \param C AST context.
1121 /// \param StartLoc Starting location of the directive kind.
1122 /// \param EndLoc Ending Location of the directive.
1123 /// \param AssociatedStmt Statement, associated with the directive.
1125 static OMPMasterDirective *Create(const ASTContext &C,
1126 SourceLocation StartLoc,
1127 SourceLocation EndLoc,
1128 Stmt *AssociatedStmt);
1130 /// \brief Creates an empty directive.
1132 /// \param C AST context.
1134 static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1136 static bool classof(const Stmt *T) {
1137 return T->getStmtClass() == OMPMasterDirectiveClass;
1141 /// \brief This represents '#pragma omp critical' directive.
1144 /// #pragma omp critical
1147 class OMPCriticalDirective : public OMPExecutableDirective {
1148 friend class ASTStmtReader;
1149 /// \brief Name of the directive.
1150 DeclarationNameInfo DirName;
1151 /// \brief Build directive with the given start and end location.
1153 /// \param Name Name of the directive.
1154 /// \param StartLoc Starting location of the directive kind.
1155 /// \param EndLoc Ending location of the directive.
1156 /// \param NumClauses Number of clauses.
1158 OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
1159 SourceLocation EndLoc, unsigned NumClauses)
1160 : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
1161 StartLoc, EndLoc, NumClauses, 1),
1164 /// \brief Build an empty directive.
1166 /// \param NumClauses Number of clauses.
1168 explicit OMPCriticalDirective(unsigned NumClauses)
1169 : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
1170 SourceLocation(), SourceLocation(), NumClauses,
1174 /// \brief Set name of the directive.
1176 /// \param Name Name of the directive.
1178 void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
1181 /// \brief Creates directive.
1183 /// \param C AST context.
1184 /// \param Name Name of the directive.
1185 /// \param StartLoc Starting location of the directive kind.
1186 /// \param EndLoc Ending Location of the directive.
1187 /// \param Clauses List of clauses.
1188 /// \param AssociatedStmt Statement, associated with the directive.
1190 static OMPCriticalDirective *
1191 Create(const ASTContext &C, const DeclarationNameInfo &Name,
1192 SourceLocation StartLoc, SourceLocation EndLoc,
1193 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1195 /// \brief Creates an empty directive.
1197 /// \param C AST context.
1198 /// \param NumClauses Number of clauses.
1200 static OMPCriticalDirective *CreateEmpty(const ASTContext &C,
1201 unsigned NumClauses, EmptyShell);
1203 /// \brief Return name of the directive.
1205 DeclarationNameInfo getDirectiveName() const { return DirName; }
1207 static bool classof(const Stmt *T) {
1208 return T->getStmtClass() == OMPCriticalDirectiveClass;
1212 /// \brief This represents '#pragma omp parallel for' directive.
1215 /// #pragma omp parallel for private(a,b) reduction(+:c,d)
1217 /// In this example directive '#pragma omp parallel for' has clauses 'private'
1218 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
1219 /// variables 'c' and 'd'.
1221 class OMPParallelForDirective : public OMPLoopDirective {
1222 friend class ASTStmtReader;
1224 /// \brief true if current region has inner cancel directive.
1227 /// \brief Build directive with the given start and end location.
1229 /// \param StartLoc Starting location of the directive kind.
1230 /// \param EndLoc Ending location of the directive.
1231 /// \param CollapsedNum Number of collapsed nested loops.
1232 /// \param NumClauses Number of clauses.
1234 OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1235 unsigned CollapsedNum, unsigned NumClauses)
1236 : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
1237 StartLoc, EndLoc, CollapsedNum, NumClauses),
1240 /// \brief Build an empty directive.
1242 /// \param CollapsedNum Number of collapsed nested loops.
1243 /// \param NumClauses Number of clauses.
1245 explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses)
1246 : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
1247 SourceLocation(), SourceLocation(), CollapsedNum,
1251 /// \brief Set cancel state.
1252 void setHasCancel(bool Has) { HasCancel = Has; }
1255 /// \brief Creates directive with a list of \a Clauses.
1257 /// \param C AST context.
1258 /// \param StartLoc Starting location of the directive kind.
1259 /// \param EndLoc Ending Location of the directive.
1260 /// \param CollapsedNum Number of collapsed loops.
1261 /// \param Clauses List of clauses.
1262 /// \param AssociatedStmt Statement, associated with the directive.
1263 /// \param Exprs Helper expressions for CodeGen.
1264 /// \param HasCancel true if current directive has inner cancel directive.
1266 static OMPParallelForDirective *
1267 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1268 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1269 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
1271 /// \brief Creates an empty directive with the place
1272 /// for \a NumClauses clauses.
1274 /// \param C AST context.
1275 /// \param CollapsedNum Number of collapsed nested loops.
1276 /// \param NumClauses Number of clauses.
1278 static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
1279 unsigned NumClauses,
1280 unsigned CollapsedNum,
1283 /// \brief Return true if current directive has inner cancel directive.
1284 bool hasCancel() const { return HasCancel; }
1286 static bool classof(const Stmt *T) {
1287 return T->getStmtClass() == OMPParallelForDirectiveClass;
1291 /// \brief This represents '#pragma omp parallel for simd' directive.
1294 /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
1296 /// In this example directive '#pragma omp parallel for simd' has clauses
1297 /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
1298 /// and linear step 's', 'reduction' with operator '+' and variables 'c' and
1301 class OMPParallelForSimdDirective : public OMPLoopDirective {
1302 friend class ASTStmtReader;
1303 /// \brief Build directive with the given start and end location.
1305 /// \param StartLoc Starting location of the directive kind.
1306 /// \param EndLoc Ending location of the directive.
1307 /// \param CollapsedNum Number of collapsed nested loops.
1308 /// \param NumClauses Number of clauses.
1310 OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1311 unsigned CollapsedNum, unsigned NumClauses)
1312 : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
1313 OMPD_parallel_for_simd, StartLoc, EndLoc, CollapsedNum,
1316 /// \brief Build an empty directive.
1318 /// \param CollapsedNum Number of collapsed nested loops.
1319 /// \param NumClauses Number of clauses.
1321 explicit OMPParallelForSimdDirective(unsigned CollapsedNum,
1322 unsigned NumClauses)
1323 : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
1324 OMPD_parallel_for_simd, SourceLocation(),
1325 SourceLocation(), CollapsedNum, NumClauses) {}
1328 /// \brief Creates directive with a list of \a Clauses.
1330 /// \param C AST context.
1331 /// \param StartLoc Starting location of the directive kind.
1332 /// \param EndLoc Ending Location of the directive.
1333 /// \param CollapsedNum Number of collapsed loops.
1334 /// \param Clauses List of clauses.
1335 /// \param AssociatedStmt Statement, associated with the directive.
1336 /// \param Exprs Helper expressions for CodeGen.
1338 static OMPParallelForSimdDirective *
1339 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1340 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1341 Stmt *AssociatedStmt, const HelperExprs &Exprs);
1343 /// \brief Creates an empty directive with the place
1344 /// for \a NumClauses clauses.
1346 /// \param C AST context.
1347 /// \param CollapsedNum Number of collapsed nested loops.
1348 /// \param NumClauses Number of clauses.
1350 static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
1351 unsigned NumClauses,
1352 unsigned CollapsedNum,
1355 static bool classof(const Stmt *T) {
1356 return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
1360 /// \brief This represents '#pragma omp parallel sections' directive.
1363 /// #pragma omp parallel sections private(a,b) reduction(+:c,d)
1365 /// In this example directive '#pragma omp parallel sections' has clauses
1366 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
1367 /// and variables 'c' and 'd'.
1369 class OMPParallelSectionsDirective : public OMPExecutableDirective {
1370 friend class ASTStmtReader;
1372 /// \brief true if current directive has inner cancel directive.
1375 /// \brief Build directive with the given start and end location.
1377 /// \param StartLoc Starting location of the directive kind.
1378 /// \param EndLoc Ending location of the directive.
1379 /// \param NumClauses Number of clauses.
1381 OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1382 unsigned NumClauses)
1383 : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
1384 OMPD_parallel_sections, StartLoc, EndLoc,
1388 /// \brief Build an empty directive.
1390 /// \param NumClauses Number of clauses.
1392 explicit OMPParallelSectionsDirective(unsigned NumClauses)
1393 : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
1394 OMPD_parallel_sections, SourceLocation(),
1395 SourceLocation(), NumClauses, 1),
1398 /// \brief Set cancel state.
1399 void setHasCancel(bool Has) { HasCancel = Has; }
1402 /// \brief Creates directive with a list of \a Clauses.
1404 /// \param C AST context.
1405 /// \param StartLoc Starting location of the directive kind.
1406 /// \param EndLoc Ending Location of the directive.
1407 /// \param Clauses List of clauses.
1408 /// \param AssociatedStmt Statement, associated with the directive.
1409 /// \param HasCancel true if current directive has inner cancel directive.
1411 static OMPParallelSectionsDirective *
1412 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1413 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
1415 /// \brief Creates an empty directive with the place for \a NumClauses
1418 /// \param C AST context.
1419 /// \param NumClauses Number of clauses.
1421 static OMPParallelSectionsDirective *
1422 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
1424 /// \brief Return true if current directive has inner cancel directive.
1425 bool hasCancel() const { return HasCancel; }
1427 static bool classof(const Stmt *T) {
1428 return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
1432 /// \brief This represents '#pragma omp task' directive.
1435 /// #pragma omp task private(a,b) final(d)
1437 /// In this example directive '#pragma omp task' has clauses 'private' with the
1438 /// variables 'a' and 'b' and 'final' with condition 'd'.
1440 class OMPTaskDirective : public OMPExecutableDirective {
1441 friend class ASTStmtReader;
1442 /// \brief true if this directive has inner cancel directive.
1445 /// \brief Build directive with the given start and end location.
1447 /// \param StartLoc Starting location of the directive kind.
1448 /// \param EndLoc Ending location of the directive.
1449 /// \param NumClauses Number of clauses.
1451 OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1452 unsigned NumClauses)
1453 : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc,
1454 EndLoc, NumClauses, 1),
1457 /// \brief Build an empty directive.
1459 /// \param NumClauses Number of clauses.
1461 explicit OMPTaskDirective(unsigned NumClauses)
1462 : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task,
1463 SourceLocation(), SourceLocation(), NumClauses,
1467 /// \brief Set cancel state.
1468 void setHasCancel(bool Has) { HasCancel = Has; }
1471 /// \brief Creates directive with a list of \a Clauses.
1473 /// \param C AST context.
1474 /// \param StartLoc Starting location of the directive kind.
1475 /// \param EndLoc Ending Location of the directive.
1476 /// \param Clauses List of clauses.
1477 /// \param AssociatedStmt Statement, associated with the directive.
1478 /// \param HasCancel true, if current directive has inner cancel directive.
1480 static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1481 SourceLocation EndLoc,
1482 ArrayRef<OMPClause *> Clauses,
1483 Stmt *AssociatedStmt, bool HasCancel);
1485 /// \brief Creates an empty directive with the place for \a NumClauses
1488 /// \param C AST context.
1489 /// \param NumClauses Number of clauses.
1491 static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1494 /// \brief Return true if current directive has inner cancel directive.
1495 bool hasCancel() const { return HasCancel; }
1497 static bool classof(const Stmt *T) {
1498 return T->getStmtClass() == OMPTaskDirectiveClass;
1502 /// \brief This represents '#pragma omp taskyield' directive.
1505 /// #pragma omp taskyield
1508 class OMPTaskyieldDirective : public OMPExecutableDirective {
1509 friend class ASTStmtReader;
1510 /// \brief Build directive with the given start and end location.
1512 /// \param StartLoc Starting location of the directive kind.
1513 /// \param EndLoc Ending location of the directive.
1515 OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1516 : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
1517 StartLoc, EndLoc, 0, 0) {}
1519 /// \brief Build an empty directive.
1521 explicit OMPTaskyieldDirective()
1522 : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
1523 SourceLocation(), SourceLocation(), 0, 0) {}
1526 /// \brief Creates directive.
1528 /// \param C AST context.
1529 /// \param StartLoc Starting location of the directive kind.
1530 /// \param EndLoc Ending Location of the directive.
1532 static OMPTaskyieldDirective *
1533 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1535 /// \brief Creates an empty directive.
1537 /// \param C AST context.
1539 static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1541 static bool classof(const Stmt *T) {
1542 return T->getStmtClass() == OMPTaskyieldDirectiveClass;
1546 /// \brief This represents '#pragma omp barrier' directive.
1549 /// #pragma omp barrier
1552 class OMPBarrierDirective : public OMPExecutableDirective {
1553 friend class ASTStmtReader;
1554 /// \brief Build directive with the given start and end location.
1556 /// \param StartLoc Starting location of the directive kind.
1557 /// \param EndLoc Ending location of the directive.
1559 OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1560 : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
1561 StartLoc, EndLoc, 0, 0) {}
1563 /// \brief Build an empty directive.
1565 explicit OMPBarrierDirective()
1566 : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
1567 SourceLocation(), SourceLocation(), 0, 0) {}
1570 /// \brief Creates directive.
1572 /// \param C AST context.
1573 /// \param StartLoc Starting location of the directive kind.
1574 /// \param EndLoc Ending Location of the directive.
1576 static OMPBarrierDirective *
1577 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1579 /// \brief Creates an empty directive.
1581 /// \param C AST context.
1583 static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1585 static bool classof(const Stmt *T) {
1586 return T->getStmtClass() == OMPBarrierDirectiveClass;
1590 /// \brief This represents '#pragma omp taskwait' directive.
1593 /// #pragma omp taskwait
1596 class OMPTaskwaitDirective : public OMPExecutableDirective {
1597 friend class ASTStmtReader;
1598 /// \brief Build directive with the given start and end location.
1600 /// \param StartLoc Starting location of the directive kind.
1601 /// \param EndLoc Ending location of the directive.
1603 OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1604 : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
1605 StartLoc, EndLoc, 0, 0) {}
1607 /// \brief Build an empty directive.
1609 explicit OMPTaskwaitDirective()
1610 : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
1611 SourceLocation(), SourceLocation(), 0, 0) {}
1614 /// \brief Creates directive.
1616 /// \param C AST context.
1617 /// \param StartLoc Starting location of the directive kind.
1618 /// \param EndLoc Ending Location of the directive.
1620 static OMPTaskwaitDirective *
1621 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1623 /// \brief Creates an empty directive.
1625 /// \param C AST context.
1627 static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1629 static bool classof(const Stmt *T) {
1630 return T->getStmtClass() == OMPTaskwaitDirectiveClass;
1634 /// \brief This represents '#pragma omp taskgroup' directive.
1637 /// #pragma omp taskgroup
1640 class OMPTaskgroupDirective : public OMPExecutableDirective {
1641 friend class ASTStmtReader;
1642 /// \brief Build directive with the given start and end location.
1644 /// \param StartLoc Starting location of the directive kind.
1645 /// \param EndLoc Ending location of the directive.
1647 OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1648 : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
1649 StartLoc, EndLoc, 0, 1) {}
1651 /// \brief Build an empty directive.
1653 explicit OMPTaskgroupDirective()
1654 : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
1655 SourceLocation(), SourceLocation(), 0, 1) {}
1658 /// \brief Creates directive.
1660 /// \param C AST context.
1661 /// \param StartLoc Starting location of the directive kind.
1662 /// \param EndLoc Ending Location of the directive.
1663 /// \param AssociatedStmt Statement, associated with the directive.
1665 static OMPTaskgroupDirective *Create(const ASTContext &C,
1666 SourceLocation StartLoc,
1667 SourceLocation EndLoc,
1668 Stmt *AssociatedStmt);
1670 /// \brief Creates an empty directive.
1672 /// \param C AST context.
1674 static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1676 static bool classof(const Stmt *T) {
1677 return T->getStmtClass() == OMPTaskgroupDirectiveClass;
1681 /// \brief This represents '#pragma omp flush' directive.
1684 /// #pragma omp flush(a,b)
1686 /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
1688 /// 'omp flush' directive does not have clauses but have an optional list of
1689 /// variables to flush. This list of variables is stored within some fake clause
1691 class OMPFlushDirective : public OMPExecutableDirective {
1692 friend class ASTStmtReader;
1693 /// \brief Build directive with the given start and end location.
1695 /// \param StartLoc Starting location of the directive kind.
1696 /// \param EndLoc Ending location of the directive.
1697 /// \param NumClauses Number of clauses.
1699 OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1700 unsigned NumClauses)
1701 : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
1702 StartLoc, EndLoc, NumClauses, 0) {}
1704 /// \brief Build an empty directive.
1706 /// \param NumClauses Number of clauses.
1708 explicit OMPFlushDirective(unsigned NumClauses)
1709 : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
1710 SourceLocation(), SourceLocation(), NumClauses,
1714 /// \brief Creates directive with a list of \a Clauses.
1716 /// \param C AST context.
1717 /// \param StartLoc Starting location of the directive kind.
1718 /// \param EndLoc Ending Location of the directive.
1719 /// \param Clauses List of clauses (only single OMPFlushClause clause is
1722 static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1723 SourceLocation EndLoc,
1724 ArrayRef<OMPClause *> Clauses);
1726 /// \brief Creates an empty directive with the place for \a NumClauses
1729 /// \param C AST context.
1730 /// \param NumClauses Number of clauses.
1732 static OMPFlushDirective *CreateEmpty(const ASTContext &C,
1733 unsigned NumClauses, EmptyShell);
1735 static bool classof(const Stmt *T) {
1736 return T->getStmtClass() == OMPFlushDirectiveClass;
1740 /// \brief This represents '#pragma omp ordered' directive.
1743 /// #pragma omp ordered
1746 class OMPOrderedDirective : public OMPExecutableDirective {
1747 friend class ASTStmtReader;
1748 /// \brief Build directive with the given start and end location.
1750 /// \param StartLoc Starting location of the directive kind.
1751 /// \param EndLoc Ending location of the directive.
1752 /// \param NumClauses Number of clauses.
1754 OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1755 unsigned NumClauses)
1756 : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
1757 StartLoc, EndLoc, NumClauses, 1) {}
1759 /// \brief Build an empty directive.
1761 /// \param NumClauses Number of clauses.
1763 explicit OMPOrderedDirective(unsigned NumClauses)
1764 : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
1765 SourceLocation(), SourceLocation(), NumClauses,
1769 /// \brief Creates directive.
1771 /// \param C AST context.
1772 /// \param StartLoc Starting location of the directive kind.
1773 /// \param EndLoc Ending Location of the directive.
1774 /// \param Clauses List of clauses.
1775 /// \param AssociatedStmt Statement, associated with the directive.
1777 static OMPOrderedDirective *
1778 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1779 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1781 /// \brief Creates an empty directive.
1783 /// \param C AST context.
1784 /// \param NumClauses Number of clauses.
1786 static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
1787 unsigned NumClauses, EmptyShell);
1789 static bool classof(const Stmt *T) {
1790 return T->getStmtClass() == OMPOrderedDirectiveClass;
1794 /// \brief This represents '#pragma omp atomic' directive.
1797 /// #pragma omp atomic capture
1799 /// In this example directive '#pragma omp atomic' has clause 'capture'.
1801 class OMPAtomicDirective : public OMPExecutableDirective {
1802 friend class ASTStmtReader;
1803 /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
1804 /// have atomic expressions of forms
1806 /// x = x binop expr;
1807 /// x = expr binop x;
1809 /// This field is true for the first form of the expression and false for the
1810 /// second. Required for correct codegen of non-associative operations (like
1812 bool IsXLHSInRHSPart;
1813 /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
1814 /// have atomic expressions of forms
1816 /// v = x; <update x>;
1817 /// <update x>; v = x;
1819 /// This field is true for the first(postfix) form of the expression and false
1821 bool IsPostfixUpdate;
1823 /// \brief Build directive with the given start and end location.
1825 /// \param StartLoc Starting location of the directive kind.
1826 /// \param EndLoc Ending location of the directive.
1827 /// \param NumClauses Number of clauses.
1829 OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1830 unsigned NumClauses)
1831 : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
1832 StartLoc, EndLoc, NumClauses, 5),
1833 IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
1835 /// \brief Build an empty directive.
1837 /// \param NumClauses Number of clauses.
1839 explicit OMPAtomicDirective(unsigned NumClauses)
1840 : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
1841 SourceLocation(), SourceLocation(), NumClauses,
1843 IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
1845 /// \brief Set 'x' part of the associated expression/statement.
1846 void setX(Expr *X) { *std::next(child_begin()) = X; }
1847 /// \brief Set helper expression of the form
1848 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
1849 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
1850 void setUpdateExpr(Expr *UE) { *std::next(child_begin(), 2) = UE; }
1851 /// \brief Set 'v' part of the associated expression/statement.
1852 void setV(Expr *V) { *std::next(child_begin(), 3) = V; }
1853 /// \brief Set 'expr' part of the associated expression/statement.
1854 void setExpr(Expr *E) { *std::next(child_begin(), 4) = E; }
1857 /// \brief Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
1858 /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
1859 /// detailed description of 'x', 'v' and 'expr').
1861 /// \param C AST context.
1862 /// \param StartLoc Starting location of the directive kind.
1863 /// \param EndLoc Ending Location of the directive.
1864 /// \param Clauses List of clauses.
1865 /// \param AssociatedStmt Statement, associated with the directive.
1866 /// \param X 'x' part of the associated expression/statement.
1867 /// \param V 'v' part of the associated expression/statement.
1868 /// \param E 'expr' part of the associated expression/statement.
1869 /// \param UE Helper expression of the form
1870 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
1871 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
1872 /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the
1874 /// \param IsPostfixUpdate true if original value of 'x' must be stored in
1875 /// 'v', not an updated one.
1876 static OMPAtomicDirective *
1877 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1878 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V,
1879 Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate);
1881 /// \brief Creates an empty directive with the place for \a NumClauses
1884 /// \param C AST context.
1885 /// \param NumClauses Number of clauses.
1887 static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
1888 unsigned NumClauses, EmptyShell);
1890 /// \brief Get 'x' part of the associated expression/statement.
1891 Expr *getX() { return cast_or_null<Expr>(*std::next(child_begin())); }
1892 const Expr *getX() const {
1893 return cast_or_null<Expr>(*std::next(child_begin()));
1895 /// \brief Get helper expression of the form
1896 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
1897 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
1898 Expr *getUpdateExpr() {
1899 return cast_or_null<Expr>(*std::next(child_begin(), 2));
1901 const Expr *getUpdateExpr() const {
1902 return cast_or_null<Expr>(*std::next(child_begin(), 2));
1904 /// \brief Return true if helper update expression has form
1905 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
1906 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
1907 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
1908 /// \brief Return true if 'v' expression must be updated to original value of
1909 /// 'x', false if 'v' must be updated to the new value of 'x'.
1910 bool isPostfixUpdate() const { return IsPostfixUpdate; }
1911 /// \brief Get 'v' part of the associated expression/statement.
1912 Expr *getV() { return cast_or_null<Expr>(*std::next(child_begin(), 3)); }
1913 const Expr *getV() const {
1914 return cast_or_null<Expr>(*std::next(child_begin(), 3));
1916 /// \brief Get 'expr' part of the associated expression/statement.
1917 Expr *getExpr() { return cast_or_null<Expr>(*std::next(child_begin(), 4)); }
1918 const Expr *getExpr() const {
1919 return cast_or_null<Expr>(*std::next(child_begin(), 4));
1922 static bool classof(const Stmt *T) {
1923 return T->getStmtClass() == OMPAtomicDirectiveClass;
1927 /// \brief This represents '#pragma omp target' directive.
1930 /// #pragma omp target if(a)
1932 /// In this example directive '#pragma omp target' has clause 'if' with
1935 class OMPTargetDirective : public OMPExecutableDirective {
1936 friend class ASTStmtReader;
1937 /// \brief Build directive with the given start and end location.
1939 /// \param StartLoc Starting location of the directive kind.
1940 /// \param EndLoc Ending location of the directive.
1941 /// \param NumClauses Number of clauses.
1943 OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1944 unsigned NumClauses)
1945 : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
1946 StartLoc, EndLoc, NumClauses, 1) {}
1948 /// \brief Build an empty directive.
1950 /// \param NumClauses Number of clauses.
1952 explicit OMPTargetDirective(unsigned NumClauses)
1953 : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
1954 SourceLocation(), SourceLocation(), NumClauses,
1958 /// \brief Creates directive with a list of \a Clauses.
1960 /// \param C AST context.
1961 /// \param StartLoc Starting location of the directive kind.
1962 /// \param EndLoc Ending Location of the directive.
1963 /// \param Clauses List of clauses.
1964 /// \param AssociatedStmt Statement, associated with the directive.
1966 static OMPTargetDirective *
1967 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1968 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1970 /// \brief Creates an empty directive with the place for \a NumClauses
1973 /// \param C AST context.
1974 /// \param NumClauses Number of clauses.
1976 static OMPTargetDirective *CreateEmpty(const ASTContext &C,
1977 unsigned NumClauses, EmptyShell);
1979 static bool classof(const Stmt *T) {
1980 return T->getStmtClass() == OMPTargetDirectiveClass;
1984 /// \brief This represents '#pragma omp target data' directive.
1987 /// #pragma omp target data device(0) if(a) map(b[:])
1989 /// In this example directive '#pragma omp target data' has clauses 'device'
1990 /// with the value '0', 'if' with condition 'a' and 'map' with array
1993 class OMPTargetDataDirective : public OMPExecutableDirective {
1994 friend class ASTStmtReader;
1995 /// \brief Build directive with the given start and end location.
1997 /// \param StartLoc Starting location of the directive kind.
1998 /// \param EndLoc Ending Location of the directive.
1999 /// \param NumClauses The number of clauses.
2001 OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2002 unsigned NumClauses)
2003 : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
2004 OMPD_target_data, StartLoc, EndLoc, NumClauses,
2007 /// \brief Build an empty directive.
2009 /// \param NumClauses Number of clauses.
2011 explicit OMPTargetDataDirective(unsigned NumClauses)
2012 : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
2013 OMPD_target_data, SourceLocation(),
2014 SourceLocation(), NumClauses, 1) {}
2017 /// \brief Creates directive with a list of \a Clauses.
2019 /// \param C AST context.
2020 /// \param StartLoc Starting location of the directive kind.
2021 /// \param EndLoc Ending Location of the directive.
2022 /// \param Clauses List of clauses.
2023 /// \param AssociatedStmt Statement, associated with the directive.
2025 static OMPTargetDataDirective *
2026 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2027 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2029 /// \brief Creates an empty directive with the place for \a N clauses.
2031 /// \param C AST context.
2032 /// \param N The number of clauses.
2034 static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N,
2037 static bool classof(const Stmt *T) {
2038 return T->getStmtClass() == OMPTargetDataDirectiveClass;
2042 /// \brief This represents '#pragma omp teams' directive.
2045 /// #pragma omp teams if(a)
2047 /// In this example directive '#pragma omp teams' has clause 'if' with
2050 class OMPTeamsDirective : public OMPExecutableDirective {
2051 friend class ASTStmtReader;
2052 /// \brief Build directive with the given start and end location.
2054 /// \param StartLoc Starting location of the directive kind.
2055 /// \param EndLoc Ending location of the directive.
2056 /// \param NumClauses Number of clauses.
2058 OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2059 unsigned NumClauses)
2060 : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
2061 StartLoc, EndLoc, NumClauses, 1) {}
2063 /// \brief Build an empty directive.
2065 /// \param NumClauses Number of clauses.
2067 explicit OMPTeamsDirective(unsigned NumClauses)
2068 : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
2069 SourceLocation(), SourceLocation(), NumClauses,
2073 /// \brief Creates directive with a list of \a Clauses.
2075 /// \param C AST context.
2076 /// \param StartLoc Starting location of the directive kind.
2077 /// \param EndLoc Ending Location of the directive.
2078 /// \param Clauses List of clauses.
2079 /// \param AssociatedStmt Statement, associated with the directive.
2081 static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2082 SourceLocation EndLoc,
2083 ArrayRef<OMPClause *> Clauses,
2084 Stmt *AssociatedStmt);
2086 /// \brief Creates an empty directive with the place for \a NumClauses
2089 /// \param C AST context.
2090 /// \param NumClauses Number of clauses.
2092 static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
2093 unsigned NumClauses, EmptyShell);
2095 static bool classof(const Stmt *T) {
2096 return T->getStmtClass() == OMPTeamsDirectiveClass;
2100 /// \brief This represents '#pragma omp cancellation point' directive.
2103 /// #pragma omp cancellation point for
2106 /// In this example a cancellation point is created for innermost 'for' region.
2107 class OMPCancellationPointDirective : public OMPExecutableDirective {
2108 friend class ASTStmtReader;
2109 OpenMPDirectiveKind CancelRegion;
2110 /// \brief Build directive with the given start and end location.
2112 /// \param StartLoc Starting location of the directive kind.
2113 /// \param EndLoc Ending location of the directive.
2115 OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2116 : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
2117 OMPD_cancellation_point, StartLoc, EndLoc, 0, 0),
2118 CancelRegion(OMPD_unknown) {}
2120 /// \brief Build an empty directive.
2122 explicit OMPCancellationPointDirective()
2123 : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
2124 OMPD_cancellation_point, SourceLocation(),
2125 SourceLocation(), 0, 0),
2126 CancelRegion(OMPD_unknown) {}
2128 /// \brief Set cancel region for current cancellation point.
2129 /// \param CR Cancellation region.
2130 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
2133 /// \brief Creates directive.
2135 /// \param C AST context.
2136 /// \param StartLoc Starting location of the directive kind.
2137 /// \param EndLoc Ending Location of the directive.
2139 static OMPCancellationPointDirective *
2140 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2141 OpenMPDirectiveKind CancelRegion);
2143 /// \brief Creates an empty directive.
2145 /// \param C AST context.
2147 static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
2150 /// \brief Get cancellation region for the current cancellation point.
2151 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
2153 static bool classof(const Stmt *T) {
2154 return T->getStmtClass() == OMPCancellationPointDirectiveClass;
2158 /// \brief This represents '#pragma omp cancel' directive.
2161 /// #pragma omp cancel for
2164 /// In this example a cancel is created for innermost 'for' region.
2165 class OMPCancelDirective : public OMPExecutableDirective {
2166 friend class ASTStmtReader;
2167 OpenMPDirectiveKind CancelRegion;
2168 /// \brief Build directive with the given start and end location.
2170 /// \param StartLoc Starting location of the directive kind.
2171 /// \param EndLoc Ending location of the directive.
2172 /// \param NumClauses Number of clauses.
2174 OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2175 unsigned NumClauses)
2176 : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
2177 StartLoc, EndLoc, NumClauses, 0),
2178 CancelRegion(OMPD_unknown) {}
2180 /// \brief Build an empty directive.
2182 /// \param NumClauses Number of clauses.
2183 explicit OMPCancelDirective(unsigned NumClauses)
2184 : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
2185 SourceLocation(), SourceLocation(), NumClauses,
2187 CancelRegion(OMPD_unknown) {}
2189 /// \brief Set cancel region for current cancellation point.
2190 /// \param CR Cancellation region.
2191 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
2194 /// \brief Creates directive.
2196 /// \param C AST context.
2197 /// \param StartLoc Starting location of the directive kind.
2198 /// \param EndLoc Ending Location of the directive.
2199 /// \param Clauses List of clauses.
2201 static OMPCancelDirective *
2202 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2203 ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
2205 /// \brief Creates an empty directive.
2207 /// \param C AST context.
2208 /// \param NumClauses Number of clauses.
2210 static OMPCancelDirective *CreateEmpty(const ASTContext &C,
2211 unsigned NumClauses, EmptyShell);
2213 /// \brief Get cancellation region for the current cancellation point.
2214 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
2216 static bool classof(const Stmt *T) {
2217 return T->getStmtClass() == OMPCancelDirectiveClass;
2221 /// \brief This represents '#pragma omp taskloop' directive.
2224 /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
2226 /// In this example directive '#pragma omp taskloop' has clauses 'private'
2227 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
2228 /// 'num_tasks' with expression 'num'.
2230 class OMPTaskLoopDirective : public OMPLoopDirective {
2231 friend class ASTStmtReader;
2232 /// \brief Build directive with the given start and end location.
2234 /// \param StartLoc Starting location of the directive kind.
2235 /// \param EndLoc Ending location of the directive.
2236 /// \param CollapsedNum Number of collapsed nested loops.
2237 /// \param NumClauses Number of clauses.
2239 OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2240 unsigned CollapsedNum, unsigned NumClauses)
2241 : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
2242 StartLoc, EndLoc, CollapsedNum, NumClauses) {}
2244 /// \brief Build an empty directive.
2246 /// \param CollapsedNum Number of collapsed nested loops.
2247 /// \param NumClauses Number of clauses.
2249 explicit OMPTaskLoopDirective(unsigned CollapsedNum, unsigned NumClauses)
2250 : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
2251 SourceLocation(), SourceLocation(), CollapsedNum,
2255 /// \brief Creates directive with a list of \a Clauses.
2257 /// \param C AST context.
2258 /// \param StartLoc Starting location of the directive kind.
2259 /// \param EndLoc Ending Location of the directive.
2260 /// \param CollapsedNum Number of collapsed loops.
2261 /// \param Clauses List of clauses.
2262 /// \param AssociatedStmt Statement, associated with the directive.
2263 /// \param Exprs Helper expressions for CodeGen.
2265 static OMPTaskLoopDirective *
2266 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2267 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2268 Stmt *AssociatedStmt, const HelperExprs &Exprs);
2270 /// \brief Creates an empty directive with the place
2271 /// for \a NumClauses clauses.
2273 /// \param C AST context.
2274 /// \param CollapsedNum Number of collapsed nested loops.
2275 /// \param NumClauses Number of clauses.
2277 static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C,
2278 unsigned NumClauses,
2279 unsigned CollapsedNum, EmptyShell);
2281 static bool classof(const Stmt *T) {
2282 return T->getStmtClass() == OMPTaskLoopDirectiveClass;
2286 /// \brief This represents '#pragma omp taskloop simd' directive.
2289 /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
2291 /// In this example directive '#pragma omp taskloop simd' has clauses 'private'
2292 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
2293 /// 'num_tasks' with expression 'num'.
2295 class OMPTaskLoopSimdDirective : public OMPLoopDirective {
2296 friend class ASTStmtReader;
2297 /// \brief Build directive with the given start and end location.
2299 /// \param StartLoc Starting location of the directive kind.
2300 /// \param EndLoc Ending location of the directive.
2301 /// \param CollapsedNum Number of collapsed nested loops.
2302 /// \param NumClauses Number of clauses.
2304 OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2305 unsigned CollapsedNum, unsigned NumClauses)
2306 : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
2307 OMPD_taskloop_simd, StartLoc, EndLoc, CollapsedNum,
2310 /// \brief Build an empty directive.
2312 /// \param CollapsedNum Number of collapsed nested loops.
2313 /// \param NumClauses Number of clauses.
2315 explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
2316 : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
2317 OMPD_taskloop_simd, SourceLocation(), SourceLocation(),
2318 CollapsedNum, NumClauses) {}
2321 /// \brief Creates directive with a list of \a Clauses.
2323 /// \param C AST context.
2324 /// \param StartLoc Starting location of the directive kind.
2325 /// \param EndLoc Ending Location of the directive.
2326 /// \param CollapsedNum Number of collapsed loops.
2327 /// \param Clauses List of clauses.
2328 /// \param AssociatedStmt Statement, associated with the directive.
2329 /// \param Exprs Helper expressions for CodeGen.
2331 static OMPTaskLoopSimdDirective *
2332 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2333 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2334 Stmt *AssociatedStmt, const HelperExprs &Exprs);
2336 /// \brief Creates an empty directive with the place
2337 /// for \a NumClauses clauses.
2339 /// \param C AST context.
2340 /// \param CollapsedNum Number of collapsed nested loops.
2341 /// \param NumClauses Number of clauses.
2343 static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
2344 unsigned NumClauses,
2345 unsigned CollapsedNum,
2348 static bool classof(const Stmt *T) {
2349 return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass;
2353 /// \brief This represents '#pragma omp distribute' directive.
2356 /// #pragma omp distribute private(a,b)
2358 /// In this example directive '#pragma omp distribute' has clauses 'private'
2359 /// with the variables 'a' and 'b'
2361 class OMPDistributeDirective : public OMPLoopDirective {
2362 friend class ASTStmtReader;
2364 /// \brief Build directive with the given start and end location.
2366 /// \param StartLoc Starting location of the directive kind.
2367 /// \param EndLoc Ending location of the directive.
2368 /// \param CollapsedNum Number of collapsed nested loops.
2369 /// \param NumClauses Number of clauses.
2371 OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2372 unsigned CollapsedNum, unsigned NumClauses)
2373 : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
2374 StartLoc, EndLoc, CollapsedNum, NumClauses)
2377 /// \brief Build an empty directive.
2379 /// \param CollapsedNum Number of collapsed nested loops.
2380 /// \param NumClauses Number of clauses.
2382 explicit OMPDistributeDirective(unsigned CollapsedNum, unsigned NumClauses)
2383 : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
2384 SourceLocation(), SourceLocation(), CollapsedNum,
2389 /// \brief Creates directive with a list of \a Clauses.
2391 /// \param C AST context.
2392 /// \param StartLoc Starting location of the directive kind.
2393 /// \param EndLoc Ending Location of the directive.
2394 /// \param CollapsedNum Number of collapsed loops.
2395 /// \param Clauses List of clauses.
2396 /// \param AssociatedStmt Statement, associated with the directive.
2397 /// \param Exprs Helper expressions for CodeGen.
2399 static OMPDistributeDirective *
2400 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2401 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2402 Stmt *AssociatedStmt, const HelperExprs &Exprs);
2404 /// \brief Creates an empty directive with the place
2405 /// for \a NumClauses clauses.
2407 /// \param C AST context.
2408 /// \param CollapsedNum Number of collapsed nested loops.
2409 /// \param NumClauses Number of clauses.
2411 static OMPDistributeDirective *CreateEmpty(const ASTContext &C,
2412 unsigned NumClauses,
2413 unsigned CollapsedNum, EmptyShell);
2415 static bool classof(const Stmt *T) {
2416 return T->getStmtClass() == OMPDistributeDirectiveClass;
2420 } // end namespace clang