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