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 those declarations that meet some run-time
97 template <class FilterPredicate> class filtered_clause_iterator {
99 ArrayRef<OMPClause *>::const_iterator Current;
100 ArrayRef<OMPClause *>::const_iterator End;
101 FilterPredicate Pred;
102 void SkipToNextClause() {
103 while (Current != End && !Pred(*Current))
108 typedef const OMPClause *value_type;
109 filtered_clause_iterator() : Current(), End() {}
110 filtered_clause_iterator(ArrayRef<OMPClause *> Arr, FilterPredicate Pred)
111 : Current(Arr.begin()), End(Arr.end()), Pred(std::move(Pred)) {
114 value_type operator*() const { return *Current; }
115 value_type operator->() const { return *Current; }
116 filtered_clause_iterator &operator++() {
122 filtered_clause_iterator operator++(int) {
123 filtered_clause_iterator tmp(*this);
128 bool operator!() { return Current == End; }
129 explicit operator bool() { return Current != End; }
130 bool empty() const { return Current == End; }
133 template <typename Fn>
134 filtered_clause_iterator<Fn> getFilteredClauses(Fn &&fn) const {
135 return filtered_clause_iterator<Fn>(clauses(), std::move(fn));
137 struct ClauseKindFilter {
138 OpenMPClauseKind Kind;
139 bool operator()(const OMPClause *clause) const {
140 return clause->getClauseKind() == Kind;
143 filtered_clause_iterator<ClauseKindFilter>
144 getClausesOfKind(OpenMPClauseKind Kind) const {
145 return getFilteredClauses(ClauseKindFilter{Kind});
148 /// \brief Gets a single clause of the specified kind \a K associated with the
149 /// current directive iff there is only one clause of this kind (and assertion
150 /// is fired if there is more than one clause is associated with the
151 /// directive). Returns nullptr if no clause of kind \a K is associated with
153 const OMPClause *getSingleClause(OpenMPClauseKind K) const;
155 /// \brief Returns starting location of directive kind.
156 SourceLocation getLocStart() const { return StartLoc; }
157 /// \brief Returns ending location of directive.
158 SourceLocation getLocEnd() const { return EndLoc; }
160 /// \brief Set starting location of directive kind.
162 /// \param Loc New starting location of directive.
164 void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
165 /// \brief Set ending location of directive.
167 /// \param Loc New ending location of directive.
169 void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
171 /// \brief Get number of clauses.
172 unsigned getNumClauses() const { return NumClauses; }
174 /// \brief Returns specified clause.
176 /// \param i Number of clause.
178 OMPClause *getClause(unsigned i) const { return clauses()[i]; }
180 /// \brief Returns true if directive has associated statement.
181 bool hasAssociatedStmt() const { return NumChildren > 0; }
183 /// \brief Returns statement associated with the directive.
184 Stmt *getAssociatedStmt() const {
185 assert(hasAssociatedStmt() && "no associated statement.");
186 return const_cast<Stmt *>(*child_begin());
189 OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
191 static bool classof(const Stmt *S) {
192 return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
193 S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
196 child_range children() {
197 if (!hasAssociatedStmt())
198 return child_range();
199 Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end());
200 return child_range(ChildStorage, ChildStorage + NumChildren);
203 ArrayRef<OMPClause *> clauses() { return getClauses(); }
205 ArrayRef<OMPClause *> clauses() const {
206 return const_cast<OMPExecutableDirective *>(this)->getClauses();
210 /// \brief This represents '#pragma omp parallel' directive.
213 /// #pragma omp parallel private(a,b) reduction(+: c,d)
215 /// In this example directive '#pragma omp parallel' has clauses 'private'
216 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
217 /// variables 'c' and 'd'.
219 class OMPParallelDirective : public OMPExecutableDirective {
220 /// \brief Build directive with the given start and end location.
222 /// \param StartLoc Starting location of the directive (directive keyword).
223 /// \param EndLoc Ending Location of the directive.
225 OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
227 : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
228 StartLoc, EndLoc, NumClauses, 1) {}
230 /// \brief Build an empty directive.
232 /// \param NumClauses Number of clauses.
234 explicit OMPParallelDirective(unsigned NumClauses)
235 : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
236 SourceLocation(), SourceLocation(), NumClauses,
240 /// \brief Creates directive with a list of \a Clauses.
242 /// \param C AST context.
243 /// \param StartLoc Starting location of the directive kind.
244 /// \param EndLoc Ending Location of the directive.
245 /// \param Clauses List of clauses.
246 /// \param AssociatedStmt Statement associated with the directive.
248 static OMPParallelDirective *
249 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
250 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
252 /// \brief Creates an empty directive with the place for \a N clauses.
254 /// \param C AST context.
255 /// \param NumClauses Number of clauses.
257 static OMPParallelDirective *CreateEmpty(const ASTContext &C,
258 unsigned NumClauses, EmptyShell);
260 static bool classof(const Stmt *T) {
261 return T->getStmtClass() == OMPParallelDirectiveClass;
265 /// \brief This is a common base class for loop directives ('omp simd', 'omp
266 /// for', 'omp for simd' etc.). It is responsible for the loop code generation.
268 class OMPLoopDirective : public OMPExecutableDirective {
269 friend class ASTStmtReader;
270 /// \brief Number of collapsed loops as specified by 'collapse' clause.
271 unsigned CollapsedNum;
273 /// \brief Offsets to the stored exprs.
274 /// This enumeration contains offsets to all the pointers to children
275 /// expressions stored in OMPLoopDirective.
276 /// The first 9 children are nesessary for all the loop directives, and
277 /// the next 7 are specific to the worksharing ones.
278 /// After the fixed children, three arrays of length CollapsedNum are
279 /// allocated: loop counters, their updates and final values.
282 AssociatedStmtOffset = 0,
283 IterationVariableOffset = 1,
284 LastIterationOffset = 2,
285 CalcLastIterationOffset = 3,
286 PreConditionOffset = 4,
288 SeparatedCondOffset = 6,
291 // The '...End' enumerators do not correspond to child expressions - they
292 // specify the offset to the end (and start of the following counters/
293 // updates/finals arrays).
295 // The following 7 exprs are used by worksharing loops only.
296 IsLastIterVariableOffset = 9,
297 LowerBoundVariableOffset = 10,
298 UpperBoundVariableOffset = 11,
299 StrideVariableOffset = 12,
300 EnsureUpperBoundOffset = 13,
301 NextLowerBoundOffset = 14,
302 NextUpperBoundOffset = 15,
303 // Offset to the end (and start of the following counters/updates/finals
304 // arrays) for worksharing loop directives.
308 /// \brief Get the counters storage.
309 MutableArrayRef<Expr *> getCounters() {
310 Expr **Storage = reinterpret_cast<Expr **>(
311 &(*(std::next(child_begin(), getArraysOffset(getDirectiveKind())))));
312 return MutableArrayRef<Expr *>(Storage, CollapsedNum);
315 /// \brief Get the updates storage.
316 MutableArrayRef<Expr *> getUpdates() {
317 Expr **Storage = reinterpret_cast<Expr **>(
318 &*std::next(child_begin(),
319 getArraysOffset(getDirectiveKind()) + CollapsedNum));
320 return MutableArrayRef<Expr *>(Storage, CollapsedNum);
323 /// \brief Get the final counter updates storage.
324 MutableArrayRef<Expr *> getFinals() {
325 Expr **Storage = reinterpret_cast<Expr **>(
326 &*std::next(child_begin(),
327 getArraysOffset(getDirectiveKind()) + 2 * CollapsedNum));
328 return MutableArrayRef<Expr *>(Storage, CollapsedNum);
332 /// \brief Build instance of loop directive of class \a Kind.
334 /// \param SC Statement class.
335 /// \param Kind Kind of OpenMP directive.
336 /// \param StartLoc Starting location of the directive (directive keyword).
337 /// \param EndLoc Ending location of the directive.
338 /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
339 /// \param NumClauses Number of clauses.
340 /// \param NumSpecialChildren Number of additional directive-specific stmts.
342 template <typename T>
343 OMPLoopDirective(const T *That, StmtClass SC, OpenMPDirectiveKind Kind,
344 SourceLocation StartLoc, SourceLocation EndLoc,
345 unsigned CollapsedNum, unsigned NumClauses,
346 unsigned NumSpecialChildren = 0)
347 : OMPExecutableDirective(That, SC, Kind, StartLoc, EndLoc, NumClauses,
348 numLoopChildren(CollapsedNum, Kind) +
350 CollapsedNum(CollapsedNum) {}
352 /// \brief Offset to the start of children expression arrays.
353 static unsigned getArraysOffset(OpenMPDirectiveKind Kind) {
354 return isOpenMPWorksharingDirective(Kind) ? WorksharingEnd
358 /// \brief Children number.
359 static unsigned numLoopChildren(unsigned CollapsedNum,
360 OpenMPDirectiveKind Kind) {
361 return getArraysOffset(Kind) +
362 3 * CollapsedNum; // Counters, Updates and Finals
365 void setIterationVariable(Expr *IV) {
366 *std::next(child_begin(), IterationVariableOffset) = IV;
368 void setLastIteration(Expr *LI) {
369 *std::next(child_begin(), LastIterationOffset) = LI;
371 void setCalcLastIteration(Expr *CLI) {
372 *std::next(child_begin(), CalcLastIterationOffset) = CLI;
374 void setPreCond(Expr *PC) {
375 *std::next(child_begin(), PreConditionOffset) = PC;
377 void setCond(Expr *Cond, Expr *SeparatedCond) {
378 *std::next(child_begin(), CondOffset) = Cond;
379 *std::next(child_begin(), SeparatedCondOffset) = SeparatedCond;
381 void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; }
382 void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; }
383 void setIsLastIterVariable(Expr *IL) {
384 assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
385 "expected worksharing loop directive");
386 *std::next(child_begin(), IsLastIterVariableOffset) = IL;
388 void setLowerBoundVariable(Expr *LB) {
389 assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
390 "expected worksharing loop directive");
391 *std::next(child_begin(), LowerBoundVariableOffset) = LB;
393 void setUpperBoundVariable(Expr *UB) {
394 assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
395 "expected worksharing loop directive");
396 *std::next(child_begin(), UpperBoundVariableOffset) = UB;
398 void setStrideVariable(Expr *ST) {
399 assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
400 "expected worksharing loop directive");
401 *std::next(child_begin(), StrideVariableOffset) = ST;
403 void setEnsureUpperBound(Expr *EUB) {
404 assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
405 "expected worksharing loop directive");
406 *std::next(child_begin(), EnsureUpperBoundOffset) = EUB;
408 void setNextLowerBound(Expr *NLB) {
409 assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
410 "expected worksharing loop directive");
411 *std::next(child_begin(), NextLowerBoundOffset) = NLB;
413 void setNextUpperBound(Expr *NUB) {
414 assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
415 "expected worksharing loop directive");
416 *std::next(child_begin(), NextUpperBoundOffset) = NUB;
418 void setCounters(ArrayRef<Expr *> A);
419 void setUpdates(ArrayRef<Expr *> A);
420 void setFinals(ArrayRef<Expr *> A);
423 /// \brief The expressions built for the OpenMP loop CodeGen for the
424 /// whole collapsed loop nest.
426 /// \brief Loop iteration variable.
427 Expr *IterationVarRef;
428 /// \brief Loop last iteration number.
430 /// \brief Loop number of iterations.
432 /// \brief Calculation of last iteration.
433 Expr *CalcLastIteration;
434 /// \brief Loop pre-condition.
436 /// \brief Loop condition.
438 /// \brief A condition with 1 iteration separated.
440 /// \brief Loop iteration variable init.
442 /// \brief Loop increment.
444 /// \brief IsLastIteration - local flag variable passed to runtime.
446 /// \brief LowerBound - local variable passed to runtime.
448 /// \brief UpperBound - local variable passed to runtime.
450 /// \brief Stride - local variable passed to runtime.
452 /// \brief EnsureUpperBound -- expression LB = min(LB, NumIterations).
454 /// \brief Update of LowerBound for statically sheduled 'omp for' loops.
456 /// \brief Update of UpperBound for statically sheduled 'omp for' loops.
458 /// \brief Counters Loop counters.
459 SmallVector<Expr *, 4> Counters;
460 /// \brief Expressions for loop counters update for CodeGen.
461 SmallVector<Expr *, 4> Updates;
462 /// \brief Final loop counter values for GodeGen.
463 SmallVector<Expr *, 4> Finals;
465 /// \brief Check if all the expressions are built (does not check the
466 /// worksharing ones).
468 return IterationVarRef != nullptr && LastIteration != nullptr &&
469 NumIterations != nullptr && PreCond != nullptr &&
470 Cond != nullptr && SeparatedCond != nullptr && Init != nullptr &&
474 /// \brief Initialize all the fields to null.
475 /// \param Size Number of elements in the counters/finals/updates arrays.
476 void clear(unsigned Size) {
477 IterationVarRef = nullptr;
478 LastIteration = nullptr;
479 CalcLastIteration = nullptr;
482 SeparatedCond = nullptr;
492 Counters.resize(Size);
493 Updates.resize(Size);
495 for (unsigned i = 0; i < Size; ++i) {
496 Counters[i] = nullptr;
497 Updates[i] = nullptr;
503 /// \brief Get number of collapsed loops.
504 unsigned getCollapsedNumber() const { return CollapsedNum; }
506 Expr *getIterationVariable() const {
507 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
508 *std::next(child_begin(), IterationVariableOffset)));
510 Expr *getLastIteration() const {
511 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
512 *std::next(child_begin(), LastIterationOffset)));
514 Expr *getCalcLastIteration() const {
515 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
516 *std::next(child_begin(), CalcLastIterationOffset)));
518 Expr *getPreCond() const {
519 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
520 *std::next(child_begin(), PreConditionOffset)));
522 Expr *getCond(bool SeparateIter) const {
523 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
524 *std::next(child_begin(),
525 (SeparateIter ? SeparatedCondOffset : CondOffset))));
527 Expr *getInit() const {
528 return const_cast<Expr *>(
529 reinterpret_cast<const Expr *>(*std::next(child_begin(), InitOffset)));
531 Expr *getInc() const {
532 return const_cast<Expr *>(
533 reinterpret_cast<const Expr *>(*std::next(child_begin(), IncOffset)));
535 Expr *getIsLastIterVariable() const {
536 assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
537 "expected worksharing loop directive");
538 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
539 *std::next(child_begin(), IsLastIterVariableOffset)));
541 Expr *getLowerBoundVariable() const {
542 assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
543 "expected worksharing loop directive");
544 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
545 *std::next(child_begin(), LowerBoundVariableOffset)));
547 Expr *getUpperBoundVariable() const {
548 assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
549 "expected worksharing loop directive");
550 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
551 *std::next(child_begin(), UpperBoundVariableOffset)));
553 Expr *getStrideVariable() const {
554 assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
555 "expected worksharing loop directive");
556 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
557 *std::next(child_begin(), StrideVariableOffset)));
559 Expr *getEnsureUpperBound() const {
560 assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
561 "expected worksharing loop directive");
562 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
563 *std::next(child_begin(), EnsureUpperBoundOffset)));
565 Expr *getNextLowerBound() const {
566 assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
567 "expected worksharing loop directive");
568 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
569 *std::next(child_begin(), NextLowerBoundOffset)));
571 Expr *getNextUpperBound() const {
572 assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
573 "expected worksharing loop directive");
574 return const_cast<Expr *>(reinterpret_cast<const Expr *>(
575 *std::next(child_begin(), NextUpperBoundOffset)));
577 const Stmt *getBody() const {
578 // This relies on the loop form is already checked by Sema.
579 Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
580 Body = cast<ForStmt>(Body)->getBody();
581 for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) {
582 Body = Body->IgnoreContainers();
583 Body = cast<ForStmt>(Body)->getBody();
588 ArrayRef<Expr *> counters() { return getCounters(); }
590 ArrayRef<Expr *> counters() const {
591 return const_cast<OMPLoopDirective *>(this)->getCounters();
594 ArrayRef<Expr *> updates() { return getUpdates(); }
596 ArrayRef<Expr *> updates() const {
597 return const_cast<OMPLoopDirective *>(this)->getUpdates();
600 ArrayRef<Expr *> finals() { return getFinals(); }
602 ArrayRef<Expr *> finals() const {
603 return const_cast<OMPLoopDirective *>(this)->getFinals();
606 static bool classof(const Stmt *T) {
607 return T->getStmtClass() == OMPSimdDirectiveClass ||
608 T->getStmtClass() == OMPForDirectiveClass ||
609 T->getStmtClass() == OMPForSimdDirectiveClass ||
610 T->getStmtClass() == OMPParallelForDirectiveClass ||
611 T->getStmtClass() == OMPParallelForSimdDirectiveClass;
615 /// \brief This represents '#pragma omp simd' directive.
618 /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
620 /// In this example directive '#pragma omp simd' has clauses 'private'
621 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
622 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
624 class OMPSimdDirective : public OMPLoopDirective {
625 friend class ASTStmtReader;
626 /// \brief Build directive with the given start and end location.
628 /// \param StartLoc Starting location of the directive kind.
629 /// \param EndLoc Ending location of the directive.
630 /// \param CollapsedNum Number of collapsed nested loops.
631 /// \param NumClauses Number of clauses.
633 OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
634 unsigned CollapsedNum, unsigned NumClauses)
635 : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
636 EndLoc, CollapsedNum, NumClauses) {}
638 /// \brief Build an empty directive.
640 /// \param CollapsedNum Number of collapsed nested loops.
641 /// \param NumClauses Number of clauses.
643 explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
644 : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd,
645 SourceLocation(), SourceLocation(), CollapsedNum,
649 /// \brief Creates directive with a list of \a Clauses.
651 /// \param C AST context.
652 /// \param StartLoc Starting location of the directive kind.
653 /// \param EndLoc Ending Location of the directive.
654 /// \param CollapsedNum Number of collapsed loops.
655 /// \param Clauses List of clauses.
656 /// \param AssociatedStmt Statement, associated with the directive.
657 /// \param Exprs Helper expressions for CodeGen.
659 static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
660 SourceLocation EndLoc, unsigned CollapsedNum,
661 ArrayRef<OMPClause *> Clauses,
662 Stmt *AssociatedStmt,
663 const HelperExprs &Exprs);
665 /// \brief Creates an empty directive with the place
666 /// for \a NumClauses clauses.
668 /// \param C AST context.
669 /// \param CollapsedNum Number of collapsed nested loops.
670 /// \param NumClauses Number of clauses.
672 static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
673 unsigned CollapsedNum, EmptyShell);
675 static bool classof(const Stmt *T) {
676 return T->getStmtClass() == OMPSimdDirectiveClass;
680 /// \brief This represents '#pragma omp for' directive.
683 /// #pragma omp for private(a,b) reduction(+:c,d)
685 /// In this example directive '#pragma omp for' has clauses 'private' with the
686 /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
689 class OMPForDirective : public OMPLoopDirective {
690 friend class ASTStmtReader;
691 /// \brief Build directive with the given start and end location.
693 /// \param StartLoc Starting location of the directive kind.
694 /// \param EndLoc Ending location of the directive.
695 /// \param CollapsedNum Number of collapsed nested loops.
696 /// \param NumClauses Number of clauses.
698 OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
699 unsigned CollapsedNum, unsigned NumClauses)
700 : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, EndLoc,
701 CollapsedNum, NumClauses) {}
703 /// \brief Build an empty directive.
705 /// \param CollapsedNum Number of collapsed nested loops.
706 /// \param NumClauses Number of clauses.
708 explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses)
709 : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, SourceLocation(),
710 SourceLocation(), CollapsedNum, NumClauses) {}
713 /// \brief Creates directive with a list of \a Clauses.
715 /// \param C AST context.
716 /// \param StartLoc Starting location of the directive kind.
717 /// \param EndLoc Ending Location of the directive.
718 /// \param CollapsedNum Number of collapsed loops.
719 /// \param Clauses List of clauses.
720 /// \param AssociatedStmt Statement, associated with the directive.
721 /// \param Exprs Helper expressions for CodeGen.
723 static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
724 SourceLocation EndLoc, unsigned CollapsedNum,
725 ArrayRef<OMPClause *> Clauses,
726 Stmt *AssociatedStmt,
727 const HelperExprs &Exprs);
729 /// \brief Creates an empty directive with the place
730 /// for \a NumClauses clauses.
732 /// \param C AST context.
733 /// \param CollapsedNum Number of collapsed nested loops.
734 /// \param NumClauses Number of clauses.
736 static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
737 unsigned CollapsedNum, EmptyShell);
739 static bool classof(const Stmt *T) {
740 return T->getStmtClass() == OMPForDirectiveClass;
744 /// \brief This represents '#pragma omp for simd' directive.
747 /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
749 /// In this example directive '#pragma omp for simd' has clauses 'private'
750 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
751 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
753 class OMPForSimdDirective : public OMPLoopDirective {
754 friend class ASTStmtReader;
755 /// \brief Build directive with the given start and end location.
757 /// \param StartLoc Starting location of the directive kind.
758 /// \param EndLoc Ending location of the directive.
759 /// \param CollapsedNum Number of collapsed nested loops.
760 /// \param NumClauses Number of clauses.
762 OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
763 unsigned CollapsedNum, unsigned NumClauses)
764 : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
765 StartLoc, EndLoc, CollapsedNum, NumClauses) {}
767 /// \brief Build an empty directive.
769 /// \param CollapsedNum Number of collapsed nested loops.
770 /// \param NumClauses Number of clauses.
772 explicit OMPForSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
773 : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
774 SourceLocation(), SourceLocation(), CollapsedNum,
778 /// \brief Creates directive with a list of \a Clauses.
780 /// \param C AST context.
781 /// \param StartLoc Starting location of the directive kind.
782 /// \param EndLoc Ending Location of the directive.
783 /// \param CollapsedNum Number of collapsed loops.
784 /// \param Clauses List of clauses.
785 /// \param AssociatedStmt Statement, associated with the directive.
786 /// \param Exprs Helper expressions for CodeGen.
788 static OMPForSimdDirective *
789 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
790 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
791 Stmt *AssociatedStmt, const HelperExprs &Exprs);
793 /// \brief Creates an empty directive with the place
794 /// for \a NumClauses clauses.
796 /// \param C AST context.
797 /// \param CollapsedNum Number of collapsed nested loops.
798 /// \param NumClauses Number of clauses.
800 static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
802 unsigned CollapsedNum, EmptyShell);
804 static bool classof(const Stmt *T) {
805 return T->getStmtClass() == OMPForSimdDirectiveClass;
809 /// \brief This represents '#pragma omp sections' directive.
812 /// #pragma omp sections private(a,b) reduction(+:c,d)
814 /// In this example directive '#pragma omp sections' has clauses 'private' with
815 /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
818 class OMPSectionsDirective : public OMPExecutableDirective {
819 friend class ASTStmtReader;
820 /// \brief Build directive with the given start and end location.
822 /// \param StartLoc Starting location of the directive kind.
823 /// \param EndLoc Ending location of the directive.
824 /// \param NumClauses Number of clauses.
826 OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
828 : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
829 StartLoc, EndLoc, NumClauses, 1) {}
831 /// \brief Build an empty directive.
833 /// \param NumClauses Number of clauses.
835 explicit OMPSectionsDirective(unsigned NumClauses)
836 : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
837 SourceLocation(), SourceLocation(), NumClauses,
841 /// \brief Creates directive with a list of \a Clauses.
843 /// \param C AST context.
844 /// \param StartLoc Starting location of the directive kind.
845 /// \param EndLoc Ending Location of the directive.
846 /// \param Clauses List of clauses.
847 /// \param AssociatedStmt Statement, associated with the directive.
849 static OMPSectionsDirective *
850 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
851 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
853 /// \brief Creates an empty directive with the place for \a NumClauses
856 /// \param C AST context.
857 /// \param NumClauses Number of clauses.
859 static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
860 unsigned NumClauses, EmptyShell);
862 static bool classof(const Stmt *T) {
863 return T->getStmtClass() == OMPSectionsDirectiveClass;
867 /// \brief This represents '#pragma omp section' directive.
870 /// #pragma omp section
873 class OMPSectionDirective : public OMPExecutableDirective {
874 friend class ASTStmtReader;
875 /// \brief Build directive with the given start and end location.
877 /// \param StartLoc Starting location of the directive kind.
878 /// \param EndLoc Ending location of the directive.
880 OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
881 : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
882 StartLoc, EndLoc, 0, 1) {}
884 /// \brief Build an empty directive.
886 explicit OMPSectionDirective()
887 : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
888 SourceLocation(), SourceLocation(), 0, 1) {}
891 /// \brief Creates directive.
893 /// \param C AST context.
894 /// \param StartLoc Starting location of the directive kind.
895 /// \param EndLoc Ending Location of the directive.
896 /// \param AssociatedStmt Statement, associated with the directive.
898 static OMPSectionDirective *Create(const ASTContext &C,
899 SourceLocation StartLoc,
900 SourceLocation EndLoc,
901 Stmt *AssociatedStmt);
903 /// \brief Creates an empty directive.
905 /// \param C AST context.
907 static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
909 static bool classof(const Stmt *T) {
910 return T->getStmtClass() == OMPSectionDirectiveClass;
914 /// \brief This represents '#pragma omp single' directive.
917 /// #pragma omp single private(a,b) copyprivate(c,d)
919 /// In this example directive '#pragma omp single' has clauses 'private' with
920 /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
922 class OMPSingleDirective : public OMPExecutableDirective {
923 friend class ASTStmtReader;
924 /// \brief Build directive with the given start and end location.
926 /// \param StartLoc Starting location of the directive kind.
927 /// \param EndLoc Ending location of the directive.
928 /// \param NumClauses Number of clauses.
930 OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc,
932 : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
933 StartLoc, EndLoc, NumClauses, 1) {}
935 /// \brief Build an empty directive.
937 /// \param NumClauses Number of clauses.
939 explicit OMPSingleDirective(unsigned NumClauses)
940 : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
941 SourceLocation(), SourceLocation(), NumClauses,
945 /// \brief Creates directive with a list of \a Clauses.
947 /// \param C AST context.
948 /// \param StartLoc Starting location of the directive kind.
949 /// \param EndLoc Ending Location of the directive.
950 /// \param Clauses List of clauses.
951 /// \param AssociatedStmt Statement, associated with the directive.
953 static OMPSingleDirective *
954 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
955 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
957 /// \brief Creates an empty directive with the place for \a NumClauses
960 /// \param C AST context.
961 /// \param NumClauses Number of clauses.
963 static OMPSingleDirective *CreateEmpty(const ASTContext &C,
964 unsigned NumClauses, EmptyShell);
966 static bool classof(const Stmt *T) {
967 return T->getStmtClass() == OMPSingleDirectiveClass;
971 /// \brief This represents '#pragma omp master' directive.
974 /// #pragma omp master
977 class OMPMasterDirective : public OMPExecutableDirective {
978 friend class ASTStmtReader;
979 /// \brief Build directive with the given start and end location.
981 /// \param StartLoc Starting location of the directive kind.
982 /// \param EndLoc Ending location of the directive.
984 OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
985 : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
986 StartLoc, EndLoc, 0, 1) {}
988 /// \brief Build an empty directive.
990 explicit OMPMasterDirective()
991 : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
992 SourceLocation(), SourceLocation(), 0, 1) {}
995 /// \brief Creates directive.
997 /// \param C AST context.
998 /// \param StartLoc Starting location of the directive kind.
999 /// \param EndLoc Ending Location of the directive.
1000 /// \param AssociatedStmt Statement, associated with the directive.
1002 static OMPMasterDirective *Create(const ASTContext &C,
1003 SourceLocation StartLoc,
1004 SourceLocation EndLoc,
1005 Stmt *AssociatedStmt);
1007 /// \brief Creates an empty directive.
1009 /// \param C AST context.
1011 static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1013 static bool classof(const Stmt *T) {
1014 return T->getStmtClass() == OMPMasterDirectiveClass;
1018 /// \brief This represents '#pragma omp critical' directive.
1021 /// #pragma omp critical
1024 class OMPCriticalDirective : public OMPExecutableDirective {
1025 friend class ASTStmtReader;
1026 /// \brief Name of the directive.
1027 DeclarationNameInfo DirName;
1028 /// \brief Build directive with the given start and end location.
1030 /// \param Name Name of the directive.
1031 /// \param StartLoc Starting location of the directive kind.
1032 /// \param EndLoc Ending location of the directive.
1034 OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
1035 SourceLocation EndLoc)
1036 : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
1037 StartLoc, EndLoc, 0, 1),
1040 /// \brief Build an empty directive.
1042 explicit OMPCriticalDirective()
1043 : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
1044 SourceLocation(), SourceLocation(), 0, 1),
1047 /// \brief Set name of the directive.
1049 /// \param Name Name of the directive.
1051 void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
1054 /// \brief Creates directive.
1056 /// \param C AST context.
1057 /// \param Name Name of the directive.
1058 /// \param StartLoc Starting location of the directive kind.
1059 /// \param EndLoc Ending Location of the directive.
1060 /// \param AssociatedStmt Statement, associated with the directive.
1062 static OMPCriticalDirective *
1063 Create(const ASTContext &C, const DeclarationNameInfo &Name,
1064 SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt);
1066 /// \brief Creates an empty directive.
1068 /// \param C AST context.
1070 static OMPCriticalDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1072 /// \brief Return name of the directive.
1074 DeclarationNameInfo getDirectiveName() const { return DirName; }
1076 static bool classof(const Stmt *T) {
1077 return T->getStmtClass() == OMPCriticalDirectiveClass;
1081 /// \brief This represents '#pragma omp parallel for' directive.
1084 /// #pragma omp parallel for private(a,b) reduction(+:c,d)
1086 /// In this example directive '#pragma omp parallel for' has clauses 'private'
1087 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
1088 /// variables 'c' and 'd'.
1090 class OMPParallelForDirective : public OMPLoopDirective {
1091 friend class ASTStmtReader;
1092 /// \brief Build directive with the given start and end location.
1094 /// \param StartLoc Starting location of the directive kind.
1095 /// \param EndLoc Ending location of the directive.
1096 /// \param CollapsedNum Number of collapsed nested loops.
1097 /// \param NumClauses Number of clauses.
1099 OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1100 unsigned CollapsedNum, unsigned NumClauses)
1101 : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
1102 StartLoc, EndLoc, CollapsedNum, NumClauses) {}
1104 /// \brief Build an empty directive.
1106 /// \param CollapsedNum Number of collapsed nested loops.
1107 /// \param NumClauses Number of clauses.
1109 explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses)
1110 : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
1111 SourceLocation(), SourceLocation(), CollapsedNum,
1115 /// \brief Creates directive with a list of \a Clauses.
1117 /// \param C AST context.
1118 /// \param StartLoc Starting location of the directive kind.
1119 /// \param EndLoc Ending Location of the directive.
1120 /// \param CollapsedNum Number of collapsed loops.
1121 /// \param Clauses List of clauses.
1122 /// \param AssociatedStmt Statement, associated with the directive.
1123 /// \param Exprs Helper expressions for CodeGen.
1125 static OMPParallelForDirective *
1126 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1127 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1128 Stmt *AssociatedStmt, const HelperExprs &Exprs);
1130 /// \brief Creates an empty directive with the place
1131 /// for \a NumClauses clauses.
1133 /// \param C AST context.
1134 /// \param CollapsedNum Number of collapsed nested loops.
1135 /// \param NumClauses Number of clauses.
1137 static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
1138 unsigned NumClauses,
1139 unsigned CollapsedNum,
1142 static bool classof(const Stmt *T) {
1143 return T->getStmtClass() == OMPParallelForDirectiveClass;
1147 /// \brief This represents '#pragma omp parallel for simd' directive.
1150 /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
1152 /// In this example directive '#pragma omp parallel for simd' has clauses
1153 /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
1154 /// and linear step 's', 'reduction' with operator '+' and variables 'c' and
1157 class OMPParallelForSimdDirective : public OMPLoopDirective {
1158 friend class ASTStmtReader;
1159 /// \brief Build directive with the given start and end location.
1161 /// \param StartLoc Starting location of the directive kind.
1162 /// \param EndLoc Ending location of the directive.
1163 /// \param CollapsedNum Number of collapsed nested loops.
1164 /// \param NumClauses Number of clauses.
1166 OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1167 unsigned CollapsedNum, unsigned NumClauses)
1168 : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
1169 OMPD_parallel_for_simd, StartLoc, EndLoc, CollapsedNum,
1172 /// \brief Build an empty directive.
1174 /// \param CollapsedNum Number of collapsed nested loops.
1175 /// \param NumClauses Number of clauses.
1177 explicit OMPParallelForSimdDirective(unsigned CollapsedNum,
1178 unsigned NumClauses)
1179 : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
1180 OMPD_parallel_for_simd, SourceLocation(),
1181 SourceLocation(), CollapsedNum, NumClauses) {}
1184 /// \brief Creates directive with a list of \a Clauses.
1186 /// \param C AST context.
1187 /// \param StartLoc Starting location of the directive kind.
1188 /// \param EndLoc Ending Location of the directive.
1189 /// \param CollapsedNum Number of collapsed loops.
1190 /// \param Clauses List of clauses.
1191 /// \param AssociatedStmt Statement, associated with the directive.
1192 /// \param Exprs Helper expressions for CodeGen.
1194 static OMPParallelForSimdDirective *
1195 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1196 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1197 Stmt *AssociatedStmt, const HelperExprs &Exprs);
1199 /// \brief Creates an empty directive with the place
1200 /// for \a NumClauses clauses.
1202 /// \param C AST context.
1203 /// \param CollapsedNum Number of collapsed nested loops.
1204 /// \param NumClauses Number of clauses.
1206 static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
1207 unsigned NumClauses,
1208 unsigned CollapsedNum,
1211 static bool classof(const Stmt *T) {
1212 return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
1216 /// \brief This represents '#pragma omp parallel sections' directive.
1219 /// #pragma omp parallel sections private(a,b) reduction(+:c,d)
1221 /// In this example directive '#pragma omp parallel sections' has clauses
1222 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
1223 /// and variables 'c' and 'd'.
1225 class OMPParallelSectionsDirective : public OMPExecutableDirective {
1226 friend class ASTStmtReader;
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 NumClauses Number of clauses.
1233 OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1234 unsigned NumClauses)
1235 : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
1236 OMPD_parallel_sections, StartLoc, EndLoc,
1239 /// \brief Build an empty directive.
1241 /// \param NumClauses Number of clauses.
1243 explicit OMPParallelSectionsDirective(unsigned NumClauses)
1244 : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
1245 OMPD_parallel_sections, SourceLocation(),
1246 SourceLocation(), NumClauses, 1) {}
1249 /// \brief Creates directive with a list of \a Clauses.
1251 /// \param C AST context.
1252 /// \param StartLoc Starting location of the directive kind.
1253 /// \param EndLoc Ending Location of the directive.
1254 /// \param Clauses List of clauses.
1255 /// \param AssociatedStmt Statement, associated with the directive.
1257 static OMPParallelSectionsDirective *
1258 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1259 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1261 /// \brief Creates an empty directive with the place for \a NumClauses
1264 /// \param C AST context.
1265 /// \param NumClauses Number of clauses.
1267 static OMPParallelSectionsDirective *
1268 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
1270 static bool classof(const Stmt *T) {
1271 return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
1275 /// \brief This represents '#pragma omp task' directive.
1278 /// #pragma omp task private(a,b) final(d)
1280 /// In this example directive '#pragma omp task' has clauses 'private' with the
1281 /// variables 'a' and 'b' and 'final' with condition 'd'.
1283 class OMPTaskDirective : public OMPExecutableDirective {
1284 friend class ASTStmtReader;
1285 /// \brief Build directive with the given start and end location.
1287 /// \param StartLoc Starting location of the directive kind.
1288 /// \param EndLoc Ending location of the directive.
1289 /// \param NumClauses Number of clauses.
1291 OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1292 unsigned NumClauses)
1293 : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc,
1294 EndLoc, NumClauses, 1) {}
1296 /// \brief Build an empty directive.
1298 /// \param NumClauses Number of clauses.
1300 explicit OMPTaskDirective(unsigned NumClauses)
1301 : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task,
1302 SourceLocation(), SourceLocation(), NumClauses,
1306 /// \brief Creates directive with a list of \a Clauses.
1308 /// \param C AST context.
1309 /// \param StartLoc Starting location of the directive kind.
1310 /// \param EndLoc Ending Location of the directive.
1311 /// \param Clauses List of clauses.
1312 /// \param AssociatedStmt Statement, associated with the directive.
1314 static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1315 SourceLocation EndLoc,
1316 ArrayRef<OMPClause *> Clauses,
1317 Stmt *AssociatedStmt);
1319 /// \brief Creates an empty directive with the place for \a NumClauses
1322 /// \param C AST context.
1323 /// \param NumClauses Number of clauses.
1325 static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1328 static bool classof(const Stmt *T) {
1329 return T->getStmtClass() == OMPTaskDirectiveClass;
1333 /// \brief This represents '#pragma omp taskyield' directive.
1336 /// #pragma omp taskyield
1339 class OMPTaskyieldDirective : public OMPExecutableDirective {
1340 friend class ASTStmtReader;
1341 /// \brief Build directive with the given start and end location.
1343 /// \param StartLoc Starting location of the directive kind.
1344 /// \param EndLoc Ending location of the directive.
1346 OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1347 : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
1348 StartLoc, EndLoc, 0, 0) {}
1350 /// \brief Build an empty directive.
1352 explicit OMPTaskyieldDirective()
1353 : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
1354 SourceLocation(), SourceLocation(), 0, 0) {}
1357 /// \brief Creates directive.
1359 /// \param C AST context.
1360 /// \param StartLoc Starting location of the directive kind.
1361 /// \param EndLoc Ending Location of the directive.
1363 static OMPTaskyieldDirective *
1364 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1366 /// \brief Creates an empty directive.
1368 /// \param C AST context.
1370 static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1372 static bool classof(const Stmt *T) {
1373 return T->getStmtClass() == OMPTaskyieldDirectiveClass;
1377 /// \brief This represents '#pragma omp barrier' directive.
1380 /// #pragma omp barrier
1383 class OMPBarrierDirective : public OMPExecutableDirective {
1384 friend class ASTStmtReader;
1385 /// \brief Build directive with the given start and end location.
1387 /// \param StartLoc Starting location of the directive kind.
1388 /// \param EndLoc Ending location of the directive.
1390 OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1391 : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
1392 StartLoc, EndLoc, 0, 0) {}
1394 /// \brief Build an empty directive.
1396 explicit OMPBarrierDirective()
1397 : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
1398 SourceLocation(), SourceLocation(), 0, 0) {}
1401 /// \brief Creates directive.
1403 /// \param C AST context.
1404 /// \param StartLoc Starting location of the directive kind.
1405 /// \param EndLoc Ending Location of the directive.
1407 static OMPBarrierDirective *
1408 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1410 /// \brief Creates an empty directive.
1412 /// \param C AST context.
1414 static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1416 static bool classof(const Stmt *T) {
1417 return T->getStmtClass() == OMPBarrierDirectiveClass;
1421 /// \brief This represents '#pragma omp taskwait' directive.
1424 /// #pragma omp taskwait
1427 class OMPTaskwaitDirective : public OMPExecutableDirective {
1428 friend class ASTStmtReader;
1429 /// \brief Build directive with the given start and end location.
1431 /// \param StartLoc Starting location of the directive kind.
1432 /// \param EndLoc Ending location of the directive.
1434 OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1435 : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
1436 StartLoc, EndLoc, 0, 0) {}
1438 /// \brief Build an empty directive.
1440 explicit OMPTaskwaitDirective()
1441 : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
1442 SourceLocation(), SourceLocation(), 0, 0) {}
1445 /// \brief Creates directive.
1447 /// \param C AST context.
1448 /// \param StartLoc Starting location of the directive kind.
1449 /// \param EndLoc Ending Location of the directive.
1451 static OMPTaskwaitDirective *
1452 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1454 /// \brief Creates an empty directive.
1456 /// \param C AST context.
1458 static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1460 static bool classof(const Stmt *T) {
1461 return T->getStmtClass() == OMPTaskwaitDirectiveClass;
1465 /// \brief This represents '#pragma omp flush' directive.
1468 /// #pragma omp flush(a,b)
1470 /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
1472 /// 'omp flush' directive does not have clauses but have an optional list of
1473 /// variables to flush. This list of variables is stored within some fake clause
1475 class OMPFlushDirective : public OMPExecutableDirective {
1476 friend class ASTStmtReader;
1477 /// \brief Build directive with the given start and end location.
1479 /// \param StartLoc Starting location of the directive kind.
1480 /// \param EndLoc Ending location of the directive.
1481 /// \param NumClauses Number of clauses.
1483 OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1484 unsigned NumClauses)
1485 : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
1486 StartLoc, EndLoc, NumClauses, 0) {}
1488 /// \brief Build an empty directive.
1490 /// \param NumClauses Number of clauses.
1492 explicit OMPFlushDirective(unsigned NumClauses)
1493 : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
1494 SourceLocation(), SourceLocation(), NumClauses,
1498 /// \brief Creates directive with a list of \a Clauses.
1500 /// \param C AST context.
1501 /// \param StartLoc Starting location of the directive kind.
1502 /// \param EndLoc Ending Location of the directive.
1503 /// \param Clauses List of clauses (only single OMPFlushClause clause is
1506 static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1507 SourceLocation EndLoc,
1508 ArrayRef<OMPClause *> Clauses);
1510 /// \brief Creates an empty directive with the place for \a NumClauses
1513 /// \param C AST context.
1514 /// \param NumClauses Number of clauses.
1516 static OMPFlushDirective *CreateEmpty(const ASTContext &C,
1517 unsigned NumClauses, EmptyShell);
1519 static bool classof(const Stmt *T) {
1520 return T->getStmtClass() == OMPFlushDirectiveClass;
1524 /// \brief This represents '#pragma omp ordered' directive.
1527 /// #pragma omp ordered
1530 class OMPOrderedDirective : public OMPExecutableDirective {
1531 friend class ASTStmtReader;
1532 /// \brief Build directive with the given start and end location.
1534 /// \param StartLoc Starting location of the directive kind.
1535 /// \param EndLoc Ending location of the directive.
1537 OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1538 : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
1539 StartLoc, EndLoc, 0, 1) {}
1541 /// \brief Build an empty directive.
1543 explicit OMPOrderedDirective()
1544 : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
1545 SourceLocation(), SourceLocation(), 0, 1) {}
1548 /// \brief Creates directive.
1550 /// \param C AST context.
1551 /// \param StartLoc Starting location of the directive kind.
1552 /// \param EndLoc Ending Location of the directive.
1553 /// \param AssociatedStmt Statement, associated with the directive.
1555 static OMPOrderedDirective *Create(const ASTContext &C,
1556 SourceLocation StartLoc,
1557 SourceLocation EndLoc,
1558 Stmt *AssociatedStmt);
1560 /// \brief Creates an empty directive.
1562 /// \param C AST context.
1564 static OMPOrderedDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1566 static bool classof(const Stmt *T) {
1567 return T->getStmtClass() == OMPOrderedDirectiveClass;
1571 /// \brief This represents '#pragma omp atomic' directive.
1574 /// #pragma omp atomic capture
1576 /// In this example directive '#pragma omp atomic' has clause 'capture'.
1578 class OMPAtomicDirective : public OMPExecutableDirective {
1579 friend class ASTStmtReader;
1580 /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
1581 /// have atomic expressions of forms
1583 /// x = x binop expr;
1584 /// x = expr binop x;
1586 /// This field is true for the first form of the expression and false for the
1587 /// second. Required for correct codegen of non-associative operations (like
1589 bool IsXLHSInRHSPart;
1590 /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
1591 /// have atomic expressions of forms
1593 /// v = x; <update x>;
1594 /// <update x>; v = x;
1596 /// This field is true for the first(postfix) form of the expression and false
1598 bool IsPostfixUpdate;
1600 /// \brief Build directive with the given start and end location.
1602 /// \param StartLoc Starting location of the directive kind.
1603 /// \param EndLoc Ending location of the directive.
1604 /// \param NumClauses Number of clauses.
1606 OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1607 unsigned NumClauses)
1608 : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
1609 StartLoc, EndLoc, NumClauses, 5),
1610 IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
1612 /// \brief Build an empty directive.
1614 /// \param NumClauses Number of clauses.
1616 explicit OMPAtomicDirective(unsigned NumClauses)
1617 : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
1618 SourceLocation(), SourceLocation(), NumClauses,
1620 IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
1622 /// \brief Set 'x' part of the associated expression/statement.
1623 void setX(Expr *X) { *std::next(child_begin()) = X; }
1624 /// \brief Set helper expression of the form
1625 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
1626 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
1627 void setUpdateExpr(Expr *UE) { *std::next(child_begin(), 2) = UE; }
1628 /// \brief Set 'v' part of the associated expression/statement.
1629 void setV(Expr *V) { *std::next(child_begin(), 3) = V; }
1630 /// \brief Set 'expr' part of the associated expression/statement.
1631 void setExpr(Expr *E) { *std::next(child_begin(), 4) = E; }
1634 /// \brief Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
1635 /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
1636 /// detailed description of 'x', 'v' and 'expr').
1638 /// \param C AST context.
1639 /// \param StartLoc Starting location of the directive kind.
1640 /// \param EndLoc Ending Location of the directive.
1641 /// \param Clauses List of clauses.
1642 /// \param AssociatedStmt Statement, associated with the directive.
1643 /// \param X 'x' part of the associated expression/statement.
1644 /// \param V 'v' part of the associated expression/statement.
1645 /// \param E 'expr' part of the associated expression/statement.
1646 /// \param UE Helper expression of the form
1647 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
1648 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
1649 /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the
1651 /// \param IsPostfixUpdate true if original value of 'x' must be stored in
1652 /// 'v', not an updated one.
1653 static OMPAtomicDirective *
1654 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1655 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V,
1656 Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate);
1658 /// \brief Creates an empty directive with the place for \a NumClauses
1661 /// \param C AST context.
1662 /// \param NumClauses Number of clauses.
1664 static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
1665 unsigned NumClauses, EmptyShell);
1667 /// \brief Get 'x' part of the associated expression/statement.
1668 Expr *getX() { return cast_or_null<Expr>(*std::next(child_begin())); }
1669 const Expr *getX() const {
1670 return cast_or_null<Expr>(*std::next(child_begin()));
1672 /// \brief Get helper expression of the form
1673 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
1674 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
1675 Expr *getUpdateExpr() {
1676 return cast_or_null<Expr>(*std::next(child_begin(), 2));
1678 const Expr *getUpdateExpr() const {
1679 return cast_or_null<Expr>(*std::next(child_begin(), 2));
1681 /// \brief Return true if helper update expression has form
1682 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
1683 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
1684 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
1685 /// \brief Return true if 'v' expression must be updated to original value of
1686 /// 'x', false if 'v' must be updated to the new value of 'x'.
1687 bool isPostfixUpdate() const { return IsPostfixUpdate; }
1688 /// \brief Get 'v' part of the associated expression/statement.
1689 Expr *getV() { return cast_or_null<Expr>(*std::next(child_begin(), 3)); }
1690 const Expr *getV() const {
1691 return cast_or_null<Expr>(*std::next(child_begin(), 3));
1693 /// \brief Get 'expr' part of the associated expression/statement.
1694 Expr *getExpr() { return cast_or_null<Expr>(*std::next(child_begin(), 4)); }
1695 const Expr *getExpr() const {
1696 return cast_or_null<Expr>(*std::next(child_begin(), 4));
1699 static bool classof(const Stmt *T) {
1700 return T->getStmtClass() == OMPAtomicDirectiveClass;
1704 /// \brief This represents '#pragma omp target' directive.
1707 /// #pragma omp target if(a)
1709 /// In this example directive '#pragma omp target' has clause 'if' with
1712 class OMPTargetDirective : public OMPExecutableDirective {
1713 friend class ASTStmtReader;
1714 /// \brief Build directive with the given start and end location.
1716 /// \param StartLoc Starting location of the directive kind.
1717 /// \param EndLoc Ending location of the directive.
1718 /// \param NumClauses Number of clauses.
1720 OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1721 unsigned NumClauses)
1722 : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
1723 StartLoc, EndLoc, NumClauses, 1) {}
1725 /// \brief Build an empty directive.
1727 /// \param NumClauses Number of clauses.
1729 explicit OMPTargetDirective(unsigned NumClauses)
1730 : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
1731 SourceLocation(), SourceLocation(), NumClauses,
1735 /// \brief Creates directive with a list of \a Clauses.
1737 /// \param C AST context.
1738 /// \param StartLoc Starting location of the directive kind.
1739 /// \param EndLoc Ending Location of the directive.
1740 /// \param Clauses List of clauses.
1741 /// \param AssociatedStmt Statement, associated with the directive.
1743 static OMPTargetDirective *
1744 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1745 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1747 /// \brief Creates an empty directive with the place for \a NumClauses
1750 /// \param C AST context.
1751 /// \param NumClauses Number of clauses.
1753 static OMPTargetDirective *CreateEmpty(const ASTContext &C,
1754 unsigned NumClauses, EmptyShell);
1756 static bool classof(const Stmt *T) {
1757 return T->getStmtClass() == OMPTargetDirectiveClass;
1761 /// \brief This represents '#pragma omp teams' directive.
1764 /// #pragma omp teams if(a)
1766 /// In this example directive '#pragma omp teams' has clause 'if' with
1769 class OMPTeamsDirective : public OMPExecutableDirective {
1770 friend class ASTStmtReader;
1771 /// \brief Build directive with the given start and end location.
1773 /// \param StartLoc Starting location of the directive kind.
1774 /// \param EndLoc Ending location of the directive.
1775 /// \param NumClauses Number of clauses.
1777 OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1778 unsigned NumClauses)
1779 : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
1780 StartLoc, EndLoc, NumClauses, 1) {}
1782 /// \brief Build an empty directive.
1784 /// \param NumClauses Number of clauses.
1786 explicit OMPTeamsDirective(unsigned NumClauses)
1787 : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
1788 SourceLocation(), SourceLocation(), NumClauses,
1792 /// \brief Creates directive with a list of \a Clauses.
1794 /// \param C AST context.
1795 /// \param StartLoc Starting location of the directive kind.
1796 /// \param EndLoc Ending Location of the directive.
1797 /// \param Clauses List of clauses.
1798 /// \param AssociatedStmt Statement, associated with the directive.
1800 static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1801 SourceLocation EndLoc,
1802 ArrayRef<OMPClause *> Clauses,
1803 Stmt *AssociatedStmt);
1805 /// \brief Creates an empty directive with the place for \a NumClauses
1808 /// \param C AST context.
1809 /// \param NumClauses Number of clauses.
1811 static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
1812 unsigned NumClauses, EmptyShell);
1814 static bool classof(const Stmt *T) {
1815 return T->getStmtClass() == OMPTeamsDirectiveClass;
1819 } // end namespace clang