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 7 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.
307 AssociatedStmtOffset = 0,
308 IterationVariableOffset = 1,
309 LastIterationOffset = 2,
310 CalcLastIterationOffset = 3,
311 PreConditionOffset = 4,
315 // The '...End' enumerators do not correspond to child expressions - they
316 // specify the offset to the end (and start of the following counters/
317 // updates/finals arrays).
319 // The following 7 exprs are used by worksharing loops only.
320 IsLastIterVariableOffset = 8,
321 LowerBoundVariableOffset = 9,
322 UpperBoundVariableOffset = 10,
323 StrideVariableOffset = 11,
324 EnsureUpperBoundOffset = 12,
325 NextLowerBoundOffset = 13,
326 NextUpperBoundOffset = 14,
327 // Offset to the end (and start of the following counters/updates/finals
328 // arrays) for worksharing loop directives.
332 /// \brief Get the counters storage.
333 MutableArrayRef<Expr *> getCounters() {
334 Expr **Storage = reinterpret_cast<Expr **>(
335 &(*(std::next(child_begin(), getArraysOffset(getDirectiveKind())))));
336 return MutableArrayRef<Expr *>(Storage, CollapsedNum);
339 /// \brief Get the private counters storage.
340 MutableArrayRef<Expr *> getPrivateCounters() {
341 Expr **Storage = reinterpret_cast<Expr **>(&*std::next(
342 child_begin(), getArraysOffset(getDirectiveKind()) + CollapsedNum));
343 return MutableArrayRef<Expr *>(Storage, CollapsedNum);
346 /// \brief Get the updates storage.
347 MutableArrayRef<Expr *> getInits() {
348 Expr **Storage = reinterpret_cast<Expr **>(
349 &*std::next(child_begin(),
350 getArraysOffset(getDirectiveKind()) + 2 * CollapsedNum));
351 return MutableArrayRef<Expr *>(Storage, CollapsedNum);
354 /// \brief Get the updates storage.
355 MutableArrayRef<Expr *> getUpdates() {
356 Expr **Storage = reinterpret_cast<Expr **>(
357 &*std::next(child_begin(),
358 getArraysOffset(getDirectiveKind()) + 3 * CollapsedNum));
359 return MutableArrayRef<Expr *>(Storage, CollapsedNum);
362 /// \brief Get the final counter updates storage.
363 MutableArrayRef<Expr *> getFinals() {
364 Expr **Storage = reinterpret_cast<Expr **>(
365 &*std::next(child_begin(),
366 getArraysOffset(getDirectiveKind()) + 4 * CollapsedNum));
367 return MutableArrayRef<Expr *>(Storage, CollapsedNum);
371 /// \brief Build instance of loop directive of class \a Kind.
373 /// \param SC Statement class.
374 /// \param Kind Kind of OpenMP directive.
375 /// \param StartLoc Starting location of the directive (directive keyword).
376 /// \param EndLoc Ending location of the directive.
377 /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
378 /// \param NumClauses Number of clauses.
379 /// \param NumSpecialChildren Number of additional directive-specific stmts.
381 template <typename T>
382 OMPLoopDirective(const T *That, StmtClass SC, OpenMPDirectiveKind Kind,
383 SourceLocation StartLoc, SourceLocation EndLoc,
384 unsigned CollapsedNum, unsigned NumClauses,
385 unsigned NumSpecialChildren = 0)
386 : OMPExecutableDirective(That, SC, Kind, StartLoc, EndLoc, NumClauses,
387 numLoopChildren(CollapsedNum, Kind) +
389 CollapsedNum(CollapsedNum) {}
391 /// \brief Offset to the start of children expression arrays.
392 static unsigned getArraysOffset(OpenMPDirectiveKind Kind) {
393 return (isOpenMPWorksharingDirective(Kind) ||
394 isOpenMPTaskLoopDirective(Kind) ||
395 isOpenMPDistributeDirective(Kind))
400 /// \brief Children number.
401 static unsigned numLoopChildren(unsigned CollapsedNum,
402 OpenMPDirectiveKind Kind) {
403 return getArraysOffset(Kind) + 5 * CollapsedNum; // Counters,
404 // PrivateCounters, Inits,
405 // Updates and Finals
408 void setIterationVariable(Expr *IV) {
409 *std::next(child_begin(), IterationVariableOffset) = IV;
411 void setLastIteration(Expr *LI) {
412 *std::next(child_begin(), LastIterationOffset) = LI;
414 void setCalcLastIteration(Expr *CLI) {
415 *std::next(child_begin(), CalcLastIterationOffset) = CLI;
417 void setPreCond(Expr *PC) {
418 *std::next(child_begin(), PreConditionOffset) = PC;
420 void setCond(Expr *Cond) {
421 *std::next(child_begin(), CondOffset) = Cond;
423 void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; }
424 void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; }
425 void setIsLastIterVariable(Expr *IL) {
426 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
427 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
428 isOpenMPDistributeDirective(getDirectiveKind())) &&
429 "expected worksharing loop directive");
430 *std::next(child_begin(), IsLastIterVariableOffset) = IL;
432 void setLowerBoundVariable(Expr *LB) {
433 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
434 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
435 isOpenMPDistributeDirective(getDirectiveKind())) &&
436 "expected worksharing loop directive");
437 *std::next(child_begin(), LowerBoundVariableOffset) = LB;
439 void setUpperBoundVariable(Expr *UB) {
440 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
441 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
442 isOpenMPDistributeDirective(getDirectiveKind())) &&
443 "expected worksharing loop directive");
444 *std::next(child_begin(), UpperBoundVariableOffset) = UB;
446 void setStrideVariable(Expr *ST) {
447 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
448 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
449 isOpenMPDistributeDirective(getDirectiveKind())) &&
450 "expected worksharing loop directive");
451 *std::next(child_begin(), StrideVariableOffset) = ST;
453 void setEnsureUpperBound(Expr *EUB) {
454 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
455 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
456 isOpenMPDistributeDirective(getDirectiveKind())) &&
457 "expected worksharing loop directive");
458 *std::next(child_begin(), EnsureUpperBoundOffset) = EUB;
460 void setNextLowerBound(Expr *NLB) {
461 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
462 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
463 isOpenMPDistributeDirective(getDirectiveKind())) &&
464 "expected worksharing loop directive");
465 *std::next(child_begin(), NextLowerBoundOffset) = NLB;
467 void setNextUpperBound(Expr *NUB) {
468 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
469 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
470 isOpenMPDistributeDirective(getDirectiveKind())) &&
471 "expected worksharing loop directive");
472 *std::next(child_begin(), NextUpperBoundOffset) = NUB;
474 void setCounters(ArrayRef<Expr *> A);
475 void setPrivateCounters(ArrayRef<Expr *> A);
476 void setInits(ArrayRef<Expr *> A);
477 void setUpdates(ArrayRef<Expr *> A);
478 void setFinals(ArrayRef<Expr *> A);
481 /// \brief The expressions built for the OpenMP loop CodeGen for the
482 /// whole collapsed loop nest.
484 /// \brief Loop iteration variable.
485 Expr *IterationVarRef;
486 /// \brief Loop last iteration number.
488 /// \brief Loop number of iterations.
490 /// \brief Calculation of last iteration.
491 Expr *CalcLastIteration;
492 /// \brief Loop pre-condition.
494 /// \brief Loop condition.
496 /// \brief Loop iteration variable init.
498 /// \brief Loop increment.
500 /// \brief IsLastIteration - local flag variable passed to runtime.
502 /// \brief LowerBound - local variable passed to runtime.
504 /// \brief UpperBound - local variable passed to runtime.
506 /// \brief Stride - local variable passed to runtime.
508 /// \brief EnsureUpperBound -- expression LB = min(LB, NumIterations).
510 /// \brief Update of LowerBound for statically sheduled 'omp for' loops.
512 /// \brief Update of UpperBound for statically sheduled 'omp for' loops.
514 /// \brief Counters Loop counters.
515 SmallVector<Expr *, 4> Counters;
516 /// \brief PrivateCounters Loop counters.
517 SmallVector<Expr *, 4> PrivateCounters;
518 /// \brief Expressions for loop counters inits for CodeGen.
519 SmallVector<Expr *, 4> Inits;
520 /// \brief Expressions for loop counters update for CodeGen.
521 SmallVector<Expr *, 4> Updates;
522 /// \brief Final loop counter values for GodeGen.
523 SmallVector<Expr *, 4> Finals;
525 /// \brief Check if all the expressions are built (does not check the
526 /// worksharing ones).
528 return IterationVarRef != nullptr && LastIteration != nullptr &&
529 NumIterations != nullptr && PreCond != nullptr &&
530 Cond != nullptr && Init != nullptr && Inc != nullptr;
533 /// \brief Initialize all the fields to null.
534 /// \param Size Number of elements in the counters/finals/updates arrays.
535 void clear(unsigned Size) {
536 IterationVarRef = nullptr;
537 LastIteration = nullptr;
538 CalcLastIteration = nullptr;
550 Counters.resize(Size);
551 PrivateCounters.resize(Size);
553 Updates.resize(Size);
555 for (unsigned i = 0; i < Size; ++i) {
556 Counters[i] = nullptr;
557 PrivateCounters[i] = nullptr;
559 Updates[i] = nullptr;
565 /// \brief Get number of collapsed loops.
566 unsigned getCollapsedNumber() const { return CollapsedNum; }
568 Expr *getIterationVariable() const {
569 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
570 *std::next(child_begin(), IterationVariableOffset)));
572 Expr *getLastIteration() const {
573 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
574 *std::next(child_begin(), LastIterationOffset)));
576 Expr *getCalcLastIteration() const {
577 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
578 *std::next(child_begin(), CalcLastIterationOffset)));
580 Expr *getPreCond() const {
581 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
582 *std::next(child_begin(), PreConditionOffset)));
584 Expr *getCond() const {
585 return const_cast<Expr *>(
586 reinterpret_cast<const Expr *>(*std::next(child_begin(), CondOffset)));
588 Expr *getInit() const {
589 return const_cast<Expr *>(
590 reinterpret_cast<const Expr *>(*std::next(child_begin(), InitOffset)));
592 Expr *getInc() const {
593 return const_cast<Expr *>(
594 reinterpret_cast<const Expr *>(*std::next(child_begin(), IncOffset)));
596 Expr *getIsLastIterVariable() const {
597 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
598 isOpenMPTaskLoopDirective(getDirectiveKind())) &&
599 "expected worksharing loop directive");
600 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
601 *std::next(child_begin(), IsLastIterVariableOffset)));
603 Expr *getLowerBoundVariable() const {
604 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
605 isOpenMPTaskLoopDirective(getDirectiveKind())) &&
606 "expected worksharing loop directive");
607 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
608 *std::next(child_begin(), LowerBoundVariableOffset)));
610 Expr *getUpperBoundVariable() const {
611 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
612 isOpenMPTaskLoopDirective(getDirectiveKind())) &&
613 "expected worksharing loop directive");
614 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
615 *std::next(child_begin(), UpperBoundVariableOffset)));
617 Expr *getStrideVariable() const {
618 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
619 isOpenMPTaskLoopDirective(getDirectiveKind())) &&
620 "expected worksharing loop directive");
621 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
622 *std::next(child_begin(), StrideVariableOffset)));
624 Expr *getEnsureUpperBound() const {
625 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
626 isOpenMPTaskLoopDirective(getDirectiveKind())) &&
627 "expected worksharing loop directive");
628 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
629 *std::next(child_begin(), EnsureUpperBoundOffset)));
631 Expr *getNextLowerBound() const {
632 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
633 isOpenMPTaskLoopDirective(getDirectiveKind())) &&
634 "expected worksharing loop directive");
635 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
636 *std::next(child_begin(), NextLowerBoundOffset)));
638 Expr *getNextUpperBound() const {
639 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
640 isOpenMPTaskLoopDirective(getDirectiveKind())) &&
641 "expected worksharing loop directive");
642 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
643 *std::next(child_begin(), NextUpperBoundOffset)));
645 const Stmt *getBody() const {
646 // This relies on the loop form is already checked by Sema.
647 Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
648 Body = cast<ForStmt>(Body)->getBody();
649 for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) {
650 Body = Body->IgnoreContainers();
651 Body = cast<ForStmt>(Body)->getBody();
656 ArrayRef<Expr *> counters() { return getCounters(); }
658 ArrayRef<Expr *> counters() const {
659 return const_cast<OMPLoopDirective *>(this)->getCounters();
662 ArrayRef<Expr *> private_counters() { return getPrivateCounters(); }
664 ArrayRef<Expr *> private_counters() const {
665 return const_cast<OMPLoopDirective *>(this)->getPrivateCounters();
668 ArrayRef<Expr *> inits() { return getInits(); }
670 ArrayRef<Expr *> inits() const {
671 return const_cast<OMPLoopDirective *>(this)->getInits();
674 ArrayRef<Expr *> updates() { return getUpdates(); }
676 ArrayRef<Expr *> updates() const {
677 return const_cast<OMPLoopDirective *>(this)->getUpdates();
680 ArrayRef<Expr *> finals() { return getFinals(); }
682 ArrayRef<Expr *> finals() const {
683 return const_cast<OMPLoopDirective *>(this)->getFinals();
686 static bool classof(const Stmt *T) {
687 return T->getStmtClass() == OMPSimdDirectiveClass ||
688 T->getStmtClass() == OMPForDirectiveClass ||
689 T->getStmtClass() == OMPForSimdDirectiveClass ||
690 T->getStmtClass() == OMPParallelForDirectiveClass ||
691 T->getStmtClass() == OMPParallelForSimdDirectiveClass ||
692 T->getStmtClass() == OMPTaskLoopDirectiveClass ||
693 T->getStmtClass() == OMPTaskLoopSimdDirectiveClass ||
694 T->getStmtClass() == OMPDistributeDirectiveClass;
698 /// \brief This represents '#pragma omp simd' directive.
701 /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
703 /// In this example directive '#pragma omp simd' has clauses 'private'
704 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
705 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
707 class OMPSimdDirective : public OMPLoopDirective {
708 friend class ASTStmtReader;
709 /// \brief Build directive with the given start and end location.
711 /// \param StartLoc Starting location of the directive kind.
712 /// \param EndLoc Ending location of the directive.
713 /// \param CollapsedNum Number of collapsed nested loops.
714 /// \param NumClauses Number of clauses.
716 OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
717 unsigned CollapsedNum, unsigned NumClauses)
718 : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
719 EndLoc, CollapsedNum, NumClauses) {}
721 /// \brief Build an empty directive.
723 /// \param CollapsedNum Number of collapsed nested loops.
724 /// \param NumClauses Number of clauses.
726 explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
727 : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd,
728 SourceLocation(), SourceLocation(), CollapsedNum,
732 /// \brief Creates directive with a list of \a Clauses.
734 /// \param C AST context.
735 /// \param StartLoc Starting location of the directive kind.
736 /// \param EndLoc Ending Location of the directive.
737 /// \param CollapsedNum Number of collapsed loops.
738 /// \param Clauses List of clauses.
739 /// \param AssociatedStmt Statement, associated with the directive.
740 /// \param Exprs Helper expressions for CodeGen.
742 static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
743 SourceLocation EndLoc, unsigned CollapsedNum,
744 ArrayRef<OMPClause *> Clauses,
745 Stmt *AssociatedStmt,
746 const HelperExprs &Exprs);
748 /// \brief Creates an empty directive with the place
749 /// for \a NumClauses clauses.
751 /// \param C AST context.
752 /// \param CollapsedNum Number of collapsed nested loops.
753 /// \param NumClauses Number of clauses.
755 static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
756 unsigned CollapsedNum, EmptyShell);
758 static bool classof(const Stmt *T) {
759 return T->getStmtClass() == OMPSimdDirectiveClass;
763 /// \brief This represents '#pragma omp for' directive.
766 /// #pragma omp for private(a,b) reduction(+:c,d)
768 /// In this example directive '#pragma omp for' has clauses 'private' with the
769 /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
772 class OMPForDirective : public OMPLoopDirective {
773 friend class ASTStmtReader;
775 /// \brief true if current directive has inner cancel directive.
778 /// \brief Build directive with the given start and end location.
780 /// \param StartLoc Starting location of the directive kind.
781 /// \param EndLoc Ending location of the directive.
782 /// \param CollapsedNum Number of collapsed nested loops.
783 /// \param NumClauses Number of clauses.
785 OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
786 unsigned CollapsedNum, unsigned NumClauses)
787 : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, EndLoc,
788 CollapsedNum, NumClauses),
791 /// \brief Build an empty directive.
793 /// \param CollapsedNum Number of collapsed nested loops.
794 /// \param NumClauses Number of clauses.
796 explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses)
797 : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, SourceLocation(),
798 SourceLocation(), CollapsedNum, NumClauses),
801 /// \brief Set cancel state.
802 void setHasCancel(bool Has) { HasCancel = Has; }
805 /// \brief Creates directive with a list of \a Clauses.
807 /// \param C AST context.
808 /// \param StartLoc Starting location of the directive kind.
809 /// \param EndLoc Ending Location of the directive.
810 /// \param CollapsedNum Number of collapsed loops.
811 /// \param Clauses List of clauses.
812 /// \param AssociatedStmt Statement, associated with the directive.
813 /// \param Exprs Helper expressions for CodeGen.
814 /// \param HasCancel true if current directive has inner cancel directive.
816 static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
817 SourceLocation EndLoc, unsigned CollapsedNum,
818 ArrayRef<OMPClause *> Clauses,
819 Stmt *AssociatedStmt, const HelperExprs &Exprs,
822 /// \brief Creates an empty directive with the place
823 /// for \a NumClauses clauses.
825 /// \param C AST context.
826 /// \param CollapsedNum Number of collapsed nested loops.
827 /// \param NumClauses Number of clauses.
829 static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
830 unsigned CollapsedNum, EmptyShell);
832 /// \brief Return true if current directive has inner cancel directive.
833 bool hasCancel() const { return HasCancel; }
835 static bool classof(const Stmt *T) {
836 return T->getStmtClass() == OMPForDirectiveClass;
840 /// \brief This represents '#pragma omp for simd' directive.
843 /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
845 /// In this example directive '#pragma omp for simd' has clauses 'private'
846 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
847 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
849 class OMPForSimdDirective : public OMPLoopDirective {
850 friend class ASTStmtReader;
851 /// \brief Build directive with the given start and end location.
853 /// \param StartLoc Starting location of the directive kind.
854 /// \param EndLoc Ending location of the directive.
855 /// \param CollapsedNum Number of collapsed nested loops.
856 /// \param NumClauses Number of clauses.
858 OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
859 unsigned CollapsedNum, unsigned NumClauses)
860 : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
861 StartLoc, EndLoc, CollapsedNum, NumClauses) {}
863 /// \brief Build an empty directive.
865 /// \param CollapsedNum Number of collapsed nested loops.
866 /// \param NumClauses Number of clauses.
868 explicit OMPForSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
869 : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
870 SourceLocation(), SourceLocation(), CollapsedNum,
874 /// \brief Creates directive with a list of \a Clauses.
876 /// \param C AST context.
877 /// \param StartLoc Starting location of the directive kind.
878 /// \param EndLoc Ending Location of the directive.
879 /// \param CollapsedNum Number of collapsed loops.
880 /// \param Clauses List of clauses.
881 /// \param AssociatedStmt Statement, associated with the directive.
882 /// \param Exprs Helper expressions for CodeGen.
884 static OMPForSimdDirective *
885 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
886 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
887 Stmt *AssociatedStmt, const HelperExprs &Exprs);
889 /// \brief Creates an empty directive with the place
890 /// for \a NumClauses clauses.
892 /// \param C AST context.
893 /// \param CollapsedNum Number of collapsed nested loops.
894 /// \param NumClauses Number of clauses.
896 static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
898 unsigned CollapsedNum, EmptyShell);
900 static bool classof(const Stmt *T) {
901 return T->getStmtClass() == OMPForSimdDirectiveClass;
905 /// \brief This represents '#pragma omp sections' directive.
908 /// #pragma omp sections private(a,b) reduction(+:c,d)
910 /// In this example directive '#pragma omp sections' has clauses 'private' with
911 /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
914 class OMPSectionsDirective : public OMPExecutableDirective {
915 friend class ASTStmtReader;
917 /// \brief true if current directive has inner cancel directive.
920 /// \brief Build directive with the given start and end location.
922 /// \param StartLoc Starting location of the directive kind.
923 /// \param EndLoc Ending location of the directive.
924 /// \param NumClauses Number of clauses.
926 OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
928 : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
929 StartLoc, EndLoc, NumClauses, 1),
932 /// \brief Build an empty directive.
934 /// \param NumClauses Number of clauses.
936 explicit OMPSectionsDirective(unsigned NumClauses)
937 : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
938 SourceLocation(), SourceLocation(), NumClauses,
942 /// \brief Set cancel state.
943 void setHasCancel(bool Has) { HasCancel = Has; }
946 /// \brief Creates directive with a list of \a Clauses.
948 /// \param C AST context.
949 /// \param StartLoc Starting location of the directive kind.
950 /// \param EndLoc Ending Location of the directive.
951 /// \param Clauses List of clauses.
952 /// \param AssociatedStmt Statement, associated with the directive.
953 /// \param HasCancel true if current directive has inner directive.
955 static OMPSectionsDirective *
956 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
957 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
959 /// \brief Creates an empty directive with the place for \a NumClauses
962 /// \param C AST context.
963 /// \param NumClauses Number of clauses.
965 static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
966 unsigned NumClauses, EmptyShell);
968 /// \brief Return true if current directive has inner cancel directive.
969 bool hasCancel() const { return HasCancel; }
971 static bool classof(const Stmt *T) {
972 return T->getStmtClass() == OMPSectionsDirectiveClass;
976 /// \brief This represents '#pragma omp section' directive.
979 /// #pragma omp section
982 class OMPSectionDirective : public OMPExecutableDirective {
983 friend class ASTStmtReader;
985 /// \brief true if current directive has inner cancel directive.
988 /// \brief Build directive with the given start and end location.
990 /// \param StartLoc Starting location of the directive kind.
991 /// \param EndLoc Ending location of the directive.
993 OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
994 : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
995 StartLoc, EndLoc, 0, 1),
998 /// \brief Build an empty directive.
1000 explicit OMPSectionDirective()
1001 : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
1002 SourceLocation(), SourceLocation(), 0, 1),
1006 /// \brief Creates directive.
1008 /// \param C AST context.
1009 /// \param StartLoc Starting location of the directive kind.
1010 /// \param EndLoc Ending Location of the directive.
1011 /// \param AssociatedStmt Statement, associated with the directive.
1012 /// \param HasCancel true if current directive has inner directive.
1014 static OMPSectionDirective *Create(const ASTContext &C,
1015 SourceLocation StartLoc,
1016 SourceLocation EndLoc,
1017 Stmt *AssociatedStmt, bool HasCancel);
1019 /// \brief Creates an empty directive.
1021 /// \param C AST context.
1023 static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1025 /// \brief Set cancel state.
1026 void setHasCancel(bool Has) { HasCancel = Has; }
1028 /// \brief Return true if current directive has inner cancel directive.
1029 bool hasCancel() const { return HasCancel; }
1031 static bool classof(const Stmt *T) {
1032 return T->getStmtClass() == OMPSectionDirectiveClass;
1036 /// \brief This represents '#pragma omp single' directive.
1039 /// #pragma omp single private(a,b) copyprivate(c,d)
1041 /// In this example directive '#pragma omp single' has clauses 'private' with
1042 /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
1044 class OMPSingleDirective : public OMPExecutableDirective {
1045 friend class ASTStmtReader;
1046 /// \brief Build directive with the given start and end location.
1048 /// \param StartLoc Starting location of the directive kind.
1049 /// \param EndLoc Ending location of the directive.
1050 /// \param NumClauses Number of clauses.
1052 OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1053 unsigned NumClauses)
1054 : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
1055 StartLoc, EndLoc, NumClauses, 1) {}
1057 /// \brief Build an empty directive.
1059 /// \param NumClauses Number of clauses.
1061 explicit OMPSingleDirective(unsigned NumClauses)
1062 : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
1063 SourceLocation(), SourceLocation(), NumClauses,
1067 /// \brief Creates directive with a list of \a Clauses.
1069 /// \param C AST context.
1070 /// \param StartLoc Starting location of the directive kind.
1071 /// \param EndLoc Ending Location of the directive.
1072 /// \param Clauses List of clauses.
1073 /// \param AssociatedStmt Statement, associated with the directive.
1075 static OMPSingleDirective *
1076 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1077 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1079 /// \brief Creates an empty directive with the place for \a NumClauses
1082 /// \param C AST context.
1083 /// \param NumClauses Number of clauses.
1085 static OMPSingleDirective *CreateEmpty(const ASTContext &C,
1086 unsigned NumClauses, EmptyShell);
1088 static bool classof(const Stmt *T) {
1089 return T->getStmtClass() == OMPSingleDirectiveClass;
1093 /// \brief This represents '#pragma omp master' directive.
1096 /// #pragma omp master
1099 class OMPMasterDirective : public OMPExecutableDirective {
1100 friend class ASTStmtReader;
1101 /// \brief Build directive with the given start and end location.
1103 /// \param StartLoc Starting location of the directive kind.
1104 /// \param EndLoc Ending location of the directive.
1106 OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1107 : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
1108 StartLoc, EndLoc, 0, 1) {}
1110 /// \brief Build an empty directive.
1112 explicit OMPMasterDirective()
1113 : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
1114 SourceLocation(), SourceLocation(), 0, 1) {}
1117 /// \brief Creates directive.
1119 /// \param C AST context.
1120 /// \param StartLoc Starting location of the directive kind.
1121 /// \param EndLoc Ending Location of the directive.
1122 /// \param AssociatedStmt Statement, associated with the directive.
1124 static OMPMasterDirective *Create(const ASTContext &C,
1125 SourceLocation StartLoc,
1126 SourceLocation EndLoc,
1127 Stmt *AssociatedStmt);
1129 /// \brief Creates an empty directive.
1131 /// \param C AST context.
1133 static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1135 static bool classof(const Stmt *T) {
1136 return T->getStmtClass() == OMPMasterDirectiveClass;
1140 /// \brief This represents '#pragma omp critical' directive.
1143 /// #pragma omp critical
1146 class OMPCriticalDirective : public OMPExecutableDirective {
1147 friend class ASTStmtReader;
1148 /// \brief Name of the directive.
1149 DeclarationNameInfo DirName;
1150 /// \brief Build directive with the given start and end location.
1152 /// \param Name Name of the directive.
1153 /// \param StartLoc Starting location of the directive kind.
1154 /// \param EndLoc Ending location of the directive.
1155 /// \param NumClauses Number of clauses.
1157 OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
1158 SourceLocation EndLoc, unsigned NumClauses)
1159 : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
1160 StartLoc, EndLoc, NumClauses, 1),
1163 /// \brief Build an empty directive.
1165 /// \param NumClauses Number of clauses.
1167 explicit OMPCriticalDirective(unsigned NumClauses)
1168 : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
1169 SourceLocation(), SourceLocation(), NumClauses,
1173 /// \brief Set name of the directive.
1175 /// \param Name Name of the directive.
1177 void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
1180 /// \brief Creates directive.
1182 /// \param C AST context.
1183 /// \param Name Name of the directive.
1184 /// \param StartLoc Starting location of the directive kind.
1185 /// \param EndLoc Ending Location of the directive.
1186 /// \param Clauses List of clauses.
1187 /// \param AssociatedStmt Statement, associated with the directive.
1189 static OMPCriticalDirective *
1190 Create(const ASTContext &C, const DeclarationNameInfo &Name,
1191 SourceLocation StartLoc, SourceLocation EndLoc,
1192 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1194 /// \brief Creates an empty directive.
1196 /// \param C AST context.
1197 /// \param NumClauses Number of clauses.
1199 static OMPCriticalDirective *CreateEmpty(const ASTContext &C,
1200 unsigned NumClauses, EmptyShell);
1202 /// \brief Return name of the directive.
1204 DeclarationNameInfo getDirectiveName() const { return DirName; }
1206 static bool classof(const Stmt *T) {
1207 return T->getStmtClass() == OMPCriticalDirectiveClass;
1211 /// \brief This represents '#pragma omp parallel for' directive.
1214 /// #pragma omp parallel for private(a,b) reduction(+:c,d)
1216 /// In this example directive '#pragma omp parallel for' has clauses 'private'
1217 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
1218 /// variables 'c' and 'd'.
1220 class OMPParallelForDirective : public OMPLoopDirective {
1221 friend class ASTStmtReader;
1223 /// \brief true if current region has inner cancel directive.
1226 /// \brief Build directive with the given start and end location.
1228 /// \param StartLoc Starting location of the directive kind.
1229 /// \param EndLoc Ending location of the directive.
1230 /// \param CollapsedNum Number of collapsed nested loops.
1231 /// \param NumClauses Number of clauses.
1233 OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1234 unsigned CollapsedNum, unsigned NumClauses)
1235 : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
1236 StartLoc, EndLoc, CollapsedNum, NumClauses),
1239 /// \brief Build an empty directive.
1241 /// \param CollapsedNum Number of collapsed nested loops.
1242 /// \param NumClauses Number of clauses.
1244 explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses)
1245 : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
1246 SourceLocation(), SourceLocation(), CollapsedNum,
1250 /// \brief Set cancel state.
1251 void setHasCancel(bool Has) { HasCancel = Has; }
1254 /// \brief Creates directive with a list of \a Clauses.
1256 /// \param C AST context.
1257 /// \param StartLoc Starting location of the directive kind.
1258 /// \param EndLoc Ending Location of the directive.
1259 /// \param CollapsedNum Number of collapsed loops.
1260 /// \param Clauses List of clauses.
1261 /// \param AssociatedStmt Statement, associated with the directive.
1262 /// \param Exprs Helper expressions for CodeGen.
1263 /// \param HasCancel true if current directive has inner cancel directive.
1265 static OMPParallelForDirective *
1266 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1267 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1268 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
1270 /// \brief Creates an empty directive with the place
1271 /// for \a NumClauses clauses.
1273 /// \param C AST context.
1274 /// \param CollapsedNum Number of collapsed nested loops.
1275 /// \param NumClauses Number of clauses.
1277 static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
1278 unsigned NumClauses,
1279 unsigned CollapsedNum,
1282 /// \brief Return true if current directive has inner cancel directive.
1283 bool hasCancel() const { return HasCancel; }
1285 static bool classof(const Stmt *T) {
1286 return T->getStmtClass() == OMPParallelForDirectiveClass;
1290 /// \brief This represents '#pragma omp parallel for simd' directive.
1293 /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
1295 /// In this example directive '#pragma omp parallel for simd' has clauses
1296 /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
1297 /// and linear step 's', 'reduction' with operator '+' and variables 'c' and
1300 class OMPParallelForSimdDirective : public OMPLoopDirective {
1301 friend class ASTStmtReader;
1302 /// \brief Build directive with the given start and end location.
1304 /// \param StartLoc Starting location of the directive kind.
1305 /// \param EndLoc Ending location of the directive.
1306 /// \param CollapsedNum Number of collapsed nested loops.
1307 /// \param NumClauses Number of clauses.
1309 OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1310 unsigned CollapsedNum, unsigned NumClauses)
1311 : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
1312 OMPD_parallel_for_simd, StartLoc, EndLoc, CollapsedNum,
1315 /// \brief Build an empty directive.
1317 /// \param CollapsedNum Number of collapsed nested loops.
1318 /// \param NumClauses Number of clauses.
1320 explicit OMPParallelForSimdDirective(unsigned CollapsedNum,
1321 unsigned NumClauses)
1322 : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
1323 OMPD_parallel_for_simd, SourceLocation(),
1324 SourceLocation(), CollapsedNum, NumClauses) {}
1327 /// \brief Creates directive with a list of \a Clauses.
1329 /// \param C AST context.
1330 /// \param StartLoc Starting location of the directive kind.
1331 /// \param EndLoc Ending Location of the directive.
1332 /// \param CollapsedNum Number of collapsed loops.
1333 /// \param Clauses List of clauses.
1334 /// \param AssociatedStmt Statement, associated with the directive.
1335 /// \param Exprs Helper expressions for CodeGen.
1337 static OMPParallelForSimdDirective *
1338 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1339 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1340 Stmt *AssociatedStmt, const HelperExprs &Exprs);
1342 /// \brief Creates an empty directive with the place
1343 /// for \a NumClauses clauses.
1345 /// \param C AST context.
1346 /// \param CollapsedNum Number of collapsed nested loops.
1347 /// \param NumClauses Number of clauses.
1349 static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
1350 unsigned NumClauses,
1351 unsigned CollapsedNum,
1354 static bool classof(const Stmt *T) {
1355 return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
1359 /// \brief This represents '#pragma omp parallel sections' directive.
1362 /// #pragma omp parallel sections private(a,b) reduction(+:c,d)
1364 /// In this example directive '#pragma omp parallel sections' has clauses
1365 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
1366 /// and variables 'c' and 'd'.
1368 class OMPParallelSectionsDirective : public OMPExecutableDirective {
1369 friend class ASTStmtReader;
1371 /// \brief true if current directive has inner cancel directive.
1374 /// \brief Build directive with the given start and end location.
1376 /// \param StartLoc Starting location of the directive kind.
1377 /// \param EndLoc Ending location of the directive.
1378 /// \param NumClauses Number of clauses.
1380 OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1381 unsigned NumClauses)
1382 : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
1383 OMPD_parallel_sections, StartLoc, EndLoc,
1387 /// \brief Build an empty directive.
1389 /// \param NumClauses Number of clauses.
1391 explicit OMPParallelSectionsDirective(unsigned NumClauses)
1392 : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
1393 OMPD_parallel_sections, SourceLocation(),
1394 SourceLocation(), NumClauses, 1),
1397 /// \brief Set cancel state.
1398 void setHasCancel(bool Has) { HasCancel = Has; }
1401 /// \brief Creates directive with a list of \a Clauses.
1403 /// \param C AST context.
1404 /// \param StartLoc Starting location of the directive kind.
1405 /// \param EndLoc Ending Location of the directive.
1406 /// \param Clauses List of clauses.
1407 /// \param AssociatedStmt Statement, associated with the directive.
1408 /// \param HasCancel true if current directive has inner cancel directive.
1410 static OMPParallelSectionsDirective *
1411 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1412 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
1414 /// \brief Creates an empty directive with the place for \a NumClauses
1417 /// \param C AST context.
1418 /// \param NumClauses Number of clauses.
1420 static OMPParallelSectionsDirective *
1421 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
1423 /// \brief Return true if current directive has inner cancel directive.
1424 bool hasCancel() const { return HasCancel; }
1426 static bool classof(const Stmt *T) {
1427 return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
1431 /// \brief This represents '#pragma omp task' directive.
1434 /// #pragma omp task private(a,b) final(d)
1436 /// In this example directive '#pragma omp task' has clauses 'private' with the
1437 /// variables 'a' and 'b' and 'final' with condition 'd'.
1439 class OMPTaskDirective : public OMPExecutableDirective {
1440 friend class ASTStmtReader;
1441 /// \brief true if this directive has inner cancel directive.
1444 /// \brief Build directive with the given start and end location.
1446 /// \param StartLoc Starting location of the directive kind.
1447 /// \param EndLoc Ending location of the directive.
1448 /// \param NumClauses Number of clauses.
1450 OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1451 unsigned NumClauses)
1452 : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc,
1453 EndLoc, NumClauses, 1),
1456 /// \brief Build an empty directive.
1458 /// \param NumClauses Number of clauses.
1460 explicit OMPTaskDirective(unsigned NumClauses)
1461 : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task,
1462 SourceLocation(), SourceLocation(), NumClauses,
1466 /// \brief Set cancel state.
1467 void setHasCancel(bool Has) { HasCancel = Has; }
1470 /// \brief Creates directive with a list of \a Clauses.
1472 /// \param C AST context.
1473 /// \param StartLoc Starting location of the directive kind.
1474 /// \param EndLoc Ending Location of the directive.
1475 /// \param Clauses List of clauses.
1476 /// \param AssociatedStmt Statement, associated with the directive.
1477 /// \param HasCancel true, if current directive has inner cancel directive.
1479 static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1480 SourceLocation EndLoc,
1481 ArrayRef<OMPClause *> Clauses,
1482 Stmt *AssociatedStmt, bool HasCancel);
1484 /// \brief Creates an empty directive with the place for \a NumClauses
1487 /// \param C AST context.
1488 /// \param NumClauses Number of clauses.
1490 static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1493 /// \brief Return true if current directive has inner cancel directive.
1494 bool hasCancel() const { return HasCancel; }
1496 static bool classof(const Stmt *T) {
1497 return T->getStmtClass() == OMPTaskDirectiveClass;
1501 /// \brief This represents '#pragma omp taskyield' directive.
1504 /// #pragma omp taskyield
1507 class OMPTaskyieldDirective : public OMPExecutableDirective {
1508 friend class ASTStmtReader;
1509 /// \brief Build directive with the given start and end location.
1511 /// \param StartLoc Starting location of the directive kind.
1512 /// \param EndLoc Ending location of the directive.
1514 OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1515 : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
1516 StartLoc, EndLoc, 0, 0) {}
1518 /// \brief Build an empty directive.
1520 explicit OMPTaskyieldDirective()
1521 : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
1522 SourceLocation(), SourceLocation(), 0, 0) {}
1525 /// \brief Creates directive.
1527 /// \param C AST context.
1528 /// \param StartLoc Starting location of the directive kind.
1529 /// \param EndLoc Ending Location of the directive.
1531 static OMPTaskyieldDirective *
1532 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1534 /// \brief Creates an empty directive.
1536 /// \param C AST context.
1538 static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1540 static bool classof(const Stmt *T) {
1541 return T->getStmtClass() == OMPTaskyieldDirectiveClass;
1545 /// \brief This represents '#pragma omp barrier' directive.
1548 /// #pragma omp barrier
1551 class OMPBarrierDirective : public OMPExecutableDirective {
1552 friend class ASTStmtReader;
1553 /// \brief Build directive with the given start and end location.
1555 /// \param StartLoc Starting location of the directive kind.
1556 /// \param EndLoc Ending location of the directive.
1558 OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1559 : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
1560 StartLoc, EndLoc, 0, 0) {}
1562 /// \brief Build an empty directive.
1564 explicit OMPBarrierDirective()
1565 : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
1566 SourceLocation(), SourceLocation(), 0, 0) {}
1569 /// \brief Creates directive.
1571 /// \param C AST context.
1572 /// \param StartLoc Starting location of the directive kind.
1573 /// \param EndLoc Ending Location of the directive.
1575 static OMPBarrierDirective *
1576 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1578 /// \brief Creates an empty directive.
1580 /// \param C AST context.
1582 static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1584 static bool classof(const Stmt *T) {
1585 return T->getStmtClass() == OMPBarrierDirectiveClass;
1589 /// \brief This represents '#pragma omp taskwait' directive.
1592 /// #pragma omp taskwait
1595 class OMPTaskwaitDirective : public OMPExecutableDirective {
1596 friend class ASTStmtReader;
1597 /// \brief Build directive with the given start and end location.
1599 /// \param StartLoc Starting location of the directive kind.
1600 /// \param EndLoc Ending location of the directive.
1602 OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1603 : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
1604 StartLoc, EndLoc, 0, 0) {}
1606 /// \brief Build an empty directive.
1608 explicit OMPTaskwaitDirective()
1609 : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
1610 SourceLocation(), SourceLocation(), 0, 0) {}
1613 /// \brief Creates directive.
1615 /// \param C AST context.
1616 /// \param StartLoc Starting location of the directive kind.
1617 /// \param EndLoc Ending Location of the directive.
1619 static OMPTaskwaitDirective *
1620 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1622 /// \brief Creates an empty directive.
1624 /// \param C AST context.
1626 static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1628 static bool classof(const Stmt *T) {
1629 return T->getStmtClass() == OMPTaskwaitDirectiveClass;
1633 /// \brief This represents '#pragma omp taskgroup' directive.
1636 /// #pragma omp taskgroup
1639 class OMPTaskgroupDirective : public OMPExecutableDirective {
1640 friend class ASTStmtReader;
1641 /// \brief Build directive with the given start and end location.
1643 /// \param StartLoc Starting location of the directive kind.
1644 /// \param EndLoc Ending location of the directive.
1646 OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1647 : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
1648 StartLoc, EndLoc, 0, 1) {}
1650 /// \brief Build an empty directive.
1652 explicit OMPTaskgroupDirective()
1653 : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
1654 SourceLocation(), SourceLocation(), 0, 1) {}
1657 /// \brief Creates directive.
1659 /// \param C AST context.
1660 /// \param StartLoc Starting location of the directive kind.
1661 /// \param EndLoc Ending Location of the directive.
1662 /// \param AssociatedStmt Statement, associated with the directive.
1664 static OMPTaskgroupDirective *Create(const ASTContext &C,
1665 SourceLocation StartLoc,
1666 SourceLocation EndLoc,
1667 Stmt *AssociatedStmt);
1669 /// \brief Creates an empty directive.
1671 /// \param C AST context.
1673 static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1675 static bool classof(const Stmt *T) {
1676 return T->getStmtClass() == OMPTaskgroupDirectiveClass;
1680 /// \brief This represents '#pragma omp flush' directive.
1683 /// #pragma omp flush(a,b)
1685 /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
1687 /// 'omp flush' directive does not have clauses but have an optional list of
1688 /// variables to flush. This list of variables is stored within some fake clause
1690 class OMPFlushDirective : public OMPExecutableDirective {
1691 friend class ASTStmtReader;
1692 /// \brief Build directive with the given start and end location.
1694 /// \param StartLoc Starting location of the directive kind.
1695 /// \param EndLoc Ending location of the directive.
1696 /// \param NumClauses Number of clauses.
1698 OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1699 unsigned NumClauses)
1700 : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
1701 StartLoc, EndLoc, NumClauses, 0) {}
1703 /// \brief Build an empty directive.
1705 /// \param NumClauses Number of clauses.
1707 explicit OMPFlushDirective(unsigned NumClauses)
1708 : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
1709 SourceLocation(), SourceLocation(), NumClauses,
1713 /// \brief Creates directive with a list of \a Clauses.
1715 /// \param C AST context.
1716 /// \param StartLoc Starting location of the directive kind.
1717 /// \param EndLoc Ending Location of the directive.
1718 /// \param Clauses List of clauses (only single OMPFlushClause clause is
1721 static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1722 SourceLocation EndLoc,
1723 ArrayRef<OMPClause *> Clauses);
1725 /// \brief Creates an empty directive with the place for \a NumClauses
1728 /// \param C AST context.
1729 /// \param NumClauses Number of clauses.
1731 static OMPFlushDirective *CreateEmpty(const ASTContext &C,
1732 unsigned NumClauses, EmptyShell);
1734 static bool classof(const Stmt *T) {
1735 return T->getStmtClass() == OMPFlushDirectiveClass;
1739 /// \brief This represents '#pragma omp ordered' directive.
1742 /// #pragma omp ordered
1745 class OMPOrderedDirective : public OMPExecutableDirective {
1746 friend class ASTStmtReader;
1747 /// \brief Build directive with the given start and end location.
1749 /// \param StartLoc Starting location of the directive kind.
1750 /// \param EndLoc Ending location of the directive.
1751 /// \param NumClauses Number of clauses.
1753 OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1754 unsigned NumClauses)
1755 : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
1756 StartLoc, EndLoc, NumClauses, 1) {}
1758 /// \brief Build an empty directive.
1760 /// \param NumClauses Number of clauses.
1762 explicit OMPOrderedDirective(unsigned NumClauses)
1763 : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
1764 SourceLocation(), SourceLocation(), NumClauses,
1768 /// \brief Creates directive.
1770 /// \param C AST context.
1771 /// \param StartLoc Starting location of the directive kind.
1772 /// \param EndLoc Ending Location of the directive.
1773 /// \param Clauses List of clauses.
1774 /// \param AssociatedStmt Statement, associated with the directive.
1776 static OMPOrderedDirective *
1777 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1778 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1780 /// \brief Creates an empty directive.
1782 /// \param C AST context.
1783 /// \param NumClauses Number of clauses.
1785 static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
1786 unsigned NumClauses, EmptyShell);
1788 static bool classof(const Stmt *T) {
1789 return T->getStmtClass() == OMPOrderedDirectiveClass;
1793 /// \brief This represents '#pragma omp atomic' directive.
1796 /// #pragma omp atomic capture
1798 /// In this example directive '#pragma omp atomic' has clause 'capture'.
1800 class OMPAtomicDirective : public OMPExecutableDirective {
1801 friend class ASTStmtReader;
1802 /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
1803 /// have atomic expressions of forms
1805 /// x = x binop expr;
1806 /// x = expr binop x;
1808 /// This field is true for the first form of the expression and false for the
1809 /// second. Required for correct codegen of non-associative operations (like
1811 bool IsXLHSInRHSPart;
1812 /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
1813 /// have atomic expressions of forms
1815 /// v = x; <update x>;
1816 /// <update x>; v = x;
1818 /// This field is true for the first(postfix) form of the expression and false
1820 bool IsPostfixUpdate;
1822 /// \brief Build directive with the given start and end location.
1824 /// \param StartLoc Starting location of the directive kind.
1825 /// \param EndLoc Ending location of the directive.
1826 /// \param NumClauses Number of clauses.
1828 OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1829 unsigned NumClauses)
1830 : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
1831 StartLoc, EndLoc, NumClauses, 5),
1832 IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
1834 /// \brief Build an empty directive.
1836 /// \param NumClauses Number of clauses.
1838 explicit OMPAtomicDirective(unsigned NumClauses)
1839 : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
1840 SourceLocation(), SourceLocation(), NumClauses,
1842 IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
1844 /// \brief Set 'x' part of the associated expression/statement.
1845 void setX(Expr *X) { *std::next(child_begin()) = X; }
1846 /// \brief Set helper expression of the form
1847 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
1848 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
1849 void setUpdateExpr(Expr *UE) { *std::next(child_begin(), 2) = UE; }
1850 /// \brief Set 'v' part of the associated expression/statement.
1851 void setV(Expr *V) { *std::next(child_begin(), 3) = V; }
1852 /// \brief Set 'expr' part of the associated expression/statement.
1853 void setExpr(Expr *E) { *std::next(child_begin(), 4) = E; }
1856 /// \brief Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
1857 /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
1858 /// detailed description of 'x', 'v' and 'expr').
1860 /// \param C AST context.
1861 /// \param StartLoc Starting location of the directive kind.
1862 /// \param EndLoc Ending Location of the directive.
1863 /// \param Clauses List of clauses.
1864 /// \param AssociatedStmt Statement, associated with the directive.
1865 /// \param X 'x' part of the associated expression/statement.
1866 /// \param V 'v' part of the associated expression/statement.
1867 /// \param E 'expr' part of the associated expression/statement.
1868 /// \param UE Helper expression of the form
1869 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
1870 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
1871 /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the
1873 /// \param IsPostfixUpdate true if original value of 'x' must be stored in
1874 /// 'v', not an updated one.
1875 static OMPAtomicDirective *
1876 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1877 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V,
1878 Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate);
1880 /// \brief Creates an empty directive with the place for \a NumClauses
1883 /// \param C AST context.
1884 /// \param NumClauses Number of clauses.
1886 static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
1887 unsigned NumClauses, EmptyShell);
1889 /// \brief Get 'x' part of the associated expression/statement.
1890 Expr *getX() { return cast_or_null<Expr>(*std::next(child_begin())); }
1891 const Expr *getX() const {
1892 return cast_or_null<Expr>(*std::next(child_begin()));
1894 /// \brief Get helper expression of the form
1895 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
1896 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
1897 Expr *getUpdateExpr() {
1898 return cast_or_null<Expr>(*std::next(child_begin(), 2));
1900 const Expr *getUpdateExpr() const {
1901 return cast_or_null<Expr>(*std::next(child_begin(), 2));
1903 /// \brief Return true if helper update expression has form
1904 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
1905 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
1906 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
1907 /// \brief Return true if 'v' expression must be updated to original value of
1908 /// 'x', false if 'v' must be updated to the new value of 'x'.
1909 bool isPostfixUpdate() const { return IsPostfixUpdate; }
1910 /// \brief Get 'v' part of the associated expression/statement.
1911 Expr *getV() { return cast_or_null<Expr>(*std::next(child_begin(), 3)); }
1912 const Expr *getV() const {
1913 return cast_or_null<Expr>(*std::next(child_begin(), 3));
1915 /// \brief Get 'expr' part of the associated expression/statement.
1916 Expr *getExpr() { return cast_or_null<Expr>(*std::next(child_begin(), 4)); }
1917 const Expr *getExpr() const {
1918 return cast_or_null<Expr>(*std::next(child_begin(), 4));
1921 static bool classof(const Stmt *T) {
1922 return T->getStmtClass() == OMPAtomicDirectiveClass;
1926 /// \brief This represents '#pragma omp target' directive.
1929 /// #pragma omp target if(a)
1931 /// In this example directive '#pragma omp target' has clause 'if' with
1934 class OMPTargetDirective : public OMPExecutableDirective {
1935 friend class ASTStmtReader;
1936 /// \brief Build directive with the given start and end location.
1938 /// \param StartLoc Starting location of the directive kind.
1939 /// \param EndLoc Ending location of the directive.
1940 /// \param NumClauses Number of clauses.
1942 OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1943 unsigned NumClauses)
1944 : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
1945 StartLoc, EndLoc, NumClauses, 1) {}
1947 /// \brief Build an empty directive.
1949 /// \param NumClauses Number of clauses.
1951 explicit OMPTargetDirective(unsigned NumClauses)
1952 : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
1953 SourceLocation(), SourceLocation(), NumClauses,
1957 /// \brief Creates directive with a list of \a Clauses.
1959 /// \param C AST context.
1960 /// \param StartLoc Starting location of the directive kind.
1961 /// \param EndLoc Ending Location of the directive.
1962 /// \param Clauses List of clauses.
1963 /// \param AssociatedStmt Statement, associated with the directive.
1965 static OMPTargetDirective *
1966 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1967 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1969 /// \brief Creates an empty directive with the place for \a NumClauses
1972 /// \param C AST context.
1973 /// \param NumClauses Number of clauses.
1975 static OMPTargetDirective *CreateEmpty(const ASTContext &C,
1976 unsigned NumClauses, EmptyShell);
1978 static bool classof(const Stmt *T) {
1979 return T->getStmtClass() == OMPTargetDirectiveClass;
1983 /// \brief This represents '#pragma omp target data' directive.
1986 /// #pragma omp target data device(0) if(a) map(b[:])
1988 /// In this example directive '#pragma omp target data' has clauses 'device'
1989 /// with the value '0', 'if' with condition 'a' and 'map' with array
1992 class OMPTargetDataDirective : public OMPExecutableDirective {
1993 friend class ASTStmtReader;
1994 /// \brief Build directive with the given start and end location.
1996 /// \param StartLoc Starting location of the directive kind.
1997 /// \param EndLoc Ending Location of the directive.
1998 /// \param NumClauses The number of clauses.
2000 OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2001 unsigned NumClauses)
2002 : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
2003 OMPD_target_data, StartLoc, EndLoc, NumClauses,
2006 /// \brief Build an empty directive.
2008 /// \param NumClauses Number of clauses.
2010 explicit OMPTargetDataDirective(unsigned NumClauses)
2011 : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
2012 OMPD_target_data, SourceLocation(),
2013 SourceLocation(), NumClauses, 1) {}
2016 /// \brief Creates directive with a list of \a Clauses.
2018 /// \param C AST context.
2019 /// \param StartLoc Starting location of the directive kind.
2020 /// \param EndLoc Ending Location of the directive.
2021 /// \param Clauses List of clauses.
2022 /// \param AssociatedStmt Statement, associated with the directive.
2024 static OMPTargetDataDirective *
2025 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2026 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2028 /// \brief Creates an empty directive with the place for \a N clauses.
2030 /// \param C AST context.
2031 /// \param N The number of clauses.
2033 static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N,
2036 static bool classof(const Stmt *T) {
2037 return T->getStmtClass() == OMPTargetDataDirectiveClass;
2041 /// \brief This represents '#pragma omp target enter data' directive.
2044 /// #pragma omp target enter data device(0) if(a) map(b[:])
2046 /// In this example directive '#pragma omp target enter data' has clauses
2047 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
2050 class OMPTargetEnterDataDirective : 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 The number of clauses.
2058 OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2059 unsigned NumClauses)
2060 : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass,
2061 OMPD_target_enter_data, StartLoc, EndLoc,
2062 NumClauses, /*NumChildren=*/0) {}
2064 /// \brief Build an empty directive.
2066 /// \param NumClauses Number of clauses.
2068 explicit OMPTargetEnterDataDirective(unsigned NumClauses)
2069 : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass,
2070 OMPD_target_enter_data, SourceLocation(),
2071 SourceLocation(), NumClauses,
2072 /*NumChildren=*/0) {}
2075 /// \brief Creates directive with a list of \a Clauses.
2077 /// \param C AST context.
2078 /// \param StartLoc Starting location of the directive kind.
2079 /// \param EndLoc Ending Location of the directive.
2080 /// \param Clauses List of clauses.
2082 static OMPTargetEnterDataDirective *Create(const ASTContext &C,
2083 SourceLocation StartLoc,
2084 SourceLocation EndLoc,
2085 ArrayRef<OMPClause *> Clauses);
2087 /// \brief Creates an empty directive with the place for \a N clauses.
2089 /// \param C AST context.
2090 /// \param N The number of clauses.
2092 static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C,
2093 unsigned N, EmptyShell);
2095 static bool classof(const Stmt *T) {
2096 return T->getStmtClass() == OMPTargetEnterDataDirectiveClass;
2100 /// \brief This represents '#pragma omp target exit data' directive.
2103 /// #pragma omp target exit data device(0) if(a) map(b[:])
2105 /// In this example directive '#pragma omp target exit data' has clauses
2106 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
2109 class OMPTargetExitDataDirective : public OMPExecutableDirective {
2110 friend class ASTStmtReader;
2111 /// \brief Build directive with the given start and end location.
2113 /// \param StartLoc Starting location of the directive kind.
2114 /// \param EndLoc Ending Location of the directive.
2115 /// \param NumClauses The number of clauses.
2117 OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2118 unsigned NumClauses)
2119 : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass,
2120 OMPD_target_exit_data, StartLoc, EndLoc,
2121 NumClauses, /*NumChildren=*/0) {}
2123 /// \brief Build an empty directive.
2125 /// \param NumClauses Number of clauses.
2127 explicit OMPTargetExitDataDirective(unsigned NumClauses)
2128 : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass,
2129 OMPD_target_exit_data, SourceLocation(),
2130 SourceLocation(), NumClauses,
2131 /*NumChildren=*/0) {}
2134 /// \brief Creates directive with a list of \a Clauses.
2136 /// \param C AST context.
2137 /// \param StartLoc Starting location of the directive kind.
2138 /// \param EndLoc Ending Location of the directive.
2139 /// \param Clauses List of clauses.
2140 /// \param AssociatedStmt Statement, associated with the directive.
2142 static OMPTargetExitDataDirective *Create(const ASTContext &C,
2143 SourceLocation StartLoc,
2144 SourceLocation EndLoc,
2145 ArrayRef<OMPClause *> Clauses);
2147 /// \brief Creates an empty directive with the place for \a N clauses.
2149 /// \param C AST context.
2150 /// \param N The number of clauses.
2152 static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C,
2153 unsigned N, EmptyShell);
2155 static bool classof(const Stmt *T) {
2156 return T->getStmtClass() == OMPTargetExitDataDirectiveClass;
2160 /// \brief This represents '#pragma omp teams' directive.
2163 /// #pragma omp teams if(a)
2165 /// In this example directive '#pragma omp teams' has clause 'if' with
2168 class OMPTeamsDirective : public OMPExecutableDirective {
2169 friend class ASTStmtReader;
2170 /// \brief Build directive with the given start and end location.
2172 /// \param StartLoc Starting location of the directive kind.
2173 /// \param EndLoc Ending location of the directive.
2174 /// \param NumClauses Number of clauses.
2176 OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2177 unsigned NumClauses)
2178 : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
2179 StartLoc, EndLoc, NumClauses, 1) {}
2181 /// \brief Build an empty directive.
2183 /// \param NumClauses Number of clauses.
2185 explicit OMPTeamsDirective(unsigned NumClauses)
2186 : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
2187 SourceLocation(), SourceLocation(), NumClauses,
2191 /// \brief Creates directive with a list of \a Clauses.
2193 /// \param C AST context.
2194 /// \param StartLoc Starting location of the directive kind.
2195 /// \param EndLoc Ending Location of the directive.
2196 /// \param Clauses List of clauses.
2197 /// \param AssociatedStmt Statement, associated with the directive.
2199 static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2200 SourceLocation EndLoc,
2201 ArrayRef<OMPClause *> Clauses,
2202 Stmt *AssociatedStmt);
2204 /// \brief Creates an empty directive with the place for \a NumClauses
2207 /// \param C AST context.
2208 /// \param NumClauses Number of clauses.
2210 static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
2211 unsigned NumClauses, EmptyShell);
2213 static bool classof(const Stmt *T) {
2214 return T->getStmtClass() == OMPTeamsDirectiveClass;
2218 /// \brief This represents '#pragma omp cancellation point' directive.
2221 /// #pragma omp cancellation point for
2224 /// In this example a cancellation point is created for innermost 'for' region.
2225 class OMPCancellationPointDirective : public OMPExecutableDirective {
2226 friend class ASTStmtReader;
2227 OpenMPDirectiveKind CancelRegion;
2228 /// \brief Build directive with the given start and end location.
2230 /// \param StartLoc Starting location of the directive kind.
2231 /// \param EndLoc Ending location of the directive.
2233 OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2234 : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
2235 OMPD_cancellation_point, StartLoc, EndLoc, 0, 0),
2236 CancelRegion(OMPD_unknown) {}
2238 /// \brief Build an empty directive.
2240 explicit OMPCancellationPointDirective()
2241 : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
2242 OMPD_cancellation_point, SourceLocation(),
2243 SourceLocation(), 0, 0),
2244 CancelRegion(OMPD_unknown) {}
2246 /// \brief Set cancel region for current cancellation point.
2247 /// \param CR Cancellation region.
2248 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
2251 /// \brief Creates directive.
2253 /// \param C AST context.
2254 /// \param StartLoc Starting location of the directive kind.
2255 /// \param EndLoc Ending Location of the directive.
2257 static OMPCancellationPointDirective *
2258 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2259 OpenMPDirectiveKind CancelRegion);
2261 /// \brief Creates an empty directive.
2263 /// \param C AST context.
2265 static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
2268 /// \brief Get cancellation region for the current cancellation point.
2269 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
2271 static bool classof(const Stmt *T) {
2272 return T->getStmtClass() == OMPCancellationPointDirectiveClass;
2276 /// \brief This represents '#pragma omp cancel' directive.
2279 /// #pragma omp cancel for
2282 /// In this example a cancel is created for innermost 'for' region.
2283 class OMPCancelDirective : public OMPExecutableDirective {
2284 friend class ASTStmtReader;
2285 OpenMPDirectiveKind CancelRegion;
2286 /// \brief Build directive with the given start and end location.
2288 /// \param StartLoc Starting location of the directive kind.
2289 /// \param EndLoc Ending location of the directive.
2290 /// \param NumClauses Number of clauses.
2292 OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2293 unsigned NumClauses)
2294 : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
2295 StartLoc, EndLoc, NumClauses, 0),
2296 CancelRegion(OMPD_unknown) {}
2298 /// \brief Build an empty directive.
2300 /// \param NumClauses Number of clauses.
2301 explicit OMPCancelDirective(unsigned NumClauses)
2302 : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
2303 SourceLocation(), SourceLocation(), NumClauses,
2305 CancelRegion(OMPD_unknown) {}
2307 /// \brief Set cancel region for current cancellation point.
2308 /// \param CR Cancellation region.
2309 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
2312 /// \brief Creates directive.
2314 /// \param C AST context.
2315 /// \param StartLoc Starting location of the directive kind.
2316 /// \param EndLoc Ending Location of the directive.
2317 /// \param Clauses List of clauses.
2319 static OMPCancelDirective *
2320 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2321 ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
2323 /// \brief Creates an empty directive.
2325 /// \param C AST context.
2326 /// \param NumClauses Number of clauses.
2328 static OMPCancelDirective *CreateEmpty(const ASTContext &C,
2329 unsigned NumClauses, EmptyShell);
2331 /// \brief Get cancellation region for the current cancellation point.
2332 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
2334 static bool classof(const Stmt *T) {
2335 return T->getStmtClass() == OMPCancelDirectiveClass;
2339 /// \brief This represents '#pragma omp taskloop' directive.
2342 /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
2344 /// In this example directive '#pragma omp taskloop' has clauses 'private'
2345 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
2346 /// 'num_tasks' with expression 'num'.
2348 class OMPTaskLoopDirective : public OMPLoopDirective {
2349 friend class ASTStmtReader;
2350 /// \brief Build directive with the given start and end location.
2352 /// \param StartLoc Starting location of the directive kind.
2353 /// \param EndLoc Ending location of the directive.
2354 /// \param CollapsedNum Number of collapsed nested loops.
2355 /// \param NumClauses Number of clauses.
2357 OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2358 unsigned CollapsedNum, unsigned NumClauses)
2359 : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
2360 StartLoc, EndLoc, CollapsedNum, NumClauses) {}
2362 /// \brief Build an empty directive.
2364 /// \param CollapsedNum Number of collapsed nested loops.
2365 /// \param NumClauses Number of clauses.
2367 explicit OMPTaskLoopDirective(unsigned CollapsedNum, unsigned NumClauses)
2368 : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
2369 SourceLocation(), SourceLocation(), CollapsedNum,
2373 /// \brief Creates directive with a list of \a Clauses.
2375 /// \param C AST context.
2376 /// \param StartLoc Starting location of the directive kind.
2377 /// \param EndLoc Ending Location of the directive.
2378 /// \param CollapsedNum Number of collapsed loops.
2379 /// \param Clauses List of clauses.
2380 /// \param AssociatedStmt Statement, associated with the directive.
2381 /// \param Exprs Helper expressions for CodeGen.
2383 static OMPTaskLoopDirective *
2384 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2385 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2386 Stmt *AssociatedStmt, const HelperExprs &Exprs);
2388 /// \brief Creates an empty directive with the place
2389 /// for \a NumClauses clauses.
2391 /// \param C AST context.
2392 /// \param CollapsedNum Number of collapsed nested loops.
2393 /// \param NumClauses Number of clauses.
2395 static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C,
2396 unsigned NumClauses,
2397 unsigned CollapsedNum, EmptyShell);
2399 static bool classof(const Stmt *T) {
2400 return T->getStmtClass() == OMPTaskLoopDirectiveClass;
2404 /// \brief This represents '#pragma omp taskloop simd' directive.
2407 /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
2409 /// In this example directive '#pragma omp taskloop simd' has clauses 'private'
2410 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
2411 /// 'num_tasks' with expression 'num'.
2413 class OMPTaskLoopSimdDirective : public OMPLoopDirective {
2414 friend class ASTStmtReader;
2415 /// \brief Build directive with the given start and end location.
2417 /// \param StartLoc Starting location of the directive kind.
2418 /// \param EndLoc Ending location of the directive.
2419 /// \param CollapsedNum Number of collapsed nested loops.
2420 /// \param NumClauses Number of clauses.
2422 OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2423 unsigned CollapsedNum, unsigned NumClauses)
2424 : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
2425 OMPD_taskloop_simd, StartLoc, EndLoc, CollapsedNum,
2428 /// \brief Build an empty directive.
2430 /// \param CollapsedNum Number of collapsed nested loops.
2431 /// \param NumClauses Number of clauses.
2433 explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
2434 : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
2435 OMPD_taskloop_simd, SourceLocation(), SourceLocation(),
2436 CollapsedNum, NumClauses) {}
2439 /// \brief Creates directive with a list of \a Clauses.
2441 /// \param C AST context.
2442 /// \param StartLoc Starting location of the directive kind.
2443 /// \param EndLoc Ending Location of the directive.
2444 /// \param CollapsedNum Number of collapsed loops.
2445 /// \param Clauses List of clauses.
2446 /// \param AssociatedStmt Statement, associated with the directive.
2447 /// \param Exprs Helper expressions for CodeGen.
2449 static OMPTaskLoopSimdDirective *
2450 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2451 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2452 Stmt *AssociatedStmt, const HelperExprs &Exprs);
2454 /// \brief Creates an empty directive with the place
2455 /// for \a NumClauses clauses.
2457 /// \param C AST context.
2458 /// \param CollapsedNum Number of collapsed nested loops.
2459 /// \param NumClauses Number of clauses.
2461 static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
2462 unsigned NumClauses,
2463 unsigned CollapsedNum,
2466 static bool classof(const Stmt *T) {
2467 return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass;
2471 /// \brief This represents '#pragma omp distribute' directive.
2474 /// #pragma omp distribute private(a,b)
2476 /// In this example directive '#pragma omp distribute' has clauses 'private'
2477 /// with the variables 'a' and 'b'
2479 class OMPDistributeDirective : public OMPLoopDirective {
2480 friend class ASTStmtReader;
2482 /// \brief Build directive with the given start and end location.
2484 /// \param StartLoc Starting location of the directive kind.
2485 /// \param EndLoc Ending location of the directive.
2486 /// \param CollapsedNum Number of collapsed nested loops.
2487 /// \param NumClauses Number of clauses.
2489 OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2490 unsigned CollapsedNum, unsigned NumClauses)
2491 : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
2492 StartLoc, EndLoc, CollapsedNum, NumClauses)
2495 /// \brief Build an empty directive.
2497 /// \param CollapsedNum Number of collapsed nested loops.
2498 /// \param NumClauses Number of clauses.
2500 explicit OMPDistributeDirective(unsigned CollapsedNum, unsigned NumClauses)
2501 : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
2502 SourceLocation(), SourceLocation(), CollapsedNum,
2507 /// \brief Creates directive with a list of \a Clauses.
2509 /// \param C AST context.
2510 /// \param StartLoc Starting location of the directive kind.
2511 /// \param EndLoc Ending Location of the directive.
2512 /// \param CollapsedNum Number of collapsed loops.
2513 /// \param Clauses List of clauses.
2514 /// \param AssociatedStmt Statement, associated with the directive.
2515 /// \param Exprs Helper expressions for CodeGen.
2517 static OMPDistributeDirective *
2518 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2519 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2520 Stmt *AssociatedStmt, const HelperExprs &Exprs);
2522 /// \brief Creates an empty directive with the place
2523 /// for \a NumClauses clauses.
2525 /// \param C AST context.
2526 /// \param CollapsedNum Number of collapsed nested loops.
2527 /// \param NumClauses Number of clauses.
2529 static OMPDistributeDirective *CreateEmpty(const ASTContext &C,
2530 unsigned NumClauses,
2531 unsigned CollapsedNum, EmptyShell);
2533 static bool classof(const Stmt *T) {
2534 return T->getStmtClass() == OMPDistributeDirectiveClass;
2538 } // end namespace clang